From 2980aaa4cb587a0e4ca6b218d335815ceced7f09 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 12 Jul 2020 17:17:14 -0700 Subject: [PATCH 001/708] history/Credits: aeb's Hack Give an implied explanation for the seemingly odd copyright info in the source files and the run-time startup banner. The extra Hack version number, the release dates, and the newsgroup creation are from https://homepages.cwi.nl/~aeb/games/hack/hack.html which is the "Brouwer's /Hack/ page at CWI" external link near the end of Andries Brouwer's Wikipedia page. --- dat/history | 15 +++++++++++---- doc/Guidebook.mn | 21 ++++++++++++++++----- doc/Guidebook.tex | 26 +++++++++++++++++++------- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/dat/history b/dat/history index d1d6dd084..547103dd5 100644 --- a/dat/history +++ b/dat/history @@ -5,9 +5,14 @@ Behold, mortal, the origins of NetHack... Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. -Andries Brouwer did a major re-write, transforming Hack into a very different -game, and published (at least) three versions (1.0.1, 1.0.2, and 1.0.3) for -UNIX(tm) machines to the Usenet. +Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum +(now Centrum Wiskunde & Informatica), transforming Hack into a very different +game. He published the Hack source code for use on UNIX(tm) 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 it. Don G. Kneller ported Hack 1.0.3 to Microsoft(tm) C and MS-DOS(tm), producing PC HACK 1.01e, added support for DEC Rainbow graphics in version 1.03g, and @@ -20,7 +25,9 @@ producing ST Hack 1.03. 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. +and released NetHack versions 2.2 and 2.3. Like Hack, they were released by +posting their source code to Usenet where they remained available in various +archives accessible via ftp and uucp after expiring from the newsgroup. Later, Mike coordinated a major re-write of the game, heading a team which included Ken Arromdee, Jean-Christophe Collet, Steve Creps, Eric Hendrickson, diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 855c7974b..92149f78b 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.391 $ $NHDT-Date: 1594377460 2020/07/10 10:37:40 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.392 $ $NHDT-Date: 1594599425 2020/07/13 00:17:05 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -5428,11 +5428,19 @@ Main events in the course of the game development are described below: \fBJay Fenlason\fP wrote the original Hack, with help from \fBKenny Woodland\fP, \fBMike Thome\fP, and \fBJon Payne\fP. .pg -\fBAndries Brouwer\fP did a major re-write, transforming Hack into a -very different game, and published (at least) three versions (1.0.1, -1.0.2, and 1.0.3) for +\fBAndries Brouwer\fP did a major re-write while at +Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), +transforming Hack into a very different game. +He published the Hack source code for use on .UX -machines to the Usenet. +systems by posting that to Usenet +newsgroup \fInet.sources\fP (later renamed \fIcomp.sources\fP) +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 \fInet.games.hack\fP (later +renamed \fIrec.games.hack\fP, eventually replaced +by \fIrec.games.roguelike.nethack\fP) +was created for discussing it. .pg \fBDon G. Kneller\fP ported Hack 1.0.3 to Microsoft C and MS-DOS, producing PC HACK 1.01e, added support for DEC Rainbow graphics in version 1.03g, and went @@ -5447,6 +5455,9 @@ 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 Hack, they were released by posting their source code to Usenet where +they remained available in various archives accessible +via \fIftp\fP and \fIuucp\fP after expiring from the newsgroup. .pg Later, Mike coordinated a major re-write of the game, heading a team which included \fBKen Arromdee\fP, \fBJean-Christophe Collet\fP, diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 429fdbb4c..64edc17e7 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3323,7 +3323,7 @@ The default name and location of the configuration file varies on different operating systems.\\ %.lp "" -On Unix, Linux and Mac OS X it is \mbox{``.nethackrc''} in the user's home +On UNIX, Linux and Mac OS X it is \mbox{``.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.\\ @@ -5922,9 +5922,18 @@ Kenny Woodland}, {\it Mike Thome}, and {\it Jon Payne}. %.pg \medskip -\nd {\it Andries Brouwer\/} did a major re-write, transforming {\it Hack\/} -into a very different game, and published (at least) three versions (1.0.1, -1.0.2, and 1.0.3) for UNIX machines to the Usenet. +\nd {\it Andries Brouwer\/} did a major re-write while at +Stichting Mathematisch 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 {\it net.sources\/} (later renamed {\it 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 {\it net.games.hack\/} (later +renamed {\it rec.games.hack}, eventually replaced +by {\it rec.games.roguelike.nethack}) +was created for discussing it. %.pg \medskip @@ -5947,6 +5956,9 @@ incorporating many of the added features, and produced {\it NetHack\/} version 1.4 in 1987. He then coordinated a cast of thousands in enhancing and debugging {\it NetHack\/} 1.4 and released {\it NetHack\/} versions 2.2 and 2.3. +Like Hack, they were released by posting their source code to Usenet where +they remained available in various archives accessible +via {\it ftp\/} and {\it uucp\/} after expiring from the newsgroup. %.pg \medskip @@ -6238,8 +6250,8 @@ In January 2015, preparation began for the release of NetHack 3.6. %.pg \medskip -At the beginning of development for what would eventually get released -as 3.6.0, the {\it NetHack Development Team} consisted of {\it Warwick Allison}, +At the beginning of development for what would eventually get released as +3.6.0, the {\it NetHack Development Team} consisted of {\it Warwick Allison}, {\it Michael Allison}, {\it Ken Arromdee}, {\it David Cohrs}, {\it Jessie Collet}, {\it Ken Lorber}, {\it Dean Luick}, {\it Pat Rankin}, @@ -6265,7 +6277,7 @@ patches. Many bugs were fixed and some code was restructured. \medskip The {\it NetHack Development Team}, as well as {\it Steve VanDevender} and {\it Kevin Smolkowski}, ensured that {\it NetHack\/} 3.6 continued to -operate on various Unix flavors and maintained the X11 interface. +operate on various UNIX flavors and maintained the X11 interface. %.pg \medskip From 12498ffa446461f782681cd7833e6b2c5e796099 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 13 Jul 2020 01:58:44 -0700 Subject: [PATCH 002/708] fix github issue #372 - Wizard escaping dungeon If the Wizard fled up the stairs on level 1 and escaped the dungeon (which can only happen if he isn't carrying the Amulet or any of the invocation items), the number_of_wizards counter wasn't being decremented. If that was the only Wizard, he couldn't be brought back into play because he wasn't on the migrating monsters list, and he wouldn't appear on the Plane of Earth when the hero eventually went there. If that was one of two, the remaining one couldn't use Double Trouble anymore. (I'm not sure about Earth handling in that situation; should be moot now.) Wizard mode blessed genocide of "*" when the Wizard is on current level caused the same problem. Fix by keeping the number_of_wizards counter up to date if mongone() is called for the Wizard, handling both cases. Also, don't let the Wizard escape the dungeon unless he's one of two at the time, making the first case no longer possible. If wizard mode blessed genocide of "*" is used on the level where the quest nemesis is present, the killed-the-nemesis feedback will now be given. I'm not completely convinced that this was the right thing to do, but it only applies to wizard mode so may not matter. Fixes #372 --- doc/fixes37.0 | 6 +++++- src/mon.c | 9 ++++++++- src/muse.c | 8 ++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3589e3830..3c8e65b3d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.245 $ $NHDT-Date: 1594395803 2020/07/10 15:43:23 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ $NHDT-Date: 1594630713 2020/07/13 08:58:33 $ General Fixes and Modified Features ----------------------------------- @@ -217,6 +217,10 @@ the default engraving, epitaph, and bogus monster inserted by 'makedefs -s' when the corresponding file wasn't actually empty its first line ended up concatenated; default portion of the bad combined entry would be decrypted properly but the portion from the file's first line wouldn't +if the Wizard of Yendor fled up the stairs on level 1, the game would behave + as if he was still in play, but he wouldn't be on migrating monsters + list so couldn't be brought back and wouldn't appear on Plane of Earth + (stale non-zero value for context.no_of_wizards) Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index 96b12736a..beff43231 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1593306909 2020/06/28 01:15:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.338 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1594630713 2020/07/13 08:58:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.339 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1988,9 +1988,14 @@ struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */ /* to prevent an infinite relobj-flooreffects-hmon-killed loop */ mtmp->mtrapped = 0; mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */ + if (mtmp->iswiz) + wizdead(); + if (mtmp->data->msound == MS_NEMESIS) + nemdead(); if (mtmp->m_id == g.stealmid) thiefdead(); relobj(mtmp, 0, FALSE); + if (onmap || mtmp == g.level.monsters[0][0]) { if (mtmp->wormno) remove_worm(mtmp); @@ -2243,10 +2248,12 @@ register struct monst *mtmp; break; } } +#if 0 /* moved to m_detach() to kick in if mongone() happens */ if (mtmp->iswiz) wizdead(); if (mtmp->data->msound == MS_NEMESIS) nemdead(); +#endif if (mtmp->data == &mons[PM_MEDUSA]) record_achievement(ACH_MEDU); if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) diff --git a/src/muse.c b/src/muse.c index b0ff3427a..0bae9b866 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 muse.c $NHDT-Date: 1590870788 2020/05/30 20:33:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.6 muse.c $NHDT-Date: 1594630714 2020/07/13 08:58:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -938,8 +938,12 @@ struct monst *mtmp; * (mongone -> mdrop_special_objs) but we force any * monster who manages to acquire it or the invocation * tools to stick around instead of letting it escape. + * Don't let the Wizard escape even when not carrying + * anything of interest unless there are more than 1 + * of him. */ - if (mon_has_special(mtmp)) + if (mon_has_special(mtmp) + || (mtmp->iswiz && g.context.no_of_wizards < 2)) return 0; if (vismon) pline("%s escapes the dungeon!", Monnam(mtmp)); From a37975b6252440ded5a9e3a856423c1b805eb218 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 14 Jul 2020 04:55:53 -0700 Subject: [PATCH 003/708] fix pull request #367 - mind flayer psychic blast hitting a hidden monster didn't reveal that monster. It stayed hidden despite the feedback describing it as if it could be seen. The pull request's two line fix handled a monster's blast hitting another monster but left two related issues as-is: monster's blast hitting hidden poly'd hero left hero unrevealed and poly'd hero's blast left hidden monster unrevealed. Same code, different bug: poly'd hero's blast affected mindless monsters. This unhides an affected target before the message about it being hit rather than after. That would look better if preceded by a message describing the object (mimic or hides-under) or furniture (mimic) or empty spot (ceiling hider) as being or concealing a monster but I didn't put in sufficient effort to accomplish that. Fixes #367 Fixes #362 --- doc/fixes37.0 | 6 +++++- src/mon.c | 9 ++++++--- src/monmove.c | 28 +++++++++++++++++++++------- src/polyself.c | 17 ++++++++++++++--- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3c8e65b3d..e991745d2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ $NHDT-Date: 1594630713 2020/07/13 08:58:33 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ $NHDT-Date: 1594727746 2020/07/14 11:55:46 $ General Fixes and Modified Features ----------------------------------- @@ -221,6 +221,10 @@ if the Wizard of Yendor fled up the stairs on level 1, the game would behave as if he was still in play, but he wouldn't be on migrating monsters list so couldn't be brought back and wouldn't appear on Plane of Earth (stale non-zero value for context.no_of_wizards) +if a mind flayer's psychic blast targetted a hidden monster, feedback named + the monster but it wasn't brought out of hiding +hero poly'd into a mind flayer who used #monster to emit a psychic blast was + able to harm mindless monsters with it Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index beff43231..9ca2633aa 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1594630713 2020/07/13 08:58:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.339 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1594727746 2020/07/14 11:55:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.340 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3235,8 +3235,11 @@ register struct monst *mtmp; boolean via_attack; { mtmp->msleeping = 0; - if (M_AP_TYPE(mtmp)) { - seemimic(mtmp); + if (M_AP_TYPE(mtmp) != M_AP_NOTHING) { + /* mimics come out of hiding, but disguised Wizard doesn't + have to lose his disguise */ + if (M_AP_TYPE(mtmp) != M_AP_MONSTER) + seemimic(mtmp); } else if (g.context.forcefight && !g.context.mon_moving && mtmp->mundetected) { mtmp->mundetected = 0; diff --git a/src/monmove.c b/src/monmove.c index 7c03b2236..fe70cbd69 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1586091452 2020/04/05 12:57:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ */ +/* NetHack 3.6 monmove.c $NHDT-Date: 1594727747 2020/07/14 11:55:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -562,13 +562,27 @@ register struct monst *mtmp; && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) { pline("It feels quite soothing."); } else if (!u.uinvulnerable) { - register boolean m_sen = sensemon(mtmp); + int dmg; + boolean m_sen = sensemon(mtmp); if (m_sen || (Blind_telepat && rn2(2)) || !rn2(10)) { - int dmg; + /* hiding monsters are brought out of hiding when hit by + a psychic blast, so do the same for hiding poly'd hero */ + if (u.uundetected) { + u.uundetected = 0; + newsym(u.ux, u.uy); + } else if (U_AP_TYPE != M_AP_NOTHING + /* hero has no way to hide as monster but + check for that theoretical case anyway */ + && U_AP_TYPE != M_AP_MONSTER) { + g.youmonst.m_ap_type = M_AP_NOTHING; + g.youmonst.mappearance = 0; + newsym(u.ux, u.uy); + } pline("It locks on to your %s!", - m_sen ? "telepathy" : Blind_telepat ? "latent telepathy" - : "mind"); + m_sen ? "telepathy" + : Blind_telepat ? "latent telepathy" + : "mind"); /* note: hero is never mindless */ dmg = rnd(15); if (Half_spell_damage) dmg = (dmg + 1) / 2; @@ -587,13 +601,13 @@ register struct monst *mtmp; continue; if ((telepathic(m2->data) && (rn2(2) || m2->mblinded)) || !rn2(10)) { + /* wake it up first, to bring hidden monster out of hiding */ + wakeup(m2, FALSE); if (cansee(m2->mx, m2->my)) pline("It locks on to %s.", mon_nam(m2)); m2->mhp -= rnd(15); if (DEADMONSTER(m2)) monkilled(m2, "", AD_DRIN); - else - m2->msleeping = 0; } } } diff --git a/src/polyself.c b/src/polyself.c index b06f2287e..b6e22bc7a 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1583073991 2020/03/01 14:46:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.152 $ */ +/* NetHack 3.6 polyself.c $NHDT-Date: 1594727748 2020/07/14 11:55:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.154 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -1581,10 +1581,12 @@ dopoly() return 1; } +/* #monster for hero-as-mind_flayer giving psychic blast */ int domindblast() { struct monst *mtmp, *nmon; + int dmg; if (u.uen < 10) { You("concentrate but lack the energy to maintain doing so."); @@ -1605,12 +1607,21 @@ domindblast() continue; if (mtmp->mpeaceful) continue; + if (mindless(mtmp->data)) + continue; u_sen = telepathic(mtmp->data) && !mtmp->mcansee; if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) { + dmg = rnd(15); + /* wake it up first, to bring hidden monster out of hiding; + but in case it is currently peaceful, don't make it hostile + unless it will survive the psychic blast, otherwise hero + would avoid the penalty for killing it while peaceful */ + wakeup(mtmp, (dmg > mtmp->mhp) ? TRUE : FALSE); You("lock in on %s %s.", s_suffix(mon_nam(mtmp)), u_sen ? "telepathy" - : telepathic(mtmp->data) ? "latent telepathy" : "mind"); - mtmp->mhp -= rnd(15); + : telepathic(mtmp->data) ? "latent telepathy" + : "mind"); + mtmp->mhp -= dmg; if (DEADMONSTER(mtmp)) killed(mtmp); } From ee7fbc4a61052aecf1d8e23d7c7534e916a2f420 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 14 Jul 2020 05:43:51 -0700 Subject: [PATCH 004/708] mind flayer vs headless target When a mind flayer scores a hit against a headless target (or worm's tail), there's a message that says that the attack hits and that the target is unharmed. Since an ordinary mind flayer has 3 such attacks per turn and a master mind flayer has 5, it can become excessively verbose. This doesn't eliminate the attacks until a hit fails to do harm, so ordinary misses still get repeated if they happen first. Once a successful hit doesn't do anything, any remaining AT_TENT+AD_DRIN attacks are silently skipped. That way feedback isn't as verbose and mind flayers don't seem to be quite so stupid about using their tentacles when those won't work. Unfortunately they need to relearn the lesson every turn they attack. --- doc/fixes37.0 | 5 ++++- include/decl.h | 7 ++++--- src/decl.c | 9 +++++---- src/mhitm.c | 17 ++++++++++++++++- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index e991745d2..0fa488c33 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ $NHDT-Date: 1594727746 2020/07/14 11:55:46 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ $NHDT-Date: 1594730609 2020/07/14 12:43:29 $ General Fixes and Modified Features ----------------------------------- @@ -405,6 +405,9 @@ give feedback for '#chat' directed at walls add 'Sokoban' conduct, tracking the number of times the special Sokoban rules which incur luck penalties have been violated; don't report it unless/until Sokoban branch has been entered +reduce verbosity when a mind flayer attacks a headless monster; when a + tentacle-to-head attack hits but fails to accomplish anything skip + remaining attacks (mind flayer has 3, master mind flayer has 5) Platform- and/or Interface-Specific New Features diff --git a/include/decl.h b/include/decl.h index 94e4581d0..a626a76e0 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.h $NHDT-Date: 1593953331 2020/07/05 12:48:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.238 $ */ +/* NetHack 3.6 decl.h $NHDT-Date: 1594730609 2020/07/14 12:43:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -932,9 +932,10 @@ struct instance_globals { /* makemon.c */ /* mhitm.c */ - boolean vis; - boolean far_noise; long noisetime; + boolean far_noise; + boolean vis; + boolean skipdrin; /* mind flayer against headless target */ /* mhitu.c */ int mhitu_dieroll; diff --git a/src/decl.c b/src/decl.c index d390a2dbd..b57b7ba7f 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.c $NHDT-Date: 1593953345 2020/07/05 12:49:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.214 $ */ +/* NetHack 3.6 decl.c $NHDT-Date: 1594730611 2020/07/14 12:43:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.215 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -461,9 +461,10 @@ const struct instance_globals g_init = { /* makemon.c */ /* mhitm.c */ - UNDEFINED_VALUE, /* vis */ - UNDEFINED_VALUE, /* far_noise */ - UNDEFINED_VALUE, /* noisetime */ + 0L, /* noisetime */ + FALSE, /* far_noise */ + FALSE, /* vis */ + FALSE, /* skipdrin */ /* mhitu.c */ UNDEFINED_VALUE, /* mhitu_dieroll */ diff --git a/src/mhitm.c b/src/mhitm.c index 00628cc9a..50db4ba43 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitm.c $NHDT-Date: 1593614973 2020/07/01 14:49:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 3.6 mhitm.c $NHDT-Date: 1594730614 2020/07/14 12:43:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -345,12 +345,24 @@ register struct monst *magr, *mdef; */ magr->mlstmv = g.monstermoves; + /* controls whether a mind flayer uses all of its tentacle-for-DRIN + attacks; when fighting a headless monster, stop after the first + one because repeating the same failing hit (or even an ordinary + tentacle miss) is very verbose and makes the flayer look stupid */ + g.skipdrin = FALSE; + /* Now perform all attacks for the monster. */ for (i = 0; i < NATTK; i++) { res[i] = MM_MISS; mattk = getmattk(magr, mdef, i, res, &alt_attk); mwep = (struct obj *) 0; attk = 1; + /* reduce verbosity for mind flayer attacking creature without a + head (or worm's tail); this is similar to monster with multiple + attacks after a wildmiss against displaced or invisible hero */ + if (g.skipdrin && mattk->aatyp == AT_TENT && mattk->adtyp == AD_DRIN) + continue; + switch (mattk->aatyp) { case AT_WEAP: /* "hand to hand" attacks */ if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1) { @@ -1404,6 +1416,9 @@ int dieroll; pline("%s doesn't seem harmed.", Monnam(mdef)); /* Not clear what to do for green slimes */ tmp = 0; + /* don't bother with additional DRIN attacks since they wouldn't + be able to hit target on head either */ + g.skipdrin = TRUE; /* affects mattackm()'s attack loop */ break; } if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { From abe4db6e60b2f42a74a9616b31ebd13022a20ba0 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 14 Jul 2020 17:03:51 -0700 Subject: [PATCH 005/708] fix pull request #365 - monster max HP The recently added sanity check for monster maximum HP was giving false complaints when Nd8 monster had N mhpmax. Most noticeable for level 1 monsters (level 0 monsters use 1d4 instead of 0d8 and weren't affected) but possible for higher level ones if they were unlucky--from their own perspective--with all their d8 rolls. Give level N monsters a minimum of N+1 HP, so minimum of 2 for level 1 monsters, making 1/8 of those stronger. Same minimum for level 0 monsters, 25% of which will become stronger now. (The pull request's patch gave every Nd8 monster 1 extra HP; this only does so for Nd8 and 1d4 ones which have rolled lowest possible amount.) Also relax the sanity check so that existing to-be-3.7 save files don't continue to trigger sanity complaints for existing monsters that have the old minimum. Fixes 365 --- doc/fixes37.0 | 4 +++- src/makemon.c | 30 +++++++++++++++++++++--------- src/mon.c | 4 ++-- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 0fa488c33..5789b56c4 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ $NHDT-Date: 1594730609 2020/07/14 12:43:29 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ $NHDT-Date: 1594771373 2020/07/15 00:02:53 $ General Fixes and Modified Features ----------------------------------- @@ -287,6 +287,8 @@ only generate shop items on solid floor squares avoid gcc 10 warning by removing duplicate definition of 'head_engr' if a monster removed a corpse from an ice box, the corpse would never rot away monster creation on quest levels could make genocided creatures +enabling wizard mode 'sanity_check' option would complain about invalid mhpmax + value for level N monsters created with a d8 value of 1 for all N d8's tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display diff --git a/src/makemon.c b/src/makemon.c index b325c64a7..09b082ed8 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makemon.c $NHDT-Date: 1591178397 2020/06/03 09:59:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ +/* NetHack 3.6 makemon.c $NHDT-Date: 1594771378 2020/07/15 00:02:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.174 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -997,13 +997,16 @@ struct monst *mon; int mndx; { struct permonst *ptr = &mons[mndx]; + int basehp = 0; mon->m_lev = adj_lev(ptr); if (is_golem(ptr)) { + /* golems have a fixed amount of HP, varying by golem type */ mon->mhpmax = mon->mhp = golemhp(mndx); } else if (is_rider(ptr)) { /* we want low HP, but a high mlevel so they can attack well */ - mon->mhpmax = mon->mhp = d(10, 8); + basehp = 10; /* minimum is 1 per false (weaker) level */ + mon->mhpmax = mon->mhp = d(basehp, 8); } else if (ptr->mlevel > 49) { /* "special" fixed hp monster * the hit points are encoded in the mlevel in a somewhat strange @@ -1012,17 +1015,26 @@ int mndx; mon->mhpmax = mon->mhp = 2 * (ptr->mlevel - 6); mon->m_lev = mon->mhp / 4; /* approximation */ } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) { - /* adult dragons */ - mon->mhpmax = mon->mhp = - (int) (In_endgame(&u.uz) - ? (8 * mon->m_lev) - : (4 * mon->m_lev + d((int) mon->m_lev, 4))); + /* adult dragons; N*(4+rnd(4)) before endgame, N*8 once there */ + basehp = (int) mon->m_lev; /* not really applicable; isolates cast */ + mon->mhpmax = mon->mhp = In_endgame(&u.uz) ? (8 * basehp) + : (4 * basehp + d(basehp, 4)); } else if (!mon->m_lev) { + basehp = 1; /* minimum is 1, increased to 2 below */ mon->mhpmax = mon->mhp = rnd(4); } else { - mon->mhpmax = mon->mhp = d((int) mon->m_lev, 8); + basehp = (int) mon->m_lev; /* minimum possible is one per level */ + mon->mhpmax = mon->mhp = d(basehp, 8); if (is_home_elemental(ptr)) - mon->mhpmax = (mon->mhp *= 3); + mon->mhpmax = (mon->mhp *= 3); /* leave 'basehp' as-is */ + } + + /* if d(X,8) rolled a 1 all X times, give a boost; + most beneficial for level 0 and level 1 monsters, making mhpmax + and starting mhp always be at least 2 */ + if (mon->mhpmax == basehp) { + mon->mhpmax += 1; + mon->mhp = mon->mhpmax; } } diff --git a/src/mon.c b/src/mon.c index 9ca2633aa..901797938 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1594727746 2020/07/14 11:55:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.340 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1594771374 2020/07/15 00:02:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -59,7 +59,7 @@ const char *msg; /* check before DEADMONSTER() because dead monsters should still have sane mhpmax */ if (mtmp->mhpmax < 1 - || mtmp->mhpmax < (int) mtmp->m_lev + 1 + || mtmp->mhpmax < (int) mtmp->m_lev || mtmp->mhp > mtmp->mhpmax) impossible( "%s: level %d monster #%u [%s] has %d cur HP, %d max HP", From d1d956aa5661477e7ad422d13ea15ba5355ab4a9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 15 Jul 2020 20:46:18 -0400 Subject: [PATCH 006/708] from cron-daily - doc/Guidebook.txt --- doc/Guidebook.txt | 412 +++++++++++++++++++++++----------------------- 1 file changed, 206 insertions(+), 206 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index ad9ddff17..3bd5af125 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -6179,9 +6179,15 @@ Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write, transforming Hack into - a very different game, and published (at least) three versions - (1.0.1, 1.0.2, and 1.0.3) for UNIX machines to the Usenet. + Andries Brouwer did a major re-write while at Stichting + Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- + forming 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 ver- + sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- + nally 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, producing PC HACK 1.01e, added support for DEC Rainbow graphics @@ -6189,13 +6195,7 @@ sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion numbers, not contemporary NetHack ones). - 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, - 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 NetHack 3.7 July 9, 2020 @@ -6208,60 +6208,60 @@ - 2.2 and 2.3. + R. Black ported PC HACK 3.51 to Lattice C and the Atari + 520/1040ST, producing ST Hack 1.03. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + 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 Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the + newsgroup. + + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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. Along with various other Dungeoneers, they continued - to enhance the PC, Macintosh, and Amiga ports through the later + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported - NetHack 3.1 to the PC. - - Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, 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 de- - velopment, Bart House added a Think C port. - - Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua NetHack 3.7 July 9, 2020 @@ -6274,60 +6274,60 @@ - Delahunty, was responsible for the VMS version of NetHack 3.1. + NetHack 3.1 to the PC. + + Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike + Engber, 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 de- + velopment, Bart House added a Think C port. + + Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 + Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor 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 ob- + 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. - During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and - made these "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 cast- - ing system with the Wizard Patch. Warwick Allison also ported NetHack 3.7 July 9, 2020 @@ -6340,61 +6340,61 @@ + During the lifespan of NetHack 3.1 and 3.2, several enthusi- + asts of the game added their own modifications to the game and + made these "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 cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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 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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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 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 NetHack runs on: - - NetHack 3.7 July 9, 2020 @@ -6406,27 +6406,37 @@ + 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 NetHack runs on: + Pat Rankin maintained 3.4 for VMS. - Michael Allison maintained NetHack 3.4 for the MS-DOS plat- + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows 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 + 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 + 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 af- @@ -6435,31 +6445,21 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 Development 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. - - 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 + velopment 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 NetHack 3.7 July 9, 2020 @@ -6472,60 +6472,60 @@ - Warwick Allison, Michael Allison, Ken Arromdee, David Cohrs, - Jessie Collet, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the + and never used in an official NetHack release. An announcement + was posted on the NetHack Development 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. + + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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 en- - hancements 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 May 2019. - - NetHack 3.6.3 was released on December 5, 2019 containing - over 190 bug fixes to NetHack 3.6.2. NetHack 3.7 July 9, 2020 @@ -6538,10 +6538,21 @@ + In early May 2019, another 320 bug fixes along with some en- + hancements 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 May 2019. + + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6553,19 +6564,19 @@ 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6580,17 +6591,6 @@ 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 @@ -6604,6 +6604,17 @@ + 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 @@ -6623,7 +6634,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6639,17 +6650,6 @@ - - - - - - - - - - - From eab7a12b772dd16fdace7e09160fab3c3a3e7517 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 16 Jul 2020 19:57:20 -0400 Subject: [PATCH 007/708] macosx10.10-qt follow-up bit to 3073a588 --- sys/unix/hints/macosx10.10-qt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index 865c2d20a..7391291bb 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -117,8 +117,8 @@ CFLAGS += -DQT_GRAPHICS -DNOUSER_SOUNDS CFLAGS += $(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) LINK=$(CXX) -WINSRC += $(WINQT4SRC) -WINOBJ0 += $(WINQT4OBJ) +WINSRC += $(WINQTSRC) +WINOBJ0 += $(WINQTOBJ) VARDATND += rip.xpm MOC = moc From 84b598e4895a3c7a8299dff3949e1acd22e1c8c8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 16 Jul 2020 22:20:23 -0400 Subject: [PATCH 008/708] get rid of some shadowed variable warnings with Qt under OSX MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In file included from ../win/Qt/qt_bind.cpp:20: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:3: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGuiDepends:3: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/QtCore:4: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qglobal.h:1302: /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qflags.h:121:41: warning: declaration shadows a variable in the global namespace [-Wshadow] Q_DECL_CONSTEXPR inline QFlags(Enum flags) noexcept : i(Int(flags)) {} ^ […] ../include/flag.h:390:29: note: previous declaration is here extern NEARDATA struct flag flags; ^ In file included from ../win/Qt/qt_click.cpp:18: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:3: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGuiDepends:3: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/QtCore:36: /usr/local/Cellar/qt/5.15.0/lib/QtCore.framework/Headers/qcache.h:191:15: warning: declaration shadows a variable in the global namespace [-Wshadow] Node *u = n; ^ ../include/decl.h:219:23: note: previous declaration is here E NEARDATA struct you u; ^ […] In file included from ../win/Qt/qt_click.cpp:18: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:5: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h:45: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qtextlayout.h:47: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qcolor.h:44: /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qrgb.h:66:46: warning: declaration shadows a variable in the global namespace [-Wshadow] inline Q_DECL_CONSTEXPR QRgb qRgb(int r, int g, int b)// set RGB value ^ ../include/decl.h:1208:27: note: previous declaration is here E struct instance_globals g; ^ […] In file included from ../win/Qt/qt_glyph.cpp:21: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/QtGui:5: In file included from /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qabstracttextdocumentlayout.h:48: /usr/local/Cellar/qt/5.15.0/lib/QtGui.framework/Headers/qpalette.h:107:49: warning: declaration shadows a variable in the global namespace [-Wshadow] inline void setCurrentColorGroup(ColorGroup cg) { data.current_group = cg; } ^ ../include/decl.h:1216:30: note: previous declaration is here E const struct const_globals cg; ^ --- include/config.h | 1 + win/Qt/qt_bind.cpp | 2 ++ win/Qt/qt_click.cpp | 2 ++ win/Qt/qt_delay.cpp | 2 ++ win/Qt/qt_glyph.cpp | 2 ++ win/Qt/qt_icon.cpp | 2 ++ win/Qt/qt_inv.cpp | 2 ++ win/Qt/qt_key.cpp | 5 ++++- win/Qt/qt_line.cpp | 2 ++ win/Qt/qt_main.cpp | 2 ++ win/Qt/qt_map.cpp | 2 ++ win/Qt/qt_menu.cpp | 2 ++ win/Qt/qt_msg.cpp | 2 ++ win/Qt/qt_plsel.cpp | 2 ++ win/Qt/qt_redef.h | 19 +++++++++++++++++++ win/Qt/qt_rip.cpp | 2 ++ win/Qt/qt_set.cpp | 2 ++ win/Qt/qt_stat.cpp | 2 ++ win/Qt/qt_streq.cpp | 2 ++ win/Qt/qt_svsel.cpp | 2 ++ win/Qt/qt_undef.h | 17 +++++++++++++++++ win/Qt/qt_win.cpp | 2 ++ win/Qt/qt_xcmd.cpp | 2 ++ win/Qt/qt_yndlg.cpp | 2 ++ 24 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 win/Qt/qt_redef.h create mode 100644 win/Qt/qt_undef.h diff --git a/include/config.h b/include/config.h index 7083a09bf..492ff2bfc 100644 --- a/include/config.h +++ b/include/config.h @@ -96,6 +96,7 @@ #endif #ifdef QT_GRAPHICS +#include "../win/Qt/qt_redef.h" #ifndef DEFAULT_WC_TILED_MAP #define DEFAULT_WC_TILED_MAP /* Default to tiles if users doesn't say \ wc_ascii_map */ diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index cb875f115..ca34f5135 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -17,6 +17,7 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #include #if QT_VERSION >= 0x050000 @@ -25,6 +26,7 @@ extern "C" { #else #include #endif +#include "qt_redef.h" #include "qt_bind.h" #include "qt_click.h" #ifdef TIMED_DELAY diff --git a/win/Qt/qt_click.cpp b/win/Qt/qt_click.cpp index 6cee16258..30656264e 100644 --- a/win/Qt/qt_click.cpp +++ b/win/Qt/qt_click.cpp @@ -15,7 +15,9 @@ #undef min #undef max +#include "qt_undef.h" #include +#include "qt_redef.h" #include "qt_click.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_delay.cpp b/win/Qt/qt_delay.cpp index 1728b3702..592bc23cb 100644 --- a/win/Qt/qt_delay.cpp +++ b/win/Qt/qt_delay.cpp @@ -15,7 +15,9 @@ #undef min #undef max +#include "qt_undef.h" #include +#include "qt_redef.h" #include "qt_delay.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index a3e4f24ef..88349b9ee 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -18,10 +18,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_glyph.h" #include "qt_set.h" #include "qt_str.h" diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 160fc7e10..bcbc529ae 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_icon.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index be31d536e..3bb6cb55b 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -18,10 +18,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_inv.h" #include "qt_glyph.h" #include "qt_set.h" diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index 2a43f7c85..aa48741c1 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -15,7 +15,9 @@ #undef min #undef max +#include "qt_undef.h" #include +#include "qt_redef.h" #include "qt_key.h" namespace nethack_qt_ { @@ -28,9 +30,10 @@ NetHackQtKeyBuffer::NetHackQtKeyBuffer() : bool NetHackQtKeyBuffer::Empty() const { return in==out; } bool NetHackQtKeyBuffer::Full() const { return (in+1)%maxkey==out; } -void NetHackQtKeyBuffer::Put(int k, int a, int state) +void NetHackQtKeyBuffer::Put(int k, int a, int kbstate) { if ( Full() ) return; // Safety + nhUse(kbstate); key[in]=k; ascii[in]=a; in=(in+1)%maxkey; diff --git a/win/Qt/qt_line.cpp b/win/Qt/qt_line.cpp index 6374bea3f..790d72a42 100644 --- a/win/Qt/qt_line.cpp +++ b/win/Qt/qt_line.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_line.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index b27b1067c..b86f85f31 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -17,10 +17,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_main.h" #include "qt_main.moc" #include "qt_bind.h" diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 74d30b3c8..d32ebfbf0 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -17,10 +17,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_map.h" #include "qt_map.moc" #include "qt_click.h" diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index b959ad5d0..76b1aa2b5 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -17,10 +17,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_menu.h" #include "qt_menu.moc" #include "qt_glyph.h" diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index 516e992df..9cf789d96 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -17,10 +17,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_msg.h" #include "qt_msg.moc" #include "qt_map.h" diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index c77203bec..8598bbd81 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -17,10 +17,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_plsel.h" #include "qt_plsel.moc" #include "qt_bind.h" diff --git a/win/Qt/qt_redef.h b/win/Qt/qt_redef.h new file mode 100644 index 000000000..5e6c15e4a --- /dev/null +++ b/win/Qt/qt_redef.h @@ -0,0 +1,19 @@ +#if defined(QT_GRAPHICS) +#if defined(MACOSX) + +/* + * The following conflict with Qt header files so after + * undefing them in qt_undef.h, we redefine them back to + * the non-conflicting names again in here, presumably + * right after the Qt header files with the conflicts have + * been included. + */ + +#define u NETHACK_u +#define flags NETHACK_flags +#define g NETHACK_g +#define cg NETHACK_cg + +#endif /* MACOSX */ +#endif /* QT_GRAPHICS */ + diff --git a/win/Qt/qt_rip.cpp b/win/Qt/qt_rip.cpp index cbe795f85..c95089378 100644 --- a/win/Qt/qt_rip.cpp +++ b/win/Qt/qt_rip.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_rip.h" #include "qt_bind.h" #include "qt_str.h" diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index 2ac70fd9d..8748f5159 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_set.h" #include "qt_set.moc" #include "qt_glyph.h" diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 5e6918f00..c6f4ab737 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -17,10 +17,12 @@ extern "C" { #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_stat.h" #include "qt_stat.moc" #include "qt_set.h" diff --git a/win/Qt/qt_streq.cpp b/win/Qt/qt_streq.cpp index c489e5800..419aba8cc 100644 --- a/win/Qt/qt_streq.cpp +++ b/win/Qt/qt_streq.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_streq.h" #include "qt_str.h" diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 6950afd79..2b429cb98 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_svsel.h" #include "qt_bind.h" #include "qt_str.h" diff --git a/win/Qt/qt_undef.h b/win/Qt/qt_undef.h new file mode 100644 index 000000000..9b98e7737 --- /dev/null +++ b/win/Qt/qt_undef.h @@ -0,0 +1,17 @@ +#if defined(QT_GRAPHICS) +#if defined(MACOSX) + +/* + * The following conflict with Qt header files so we + * undef them in here, then redef them using qt_redef.h + * after the Qt includes. + */ + +#undef u +#undef flags +#undef g +#undef cg + +#endif /* MACOSX */ +#endif /* QT_GRAPHICS */ + diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 8c4ecac04..dbd756bf3 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -57,10 +57,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_win.h" #include "qt_bind.h" #include "qt_click.h" diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index a994d4eae..4aeffe98e 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -16,10 +16,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_xcmd.h" #include "qt_xcmd.moc" #include "qt_bind.h" diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 8d1caf400..55d31e67b 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -15,10 +15,12 @@ #undef min #undef max +#include "qt_undef.h" #include #if QT_VERSION >= 0x050000 #include #endif +#include "qt_redef.h" #include "qt_yndlg.h" #include "qt_yndlg.moc" #include "qt_str.h" From 74e0be478a15170edda97f3c45d600f5bd4f78bf Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 17 Jul 2020 10:14:24 -0700 Subject: [PATCH 009/708] remove old bonesid workaround Noticed when the comment about "this can go away when compatibility with 3.6.x is no longer needed" was modified recently. Make it and the code it applied to go away. --- doc/fixes37.0 | 6 +++++- src/bones.c | 28 +++++++++++++--------------- src/files.c | 27 +++++++++++---------------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 5789b56c4..3a3d66001 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ $NHDT-Date: 1594771373 2020/07/15 00:02:53 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.250 $ $NHDT-Date: 1595006054 2020/07/17 17:14:14 $ General Fixes and Modified Features ----------------------------------- @@ -492,3 +492,7 @@ relocated unmaintained code to outdated folder, specifically sys/amiga, include/wceconf.h removed SYSFLAGS conditional code removed MFLOPPY conditional code +get rid of 3.6.1 workaround needed to retain compatibility with 3.6.0 bones + files after fix for 3.3.0 through 3.6.0 bug for invalid 'bonesid' + designation in bones of quest levels + diff --git a/src/bones.c b/src/bones.c index 21fc01534..90d29fd60 100644 --- a/src/bones.c +++ b/src/bones.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 bones.c $NHDT-Date: 1593953344 2020/07/05 12:49:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ +/* NetHack 3.6 bones.c $NHDT-Date: 1595006054 2020/07/17 17:14:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -531,8 +531,10 @@ struct obj *corpse; store_version(nhfp); store_savefileinfo(nhfp); if (nhfp->structlevel) { + /* if a bones pool digit is in use, it precedes the bonesid + string and isn't recorded in the file */ bwrite(nhfp->fd, (genericptr_t) &c, sizeof c); - bwrite(nhfp->fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nnn */ + bwrite(nhfp->fd, (genericptr_t) bonesid, (unsigned) c); /* DD.nn */ savefruitchn(nhfp); } update_mlstmv(); /* update monsters for eventual restoration */ @@ -585,22 +587,18 @@ getbones() } } if (nhfp->structlevel) { - mread(nhfp->fd, (genericptr_t) &c, sizeof c); /* length incl. '\0' */ - mread(nhfp->fd, (genericptr_t) oldbonesid, (unsigned) c); /* DD.nnn */ + /* if a bones pool digit is in use, it precedes the bonesid + string and wasn't recorded in the file */ + mread(nhfp->fd, (genericptr_t) &c, + sizeof c); /* length including terminating '\0' */ + mread(nhfp->fd, (genericptr_t) oldbonesid, + (unsigned) c); /* DD.nn or Qrrr.n for role rrr */ } - if (strcmp(bonesid, oldbonesid) != 0 - /* from 3.3.0 through 3.6.0, bones in the quest branch stored - a bogus bonesid in the file; 3.6.1 fixed that, but for - 3.6.0 bones to remain compatible, we need an extra test; - once compatibility with 3.6.x goes away, this can too - (we don't try to make this conditional upon the value of - VERSION_COMPATIBILITY) */ - && (strlen(bonesid) <= 2 - || strcmp(bonesid + 2, oldbonesid) != 0)) { + if (strcmp(bonesid, oldbonesid) != 0) { char errbuf[BUFSZ]; - Sprintf(errbuf, "This is bones level '%s', not '%s'!", oldbonesid, - bonesid); + Sprintf(errbuf, "This is bones level '%s', not '%s'!", + oldbonesid, bonesid); if (wizard) { pline1(errbuf); ok = FALSE; /* won't die of trickery */ diff --git a/src/files.c b/src/files.c index d106ed4f3..690f88580 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 files.c $NHDT-Date: 1593953349 2020/07/05 12:49:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ */ +/* NetHack 3.7 files.c $NHDT-Date: 1595006057 2020/07/17 17:14:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.316 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -686,12 +686,12 @@ d_level *lev; char *dptr; /* - * "bonD0.nn.le" = bones for level nn in the main dungeon; - * "bonM0.T.le" = bones for Minetown; - * "bonQBar.n.le" = bones for level n in the Barbarian quest; - * "bon3D0.nn.le" = \ - * "bon3M0.T.le" = > same as above, but for bones pool #3. - * "bon3QBar.n.le" = / + * "bonD0.nn" = bones for level nn in the main dungeon; + * "bonM0.T" = bones for Minetown; + * "bonQBar.n" = bones for level n in the Barbarian quest; + * "bon3D0.nn" = \ + * "bon3M0.T" = > same as above, but for bones pool #3. + * "bon3QBar.n" = / * * Return value for content validation skips "bon" and the * pool number (if present), making it feasible for the admin @@ -707,15 +707,9 @@ d_level *lev; Sprintf(eos(file), "%u", poolnum); } #endif - dptr = eos(file); /* this used to be after the following Sprintf() - and the return value was (dptr - 2) */ + dptr = eos(file); /* when this naming scheme was adopted, 'filecode' was one letter; - 3.3.0 turned it into a three letter string (via roles[] in role.c); - from that version through 3.6.0, 'dptr' pointed past the filecode - and the return value of (dptr - 2) was wrong for bones produced - in the quest branch, skipping the boneid character 'Q' and the - first letter of the role's filecode; bones loading still worked - because the bonesid used for validation had the same error */ + 3.3.0 turned it into a three letter string for quest levels */ Sprintf(dptr, "%c%s", g.dungeons[lev->dnum].boneid, In_quest(lev) ? g.urole.filecode : "0"); if ((sptr = Is_special(lev)) != 0) @@ -779,7 +773,8 @@ char errbuf[]; /* 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); + nhfp->fd = open(file, + O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, FCMASK); #else #ifdef MAC nhfp->fd = maccreat(file, BONE_TYPE); From f6b4306ce6464fdb5a604e4179f34aeffa938c7e Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 17 Jul 2020 18:37:07 -0400 Subject: [PATCH 010/708] quiet down some build warnings with Qt under OSX clang++ --- sys/unix/hints/macosx10.10-qt | 1 + win/Qt/qt_bind.cpp | 14 +++++++++----- win/Qt/qt_delay.cpp | 2 +- win/Qt/qt_line.cpp | 2 +- win/Qt/qt_main.cpp | 6 +++--- win/Qt/qt_map.cpp | 8 ++++---- win/Qt/qt_menu.cpp | 20 ++++++++++---------- win/Qt/qt_msg.cpp | 6 +++--- win/Qt/qt_plsel.cpp | 10 +++++----- win/Qt/qt_rip.cpp | 2 +- win/Qt/qt_set.cpp | 4 ++-- win/Qt/qt_stat.cpp | 4 ++-- win/Qt/qt_str.cpp | 2 +- win/Qt/qt_svsel.cpp | 2 +- win/Qt/qt_win.cpp | 20 ++++++++++---------- win/Qt/qt_yndlg.cpp | 2 +- 16 files changed, 55 insertions(+), 50 deletions(-) diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index 7391291bb..f63050543 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -114,6 +114,7 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT CFLAGS += -DQT_GRAPHICS -DNOUSER_SOUNDS +CFLAGS += -Wno-deprecated-declarations CFLAGS += $(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) LINK=$(CXX) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index ca34f5135..3da7089e2 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -370,7 +370,7 @@ void NetHackQtBind::qt_display_file(const char *filename, BOOLEAN_P must_exist) } } -void NetHackQtBind::qt_start_menu(winid wid, unsigned long mbehavior) +void NetHackQtBind::qt_start_menu(winid wid, unsigned long mbehavior UNUSED) { NetHackQtWindow* window=id_to_window[(int)wid]; window->StartMenu(); @@ -427,7 +427,7 @@ void NetHackQtBind::qt_cliparound_window(winid wid, int x, int y) NetHackQtWindow* window=id_to_window[(int)wid]; window->ClipAround(x,y); } -void NetHackQtBind::qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph,int bkglyph) +void NetHackQtBind::qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph,int bkglyph UNUSED) { /* TODO: bkglyph */ NetHackQtWindow* window=id_to_window[(int)wid]; @@ -681,7 +681,7 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) bool macro=false; for (int i=0; !macro && key_macro[i].key; i++) { if (key_macro[i].key==k - && ((key_macro[i].state&key_event->modifiers())==key_macro[i].state)) + && ((key_macro[i].state&key_event->modifiers()) == (unsigned int) key_macro[i].state)) { keybuffer.Put(key_macro[i].macro); macro=true; @@ -720,9 +720,9 @@ QFrame* NetHackQtBind::splash=0; QStringList *NetHackQtBind::msgs_strings; boolean NetHackQtBind::msgs_saved = false; boolean NetHackQtBind::msgs_initd = false; - +#if 0 static void Qt_positionbar(char *) {} - +#endif } // namespace nethack_qt_ struct window_procs Qt_procs = { @@ -804,7 +804,11 @@ struct window_procs Qt_procs = { }; #ifndef WIN32 +#if defined(USER_SOUNDS) && !defined(QT_NO_SOUND) extern "C" void play_usersound(const char* filename, int volume) +#else +extern "C" void play_usersound(const char* filename UNUSED, int volume UNUSED) +#endif { #ifdef USER_SOUNDS #ifndef QT_NO_SOUND diff --git a/win/Qt/qt_delay.cpp b/win/Qt/qt_delay.cpp index 592bc23cb..e3dbfbe3d 100644 --- a/win/Qt/qt_delay.cpp +++ b/win/Qt/qt_delay.cpp @@ -34,7 +34,7 @@ void NetHackQtDelay::wait() m_loop.exec(); } -void NetHackQtDelay::timerEvent(QTimerEvent* timer) +void NetHackQtDelay::timerEvent(QTimerEvent* timer UNUSED) { m_loop.exit(); killTimer(m_timer); diff --git a/win/Qt/qt_line.cpp b/win/Qt/qt_line.cpp index 790d72a42..f7aab6bb9 100644 --- a/win/Qt/qt_line.cpp +++ b/win/Qt/qt_line.cpp @@ -30,7 +30,7 @@ NetHackQtLineEdit::NetHackQtLineEdit() : { } -NetHackQtLineEdit::NetHackQtLineEdit(QWidget* parent, const char* name) : +NetHackQtLineEdit::NetHackQtLineEdit(QWidget* parent, const char* name UNUSED) : QLineEdit(parent) { } diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index b86f85f31..a8beea886 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -379,7 +379,7 @@ static const char * rest_xpm[] = { " .... ", " "}; /* XPM */ -static const char * cast_a_xpm[] = { +static const char * cast_a_xpm[] UNUSED = { "12 13 3 1", " c None", ". c #FFFF6DB60000", @@ -398,7 +398,7 @@ static const char * cast_a_xpm[] = { " . X X ", " . X X "}; /* XPM */ -static const char * cast_b_xpm[] = { +static const char * cast_b_xpm[] UNUSED = { "12 13 3 1", " c None", ". c #FFFF6DB60000", @@ -417,7 +417,7 @@ static const char * cast_b_xpm[] = { " . X X ", " . XXX "}; /* XPM */ -static const char * cast_c_xpm[] = { +static const char * cast_c_xpm[] UNUSED = { "12 13 3 1", " c None", ". c #FFFF6DB60000", diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index d32ebfbf0..1ebb3434c 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -529,9 +529,9 @@ void NetHackQtMapViewport::CursorTo(int x,int y) Changed(cursor.x(),cursor.y()); } -void NetHackQtMapViewport::PrintGlyph(int x,int y,int glyph) +void NetHackQtMapViewport::PrintGlyph(int x,int y,int theglyph) { - Glyph(x,y)=glyph; + Glyph(x,y)=theglyph; Changed(x,y); } @@ -580,7 +580,7 @@ void NetHackQtMapWindow2::clearMessages() messages_rect = QRect(); } -void NetHackQtMapWindow2::putMessage(int attr, const QString& text) +void NetHackQtMapWindow2::putMessage(int attr UNUSED, const QString& text) { if ( !messages.isEmpty() ) messages += "\n"; @@ -617,7 +617,7 @@ void NetHackQtMapWindow2::CursorTo(int x,int y) m_viewport->CursorTo(x, y); } -void NetHackQtMapWindow2::PutStr(int attr, const QString& text) +void NetHackQtMapWindow2::PutStr(int attr UNUSED, const QString& text UNUSED) { puts("unexpected PutStr in MapWindow"); } diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 76b1aa2b5..8ca4fde11 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -241,7 +241,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) // Determine column widths std::vector col_widths; - for (std::size_t i = 0; i < itemlist.size(); ++i) { + for (std::size_t i = 0; i < (size_t) itemlist.size(); ++i) { QStringList columns = itemlist[i].str.split("\t"); if (!itemlist[i].Selectable() && columns.size() == 1) { @@ -249,7 +249,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) // Assume this is a section header continue; } - for (std::size_t j = 0U; j < columns.size(); ++j) { + for (std::size_t j = 0U; j < (size_t) columns.size(); ++j) { int w = fm.width(columns[j] + " \t"); if (j >= col_widths.size()) { col_widths.push_back(w); @@ -260,12 +260,12 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) } // Pad each column to its column width - for (std::size_t i = 0U; i < itemlist.size(); ++i) { + for (std::size_t i = 0U; i < (size_t) itemlist.size(); ++i) { QTableWidgetItem *twi = table->item(i, 4); if (twi == NULL) { continue; } QString text = twi->text(); QStringList columns = text.split("\t"); - for (std::size_t j = 0U; j+1U < columns.size(); ++j) { + for (std::size_t j = 0U; j+1U < (size_t) columns.size(); ++j) { columns[j] += "\t"; int width = col_widths[j]; while (fm.width(columns[j]) < width) { @@ -396,7 +396,7 @@ void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) table->item(row, 4)->setFlags(Qt::ItemIsEnabled); WidenColumn(4, fm.width(text)); - if (mi.color != -1) { + if ((int) mi.color != -1) { twi->setForeground(colors[mi.color]); } @@ -497,7 +497,7 @@ void NetHackQtMenuWindow::keyPressEvent(QKeyEvent* event) InputCount(key); else { for (int i=0; isetFont(qt_settings->normalFixedFont()); @@ -752,7 +752,7 @@ void NetHackQtTextWindow::Display(bool block) exec(); } -void NetHackQtTextWindow::PutStr(int attr, const QString& text) +void NetHackQtTextWindow::PutStr(int attr UNUSED, const QString& text) { str_fixed=str_fixed || text.contains(" "); lines->addItem(text); diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index 9cf789d96..934a7be13 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -63,7 +63,7 @@ void NetHackQtMessageWindow::updateFont() map->setFont(qt_settings->normalFont()); } -void NetHackQtMessageWindow::Scroll(int dx, int dy) +void NetHackQtMessageWindow::Scroll(int dx UNUSED, int dy UNUSED) { //RLC Is this necessary? //RLC list->Scroll(dx,dy); @@ -81,7 +81,7 @@ void NetHackQtMessageWindow::ClearMessages() list->clear(); } -void NetHackQtMessageWindow::Display(bool block) +void NetHackQtMessageWindow::Display(bool block UNUSED) { if (changed) { list->repaint(); @@ -139,7 +139,7 @@ void NetHackQtMessageWindow::PutStr(int attr, const QString& text) #endif // ATR_BLINK not supported - if (list->count() >= ::iflags.msg_history) + if (list->count() >= (int) ::iflags.msg_history) delete list->item(0); list->addItem(text2); diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index 8598bbd81..2eefe96a8 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -44,7 +44,7 @@ static const char nh_attribution[] = "
NetHack %1" class NhPSListViewItem : public QTableWidgetItem { public: - NhPSListViewItem( QTableWidget* parent, const QString& name ) : + NhPSListViewItem( QTableWidget* parent UNUSED, const QString& name ) : QTableWidgetItem(name) { } @@ -140,7 +140,7 @@ public: } }; -NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks) : +NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) : QDialog(NetHackQtBind::mainWidget()), fully_specified_role(true) { @@ -184,8 +184,8 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks) : QButtonGroup *gendergroup = new QButtonGroup(this); QGroupBox* alignbox = new QGroupBox("Alignment",this); QButtonGroup *aligngroup = new QButtonGroup(this); - QVBoxLayout* vbgb = new QVBoxLayout(genderbox); - QVBoxLayout* vbab = new QVBoxLayout(alignbox); + QVBoxLayout* vbgb UNUSED = new QVBoxLayout(genderbox); + QVBoxLayout* vbab UNUSED = new QVBoxLayout(alignbox); char versionbuf[QBUFSZ]; QLabel* logo = new QLabel(QString(nh_attribution).arg(version_string(versionbuf)), this); @@ -414,7 +414,7 @@ void NetHackQtPlayerSelector::selectRole(int crow, int ccol, int prow, int pcol) setupOthers(); } -void NetHackQtPlayerSelector::selectRace(int crow, int ccol, int prow, int pcol) +void NetHackQtPlayerSelector::selectRace(int crow UNUSED, int ccol UNUSED, int prow, int pcol UNUSED) { int ra = race->currentRow(); int ro = role->currentRow(); diff --git a/win/Qt/qt_rip.cpp b/win/Qt/qt_rip.cpp index c95089378..adcb04f9d 100644 --- a/win/Qt/qt_rip.cpp +++ b/win/Qt/qt_rip.cpp @@ -71,7 +71,7 @@ QSize NetHackQtRIP::sizeHint() const return pixmap->size(); } -void NetHackQtRIP::paintEvent(QPaintEvent* event) +void NetHackQtRIP::paintEvent(QPaintEvent* event UNUSED) { if ( riplines ) { int pix_x=(width()-pixmap->width())/2; diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index 8748f5159..d44365ab2 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -41,7 +41,7 @@ namespace nethack_qt_ { #define TILEWMIN 6 #define TILEHMIN 6 -NetHackQtSettings::NetHackQtSettings(int w, int h) : +NetHackQtSettings::NetHackQtSettings(int w UNUSED, int h UNUSED) : settings(), tilewidth(this), tileheight(this), @@ -151,7 +151,7 @@ void NetHackQtSettings::toggleGlyphSize() whichsize.toggle(); } -void NetHackQtSettings::setGlyphSize(bool which) +void NetHackQtSettings::setGlyphSize(bool which UNUSED) { QSize n = QSize(tilewidth.value(),tileheight.value()); if ( othersize.isValid() ) { diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index c6f4ab737..13cb4a773 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -211,14 +211,14 @@ QWidget* NetHackQtStatusWindow::Widget() { return this; } void NetHackQtStatusWindow::Clear() { } -void NetHackQtStatusWindow::Display(bool block) +void NetHackQtStatusWindow::Display(bool block UNUSED) { } void NetHackQtStatusWindow::CursorTo(int,int y) { cursy=y; } -void NetHackQtStatusWindow::PutStr(int attr, const QString& text) +void NetHackQtStatusWindow::PutStr(int attr UNUSED, const QString& text UNUSED) { // do a complete update when line 0 is done (as per X11 fancy status) if (cursy==0) updateStats(); diff --git a/win/Qt/qt_str.cpp b/win/Qt/qt_str.cpp index fc9cd26d7..9450bd895 100644 --- a/win/Qt/qt_str.cpp +++ b/win/Qt/qt_str.cpp @@ -35,7 +35,7 @@ QString str_titlecase(const QString& str) QString nh_capitalize_words(const QString& str) { QStringList words = str.split(" "); - for (size_t i = 0; i < words.size(); ++i) { + for (size_t i = 0; i < (size_t) words.size(); ++i) { words[i] = str_titlecase(words[i]); } return words.join(" "); diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 2b429cb98..2a3aa5d8e 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -62,7 +62,7 @@ NetHackQtSavedGameSelector::NetHackQtSavedGameSelector(const char** saved) : QGroupBox* box = new QGroupBox("Saved Characters",this); QButtonGroup *bg = new QButtonGroup(this); vbl->addWidget(box); - QVBoxLayout *bgl = new QVBoxLayout(box); + QVBoxLayout *bgl UNUSED = new QVBoxLayout(box); connect(bg, SIGNAL(buttonPressed(int)), this, SLOT(done(int))); for (int i=0; saved[i]; i++) { QPushButton* b = new QPushButton(saved[i],box); diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index dbd756bf3..501e91b12 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -121,18 +121,18 @@ NetHackQtWindow::~NetHackQtWindow() // XXX Use "expected ..." for now, abort or default later. // void NetHackQtWindow::Clear() { puts("unexpected Clear"); } -void NetHackQtWindow::Display(bool block) { puts("unexpected Display"); } +void NetHackQtWindow::Display(bool block UNUSED) { puts("unexpected Display"); } bool NetHackQtWindow::Destroy() { return true; } -void NetHackQtWindow::CursorTo(int x,int y) { puts("unexpected CursorTo"); } -void NetHackQtWindow::PutStr(int attr, const QString& text) { puts("unexpected PutStr"); } +void NetHackQtWindow::CursorTo(int x UNUSED,int y UNUSED) { puts("unexpected CursorTo"); } +void NetHackQtWindow::PutStr(int attr UNUSED, const QString& text UNUSED) { puts("unexpected PutStr"); } void NetHackQtWindow::StartMenu() { puts("unexpected StartMenu"); } -void NetHackQtWindow::AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, unsigned itemflags) { puts("unexpected AddMenu"); } -void NetHackQtWindow::EndMenu(const QString& prompt) { puts("unexpected EndMenu"); } -int NetHackQtWindow::SelectMenu(int how, MENU_ITEM_P **menu_list) { puts("unexpected SelectMenu"); return 0; } -void NetHackQtWindow::ClipAround(int x,int y) { puts("unexpected ClipAround"); } -void NetHackQtWindow::PrintGlyph(int x,int y,int glyph) { puts("unexpected PrintGlyph"); } +void NetHackQtWindow::AddMenu(int glyph UNUSED, const ANY_P* identifier UNUSED, char ch UNUSED, char gch UNUSED, int attr UNUSED, + const QString& str UNUSED, unsigned itemflags UNUSED) { puts("unexpected AddMenu"); } +void NetHackQtWindow::EndMenu(const QString& prompt UNUSED) { puts("unexpected EndMenu"); } +int NetHackQtWindow::SelectMenu(int how UNUSED, MENU_ITEM_P **menu_list UNUSED) { puts("unexpected SelectMenu"); return 0; } +void NetHackQtWindow::ClipAround(int x UNUSED,int y UNUSED) { puts("unexpected ClipAround"); } +void NetHackQtWindow::PrintGlyph(int x UNUSED,int y UNUSED,int glyph UNUSED) { puts("unexpected PrintGlyph"); } //void NetHackQtWindow::PrintGlyphCompose(int x,int y,int,int) { puts("unexpected PrintGlyphCompose"); } -void NetHackQtWindow::UseRIP(int how, time_t when) { puts("unexpected UseRIP"); } +void NetHackQtWindow::UseRIP(int how UNUSED, time_t when UNUSED) { puts("unexpected UseRIP"); } } // namespace nethack_qt_ diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 55d31e67b..8e49cd673 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -184,7 +184,7 @@ char NetHackQtYnDialog::Exec() show(); char choice=0; char ch_esc=0; - for (uint i=0; i Date: Fri, 17 Jul 2020 20:27:32 -0400 Subject: [PATCH 011/708] update OSX hints/macosx10.10-qt VARDATND to include nhtiles.bmp Match it to the linux Qt VARDATND void NetHackQtWindow::CursorTo(int x,int y UNUSED) { puts("unexpected CursorTo"); } --- sys/unix/hints/macosx10.10-qt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index f63050543..c190364e7 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -120,7 +120,7 @@ WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Wi LINK=$(CXX) WINSRC += $(WINQTSRC) WINOBJ0 += $(WINQTOBJ) -VARDATND += rip.xpm +VARDATND += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm MOC = moc # XXX if /Developer/qt exists and QTDIR not set, use that From c9ea607e46581744aee3256deb279a7532a66fa8 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 18 Jul 2020 01:36:21 -0700 Subject: [PATCH 012/708] bring Unix 'make depend' up to date and run it. We need to do some about preserving the Makefiles as they were before the obsolete code went away, because many of the bits that that obsolete code depended on are now going away too. --- sys/unix/Makefile.src | 299 ++++++++++++++++-------------------------- 1 file changed, 113 insertions(+), 186 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index c7c955888..35381793f 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -165,7 +165,7 @@ SYSOBJ = ioctl.o unixmain.o unixtty.o unixunix.o unixres.o ../lib/lua/liblua.a # directories. The ones given below is the usual spot for linux systems. # The paths are for glibconfig.h and gnomesupport.h respectively. # -GNOMEINC=-I/usr/lib/glib/include -I/usr/lib/gnome-libs/include -I../win/gnome +#GNOMEINC=-I/usr/lib/glib/include -I/usr/lib/gnome-libs/include -I../win/gnome # flags for debugging: # CFLAGS = -g -I../include @@ -226,9 +226,13 @@ WINX11OBJ = Window.o dialogs.o winX.o winmap.o winmenu.o winmesg.o \ # # Files for a Qt 3 port (renamed since nethack 3.6.x) # -WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ - ../win/Qt3/qt3tableview.cpp -WINQT3OBJ = qt3_win.o qt3_clust.o qt3tableview.o tile.o +#WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ +# ../win/Qt3/qt3tableview.cpp +#WINQT3OBJ = qt3_win.o qt3_clust.o qt3tableview.o tile.o +# empty values for 'make depend' +WINQT3SRC = +WINQT3OBJ = + # # Files for a Qt 4 or 5 port # @@ -248,20 +252,28 @@ WINQTOBJ = qt_bind.o qt_click.o qt_clust.o qt_delay.o qt_glyph.o qt_icon.o \ # # Files for a Gnome port # -WINGNOMESRC = ../win/gnome/gnaskstr.c ../win/gnome/gnbind.c \ - ../win/gnome/gnglyph.c ../win/gnome/gnmain.c ../win/gnome/gnmap.c \ - ../win/gnome/gnmenu.c ../win/gnome/gnmesg.c ../win/gnome/gnopts.c \ - ../win/gnome/gnplayer.c ../win/gnome/gnsignal.c \ - ../win/gnome/gnstatus.c ../win/gnome/gntext.c ../win/gnome/gnyesno.c \ - ../win/gnome/gnworn.c -WINGNOMEOBJ = gnaskstr.o gnbind.o gnglyph.o gnmain.o gnmap.o gnmenu.o \ - gnmesg.o gnopts.o gnplayer.o gnsignal.o gnstatus.o gntext.o \ - gnyesno.o gnworn.o tile.o +#WINGNOMESRC = ../win/gnome/gnaskstr.c ../win/gnome/gnbind.c \ +# ../win/gnome/gnglyph.c ../win/gnome/gnmain.c ../win/gnome/gnmap.c \ +# ../win/gnome/gnmenu.c ../win/gnome/gnmesg.c ../win/gnome/gnopts.c \ +# ../win/gnome/gnplayer.c ../win/gnome/gnsignal.c \ +# ../win/gnome/gnstatus.c ../win/gnome/gntext.c ../win/gnome/gnyesno.c \ +# ../win/gnome/gnworn.c +#WINGNOMEOBJ = gnaskstr.o gnbind.o gnglyph.o gnmain.o gnmap.o gnmenu.o \ +# gnmesg.o gnopts.o gnplayer.o gnsignal.o gnstatus.o gntext.o \ +# gnyesno.o gnworn.o tile.o +# empty values for 'make depend' +WINGNOMESRC = +WINGNOMEOBJ = + # # Files for a Gem port -WINGEMSRC = ../win/gem/wingem.c ../win/gem/wingem1.c ../win/gem/load_img.c \ - ../win/gem/gr_rect.c tile.c -WINGEMOBJ = wingem.o wingem1.o load_img.o gr_rect.o tile.o +#WINGEMSRC = ../win/gem/wingem.c ../win/gem/wingem1.c ../win/gem/load_img.c \ +# ../win/gem/gr_rect.c tile.c +#WINGEMOBJ = wingem.o wingem1.o load_img.o gr_rect.o tile.o +# empty values for 'make depend' +WINGEMSRC = +WINGEMOBJ = + # # Files for a BeOS InterfaceKit port -- not ready for prime time WINBESRC = @@ -461,12 +473,12 @@ HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ windows.c wizard.c worm.c worn.c write.c zap.c # all operating-system-dependent .c (for dependencies and such) -SYSCSRC = ../sys/atari/tos.c ../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 ../sys/be/bemain.c + ../sys/unix/unixunix.c ../sys/unix/unixres.c SYSCXXSRC = ../sys/share/cppregex.cpp # generated source files (tile.c is handled separately via WINxxxSRC) @@ -730,11 +742,12 @@ depend: ../sys/unix/depend.awk \ # DO NOT DELETE THIS LINE OR CHANGE ANYTHING BEYOND IT # config.h timestamp -$(CONFIG_H): ../include/config.h ../include/patchlevel.h ../include/config1.h \ - ../include/tradstdc.h ../include/global.h ../include/coord.h \ - ../include/vmsconf.h ../include/system.h ../include/nhlua.h \ - ../include/unixconf.h ../include/micro.h ../include/pcconf.h \ - ../include/ntconf.h ../include/fnamesiz.h +$(CONFIG_H): ../include/config.h ../include/config1.h ../include/patchlevel.h \ + ../include/../win/Qt/qt_redef.h ../include/tradstdc.h \ + ../include/global.h ../include/coord.h ../include/vmsconf.h \ + ../include/system.h ../include/nhlua.h ../include/unixconf.h \ + ../include/pcconf.h ../include/micro.h ../include/ntconf.h \ + ../include/fnamesiz.h touch $(CONFIG_H) # hack.h timestamp $(HACK_H): ../include/hack.h $(CONFIG_H) ../include/lint.h ../include/align.h \ @@ -745,17 +758,14 @@ $(HACK_H): ../include/hack.h $(CONFIG_H) ../include/lint.h ../include/align.h \ ../include/wintype.h ../include/context.h ../include/rm.h \ ../include/botl.h ../include/rect.h ../include/region.h \ ../include/decl.h ../include/quest.h ../include/spell.h \ - ../include/color.h ../include/obj.h ../include/you.h \ - ../include/attrib.h ../include/monst.h ../include/mextra.h \ - ../include/skills.h ../include/onames.h ../include/timeout.h \ - ../include/trap.h ../include/flag.h ../include/vision.h \ - ../include/display.h ../include/engrave.h \ - ../include/winprocs.h ../include/sys.h ../include/wintty.h \ - ../include/trampoli.h + ../include/color.h ../include/obj.h ../include/engrave.h \ + ../include/you.h ../include/attrib.h ../include/monst.h \ + ../include/mextra.h ../include/skills.h ../include/onames.h \ + ../include/timeout.h ../include/trap.h ../include/flag.h \ + ../include/vision.h ../include/display.h ../include/winprocs.h \ + ../include/sys.h ../include/wintty.h ../include/trampoli.h touch $(HACK_H) # -tos.o: ../sys/atari/tos.c $(HACK_H) ../include/tcap.h - $(CC) $(CFLAGS) -c -o $@ ../sys/atari/tos.c pcmain.o: ../sys/share/pcmain.c $(HACK_H) ../include/dlb.h $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcmain.c pcsys.o: ../sys/share/pcsys.c $(HACK_H) @@ -780,8 +790,6 @@ unixunix.o: ../sys/unix/unixunix.c $(HACK_H) $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixunix.c unixres.o: ../sys/unix/unixres.c $(CONFIG_H) $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixres.c -bemain.o: ../sys/be/bemain.c $(HACK_H) ../include/dlb.h - $(CC) $(CFLAGS) -c -o $@ ../sys/be/bemain.c getline.o: ../win/tty/getline.c $(HACK_H) ../include/func_tab.h $(CC) $(CFLAGS) -c -o $@ ../win/tty/getline.c termcap.o: ../win/tty/termcap.c $(HACK_H) ../include/tcap.h @@ -841,195 +849,113 @@ wintext.o: ../win/X11/wintext.c $(HACK_H) ../include/winX.h ../include/xwindow.h winval.o: ../win/X11/winval.c $(HACK_H) ../include/winX.h $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winval.c tile.o: tile.c $(HACK_H) -gnaskstr.o: ../win/gnome/gnaskstr.c ../win/gnome/gnaskstr.h \ - ../win/gnome/gnmain.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnaskstr.c -gnbind.o: ../win/gnome/gnbind.c ../win/gnome/gnbind.h ../win/gnome/gnomeprv.h \ - $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h ../win/gnome/gnmain.h \ - ../win/gnome/gnmap.h ../win/gnome/gnmenu.h \ - ../win/gnome/gnplayer.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnglyph.h ../win/gnome/gnstatus.h \ - ../win/gnome/gntext.h ../win/gnome/gnmesg.h \ - ../win/gnome/gnyesno.h ../win/gnome/gnworn.h \ - ../win/gnome/gnaskstr.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnbind.c -gnglyph.o: ../win/gnome/gnglyph.c ../win/gnome/gnglyph.h $(CONFIG_H) \ - ../include/tile2x11.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnglyph.c -gnmain.o: ../win/gnome/gnmain.c ../win/gnome/gnmain.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnomeprv.h $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnbind.h ../win/gnome/gnmap.h \ - ../win/gnome/gnmenu.h ../win/gnome/gnplayer.h \ - ../win/gnome/gnstatus.h ../win/gnome/gntext.h \ - ../win/gnome/gnmesg.h ../win/gnome/gnyesno.h \ - ../win/gnome/gnworn.h ../win/gnome/gnopts.h ../include/date.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnmain.c -gnmap.o: ../win/gnome/gnmap.c ../win/gnome/gnmap.h $(CONFIG_H) \ - ../win/gnome/gnglyph.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnomeprv.h $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnmap.c -gnmenu.o: ../win/gnome/gnmenu.c ../win/gnome/gnmenu.h $(CONFIG_H) \ - ../win/gnome/gnomeprv.h $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h ../win/gnome/gnmain.h \ - ../win/gnome/gnbind.h ../win/gnome/gnmap.h \ - ../win/gnome/gnplayer.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnglyph.h ../win/gnome/gnstatus.h \ - ../win/gnome/gntext.h ../win/gnome/gnmesg.h \ - ../win/gnome/gnyesno.h ../win/gnome/gnworn.h \ - ../include/func_tab.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnmenu.c -gnmesg.o: ../win/gnome/gnmesg.c ../win/gnome/gnmesg.h $(CONFIG_H) \ - ../win/gnome/gnsignal.h ../win/gnome/gnomeprv.h $(HACK_H) \ - ../include/dlb.h ../include/winGnome.h ../win/gnome/gnglyph.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnmesg.c -gnopts.o: ../win/gnome/gnopts.c ../win/gnome/gnopts.h ../win/gnome/gnglyph.h \ - $(CONFIG_H) ../win/gnome/gnmain.h ../win/gnome/gnmap.h $(HACK_H) - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnopts.c -gnplayer.o: ../win/gnome/gnplayer.c ../win/gnome/gnplayer.h \ - ../win/gnome/gnmain.h $(HACK_H) - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnplayer.c -gnsignal.o: ../win/gnome/gnsignal.c ../win/gnome/gnsignal.h \ - ../win/gnome/gnomeprv.h $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnmain.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnsignal.c -gnstatus.o: ../win/gnome/gnstatus.c ../win/gnome/gnstatus.h $(CONFIG_H) \ - ../win/gnome/gnsignal.h ../win/gnome/gnomeprv.h $(HACK_H) \ - ../include/dlb.h ../include/winGnome.h \ - ../win/gnome/gnglyph.h ../win/gnome/gn_xpms.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnstatus.c -gntext.o: ../win/gnome/gntext.c ../win/gnome/gntext.h $(CONFIG_H) \ - ../win/gnome/gnmain.h ../win/gnome/gn_rip.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gntext.c -gnyesno.o: ../win/gnome/gnyesno.c ../win/gnome/gnbind.h \ - ../win/gnome/gnomeprv.h $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h ../win/gnome/gnmain.h \ - ../win/gnome/gnmap.h ../win/gnome/gnmenu.h \ - ../win/gnome/gnplayer.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnglyph.h ../win/gnome/gnstatus.h \ - ../win/gnome/gntext.h ../win/gnome/gnmesg.h \ - ../win/gnome/gnyesno.h ../win/gnome/gnworn.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnyesno.c -gnworn.o: ../win/gnome/gnworn.c ../win/gnome/gnworn.h $(CONFIG_H) \ - ../win/gnome/gnglyph.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnomeprv.h $(HACK_H) ../include/dlb.h \ - ../include/winGnome.h - $(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ ../win/gnome/gnworn.c -wingem.o: ../win/gem/wingem.c $(HACK_H) ../include/func_tab.h ../include/dlb.h \ - ../include/wingem.h - $(CC) $(CFLAGS) -c -o $@ ../win/gem/wingem.c -wingem1.o: ../win/gem/wingem1.c ../include/gem_rsc.h ../include/load_img.h \ - ../include/gr_rect.h ../include/wintype.h ../include/wingem.h - $(CC) $(CFLAGS) -c -o $@ ../win/gem/wingem1.c -load_img.o: ../win/gem/load_img.c ../include/load_img.h - $(CC) $(CFLAGS) -c -o $@ ../win/gem/load_img.c -gr_rect.o: ../win/gem/gr_rect.c ../include/gr_rect.h - $(CC) $(CFLAGS) -c -o $@ ../win/gem/gr_rect.c -tile.o: tile.c $(HACK_H) cppregex.o: ../sys/share/cppregex.cpp $(CXX) $(CXXFLAGS) -c -o $@ ../sys/share/cppregex.cpp -qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_bind.h \ - ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h \ - ../win/Qt/qt_delay.h ../win/Qt/qt_xcmd.h ../win/Qt/qt_key.h \ - ../win/Qt/qt_map.h ../win/Qt/qt_win.h ../win/Qt/qt_clust.h \ - ../win/Qt/qt_menu.h ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h \ - ../win/Qt/qt_plsel.h ../win/Qt/qt_svsel.h ../win/Qt/qt_set.h \ - ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h ../win/Qt/qt_streq.h \ - ../win/Qt/qt_line.h ../win/Qt/qt_yndlg.h ../win/Qt/qt_str.h \ - ../include/dlb.h +qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h ../win/Qt/qt_delay.h \ + ../win/Qt/qt_xcmd.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_menu.h \ + ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h ../win/Qt/qt_plsel.h \ + ../win/Qt/qt_svsel.h ../win/Qt/qt_set.h ../win/Qt/qt_stat.h \ + ../win/Qt/qt_icon.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_yndlg.h ../win/Qt/qt_str.h ../include/dlb.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_bind.cpp -qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_click.h +qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_click.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_click.cpp qt_clust.o: ../win/Qt/qt_clust.cpp ../win/Qt/qt_clust.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_clust.cpp -qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_delay.h +qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_delay.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) ../include/tile2x11.h \ - ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h + ../win/Qt/qt_undef.h ../win/Qt/qt_redef.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp -qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_icon.h +qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_icon.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp -qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_inv.h \ - ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h +qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp -qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_key.h +qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_key.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_key.cpp -qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_line.h +qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_line.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_line.cpp -qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) \ - ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h qt_main.moc \ - ../win/Qt/qt_bind.h ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h \ - ../win/Qt/qt_key.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ - ../win/Qt/qt_clust.h ../win/Qt/qt_msg.h ../win/Qt/qt_set.h \ - ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h ../win/Qt/qt_str.h \ - qt_kde0.moc +qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + qt_main.moc ../win/Qt/qt_bind.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_inv.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_msg.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h \ + ../win/Qt/qt_str.h qt_kde0.moc $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_main.cpp -qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ +qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_xpms.h ../win/Qt/qt_set.h \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp -qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_menu.h \ - ../win/Qt/qt_win.h ../win/Qt/qt_rip.h qt_menu.moc \ - ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_streq.h \ - ../win/Qt/qt_line.h ../win/Qt/qt_str.h +qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_rip.h qt_menu.moc ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp -qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ +qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ qt_msg.moc ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp -qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_plsel.h qt_plsel.moc \ +qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_plsel.h qt_plsel.moc \ ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_plsel.cpp -qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_rip.h \ - ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ - ../win/Qt/qt_str.h +qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_rip.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp -qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_set.h qt_set.moc \ +qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_set.h qt_set.moc \ ../win/Qt/qt_glyph.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp -qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_stat.h \ - ../win/Qt/qt_win.h ../win/Qt/qt_icon.h qt_stat.moc \ - ../win/Qt/qt_set.h ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h +qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_icon.h qt_stat.moc ../win/Qt/qt_set.h \ + ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_str.cpp -qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_streq.h \ - ../win/Qt/qt_line.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp -qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_svsel.h \ - ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ +qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp +qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp -qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_win.h \ - ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ - ../win/Qt/qt_click.h ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h \ - ../win/Qt/qt_key.h ../win/Qt/qt_icon.h ../win/Qt/qt_map.h \ - ../win/Qt/qt_clust.h ../win/Qt/qt_menu.h ../win/Qt/qt_rip.h \ - ../win/Qt/qt_msg.h ../win/Qt/qt_set.h +qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h ../win/Qt/qt_key.h \ + ../win/Qt/qt_icon.h ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ + ../win/Qt/qt_menu.h ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h \ + ../win/Qt/qt_set.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_win.cpp qt_xcmd.o: ../win/Qt/qt_xcmd.cpp $(HACK_H) ../include/func_tab.h \ - ../win/Qt/qt_xcmd.h qt_xcmd.moc ../win/Qt/qt_bind.h \ - ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h \ - ../win/Qt/qt_str.h + ../win/Qt/qt_undef.h ../win/Qt/qt_redef.h ../win/Qt/qt_xcmd.h \ + qt_xcmd.moc ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_xcmd.cpp -qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_yndlg.h qt_yndlg.moc \ +qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_undef.h \ + ../win/Qt/qt_redef.h ../win/Qt/qt_yndlg.h qt_yndlg.moc \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp -qt3_win.o: ../win/Qt3/qt3_win.cpp $(HACK_H) ../include/func_tab.h \ - ../include/dlb.h ../include/tile2x11.h \ - ../win/Qt3/qt3_win.h ../win/Qt3/qt3_clust.h \ - ../win/Qt3/qt3_kde0.h ../win/Qt3/qt3_xpms.h qt3_win.moc \ - qt3_kde0.moc qt3tableview.moc - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt3/qt3_win.cpp -qt3_clust.o: ../win/Qt3/qt3_clust.cpp ../win/Qt3/qt3_clust.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt3/qt3_clust.cpp -qt3tableview.o: ../win/Qt3/qt3tableview.cpp ../win/Qt3/qt3tableview.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt3/qt3tableview.cpp wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_chainin.c wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) @@ -1059,7 +985,8 @@ dog.o: dog.c $(HACK_H) dogmove.o: dogmove.c $(HACK_H) ../include/mfndpos.h dokick.o: dokick.c $(HACK_H) dothrow.o: dothrow.c $(HACK_H) -drawing.o: drawing.c $(CONFIG_H) +drawing.o: drawing.c $(CONFIG_H) ../include/color.h ../include/rm.h \ + ../include/objclass.h ../include/monsym.h dungeon.o: dungeon.c $(HACK_H) ../include/dgn_file.h ../include/dlb.h eat.o: eat.c $(HACK_H) end.o: end.c $(HACK_H) ../include/dlb.h From 9b580108809e4ff045f68f356153b48b43593634 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 18 Jul 2020 08:31:51 -0400 Subject: [PATCH 013/708] turn off clang -Wshadow when processing some qt headers removes recently added win/Qt/qt_undef.h and win/Qt/qt_redef.h adds win/Qt/qt_pre.h win/Qt/qt_post.h --- include/config.h | 1 - sys/unix/Makefile.src | 89 +++++++++++++++++++++---------------------- win/Qt/qt_bind.cpp | 4 +- win/Qt/qt_click.cpp | 4 +- win/Qt/qt_delay.cpp | 4 +- win/Qt/qt_glyph.cpp | 4 +- win/Qt/qt_icon.cpp | 4 +- win/Qt/qt_inv.cpp | 4 +- win/Qt/qt_key.cpp | 4 +- win/Qt/qt_line.cpp | 4 +- win/Qt/qt_main.cpp | 4 +- win/Qt/qt_map.cpp | 4 +- win/Qt/qt_menu.cpp | 4 +- win/Qt/qt_msg.cpp | 4 +- win/Qt/qt_plsel.cpp | 4 +- win/Qt/qt_post.h | 4 ++ win/Qt/qt_pre.h | 5 +++ win/Qt/qt_redef.h | 19 --------- win/Qt/qt_rip.cpp | 4 +- win/Qt/qt_set.cpp | 4 +- win/Qt/qt_stat.cpp | 4 +- win/Qt/qt_streq.cpp | 4 +- win/Qt/qt_svsel.cpp | 4 +- win/Qt/qt_undef.h | 17 --------- win/Qt/qt_win.cpp | 4 +- win/Qt/qt_xcmd.cpp | 4 +- win/Qt/qt_yndlg.cpp | 4 +- 27 files changed, 95 insertions(+), 124 deletions(-) create mode 100644 win/Qt/qt_post.h create mode 100644 win/Qt/qt_pre.h delete mode 100644 win/Qt/qt_redef.h delete mode 100644 win/Qt/qt_undef.h diff --git a/include/config.h b/include/config.h index 492ff2bfc..7083a09bf 100644 --- a/include/config.h +++ b/include/config.h @@ -96,7 +96,6 @@ #endif #ifdef QT_GRAPHICS -#include "../win/Qt/qt_redef.h" #ifndef DEFAULT_WC_TILED_MAP #define DEFAULT_WC_TILED_MAP /* Default to tiles if users doesn't say \ wc_ascii_map */ diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 35381793f..6b1da0794 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -743,11 +743,10 @@ depend: ../sys/unix/depend.awk \ # config.h timestamp $(CONFIG_H): ../include/config.h ../include/config1.h ../include/patchlevel.h \ - ../include/../win/Qt/qt_redef.h ../include/tradstdc.h \ - ../include/global.h ../include/coord.h ../include/vmsconf.h \ - ../include/system.h ../include/nhlua.h ../include/unixconf.h \ - ../include/pcconf.h ../include/micro.h ../include/ntconf.h \ - ../include/fnamesiz.h + ../include/tradstdc.h ../include/global.h ../include/coord.h \ + ../include/vmsconf.h ../include/system.h ../include/nhlua.h \ + ../include/unixconf.h ../include/pcconf.h ../include/micro.h \ + ../include/ntconf.h ../include/fnamesiz.h touch $(CONFIG_H) # hack.h timestamp $(HACK_H): ../include/hack.h $(CONFIG_H) ../include/lint.h ../include/align.h \ @@ -851,8 +850,8 @@ winval.o: ../win/X11/winval.c $(HACK_H) ../include/winX.h tile.o: tile.c $(HACK_H) cppregex.o: ../sys/share/cppregex.cpp $(CXX) $(CXXFLAGS) -c -o $@ ../sys/share/cppregex.cpp -qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ +qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h ../win/Qt/qt_delay.h \ ../win/Qt/qt_xcmd.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_menu.h \ @@ -861,86 +860,86 @@ qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_undef.h \ ../win/Qt/qt_icon.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_yndlg.h ../win/Qt/qt_str.h ../include/dlb.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_bind.cpp -qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_click.h +qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_click.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_click.cpp qt_clust.o: ../win/Qt/qt_clust.cpp ../win/Qt/qt_clust.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_clust.cpp -qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_delay.h +qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_delay.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) ../include/tile2x11.h \ - ../win/Qt/qt_undef.h ../win/Qt/qt_redef.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_glyph.h \ ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp -qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_icon.h +qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_icon.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp -qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ +qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ ../win/Qt/qt_set.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp -qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_key.h +qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_key.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_key.cpp -qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_line.h +qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_line.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_line.cpp -qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ +qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ qt_main.moc ../win/Qt/qt_bind.h ../win/Qt/qt_glyph.h \ ../win/Qt/qt_inv.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_msg.h \ ../win/Qt/qt_set.h ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h \ ../win/Qt/qt_str.h qt_kde0.moc $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_main.cpp -qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ +qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_xpms.h ../win/Qt/qt_set.h \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp -qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ +qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ ../win/Qt/qt_rip.h qt_menu.moc ../win/Qt/qt_glyph.h \ ../win/Qt/qt_set.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp -qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ +qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ qt_msg.moc ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp -qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_plsel.h qt_plsel.moc \ +qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_plsel.h qt_plsel.moc \ ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_plsel.cpp -qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_rip.h ../win/Qt/qt_bind.h \ +qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_rip.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp -qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_set.h qt_set.moc \ +qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_set.h qt_set.moc \ ../win/Qt/qt_glyph.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp -qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ +qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ ../win/Qt/qt_icon.h qt_stat.moc ../win/Qt/qt_set.h \ ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_str.cpp -qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ +qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp -qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ +qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp -qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ +qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h ../win/Qt/qt_key.h \ ../win/Qt/qt_icon.h ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ @@ -948,12 +947,12 @@ qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_undef.h \ ../win/Qt/qt_set.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_win.cpp qt_xcmd.o: ../win/Qt/qt_xcmd.cpp $(HACK_H) ../include/func_tab.h \ - ../win/Qt/qt_undef.h ../win/Qt/qt_redef.h ../win/Qt/qt_xcmd.h \ + ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_xcmd.h \ qt_xcmd.moc ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_xcmd.cpp -qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_undef.h \ - ../win/Qt/qt_redef.h ../win/Qt/qt_yndlg.h qt_yndlg.moc \ +qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_yndlg.h qt_yndlg.moc \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 3da7089e2..3f0c257fc 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -17,7 +17,7 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #include #if QT_VERSION >= 0x050000 @@ -26,7 +26,7 @@ extern "C" { #else #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_bind.h" #include "qt_click.h" #ifdef TIMED_DELAY diff --git a/win/Qt/qt_click.cpp b/win/Qt/qt_click.cpp index 30656264e..6b9c7b4da 100644 --- a/win/Qt/qt_click.cpp +++ b/win/Qt/qt_click.cpp @@ -15,9 +15,9 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include -#include "qt_redef.h" +#include "qt_post.h" #include "qt_click.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_delay.cpp b/win/Qt/qt_delay.cpp index e3dbfbe3d..803946aea 100644 --- a/win/Qt/qt_delay.cpp +++ b/win/Qt/qt_delay.cpp @@ -15,9 +15,9 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include -#include "qt_redef.h" +#include "qt_post.h" #include "qt_delay.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 88349b9ee..1e01adb9d 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -18,12 +18,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_glyph.h" #include "qt_set.h" #include "qt_str.h" diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index bcbc529ae..87dfac10f 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_icon.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 3bb6cb55b..bf8cc9add 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -18,12 +18,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_inv.h" #include "qt_glyph.h" #include "qt_set.h" diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index aa48741c1..04d1b3d21 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -15,9 +15,9 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include -#include "qt_redef.h" +#include "qt_post.h" #include "qt_key.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_line.cpp b/win/Qt/qt_line.cpp index f7aab6bb9..4c1f63eba 100644 --- a/win/Qt/qt_line.cpp +++ b/win/Qt/qt_line.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_line.h" namespace nethack_qt_ { diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index a8beea886..50a28828b 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -17,12 +17,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_main.h" #include "qt_main.moc" #include "qt_bind.h" diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 1ebb3434c..1508b2213 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -17,12 +17,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_map.h" #include "qt_map.moc" #include "qt_click.h" diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 8ca4fde11..fb7e391e4 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -17,12 +17,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_menu.h" #include "qt_menu.moc" #include "qt_glyph.h" diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index 934a7be13..e3e02d9a1 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -17,12 +17,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_msg.h" #include "qt_msg.moc" #include "qt_map.h" diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index 2eefe96a8..8fbafd527 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -17,12 +17,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_plsel.h" #include "qt_plsel.moc" #include "qt_bind.h" diff --git a/win/Qt/qt_post.h b/win/Qt/qt_post.h new file mode 100644 index 000000000..d4eaba254 --- /dev/null +++ b/win/Qt/qt_post.h @@ -0,0 +1,4 @@ +#ifdef __clang__ +#pragma clang diagnostic pop +#endif /* __clang__ */ + diff --git a/win/Qt/qt_pre.h b/win/Qt/qt_pre.h new file mode 100644 index 000000000..ea891fcf4 --- /dev/null +++ b/win/Qt/qt_pre.h @@ -0,0 +1,5 @@ +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wshadow" +#endif + diff --git a/win/Qt/qt_redef.h b/win/Qt/qt_redef.h deleted file mode 100644 index 5e6c15e4a..000000000 --- a/win/Qt/qt_redef.h +++ /dev/null @@ -1,19 +0,0 @@ -#if defined(QT_GRAPHICS) -#if defined(MACOSX) - -/* - * The following conflict with Qt header files so after - * undefing them in qt_undef.h, we redefine them back to - * the non-conflicting names again in here, presumably - * right after the Qt header files with the conflicts have - * been included. - */ - -#define u NETHACK_u -#define flags NETHACK_flags -#define g NETHACK_g -#define cg NETHACK_cg - -#endif /* MACOSX */ -#endif /* QT_GRAPHICS */ - diff --git a/win/Qt/qt_rip.cpp b/win/Qt/qt_rip.cpp index adcb04f9d..49402c85f 100644 --- a/win/Qt/qt_rip.cpp +++ b/win/Qt/qt_rip.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_rip.h" #include "qt_bind.h" #include "qt_str.h" diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index d44365ab2..d265acaf2 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_set.h" #include "qt_set.moc" #include "qt_glyph.h" diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 13cb4a773..2ed28612e 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -17,12 +17,12 @@ extern "C" { #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_stat.h" #include "qt_stat.moc" #include "qt_set.h" diff --git a/win/Qt/qt_streq.cpp b/win/Qt/qt_streq.cpp index 419aba8cc..9254ad04d 100644 --- a/win/Qt/qt_streq.cpp +++ b/win/Qt/qt_streq.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_streq.h" #include "qt_str.h" diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 2a3aa5d8e..66ecd13e8 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_svsel.h" #include "qt_bind.h" #include "qt_str.h" diff --git a/win/Qt/qt_undef.h b/win/Qt/qt_undef.h deleted file mode 100644 index 9b98e7737..000000000 --- a/win/Qt/qt_undef.h +++ /dev/null @@ -1,17 +0,0 @@ -#if defined(QT_GRAPHICS) -#if defined(MACOSX) - -/* - * The following conflict with Qt header files so we - * undef them in here, then redef them using qt_redef.h - * after the Qt includes. - */ - -#undef u -#undef flags -#undef g -#undef cg - -#endif /* MACOSX */ -#endif /* QT_GRAPHICS */ - diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 501e91b12..7a636ac16 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -57,12 +57,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_win.h" #include "qt_bind.h" #include "qt_click.h" diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 4aeffe98e..4eb9ac4a5 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -16,12 +16,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_xcmd.h" #include "qt_xcmd.moc" #include "qt_bind.h" diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 8e49cd673..cac810394 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -15,12 +15,12 @@ #undef min #undef max -#include "qt_undef.h" +#include "qt_pre.h" #include #if QT_VERSION >= 0x050000 #include #endif -#include "qt_redef.h" +#include "qt_post.h" #include "qt_yndlg.h" #include "qt_yndlg.moc" #include "qt_str.h" From d6b5241929847e8673eb2f571776839e22e871e2 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 18 Jul 2020 09:25:12 -0400 Subject: [PATCH 014/708] Files bit --- Files | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Files b/Files index a4bac931f..7a407869a 100644 --- a/Files +++ b/Files @@ -343,11 +343,11 @@ qt_clust.h qt_delay.cpp qt_delay.h qt_glyph.cpp qt_glyph.h qt_icon.cpp qt_icon.h qt_inv.cpp qt_inv.h qt_kde0.h qt_key.cpp qt_key.h qt_line.cpp qt_line.h qt_main.cpp qt_main.h qt_map.cpp qt_map.h qt_menu.cpp qt_menu.h -qt_msg.cpp qt_msg.h qt_plsel.cpp qt_plsel.h qt_rip.cpp -qt_rip.h qt_set.cpp qt_set.h qt_stat.cpp qt_stat.h -qt_str.cpp qt_str.h qt_streq.cpp qt_streq.h qt_svsel.cpp -qt_svsel.h qt_win.cpp qt_win.h qt_xcmd.cpp qt_xcmd.h -qt_xpms.h qt_yndlg.cpp qt_yndlg.h +qt_msg.cpp qt_msg.h qt_plsel.cpp qt_plsel.h qt_post.h +qt_rip.cpp qt_rip.h qt_set.cpp qt_set.h qt_stat.cpp +qt_stat.h qt_str.cpp qt_str.h qt_streq.cpp qt_streq.h +qt_svsel.cpp qt_svsel.h qt_pre.h qt_win.cpp qt_win.h +qt_xcmd.cpp qt_xcmd.h qt_xpms.h qt_yndlg.cpp qt_yndlg.h win/X11: (files for X versions) From e09c196af6f03405d6c978e19444ffc2010e7c1b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 18 Jul 2020 09:27:52 -0400 Subject: [PATCH 015/708] cron-daily update - Files --- Files | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Files b/Files index 7a407869a..881c2eaf2 100644 --- a/Files +++ b/Files @@ -344,9 +344,9 @@ qt_icon.cpp qt_icon.h qt_inv.cpp qt_inv.h qt_kde0.h qt_key.cpp qt_key.h qt_line.cpp qt_line.h qt_main.cpp qt_main.h qt_map.cpp qt_map.h qt_menu.cpp qt_menu.h qt_msg.cpp qt_msg.h qt_plsel.cpp qt_plsel.h qt_post.h -qt_rip.cpp qt_rip.h qt_set.cpp qt_set.h qt_stat.cpp -qt_stat.h qt_str.cpp qt_str.h qt_streq.cpp qt_streq.h -qt_svsel.cpp qt_svsel.h qt_pre.h qt_win.cpp qt_win.h +qt_pre.h qt_rip.cpp qt_rip.h qt_set.cpp qt_set.h +qt_stat.cpp qt_stat.h qt_str.cpp qt_str.h qt_streq.cpp +qt_streq.h qt_svsel.cpp qt_svsel.h qt_win.cpp qt_win.h qt_xcmd.cpp qt_xcmd.h qt_xpms.h qt_yndlg.cpp qt_yndlg.h win/X11: From aa69f6be045e5f8740ba54cb2160a81adafd1bdf Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 18 Jul 2020 09:53:30 -0400 Subject: [PATCH 016/708] mirror the recent make depends update in some other Makefiles --- sys/msdos/Makefile1.cross | 3 ++- sys/msdos/Makefile2.cross | 4 ++-- sys/winnt/Makefile.gcc | 3 ++- sys/winnt/Makefile.msc | 3 ++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sys/msdos/Makefile1.cross b/sys/msdos/Makefile1.cross index ae7e3fe19..9bf2a52f5 100644 --- a/sys/msdos/Makefile1.cross +++ b/sys/msdos/Makefile1.cross @@ -621,7 +621,8 @@ spotless: clean # src dependencies -$(HOST_O)drawing.o: $(CONFIG_H) +$(HOST_O)drawing.o: $(CONFIG_H) $(INCL)/color.h $(INCL)/rm.h \ + $(INCL)/objclass.h $(INCL)/monsym.h $(HOST_O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h $(HOST_O)alloc.o: alloc.c $(CONFIG_H) $(HOST_O)dlb.o: dlb.c $(CONFIG_H) $(INCL)/dlb.h diff --git a/sys/msdos/Makefile2.cross b/sys/msdos/Makefile2.cross index ac1b12a35..0f8415667 100644 --- a/sys/msdos/Makefile2.cross +++ b/sys/msdos/Makefile2.cross @@ -755,7 +755,8 @@ $(O)pdcurses.a : $(PDCLIBOBJS) $(PDCOBJS) $(O)alloc.o: $(CONFIG_H) alloc.c $(TARGET_CC) $(cflags) -o$@ alloc.c -$(O)drawing.o: $(CONFIG_H) drawing.c $(MSYS)/pcvideo.h +$(O)drawing.o: drawing.c $(CONFIG_H) $(INCL)/color.h $(INCL)/rm.h \ + $(INCL)/objclass.h $(INCL)/monsym.h $(MSYS)/pcvideo.h $(TARGET_CC) $(cflags) -I$(MSYS) -o$@ drawing.c $(O)decl.o: $(CONFIG_H) decl.c @@ -1042,7 +1043,6 @@ $(O)dog.o: dog.c $(HACK_H) $(O)dogmove.o: dogmove.c $(HACK_H) $(INCL)/mfndpos.h $(O)dokick.o: dokick.c $(HACK_H) $(O)dothrow.o: dothrow.c $(HACK_H) -$(O)drawing.o: drawing.c $(CONFIG_H) $(O)dungeon.o: dungeon.c $(HACK_H) $(INCL)/dgn_file.h $(INCL)/dlb.h $(O)eat.o: eat.c $(HACK_H) $(O)end.o: end.c $(HACK_H) $(INCL)/dlb.h diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 8806db9f3..ca506a6db 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -1562,7 +1562,8 @@ $(O)dog.o: dog.c $(HACK_H) $(O)dogmove.o: dogmove.c $(HACK_H) $(INCL)/mfndpos.h $(O)dokick.o: dokick.c $(HACK_H) $(O)dothrow.o: dothrow.c $(HACK_H) -$(O)drawing.o: drawing.c $(CONFIG_H) +$(O)drawing.o: drawing.c $(CONFIG_H) $(INCL)/color.h $(INCL)/rm.h \ + $(INCL)/objclass.h $(INCL)/monsym.h $(O)dungeon.o: dungeon.c $(HACK_H) $(INCL)/dgn_file.h $(INCL)/dlb.h $(O)eat.o: eat.c $(HACK_H) $(O)end.o: end.c $(HACK_H) $(INCL)/dlb.h diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 046016feb..05fc3d8eb 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1505,7 +1505,8 @@ $(O)panic.o: $(U)panic.c $(CONFIG_H) $(O)drawing_host.o: drawing.c $(CONFIG_H) @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ drawing.c -$(O)drawing.o: drawing.c $(CONFIG_H) +$(O)drawing.o: drawing.c $(CONFIG_H) $(INCL)\color.h $(INCL)\rm.h \ + $(INCL)\objclass.h $(INCL)\monsym.h @$(cc) $(cflagsBuild) -Fo$@ drawing.c $(O)monst_host.o: monst.c $(CONFIG_H) $(INCL)\permonst.h $(INCL)\align.h \ From a3bfb599ca655028d34fd7382caaf0a1cc6ba899 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 18 Jul 2020 10:31:34 -0400 Subject: [PATCH 017/708] more Makefile maintenance for Windows, msdos --- sys/msdos/Makefile2.cross | 54 ------- sys/winnt/Makefile.gcc | 167 ++++++++------------- sys/winnt/Makefile.msc | 300 ++++++++++++++------------------------ 3 files changed, 168 insertions(+), 353 deletions(-) diff --git a/sys/msdos/Makefile2.cross b/sys/msdos/Makefile2.cross index 0f8415667..76c33e890 100644 --- a/sys/msdos/Makefile2.cross +++ b/sys/msdos/Makefile2.cross @@ -899,8 +899,6 @@ $(O)stubvid.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/video.c # # # src dependencies -#$(O)tos.o: ../sys/atari/tos.c $(HACK_H) $(INCL)/tcap.h - $(TARGET_CC) $(cflags) -o$@ ../sys/atari/tos.c $(O)pcmain.o: ../sys/share/pcmain.c $(HACK_H) $(INCL)/dlb.h \ #$(INCL)/win32api.h $(TARGET_CC) $(cflags) -o$@ ../sys/share/pcmain.c @@ -958,57 +956,6 @@ $(O)winval.o: ../win/X11/winval.c $(HACK_H) $(INCL)/winX.h $(TARGET_CC) $(cflags) -o$@ ../win/X11/winval.c #$(O)tile.o: tile.c $(HACK_H) #$(HOST_O)tile.o: tile.c $(HACK_H) -$(O)gnaskstr.o: ../win/gnome/gnaskstr.c ../win/gnome/gnaskstr.h \ - ../win/gnome/gnmain.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnaskstr.c -$(O)gnbind.o: ../win/gnome/gnbind.c ../win/gnome/gnbind.h ../win/gnome/gnmain.h \ - ../win/gnome/gnaskstr.h ../win/gnome/gnyesno.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnbind.c -$(O)gnglyph.o: ../win/gnome/gnglyph.c ../win/gnome/gnglyph.h $(INCL)/tile2x11.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnglyph.c -$(O)gnmain.o: ../win/gnome/gnmain.c ../win/gnome/gnmain.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnbind.h ../win/gnome/gnopts.h $(HACK_H) \ - $(INCL)/date.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnmain.c -$(O)gnmap.o: ../win/gnome/gnmap.c ../win/gnome/gnmap.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnsignal.h $(HACK_H) - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnmap.c -$(O)gnmenu.o: ../win/gnome/gnmenu.c ../win/gnome/gnmenu.h ../win/gnome/gnmain.h \ - ../win/gnome/gnbind.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnmenu.c -$(O)gnmesg.o: ../win/gnome/gnmesg.c ../win/gnome/gnmesg.h ../win/gnome/gnsignal.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnmesg.c -$(O)gnopts.o: ../win/gnome/gnopts.c ../win/gnome/gnopts.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnmain.h ../win/gnome/gnmap.h $(HACK_H) - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnopts.c -$(O)gnplayer.o: ../win/gnome/gnplayer.c ../win/gnome/gnplayer.h \ - ../win/gnome/gnmain.h $(HACK_H) - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnplayer.c -$(O)gnsignal.o: ../win/gnome/gnsignal.c ../win/gnome/gnsignal.h \ - ../win/gnome/gnmain.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnsignal.c -$(O)gnstatus.o: ../win/gnome/gnstatus.c ../win/gnome/gnstatus.h \ - ../win/gnome/gnsignal.h ../win/gnome/gn_xpms.h \ - ../win/gnome/gnomeprv.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnstatus.c -$(O)gntext.o: ../win/gnome/gntext.c ../win/gnome/gntext.h ../win/gnome/gnmain.h \ - ../win/gnome/gn_rip.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gntext.c -$(O)gnworn.o: ../win/gnome/gnworn.c ../win/gnome/gnworn.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnsignal.h ../win/gnome/gnomeprv.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnworn.c -$(O)gnyesno.o: ../win/gnome/gnyesno.c ../win/gnome/gnbind.h ../win/gnome/gnyesno.h - $(TARGET_CC) $(cflags) $(GNOMEINC) -o$@ ../win/gnome/gnyesno.c -$(O)wingem.o: ../win/gem/wingem.c $(HACK_H) $(INCL)/func_tab.h $(INCL)/dlb.h \ - $(INCL)/wingem.h - $(TARGET_CC) $(cflags) -o$@ ../win/gem/wingem.c -$(O)wingem1.o: ../win/gem/wingem1.c $(INCL)/gem_rsc.h $(INCL)/load_img.h \ - $(INCL)/gr_rect.h $(INCL)/wintype.h $(INCL)/wingem.h - $(TARGET_CC) $(cflags) -o$@ ../win/gem/wingem1.c -$(O)load_img.o: ../win/gem/load_img.c $(INCL)/load_img.h - $(TARGET_CC) $(cflags) -o$@ ../win/gem/load_img.c -$(O)gr_rect.o: ../win/gem/gr_rect.c $(INCL)/gr_rect.h - $(TARGET_CC) $(cflags) -o$@ ../win/gem/gr_rect.c $(O)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) $(INCL)/func_tab.h \ $(INCL)/dlb.h $(INCL)/tile2x11.h \ $(INCL)/qt_win.h $(INCL)/qt_clust.h $(INCL)/qt_kde0.h \ @@ -1018,7 +965,6 @@ $(O)qt_clust.o: ../win/Qt/qt_clust.cpp $(INCL)/qt_clust.h $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_clust.cpp $(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qttableview.cpp -#$(O)monstr.o: monstr.c $(CONFIG_H) $(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h $(O)allmain.o: allmain.c $(HACK_H) $(O)alloc.o: alloc.c $(CONFIG_H) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index ca506a6db..380cb0c8f 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -104,19 +104,19 @@ TARGET_CPU=x86 #4b Qt # -#WANT_WIN_QT4 = N +#WANT_WIN_QT = N -# WANT_WIN_QT4 requires Qt 4 or Qt 5, see +# WANT_WIN_QT requires Qt 4 or Qt 5, see # https://www.qt.io/download-open-source/ # Earlier versions of Qt are not compatible with Windows # For Qt 5, use: # -#QT4_DIRECTORY = c:/Qt/Qt5.9.2/5.9.2/mingw53_32 +#QT_DIRECTORY = c:/Qt/Qt5.9.2/5.9.2/mingw53_32 #HAVE_QT5 = Y # For Qt 4, comment out the above two lines and use: # -#QT4_DIRECTORY = c:/Qt/4.8.6 +#QT_DIRECTORY = c:/Qt/4.8.6 #HAVE_QT5 = N # @@ -187,6 +187,7 @@ NHV=$(subst ",,$(NHV1)) # MSWIN - window port files (win32) # WCURSES - window port files (curses) # WSHR - Tile support files +# QT - QT window support files INCL =../include DAT =../dat @@ -199,6 +200,7 @@ TTY =../win/tty MSWIN =../win/win32 WCURSES =../win/curses WSHR =../win/share +QT =../win/Qt # # Object directory. @@ -216,7 +218,7 @@ RANDOM = $(OBJ)/random.o BCRYPT=-lbcrypt WINPFLAG = -DTILES -DMSWIN_GRAPHICS -DWIN32CON -D_WIN32_IE=0x0400 -D_WIN32_WINNT=0x0601 -DWINVER=0x0601 -ifeq "$(WANT_WIN_QT4)" "Y" +ifeq "$(WANT_WIN_QT)" "Y" WINPFLAG += -DQT_GRAPHICS -DPIXMAPDIR='"."' endif # To store all the level files, @@ -366,12 +368,12 @@ GUIOBJ = $(O)mhaskyn.o $(O)mhdlg.o \ endif -ifeq "$(WANT_WIN_QT4)" "Y" - GUIOBJ += $(O)qt4bind.o $(O)qt4click.o $(O)qt4clust.o $(O)qt4delay.o \ - $(O)qt4glyph.o $(O)qt4icon.o $(O)qt4inv.o $(O)qt4key.o $(O)qt4line.o \ - $(O)qt4main.o $(O)qt4map.o $(O)qt4menu.o $(O)qt4msg.o $(O)qt4plsel.o \ - $(O)qt4rip.o $(O)qt4set.o $(O)qt4stat.o $(O)qt4str.o $(O)qt4streq.o \ - $(O)qt4svsel.o $(O)qt4win.o $(O)qt4xcmd.o $(O)qt4yndlg.o +ifeq "$(WANT_WIN_QT)" "Y" + GUIOBJ += $(O)qt_bind.o $(O)qt_click.o $(O)qt_clust.o $(O)qt_delay.o \ + $(O)qt_glyph.o $(O)qt_icon.o $(O)qt_inv.o $(O)qt_key.o $(O)qt_line.o \ + $(O)qt_main.o $(O)qt_map.o $(O)qt_menu.o $(O)qt_msg.o $(O)qt_plsel.o \ + $(O)qt_rip.o $(O)qt_set.o $(O)qt_stat.o $(O)qt_str.o $(O)qt_streq.o \ + $(O)qt_svsel.o $(O)qt_win.o $(O)qt_xcmd.o $(O)qt_yndlg.o endif ifneq "$(SKIP_NETHACKW)" "Y" @@ -382,14 +384,14 @@ GUIHDR = $(MSWIN)/mhaskyn.h $(MSWIN)/mhdlg.h $(MSWIN)/mhfont.h \ $(MSWIN)/mhtext.h $(MSWIN)/resource.h $(MSWIN)/winMS.h endif -ifeq "$(WANT_WIN_QT4)" "Y" - GUIHDR += $(QT4)/qt4bind.h $(QT4)/qt4click.h $(QT4)/qt4clust.h \ - $(QT4)/qt4delay.h $(QT4)/qt4glyph.h $(QT4)/qt4icon.h $(QT4)/qt4inv.h \ - $(QT4)/qt4kde0.h $(QT4)/qt4key.h $(QT4)/qt4line.h $(QT4)/qt4main.h \ - $(QT4)/qt4map.h $(QT4)/qt4menu.h $(QT4)/qt4msg.h $(QT4)/qt4plsel.h \ - $(QT4)/qt4rip.h $(QT4)/qt4set.h $(QT4)/qt4stat.h $(QT4)/qt4str.h \ - $(QT4)/qt4streq.h $(QT4)/qt4svsel.h $(QT4)/qt4win.h $(QT4)/qt4xcmd.h \ - $(QT4)/qt4yndlg.h +ifeq "$(WANT_WIN_QT)" "Y" + GUIHDR += $(QT)/qt_bind.h $(QT)/qt_click.h $(QT)/qt_clust.h \ + $(QT)/qt_delay.h $(QT)/qt_glyph.h $(QT)/qt_icon.h $(QT)/qt_inv.h \ + $(QT)/qt_kde0.h $(QT)/qt_key.h $(QT)/qt_line.h $(QT)/qt_main.h \ + $(QT)/qt_map.h $(QT)/qt_menu.h $(QT)/qt_msg.h $(QT)/qt_plsel.h \ + $(QT)/qt_rip.h $(QT)/qt_set.h $(QT)/qt_stat.h $(QT)/qt_str.h \ + $(QT)/qt_streq.h $(QT)/qt_svsel.h $(QT)/qt_win.h $(QT)/qt_xcmd.h \ + $(QT)/qt_yndlg.h endif COMCTRL = comctl32.lib @@ -543,7 +545,7 @@ rc = windres link = gcc endif -ifeq "$(WANT_WIN_QT4)" "Y" +ifeq "$(WANT_WIN_QT)" "Y" link = g++ endif @@ -563,17 +565,17 @@ CFLAGSBASE = -c $(cflags) $(WINPINC) $(cdebug) $(CURSESDEF) baselibs = -lwinmm -lshell32 -lole32 -luuid conlibs = -lgdi32 $(baselibs) $(BCRYPT) guilibs = -lcomctl32 $(baselibs) $(BCRYPT) -ifeq "$(WANT_WIN_QT4)" "Y" +ifeq "$(WANT_WIN_QT)" "Y" # Might be either Qt 4 or Qt 5 ifeq "$(HAVE_QT5)" "Y" - guilibs += $(QT4_DIRECTORY)/lib/libQt5Core.a - guilibs += $(QT4_DIRECTORY)/lib/libQt5Gui.a - guilibs += $(QT4_DIRECTORY)/lib/libQt5Widgets.a - conlibs += $(QT4_DIRECTORY)/lib/libQt5Core.a + guilibs += $(QT_DIRECTORY)/lib/libQt5Core.a + guilibs += $(QT_DIRECTORY)/lib/libQt5Gui.a + guilibs += $(QT_DIRECTORY)/lib/libQt5Widgets.a + conlibs += $(QT_DIRECTORY)/lib/libQt5Core.a else - guilibs += $(QT4_DIRECTORY)/lib/libQtCore4.a - guilibs += $(QT4_DIRECTORY)/lib/libQtGui4.a - conlibs += $(QT4_DIRECTORY)/lib/libQtCore4.a + guilibs += $(QT_DIRECTORY)/lib/libQtCore4.a + guilibs += $(QT_DIRECTORY)/lib/libQtGui4.a + conlibs += $(QT_DIRECTORY)/lib/libQtCore4.a endif endif @@ -581,7 +583,7 @@ endif # Extra files needed for some ports #========================================== EXTRA_FILES = -ifeq "$(WANT_WIN_QT4)" "Y" +ifeq "$(WANT_WIN_QT)" "Y" ifeq "$(HAVE_QT5)" "Y" EXTRA_FILES += $(GAMEDIR)/Qt5Core.dll EXTRA_FILES += $(GAMEDIR)/Qt5Gui.dll @@ -711,19 +713,19 @@ $(OBJ)/%.o : $(LUASRC)/%.c $(cc) $(CFLAGS) -o$@ $< #========================================== -# Rules for files in win/Qt4 +# Rules for files in win/Qt #========================================== ifeq "$(HAVE_QT5)" "Y" -QT4_CXXFLAGS = -std=c++11 +QT_CXXFLAGS = -std=c++11 else -QT4_CXXFLAGS = +QT_CXXFLAGS = endif -$(OBJ)/%.o : $(QT4)/%.cpp - $(cxx) $(CXXFLAGS) $(QT4_CXXFLAGS) -I$(MSWIN) -I$(QT4_DIRECTORY)/include -o$@ $< +$(OBJ)/%.o : $(QT)/%.cpp + $(cxx) $(CXXFLAGS) $(QT_CXXFLAGS) -I$(MSWIN) -I$(QT_DIRECTORY)/include -o$@ $< -$(QT4)/%.moc : $(QT4)/%.h - $(QT4_DIRECTORY)\bin\moc -o $@ $< +$(QT)/%.moc : $(QT)/%.h + $(QT_DIRECTORY)\bin\moc -o $@ $< ifeq "$(SKIP_NETHACKW)" "Y" NETHACKW_EXE = @@ -1373,22 +1375,22 @@ $(O)cursstat.o: $(WCURSES)/cursstat.c $(WCURSES)/cursstat.h $(INCL)/wincurs.h $(O)curswins.o: $(WCURSES)/curswins.c $(WCURSES)/curswins.h $(INCL)/wincurs.h endif -ifeq "$(WANT_WIN_QT4)" "Y" +ifeq "$(WANT_WIN_QT)" "Y" # Qt dependencies -$(GAMEDIR))/Qt5Core.dll : $(QT4_DIRECTORY)/bin/Qt5Core.dll +$(GAMEDIR))/Qt5Core.dll : $(QT_DIRECTORY)/bin/Qt5Core.dll $(subst /,\,@copy $< $@ >nul) -$(GAMEDIR))/Qt5Gui.dll : $(QT4_DIRECTORY)/bin/Qt5Gui.dll +$(GAMEDIR))/Qt5Gui.dll : $(QT_DIRECTORY)/bin/Qt5Gui.dll $(subst /,\,@copy $< $@ >nul) -$(GAMEDIR)/Qt5Widgets.dll : $(QT4_DIRECTORY)/bin/Qt5Widgets.dll +$(GAMEDIR)/Qt5Widgets.dll : $(QT_DIRECTORY)/bin/Qt5Widgets.dll $(subst /,\,@copy $< $@ >nul) -$(GAMEDIR)/QtCore4.dll : $(QT4_DIRECTORY)/bin/QtCore4.dll +$(GAMEDIR)/QtCore4.dll : $(QT_DIRECTORY)/bin/QtCore4.dll $(subst /,\,@copy $< $@ >nul) -$(GAMEDIR)/QtGui4.dll : $(QT4_DIRECTORY)/bin/QtGui4.dll +$(GAMEDIR)/QtGui4.dll : $(QT_DIRECTORY)/bin/QtGui4.dll $(subst /,\,@copy $< $@ >nul) $(GAMEDIR)/nhtiles.bmp : $(SRC)/tiles.bmp @@ -1397,15 +1399,15 @@ $(GAMEDIR)/nhtiles.bmp : $(SRC)/tiles.bmp $(GAMEDIR)/rip.xpm : ../win/X11/rip.xpm $(subst /,\,@copy $< $@ >nul) # Dependencies on .moc files (for Qt 4 or 5) -$(OBJ)/qt4main.o : $(QT4)/qt4main.cpp $(QT4)/qt4main.moc $(QT4)/qt4kde0.moc -$(OBJ)/qt4map.o : $(QT4)/qt4map.cpp $(QT4)/qt4map.moc -$(OBJ)/qt4menu.o : $(QT4)/qt4menu.cpp $(QT4)/qt4menu.moc -$(OBJ)/qt4msg.o : $(QT4)/qt4msg.cpp $(QT4)/qt4msg.moc -$(OBJ)/qt4plsel.o : $(QT4)/qt4plsel.cpp $(QT4)/qt4plsel.moc -$(OBJ)/qt4set.o : $(QT4)/qt4set.cpp $(QT4)/qt4set.moc -$(OBJ)/qt4stat.o : $(QT4)/qt4stat.cpp $(QT4)/qt4stat.moc -$(OBJ)/qt4xcmd.o : $(QT4)/qt4xcmd.cpp $(QT4)/qt4xcmd.moc -$(OBJ)/qt4yndlg.o : $(QT4)/qt4yndlg.cpp $(QT4)/qt4yndlg.moc +$(OBJ)/qt_main.o : $(QT)/qt_main.cpp $(QT)/qt_main.moc $(QT)/qt_kde0.moc +$(OBJ)/qt_map.o : $(QT)/qt_map.cpp $(QT)/qt_map.moc +$(OBJ)/qt_menu.o : $(QT)/qt_menu.cpp $(QT)/qt_menu.moc +$(OBJ)/qt_msg.o : $(QT)/qt_msg.cpp $(QT)/qt_msg.moc +$(OBJ)/qt_plsel.o : $(QT)/qt_plsel.cpp $(QT)/qt_plsel.moc +$(OBJ)/qt_set.o : $(QT)/qt_set.cpp $(QT)/qt_set.moc +$(OBJ)/qt_stat.o : $(QT)/qt_stat.cpp $(QT)/qt_stat.moc +$(OBJ)/qt_xcmd.o : $(QT)/qt_xcmd.cpp $(QT)/qt_xcmd.moc +$(OBJ)/qt_yndlg.o : $(QT)/qt_yndlg.cpp $(QT)/qt_yndlg.moc endif # @@ -1479,66 +1481,15 @@ $(O)wintext.o: ../win/X11/wintext.c $(HACK_H) $(INCL)/winX.h $(INCL)/xwindow.h $(O)winval.o: ../win/X11/winval.c $(HACK_H) $(INCL)/winX.h $(cc) $(CFLAGS) -o$@ ../win/X11/winval.c $(O)tile.o: $(SRC)/tile.c $(HACK_H) -$(O)gnaskstr.o: ../win/gnome/gnaskstr.c ../win/gnome/gnaskstr.h \ - ../win/gnome/gnmain.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnaskstr.c -$(O)gnbind.o: ../win/gnome/gnbind.c ../win/gnome/gnbind.h ../win/gnome/gnmain.h \ - ../win/gnome/gnaskstr.h ../win/gnome/gnyesno.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnbind.c -$(O)gnglyph.o: ../win/gnome/gnglyph.c ../win/gnome/gnglyph.h $(INCL)/tile2x11.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnglyph.c -$(O)gnmain.o: ../win/gnome/gnmain.c ../win/gnome/gnmain.h ../win/gnome/gnsignal.h \ - ../win/gnome/gnbind.h ../win/gnome/gnopts.h $(HACK_H) \ - $(INCL)/date.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmain.c -$(O)gnmap.o: ../win/gnome/gnmap.c ../win/gnome/gnmap.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnsignal.h $(HACK_H) - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmap.c -$(O)gnmenu.o: ../win/gnome/gnmenu.c ../win/gnome/gnmenu.h ../win/gnome/gnmain.h \ - ../win/gnome/gnbind.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmenu.c -$(O)gnmesg.o: ../win/gnome/gnmesg.c ../win/gnome/gnmesg.h ../win/gnome/gnsignal.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmesg.c -$(O)gnopts.o: ../win/gnome/gnopts.c ../win/gnome/gnopts.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnmain.h ../win/gnome/gnmap.h $(HACK_H) - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnopts.c -$(O)gnplayer.o: ../win/gnome/gnplayer.c ../win/gnome/gnplayer.h \ - ../win/gnome/gnmain.h $(HACK_H) - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnplayer.c -$(O)gnsignal.o: ../win/gnome/gnsignal.c ../win/gnome/gnsignal.h \ - ../win/gnome/gnmain.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnsignal.c -$(O)gnstatus.o: ../win/gnome/gnstatus.c ../win/gnome/gnstatus.h \ - ../win/gnome/gnsignal.h ../win/gnome/gn_xpms.h \ - ../win/gnome/gnomeprv.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnstatus.c -$(O)gntext.o: ../win/gnome/gntext.c ../win/gnome/gntext.h ../win/gnome/gnmain.h \ - ../win/gnome/gn_rip.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gntext.c -$(O)gnworn.o: ../win/gnome/gnworn.c ../win/gnome/gnworn.h ../win/gnome/gnglyph.h \ - ../win/gnome/gnsignal.h ../win/gnome/gnomeprv.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnworn.c -$(O)gnyesno.o: ../win/gnome/gnyesno.c ../win/gnome/gnbind.h ../win/gnome/gnyesno.h - $(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnyesno.c -$(O)wingem.o: ../win/gem/wingem.c $(HACK_H) $(INCL)/func_tab.h $(INCL)/dlb.h \ - $(INCL)/wingem.h - $(cc) $(CFLAGS) -o$@ ../win/gem/wingem.c -$(O)wingem1.o: ../win/gem/wingem1.c $(INCL)/gem_rsc.h $(INCL)/load_img.h \ - $(INCL)/gr_rect.h $(INCL)/wintype.h $(INCL)/wingem.h - $(cc) $(CFLAGS) -o$@ ../win/gem/wingem1.c -$(O)load_img.o: ../win/gem/load_img.c $(INCL)/load_img.h - $(cc) $(CFLAGS) -o$@ ../win/gem/load_img.c -$(O)gr_rect.o: ../win/gem/gr_rect.c $(INCL)/gr_rect.h - $(cc) $(CFLAGS) -o$@ ../win/gem/gr_rect.c -$(O)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) $(INCL)/func_tab.h \ +$(O)qt_win.o: $(QT)/qt_win.cpp $(HACK_H) $(INCL)/func_tab.h \ $(INCL)/dlb.h $(INCL)/tile2x11.h \ $(INCL)/qt_win.h $(INCL)/qt_clust.h $(INCL)/qt_kde0.h \ $(INCL)/qt_xpms.h qt_win.moc qt_kde0.moc qttableview.moc - $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_win.cpp -$(O)qt_clust.o: ../win/Qt/qt_clust.cpp $(INCL)/qt_clust.h - $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_clust.cpp -$(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h - $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qttableview.cpp + $(CXX) $(CXXFLAGS) -o$@ $(QT)/qt_win.cpp +$(O)qt_clust.o: $(QT)/qt_clust.cpp $(INCL)/qt_clust.h + $(CXX) $(CXXFLAGS) -o$@ $(QT)/qt_clust.cpp +$(O)qttableview.o: $(QT)/qttableview.cpp $(INCL)/qttableview.h + $(CXX) $(CXXFLAGS) -o$@ $(QT)/qttableview.cpp $(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h $(O)allmain.o: allmain.c $(HACK_H) $(O)alloc.o: alloc.c $(CONFIG_H) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 05fc3d8eb..629213b47 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -189,6 +189,7 @@ TTY = ..\win\tty # window port files (tty) MSWIN = ..\win\win32 # window port files (win32) WCURSES = ..\win\curses # window port files (curses) WSHR = ..\win\share # Tile support files +QT = ..\win\Qt # QT support files # # Object directory. @@ -1676,8 +1677,6 @@ clean: # That means that there is some irrelevant stuff # in here, but maintenance should be easier. # -$(O)tos.o: ..\sys\atari\tos.c $(HACK_H) $(INCL)\tcap.h -# @$(cc) $(cflagsBuild) -Fo$@ ..\sys\atari\tos.c $(O)pcmain.o: ..\sys\share\pcmain.c $(HACK_H) $(INCL)\dlb.h # @$(cc) $(cflagsBuild) -Fo$@ ..\sys\share\pcmain.c $(O)pcsys.o: ..\sys\share\pcsys.c $(HACK_H) @@ -1762,198 +1761,118 @@ $(O)wintext.o: ..\win\X11\wintext.c $(HACK_H) $(INCL)\winX.h $(INCL)\xwindow.h $(O)winval.o: ..\win\X11\winval.c $(HACK_H) $(INCL)\winX.h # @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winval.c $(O)tile.o: $(SRC)\tile.c $(HACK_H) -$(O)gnaskstr.o: ..\win\gnome\gnaskstr.c ..\win\gnome\gnaskstr.h \ - ..\win\gnome\gnmain.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnaskstr.c -$(O)gnbind.o: ..\win\gnome\gnbind.c ..\win\gnome\gnbind.h ..\win\gnome\gnomeprv.h \ - $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h ..\win\gnome\gnmain.h \ - ..\win\gnome\gnmap.h ..\win\gnome\gnmenu.h \ - ..\win\gnome\gnplayer.h ..\win\gnome\gnsignal.h \ - ..\win\gnome\gnglyph.h ..\win\gnome\gnstatus.h \ - ..\win\gnome\gntext.h ..\win\gnome\gnmesg.h \ - ..\win\gnome\gnyesno.h ..\win\gnome\gnworn.h \ - ..\win\gnome\gnaskstr.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnbind.c -$(O)gnglyph.o: ..\win\gnome\gnglyph.c ..\win\gnome\gnglyph.h $(CONFIG_H) \ - $(INCL)\tile2x11.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnglyph.c -$(O)gnmain.o: ..\win\gnome\gnmain.c ..\win\gnome\gnmain.h ..\win\gnome\gnsignal.h \ - ..\win\gnome\gnomeprv.h $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h \ - ..\win\gnome\gnglyph.h ..\win\gnome\gnbind.h \ - ..\win\gnome\gnmap.h ..\win\gnome\gnmenu.h \ - ..\win\gnome\gnplayer.h ..\win\gnome\gnstatus.h \ - ..\win\gnome\gntext.h ..\win\gnome\gnmesg.h \ - ..\win\gnome\gnyesno.h ..\win\gnome\gnworn.h \ - ..\win\gnome\gnopts.h $(INCL)\date.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnmain.c -$(O)gnmap.o: ..\win\gnome\gnmap.c ..\win\gnome\gnmap.h $(CONFIG_H) \ - ..\win\gnome\gnglyph.h ..\win\gnome\gnsignal.h \ - ..\win\gnome\gnomeprv.h $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnmap.c -$(O)gnmenu.o: ..\win\gnome\gnmenu.c ..\win\gnome\gnmenu.h $(CONFIG_H) \ - ..\win\gnome\gnomeprv.h $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h \ - ..\win\gnome\gnmain.h ..\win\gnome\gnbind.h \ - ..\win\gnome\gnmap.h ..\win\gnome\gnplayer.h \ - ..\win\gnome\gnsignal.h ..\win\gnome\gnglyph.h \ - ..\win\gnome\gnstatus.h ..\win\gnome\gntext.h \ - ..\win\gnome\gnmesg.h ..\win\gnome\gnyesno.h \ - ..\win\gnome\gnworn.h $(INCL)\func_tab.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnmenu.c -$(O)gnmesg.o: ..\win\gnome\gnmesg.c ..\win\gnome\gnmesg.h $(CONFIG_H) \ - ..\win\gnome\gnsignal.h ..\win\gnome\gnomeprv.h $(HACK_H) \ - $(INCL)\dlb.h $(INCL)\winGnome.h \ - ..\win\gnome\gnglyph.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnmesg.c -$(O)gnopts.o: ..\win\gnome\gnopts.c ..\win\gnome\gnopts.h ..\win\gnome\gnglyph.h \ - $(CONFIG_H) ..\win\gnome\gnmain.h ..\win\gnome\gnmap.h $(HACK_H) -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnopts.c -$(O)gnplayer.o: ..\win\gnome\gnplayer.c ..\win\gnome\gnplayer.h \ - ..\win\gnome\gnmain.h $(HACK_H) -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnplayer.c -$(O)gnsignal.o: ..\win\gnome\gnsignal.c ..\win\gnome\gnsignal.h \ - ..\win\gnome\gnomeprv.h $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h \ - ..\win\gnome\gnglyph.h ..\win\gnome\gnmain.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnsignal.c -$(O)gnstatus.o: ..\win\gnome\gnstatus.c ..\win\gnome\gnstatus.h $(CONFIG_H) \ - ..\win\gnome\gnsignal.h ..\win\gnome\gnomeprv.h $(HACK_H) \ - $(INCL)\dlb.h $(INCL)\winGnome.h \ - ..\win\gnome\gnglyph.h ..\win\gnome\gn_xpms.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnstatus.c -$(O)gntext.o: ..\win\gnome\gntext.c ..\win\gnome\gntext.h $(CONFIG_H) \ - ..\win\gnome\gnmain.h ..\win\gnome\gn_rip.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gntext.c -$(O)gnyesno.o: ..\win\gnome\gnyesno.c ..\win\gnome\gnbind.h \ - ..\win\gnome\gnomeprv.h $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h \ - ..\win\gnome\gnmain.h ..\win\gnome\gnmap.h \ - ..\win\gnome\gnmenu.h ..\win\gnome\gnplayer.h \ - ..\win\gnome\gnsignal.h ..\win\gnome\gnglyph.h \ - ..\win\gnome\gnstatus.h ..\win\gnome\gntext.h \ - ..\win\gnome\gnmesg.h ..\win\gnome\gnyesno.h \ - ..\win\gnome\gnworn.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnyesno.c -$(O)gnworn.o: ..\win\gnome\gnworn.c ..\win\gnome\gnworn.h $(CONFIG_H) \ - ..\win\gnome\gnglyph.h ..\win\gnome\gnsignal.h \ - ..\win\gnome\gnomeprv.h $(HACK_H) $(INCL)\dlb.h \ - $(INCL)\winGnome.h -# @$(cc) $(cflagsBuild) $(GNOMEINC) -Fo$@ ..\win\gnome\gnworn.c -$(O)wingem.o: ..\win\gem\wingem.c $(HACK_H) $(INCL)\func_tab.h $(INCL)\dlb.h \ - $(INCL)\wingem.h -# @$(cc) $(cflagsBuild) -Fo$@ ..\win\gem\wingem.c -$(O)wingem1.o: ..\win\gem\wingem1.c $(INCL)\gem_rsc.h $(INCL)\load_img.h \ - $(INCL)\gr_rect.h $(INCL)\wintype.h $(INCL)\wingem.h -# @$(cc) $(cflagsBuild) -Fo$@ ..\win\gem\wingem1.c -$(O)load_img.o: ..\win\gem\load_img.c $(INCL)\load_img.h -# @$(cc) $(cflagsBuild) -Fo$@ ..\win\gem\load_img.c -$(O)gr_rect.o: ..\win\gem\gr_rect.c $(INCL)\gr_rect.h -# @$(cc) $(cflagsBuild) -Fo$@ ..\win\gem\gr_rect.c -$(O)tile.o: $(SRC)\tile.c $(HACK_H) #cppregex.o: ..\sys\share\cppregex.cpp # $(CXX) $(CXXFLAGS) -Fo$@ ..\sys\share\cppregex.cpp -$(O)qt_bind.o: ..\win\Qt\qt_bind.cpp $(HACK_H) ..\win\Qt\qt_bind.h \ - ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h ..\win\Qt\qt_click.h \ - ..\win\Qt\qt_delay.h ..\win\Qt\qt_xcmd.h ..\win\Qt\qt_key.h \ - ..\win\Qt\qt_map.h ..\win\Qt\qt_win.h ..\win\Qt\qt_clust.h \ - ..\win\Qt\qt_menu.h ..\win\Qt\qt_rip.h ..\win\Qt\qt_msg.h \ - ..\win\Qt\qt_plsel.h ..\win\Qt\qt_svsel.h ..\win\Qt\qt_set.h \ - ..\win\Qt\qt_stat.h ..\win\Qt\qt_icon.h ..\win\Qt\qt_streq.h \ - ..\win\Qt\qt_line.h ..\win\Qt\qt_yndlg.h ..\win\Qt\qt_str.h \ +$(O)qt_bind.o: $(QT)\qt_bind.cpp $(HACK_H) $(QT)\qt_bind.h \ + $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_click.h \ + $(QT)\qt_delay.h $(QT)\qt_xcmd.h $(QT)\qt_key.h \ + $(QT)\qt_map.h $(QT)\qt_win.h $(QT)\qt_clust.h \ + $(QT)\qt_menu.h $(QT)\qt_rip.h $(QT)\qt_msg.h \ + $(QT)\qt_plsel.h $(QT)\qt_svsel.h $(QT)\qt_set.h \ + $(QT)\qt_stat.h $(QT)\qt_icon.h $(QT)\qt_streq.h \ + $(QT)\qt_line.h $(QT)\qt_yndlg.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h \ $(INCL)\dlb.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_bind.cpp -$(O)qt_click.o: ..\win\Qt\qt_click.cpp $(HACK_H) ..\win\Qt\qt_click.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_click.cpp -$(O)qt_clust.o: ..\win\Qt\qt_clust.cpp ..\win\Qt\qt_clust.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_clust.cpp -$(O)qt_delay.o: ..\win\Qt\qt_delay.cpp $(HACK_H) ..\win\Qt\qt_delay.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_delay.cpp -$(O)qt_glyph.o: ..\win\Qt\qt_glyph.cpp $(HACK_H) $(INCL)\tile2x11.h \ - ..\win\Qt\qt_glyph.h ..\win\Qt\qt_set.h ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_glyph.cpp -$(O)qt_icon.o: ..\win\Qt\qt_icon.cpp $(HACK_H) ..\win\Qt\qt_icon.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_icon.cpp -$(O)qt_inv.o: ..\win\Qt\qt_inv.cpp $(HACK_H) ..\win\Qt\qt_inv.h \ - ..\win\Qt\qt_glyph.h ..\win\Qt\qt_set.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_inv.cpp -$(O)qt_key.o: ..\win\Qt\qt_key.cpp $(HACK_H) ..\win\Qt\qt_key.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_key.cpp -$(O)qt_line.o: ..\win\Qt\qt_line.cpp $(HACK_H) ..\win\Qt\qt_line.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_line.cpp -$(O)qt_main.o: ..\win\Qt\qt_main.cpp $(HACK_H) \ - ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h qt_main.moc \ - ..\win\Qt\qt_bind.h ..\win\Qt\qt_glyph.h ..\win\Qt\qt_inv.h \ - ..\win\Qt\qt_key.h ..\win\Qt\qt_map.h ..\win\Qt\qt_win.h \ - ..\win\Qt\qt_clust.h ..\win\Qt\qt_msg.h ..\win\Qt\qt_set.h \ - ..\win\Qt\qt_stat.h ..\win\Qt\qt_icon.h ..\win\Qt\qt_str.h \ + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_bind.cpp +$(O)qt_click.o: $(QT)\qt_click.cpp $(HACK_H) $(QT)\qt_click.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_click.cpp \ + $(QT)\qt_pre.h $(QT)\qt_post.h +$(O)qt_clust.o: $(QT)\qt_clust.cpp $(QT)\qt_clust.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_clust.cpp +$(O)qt_delay.o: $(QT)\qt_delay.cpp $(HACK_H) $(QT)\qt_delay.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_delay.cpp \ + $(QT)\qt_pre.h $(QT)\qt_post.h +$(O)qt_glyph.o: $(QT)\qt_glyph.cpp $(HACK_H) $(INCL)\tile2x11.h \ + $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_glyph.cpp +$(O)qt_icon.o: $(QT)\qt_icon.cpp $(HACK_H) $(QT)\qt_icon.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_icon.cpp +$(O)qt_inv.o: $(QT)\qt_inv.cpp $(HACK_H) $(QT)\qt_inv.h \ + $(QT)\qt_glyph.h $(QT)\qt_set.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_inv.cpp +$(O)qt_key.o: $(QT)\qt_key.cpp $(HACK_H) $(QT)\qt_key.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_key.cpp +$(O)qt_line.o: $(QT)\qt_line.cpp $(HACK_H) $(QT)\qt_line.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_line.cpp +$(O)qt_main.o: $(QT)\qt_main.cpp $(HACK_H) \ + $(QT)\qt_main.h $(QT)\qt_kde0.h qt_main.moc \ + $(QT)\qt_bind.h $(QT)\qt_glyph.h $(QT)\qt_inv.h \ + $(QT)\qt_key.h $(QT)\qt_map.h $(QT)\qt_win.h \ + $(QT)\qt_clust.h $(QT)\qt_msg.h $(QT)\qt_set.h \ + $(QT)\qt_stat.h $(QT)\qt_icon.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h \ qt_kde0.moc - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_main.cpp -$(O)qt_map.o: ..\win\Qt\qt_map.cpp $(HACK_H) ..\win\Qt\qt_map.h ..\win\Qt\qt_win.h \ - ..\win\Qt\qt_clust.h qt_map.moc ..\win\Qt\qt_click.h \ - ..\win\Qt\qt_glyph.h ..\win\Qt\qt_xpms.h ..\win\Qt\qt_set.h \ - ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_map.cpp -$(O)qt_menu.o: ..\win\Qt\qt_menu.cpp $(HACK_H) ..\win\Qt\qt_menu.h \ - ..\win\Qt\qt_win.h ..\win\Qt\qt_rip.h qt_menu.moc \ - ..\win\Qt\qt_glyph.h ..\win\Qt\qt_set.h ..\win\Qt\qt_streq.h \ - ..\win\Qt\qt_line.h ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_menu.cpp -$(O)qt_msg.o: ..\win\Qt\qt_msg.cpp $(HACK_H) ..\win\Qt\qt_msg.h ..\win\Qt\qt_win.h \ - qt_msg.moc ..\win\Qt\qt_map.h ..\win\Qt\qt_clust.h \ - ..\win\Qt\qt_set.h ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_msg.cpp -$(O)qt_plsel.o: ..\win\Qt\qt_plsel.cpp $(HACK_H) ..\win\Qt\qt_plsel.h qt_plsel.moc \ - ..\win\Qt\qt_bind.h ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h \ - ..\win\Qt\qt_glyph.h ..\win\Qt\qt_set.h ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_plsel.cpp -$(O)qt_rip.o: ..\win\Qt\qt_rip.cpp $(HACK_H) ..\win\Qt\qt_rip.h \ - ..\win\Qt\qt_bind.h ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h \ - ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_rip.cpp -$(O)qt_set.o: ..\win\Qt\qt_set.cpp $(HACK_H) ..\win\Qt\qt_set.h qt_set.moc \ - ..\win\Qt\qt_glyph.h ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_set.cpp -$(O)qt_stat.o: ..\win\Qt\qt_stat.cpp $(HACK_H) ..\win\Qt\qt_stat.h \ - ..\win\Qt\qt_win.h ..\win\Qt\qt_icon.h qt_stat.moc \ - ..\win\Qt\qt_set.h ..\win\Qt\qt_str.h ..\win\Qt\qt_xpms.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_stat.cpp -$(O)qt_str.o: ..\win\Qt\qt_str.cpp ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_str.cpp -$(O)qt_streq.o: ..\win\Qt\qt_streq.cpp $(HACK_H) ..\win\Qt\qt_streq.h \ - ..\win\Qt\qt_line.h ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_streq.cpp -$(O)qt_svsel.o: ..\win\Qt\qt_svsel.cpp $(HACK_H) ..\win\Qt\qt_svsel.h \ - ..\win\Qt\qt_bind.h ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h \ - ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_svsel.cpp -$(O)qt_win.o: ..\win\Qt\qt_win.cpp $(HACK_H) ..\win\Qt\qt_win.h \ - ..\win\Qt\qt_bind.h ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h \ - ..\win\Qt\qt_click.h ..\win\Qt\qt_glyph.h ..\win\Qt\qt_inv.h \ - ..\win\Qt\qt_key.h ..\win\Qt\qt_icon.h ..\win\Qt\qt_map.h \ - ..\win\Qt\qt_clust.h ..\win\Qt\qt_menu.h ..\win\Qt\qt_rip.h \ - ..\win\Qt\qt_msg.h ..\win\Qt\qt_set.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_win.cpp -$(O)qt_xcmd.o: ..\win\Qt\qt_xcmd.cpp $(HACK_H) $(INCL)\func_tab.h \ - ..\win\Qt\qt_xcmd.h qt_xcmd.moc ..\win\Qt\qt_bind.h \ - ..\win\Qt\qt_main.h ..\win\Qt\qt_kde0.h ..\win\Qt\qt_set.h \ - ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_xcmd.cpp -$(O)qt_yndlg.o: ..\win\Qt\qt_yndlg.cpp $(HACK_H) ..\win\Qt\qt_yndlg.h qt_yndlg.moc \ - ..\win\Qt\qt_str.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt\qt_yndlg.cpp -$(O)qt3_win.o: ..\win\Qt3\qt3_win.cpp $(HACK_H) $(INCL)\func_tab.h \ - $(INCL)\dlb.h $(INCL)\tile2x11.h \ - ..\win\Qt3\qt3_win.h ..\win\Qt3\qt3_clust.h \ - ..\win\Qt3\qt3_kde0.h ..\win\Qt3\qt3_xpms.h qt3_win.moc \ - qt3_kde0.moc qt3tableview.moc - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt3\qt3_win.cpp -$(O)qt3_clust.o: ..\win\Qt3\qt3_clust.cpp ..\win\Qt3\qt3_clust.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt3\qt3_clust.cpp -$(O)qt3tableview.o: ..\win\Qt3\qt3tableview.cpp ..\win\Qt3\qt3tableview.h - $(CXX) $(CXXFLAGS) -Fo$@ ..\win\Qt3\qt3tableview.cpp + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_main.cpp +$(O)qt_map.o: $(QT)\qt_map.cpp $(HACK_H) $(QT)\qt_map.h $(QT)\qt_win.h \ + $(QT)\qt_clust.h qt_map.moc $(QT)\qt_click.h \ + $(QT)\qt_glyph.h $(QT)\qt_xpms.h $(QT)\qt_set.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h \ + $(QT)\qt_str.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_map.cpp +$(O)qt_menu.o: $(QT)\qt_menu.cpp $(HACK_H) $(QT)\qt_menu.h \ + $(QT)\qt_win.h $(QT)\qt_rip.h qt_menu.moc \ + $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_streq.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h \ + $(QT)\qt_line.h $(QT)\qt_str.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_menu.cpp +$(O)qt_msg.o: $(QT)\qt_msg.cpp $(HACK_H) $(QT)\qt_msg.h $(QT)\qt_win.h \ + qt_msg.moc $(QT)\qt_map.h $(QT)\qt_clust.h \ + $(QT)\qt_set.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_msg.cpp +$(O)qt_plsel.o: $(QT)\qt_plsel.cpp $(HACK_H) $(QT)\qt_plsel.h qt_plsel.moc \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_plsel.cpp +$(O)qt_rip.o: $(QT)\qt_rip.cpp $(HACK_H) $(QT)\qt_rip.h \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_rip.cpp +$(O)qt_set.o: $(QT)\qt_set.cpp $(HACK_H) $(QT)\qt_set.h qt_set.moc \ + $(QT)\qt_glyph.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_set.cpp +$(O)qt_stat.o: $(QT)\qt_stat.cpp $(HACK_H) $(QT)\qt_stat.h \ + $(QT)\qt_win.h $(QT)\qt_icon.h qt_stat.moc \ + $(QT)\qt_set.h $(QT)\qt_str.h $(QT)\qt_xpms.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_stat.cpp +$(O)qt_str.o: $(QT)\qt_str.cpp $(QT)\qt_str.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_str.cpp +$(O)qt_streq.o: $(QT)\qt_streq.cpp $(HACK_H) $(QT)\qt_streq.h \ + $(QT)\qt_line.h $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_streq.cpp +$(O)qt_svsel.o: $(QT)\qt_svsel.cpp $(HACK_H) $(QT)\qt_svsel.h \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_svsel.cpp +$(O)qt_win.o: $(QT)\qt_win.cpp $(HACK_H) $(QT)\qt_win.h \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + $(QT)\qt_click.h $(QT)\qt_glyph.h $(QT)\qt_inv.h \ + $(QT)\qt_key.h $(QT)\qt_icon.h $(QT)\qt_map.h \ + $(QT)\qt_clust.h $(QT)\qt_menu.h $(QT)\qt_rip.h \ + $(QT)\qt_msg.h $(QT)\qt_set.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_win.cpp +$(O)qt_xcmd.o: $(QT)\qt_xcmd.cpp $(HACK_H) $(INCL)\func_tab.h \ + $(QT)\qt_xcmd.h qt_xcmd.moc $(QT)\qt_bind.h \ + $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_set.h \ + $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_xcmd.cpp +$(O)qt_yndlg.o: $(QT)\qt_yndlg.cpp $(HACK_H) $(QT)\qt_yndlg.h qt_yndlg.moc \ + $(QT)\qt_str.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_yndlg.cpp $(O)wc_chainin.o: ..\win\chain\wc_chainin.c $(HACK_H) # @$(cc) $(cflagsBuild) -Fo$@ ..\win\chain\wc_chainin.c $(O)wc_chainout.o: ..\win\chain\wc_chainout.c $(HACK_H) @@ -1983,7 +1902,6 @@ $(O)dog.o: dog.c $(HACK_H) $(O)dogmove.o: dogmove.c $(HACK_H) $(INCL)\mfndpos.h $(O)dokick.o: dokick.c $(HACK_H) $(O)dothrow.o: dothrow.c $(HACK_H) -$(O)drawing.o: drawing.c $(CONFIG_H) $(O)dungeon.o: dungeon.c $(HACK_H) $(INCL)\dgn_file.h $(INCL)\dlb.h $(O)eat.o: eat.c $(HACK_H) $(O)end.o: end.c $(HACK_H) $(INCL)\dlb.h From d8e383c63f7753f895296856332eefbdc6145015 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 18 Jul 2020 08:18:25 -0700 Subject: [PATCH 018/708] unix/hints/macosx10.10-qt macosx10.10-qt was derived from an out of date version of macosx10.10. This tries to make combined X11+Qt behave sanely but I have no way of testing it. It appears to require homebrew, at least that's what the construct $(shell brew ...) to set up QTDIR suggests. That seems iffy and should at least be documented. It includes tty along with Qt but lacks support for including the curses interface so definitely needs more updating. --- sys/unix/hints/macosx10.10-qt | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index c190364e7..759703a5b 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.11 $NHDT-Date: 1566346604 2019/08/21 00:16:44 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.51 $ +# NetHack 3.6 macosx10.11 $NHDT-Date: 1595085485 2020/07/18 15:18:05 $ $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. # @@ -24,7 +24,7 @@ WANT_WIN_QT=1 # 1a. What is the default window system? #WANT_DEFAULT=tty -#WANT_DEFAULT=x11 +#WANT_DEFAULT=X11 WANT_DEFAULT=Qt # 1b. If you set WANT_WIN_QT, you need to @@ -101,15 +101,22 @@ CFLAGS += -DNOTTYGRAPHICS endif # !WANT_WIN_TTY ifdef WANT_WIN_X11 +VARDATND0 = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); +CFLAGS += -DX11_GRAPHICS +# separate from CFLAGS so that we don't pass it to every file +X11CFLAGS = -I/opt/X11/include +# avoid repeated complaints about _X_NONNULL(args...) in +X11CFLAGS += -Wno-variadic-macros +ifdef USE_XPM +CFLAGS += -DUSE_XPM +WINX11LIB += -lXpm +VARDATND0 += rip.xpm +endif WINSRC += $(WINX11SRC) WINOBJ0 += $(WINX11OBJ) WINLIB += $(WINX11LIB) -LFLAGS += -L/opt/X11/lib -VARDATND += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm -POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(HACKDIR)/nh10.pcf; ( cd $(HACKDIR); mkfontdir -x .lev ); -CFLAGS += -DX11_GRAPHICS -I/opt/X11/include -# avoid repeated complaints about _X_NONNULL(args...) in -CFLAGS += -Wno-variadic-macros +LFLAGS=-L/opt/X11/lib endif # WANT_WIN_X11 ifdef WANT_WIN_QT @@ -120,7 +127,7 @@ WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Wi LINK=$(CXX) WINSRC += $(WINQTSRC) WINOBJ0 += $(WINQTOBJ) -VARDATND += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm +VARDATND0 = nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm MOC = moc # XXX if /Developer/qt exists and QTDIR not set, use that @@ -132,6 +139,8 @@ endif # WANT_WIN_QT # prevent duplicate tile.o in WINOBJ WINOBJ = $(sort $(WINOBJ0)) +# also prevent duplicate data files if both X11 and Qt are being supported +VARDATND+= $(sort $(VARDATND0)) ifdef WANT_SHARE_INSTALL # if $GAMEUID is root, we install into roughly proper Mac locations, otherwise From 22cbabde8d96ed9023d0d2fe12de0faf192beff3 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 18 Jul 2020 12:59:24 -0700 Subject: [PATCH 019/708] Qt tiles loading failure For Qt, if unable to load either nhfiles.bmp or x11tiles, quit after giving the can't-load-tiles feedback instead of continuing on and eventually triggering a segfault. --- doc/fixes37.0 | 3 ++- win/Qt/qt_glyph.cpp | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3a3d66001..b942f6c9e 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.250 $ $NHDT-Date: 1595006054 2020/07/17 17:14:14 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ $NHDT-Date: 1595102359 2020/07/18 19:59:19 $ General Fixes and Modified Features ----------------------------------- @@ -310,6 +310,7 @@ curses: for vertical status, line up conditions in columns; usually two but used to align entries in their columns--that's a feature...] msdos: add -DSTATUES_LOOK_LIKE_MONSTERS to Makefile1.cross so the VESA mode can display statue glyphs +Qt: quit if can't load tiles file instead of continuing and then segfaulting tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 1e01adb9d..b804b939e 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -25,6 +25,7 @@ extern "C" { #endif #include "qt_post.h" #include "qt_glyph.h" +#include "qt_bind.h" #include "qt_set.h" #include "qt_str.h" @@ -47,6 +48,7 @@ static int tilefile_tile_H=16; NetHackQtGlyphs::NetHackQtGlyphs() { const char* tile_file = PIXMAPDIR "/nhtiles.bmp"; + if ( iflags.wc_tile_file ) tile_file = iflags.wc_tile_file; @@ -54,13 +56,17 @@ NetHackQtGlyphs::NetHackQtGlyphs() tile_file = PIXMAPDIR "/x11tiles"; if (!img.load(tile_file)) { QString msg; - msg.sprintf("Cannot load x11tiles or nhtiles.bmp"); + + msg.sprintf("Cannot load 'nhtiles.bmp' or 'x11tiles'."); QMessageBox::warning(0, "IO Error", msg); + NetHackQtBind::qt_exit_nhwindows((const char *) 0); + nh_terminate(EXIT_FAILURE); } else { tiles_per_row = TILES_PER_ROW; - if (img.width()%tiles_per_row) { - impossible("Tile file \"%s\" has %d columns, not multiple of row count (%d)", - tile_file, img.width(), tiles_per_row); + if (img.width() % tiles_per_row) { + impossible( + "Tile file \"%s\" has %d columns, not multiple of row count (%d)", + tile_file, img.width(), tiles_per_row); } } } else { From afbcf3f9a9b122c5e47ac17c4d55cc203e9fe45e Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 20 Jul 2020 03:00:28 -0700 Subject: [PATCH 020/708] monk's to-hit penalty for wearing a suit If hero is a monk who is wearing a suit, have ^X mention the to-hit penalty for that in the status section even though it isn't a normal status line item. Combat feedback makes it annoyingly obvious, but player might forget if MSGTYPE=hide is used to suppress the "Your armor is rather cumbersome..." message. --- doc/fixes37.0 | 1 + include/flag.h | 1 + src/insight.c | 18 ++++++++++++++++-- src/worn.c | 11 ++++++++--- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b942f6c9e..54eaa0d11 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -391,6 +391,7 @@ for !fixinv option where inventory letters normally don't stick, try to put thrown from; only works if it does return and is successfully caught wizard mode #wizborn command include more skill information in ^X output when dual-wielding +include monk's to-hit penalty for worn suit in the status section of ^X output item-using monsters will zap wand of undead turning at corpse-wielding hero when the corpse is harmful boiling a pool or fountain now creates a temporary cloud of steam diff --git a/include/flag.h b/include/flag.h index 3439cc5b1..6750e336f 100644 --- a/include/flag.h +++ b/include/flag.h @@ -238,6 +238,7 @@ struct instance_flags { * disable to avoid excessive noise when using * a screen reader (use ^X to review status) */ boolean toptenwin; /* ending list in window instead of stdout */ + boolean tux_penalty; /* True iff hero is a monk and wearing a suit */ boolean use_background_glyph; /* use background glyph when appropriate */ boolean use_menu_color; /* use color in menus; only if wc_color */ #ifdef STATUS_HILITES diff --git a/src/insight.c b/src/insight.c index b26e1efbf..a110c1cea 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1018,6 +1018,15 @@ int final; } /* current weapon(s) and corresponding skill level(s) */ weapon_insight(final); + /* unlike ring of increase accuracy's effect, the monk's suit penalty + is too blatant to be restricted to magical enlightenment */ + if (iflags.tux_penalty && !Upolyd) { + (void) enlght_combatinc("to hit", -g.urole.spelarmr, final, buf); + /* if from_what() ever gets extended from wizard mode to normal + play, it could be adapted to handled this */ + Sprintf(eos(buf), " due to your %s", suit_simple_name(uarm)); + you_have(buf, ""); + } /* report 'nudity' */ if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) { if (u.uroleplay.nudist) @@ -1467,8 +1476,13 @@ int final; enl_msg("You regenerate", "", "d", "", from_what(REGENERATION)); if (Slow_digestion) you_have("slower digestion", from_what(SLOW_DIGESTION)); - if (u.uhitinc) - you_have(enlght_combatinc("to hit", u.uhitinc, final, buf), ""); + if (u.uhitinc) { + (void) enlght_combatinc("to hit", u.uhitinc, final, buf); + if (iflags.tux_penalty && !Upolyd) + Sprintf(eos(buf), " %s your suit penalty", + (u.uhitinc < 0) ? "increasing" : "offsetting"); + you_have(buf, ""); + } if (u.udaminc) you_have(enlght_combatinc("damage", u.udaminc, final, buf), ""); if (u.uspellprot || Protection) { diff --git a/src/worn.c b/src/worn.c index 231df0961..918a3b143 100644 --- a/src/worn.c +++ b/src/worn.c @@ -57,9 +57,7 @@ long mask; uskin = obj; /* assert( !uarm ); */ } else { - if ((mask & W_ARMOR)) - u.uroleplay.nudist = FALSE; - for (wp = worn; wp->w_mask; wp++) + for (wp = worn; wp->w_mask; wp++) { if (wp->w_mask & mask) { oobj = *(wp->w_obj); if (oobj && !(oobj->owornmask & wp->w_mask)) @@ -105,6 +103,11 @@ long mask; } } } + } + if (obj && (obj->owornmask & W_ARMOR) != 0L) + u.uroleplay.nudist = FALSE; + /* tux -> tuxedo -> "monkey suit" -> monk's suit */ + iflags.tux_penalty = (uarm && Role_if(PM_MONK) && g.urole.spelarmr); } update_inventory(); } @@ -137,6 +140,8 @@ register struct obj *obj; if ((p = w_blocks(obj, wp->w_mask)) != 0) u.uprops[p].blocked &= ~wp->w_mask; } + if (!uarm) + iflags.tux_penalty = FALSE; update_inventory(); } From 97cbbaa0ac7cfaea95b40e5bcf58f9a907dc7404 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 20 Jul 2020 15:04:25 -0700 Subject: [PATCH 021/708] more feedback for monk suit penalty Refine the enlightenment feedback when a monk has both a suit penalty and an increase accuracy bonus. --- src/insight.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/insight.c b/src/insight.c index a110c1cea..021d06753 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1593771616 2020/07/03 10:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1595282650 2020/07/20 22:04:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1479,8 +1479,12 @@ int final; if (u.uhitinc) { (void) enlght_combatinc("to hit", u.uhitinc, final, buf); if (iflags.tux_penalty && !Upolyd) - Sprintf(eos(buf), " %s your suit penalty", - (u.uhitinc < 0) ? "increasing" : "offsetting"); + Sprintf(eos(buf), " %s your suit's penalty", + (u.uhitinc < 0) ? "increasing" + : (u.uhitinc < 4 * g.urole.spelarmr / 5) + ? "partly offsetting" + : (u.uhitinc < g.urole.spelarmr) ? "nearly offseting" + : "overcoming"); you_have(buf, ""); } if (u.udaminc) From c1c515af9f2528b3d26a93fc8b708454a3153ed1 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 24 Jul 2020 13:12:13 -0700 Subject: [PATCH 022/708] weapon skill usage A recent newsgroup or reddit complaint stated that only 75% of a monks attacks used martial arts. It turned out to be true; the 'valid_weapon_attack' intended to control whether skill gets exercised was being overloaded for skill use. So the monk's 1..4 base damage used skill for 2..4 but not for 1. That was never intended (nor for other roles and other skills; a damage value of 1 is meant to miss out on a chance to train the skill for future enhancement but should still get a skill bonus or penalty for the current attack). --- doc/fixes37.0 | 3 +- src/uhitm.c | 150 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 107 insertions(+), 46 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 54eaa0d11..201ca8174 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.251 $ $NHDT-Date: 1595102359 2020/07/18 19:59:19 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ $NHDT-Date: 1595621524 2020/07/24 20:12:04 $ General Fixes and Modified Features ----------------------------------- @@ -225,6 +225,7 @@ if a mind flayer's psychic blast targetted a hidden monster, feedback named the monster but it wasn't brought out of hiding hero poly'd into a mind flayer who used #monster to emit a psychic blast was able to harm mindless monsters with it +some hero attacks that should have gotten a skill bonus or penalty weren't Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/uhitm.c b/src/uhitm.c index 59e32e61c..2bbe579a4 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1593306911 2020/06/28 01:15:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.237 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1595621524 2020/07/24 20:12:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.238 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -680,7 +680,7 @@ int dieroll; unpoisonmsg = FALSE; boolean silvermsg = FALSE, silverobj = FALSE; boolean lightobj = FALSE; - boolean valid_weapon_attack = FALSE; + boolean use_weapon_skill = FALSE, train_weapon_skill = FALSE; boolean unarmed = !uwep && !uarm && !uarms; boolean hand_to_hand = (thrown == HMON_MELEE /* not grapnels; applied implies uwep */ @@ -695,13 +695,16 @@ int dieroll; wakeup(mon, TRUE); if (!obj) { /* attack with bare hands */ - if (mdat == &mons[PM_SHADE]) + if (mdat == &mons[PM_SHADE]) { tmp = 0; - else if (martial_bonus()) - tmp = rnd(4); /* bonus for martial arts */ - else - tmp = rnd(2); - valid_weapon_attack = (tmp > 1); + } else { + /* note: 1..2 or 1..4 can be substantiallly increased by + strength bonus or skill bonus, usually both... */ + tmp = rnd(!martial_bonus() ? 2 : 4); + use_weapon_skill = TRUE; + train_weapon_skill = (tmp > 1); + } + /* Blessed gloves give bonuses when fighting 'bare-handed'. So do silver rings. Note: rings are worn under gloves, so you don't get both bonuses, and two silver rings don't give double bonus. */ @@ -711,6 +714,7 @@ int dieroll; + ((silverhit & W_RINGR) ? 1 : 0)); if (barehand_silver_rings > 0) silvermsg = TRUE; + } else { if (!(artifact_light(obj) && obj->lamplit)) Strcpy(saved_oname, cxname(obj)); @@ -728,7 +732,8 @@ int dieroll; /* or throw a missile without the proper bow... */ || (is_ammo(obj) && (thrown != HMON_THROWN || !ammo_and_launcher(obj, uwep)))) { - /* then do only 1-2 points of damage */ + /* then do only 1-2 points of damage and don't use or + train weapon's skill */ if (mdat == &mons[PM_SHADE] && !shade_glare(obj)) tmp = 0; else @@ -757,10 +762,13 @@ int dieroll; tmp++; } } else { + /* "normal" weapon usage */ + use_weapon_skill = TRUE; tmp = dmgval(obj, mon); /* a minimal hit doesn't exercise proficiency */ - valid_weapon_attack = (tmp > 1); - if (!valid_weapon_attack || mon == u.ustuck || u.twoweap + train_weapon_skill = (tmp > 1); + /* special attack actions */ + if (!train_weapon_skill || mon == u.ustuck || u.twoweap /* Cleaver can hit up to three targets at once so don't let it also hit from behind or shatter foes' weapons */ || (hand_to_hand && obj->oartifact == ART_CLEAVER)) { @@ -813,6 +821,7 @@ int dieroll; destroyed and they might do so */ if (DEADMONSTER(mon)) /* artifact killed monster */ return FALSE; + /* perhaps artifact tried to behead a headless monster */ if (tmp == 0) return TRUE; hittxt = TRUE; @@ -830,25 +839,27 @@ int dieroll; jousting = joust(mon, obj); /* exercise skill even for minimal damage hits */ if (jousting) - valid_weapon_attack = TRUE; + train_weapon_skill = TRUE; } if (thrown == HMON_THROWN && (is_ammo(obj) || is_missile(obj))) { if (ammo_and_launcher(obj, uwep)) { - /* Elves and Samurai do extra damage using - * their bows&arrows; they're highly trained. - */ + /* elves and samurai do extra damage using their own + bows with own arrows; they're highly trained */ if (Role_if(PM_SAMURAI) && obj->otyp == YA && uwep->otyp == YUMI) tmp++; else if (Race_if(PM_ELF) && obj->otyp == ELVEN_ARROW && uwep->otyp == ELVEN_BOW) tmp++; + train_weapon_skill = (tmp > 0); } if (obj->opoisoned && is_poisonable(obj)) ispoisoned = TRUE; } } + + /* attacking with non-weapons */ } else if (obj->oclass == POTION_CLASS) { if (obj->quan > 1L) obj = splitobj(obj, 1L); @@ -1030,10 +1041,17 @@ int dieroll; pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!"); setmangry(mon, TRUE); } - if (thrown) - obfree(obj, (struct obj *) 0); - else - useup(obj); + { + boolean more_than_1 = (obj->quan > 1L); + + if (thrown) + obfree(obj, (struct obj *) 0); + else + useup(obj); + + if (!more_than_1) + obj = (struct obj *) 0; + } hittxt = TRUE; get_dmg_bonus = FALSE; tmp = 0; @@ -1046,10 +1064,17 @@ int dieroll; Your("venom burns %s!", mon_nam(mon)); tmp = dmgval(obj, mon); } - if (thrown) - obfree(obj, (struct obj *) 0); - else - useup(obj); + { + boolean more_than_1 = (obj->quan > 1L); + + if (thrown) + obfree(obj, (struct obj *) 0); + else + useup(obj); + + if (!more_than_1) + obj = (struct obj *) 0; + } hittxt = TRUE; get_dmg_bonus = FALSE; break; @@ -1086,28 +1111,62 @@ int dieroll; } } - /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) - * *OR* if attacking bare-handed!! */ + /* + ***** NOTE: perhaps obj is undefined! (if !thrown && BOOMERANG) + * *OR* if attacking bare-handed! + * Note too: the cases where obj might get destroyed do not + * set 'use_weapon_skill', bare-handed does. + */ - if (get_dmg_bonus && tmp > 0) { - tmp += u.udaminc; - /* If you throw using a propellor, you don't get a strength - * bonus but you do get an increase-damage bonus. + if (tmp > 0) { + int dmgbonus = 0; + + /* + * Potential bonus (or penalty) from worn ring of increase damage + * (or intrinsic bonus from eating same) or from strength. */ - if (thrown != HMON_THROWN || !obj || !uwep - || !ammo_and_launcher(obj, uwep)) - tmp += dbon(); - } + if (get_dmg_bonus) { + dmgbonus = u.udaminc; + /* throwing using a propellor gets an increase-damage bonus + but not a strength one; other attacks get both */ + if (thrown != HMON_THROWN + || !obj || !uwep || !ammo_and_launcher(obj, uwep)) + dmgbonus += dbon(); + } - if (valid_weapon_attack) { - struct obj *wep; + /* + * Potential bonus (or penalty) from weapon skill. + * 'use_weapon_skill' is True for hand-to-hand ordinary weapon, + * applied or jousting polearm or lance, thrown missile (dart, + * shuriken, boomerang), or shot ammo (arrow, bolt, rock/gem when + * wielding corresponding launcher). + * It is False for hand-to-hand or thrown non-weapon, hand-to-hand + * polearm or lance when not mounted, hand-to-hand missile or ammo + * or launcher, thrown non-missile, or thrown ammo (including rocks) + * when not wielding corresponding launcher. + */ + if (use_weapon_skill) { + struct obj *skillwep = obj; - /* to be valid a projectile must have had the correct projector */ - wep = PROJECTILE(obj) ? uwep : obj; - tmp += weapon_dam_bonus(wep); - /* [this assumes that `!thrown' implies wielded...] */ - wtype = thrown ? weapon_type(wep) : uwep_skill_type(); - use_skill(wtype, 1); + if (PROJECTILE(obj) && ammo_and_launcher(obj, uwep)) + skillwep = uwep; + dmgbonus += weapon_dam_bonus(skillwep); + + /* hit for more than minimal damage (before being adjusted + for damage or skill bonus) trains the skill toward future + enhancement */ + if (train_weapon_skill) { + /* [this assumes that `!thrown' implies wielded...] */ + wtype = thrown ? weapon_type(skillwep) : uwep_skill_type(); + use_skill(wtype, 1); + } + } + + /* apply combined damage+strength and skill bonuses */ + tmp += dmgbonus; + /* don't let penalty, if bonus is negative, turn a hit into a miss */ + if (tmp < 1) + tmp = 1; } if (ispoisoned) { @@ -1152,12 +1211,13 @@ int dieroll; if (jousting < 0) { pline("%s shatters on impact!", Yname2(obj)); /* (must be either primary or secondary weapon to get here) */ - set_twoweap(FALSE); /* u.twoweap = FALSE; untwoweapon() is too verbose */ + set_twoweap(FALSE); /* sets u.twoweap = FALSE; + * untwoweapon() is too verbose here */ if (obj == uwep) uwepgone(); /* set g.unweapon */ /* minor side-effect: broken lance won't split puddings */ useup(obj); - obj = 0; + obj = (struct obj *) 0; } /* avoid migrating a dead monster */ if (mon->mhp > tmp) { @@ -1214,9 +1274,9 @@ int dieroll; && !(is_ammo(obj) || is_missile(obj))) && hand_to_hand) { struct monst *mclone; - if ((mclone = clone_mon(mon, 0, 0)) != 0) { - char withwhat[BUFSZ]; + char withwhat[BUFSZ]; + if ((mclone = clone_mon(mon, 0, 0)) != 0) { withwhat[0] = '\0'; if (u.twoweap && flags.verbose) Sprintf(withwhat, " with %s", yname(obj)); From 42245f8e67d275de38a59a6257cb1b8d81dcf5b7 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 24 Jul 2020 14:45:59 -0700 Subject: [PATCH 023/708] wizard mode vs venom object names I tried wishing for "splashes of venom" but was told that no such thing exists even though "splashs of venom" and "2 splash of venom" both work to produce "2 splashes of venom". After the spurious failure, retrying with EDIT_GETLIN enabled showed that "splashes" had been singularized to "splashe" so fix that. "2 splashes of venom" IDed to "2 uncursed blinding venoms" because the base name omits "splash of" prefix. And due to that, explicitly wishing for "splash of {acid,blinding} venom" didn't work either. Change the names to include the prefix, and add a hack to makedefs to keep generating the old macro names without the prefix. (Wishing for "{acid,blinding} venom" still works due to post-3.6.6 changes to " of " matching.) --- doc/fixes37.0 | 4 +++- src/objects.c | 6 +++--- src/objnam.c | 4 +++- util/makedefs.c | 12 +++++++++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 201ca8174..6dc8c6919 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.253 $ $NHDT-Date: 1595621524 2020/07/24 20:12:04 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.254 $ $NHDT-Date: 1595627151 2020/07/24 21:45:51 $ General Fixes and Modified Features ----------------------------------- @@ -226,6 +226,8 @@ if a mind flayer's psychic blast targetted a hidden monster, feedback named hero poly'd into a mind flayer who used #monster to emit a psychic blast was able to harm mindless monsters with it some hero attacks that should have gotten a skill bonus or penalty weren't +change internal name of " venom" to "splash of venom" +singularize "splashes" to "splash" instead of "splashe" Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/objects.c b/src/objects.c index 8c4d2a9ab..771178eed 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objects.c $NHDT-Date: 1578855624 2020/01/12 19:00:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.61 $ */ +/* NetHack 3.6 objects.c $NHDT-Date: 1595627151 2020/07/24 21:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) Mike Threepoint, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1150,10 +1150,10 @@ OBJECT(OBJ("iron chain", None), /* Venom is normally a transitory missile (spit by various creatures) * but can be wished for in wizard mode so could occur in bones data. */ -OBJECT(OBJ("blinding venom", "splash of venom"), +OBJECT(OBJ("splash of blinding venom", "splash of venom"), BITS(0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, P_NONE, LIQUID), 0, VENOM_CLASS, 500, 0, 1, 0, 0, 0, 0, 0, 0, HI_ORGANIC), -OBJECT(OBJ("acid venom", "splash of venom"), +OBJECT(OBJ("splash of acid venom", "splash of venom"), BITS(0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, P_NONE, LIQUID), 0, VENOM_CLASS, 500, 0, 1, 0, 6, 6, 0, 0, 0, HI_ORGANIC), /* +d6 small or large */ diff --git a/src/objnam.c b/src/objnam.c index ab70f3c03..4dc8c585b 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1583315888 2020/03/04 09:58:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.293 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1595627152 2020/07/24 21:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.303 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -713,6 +713,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ } default: Sprintf(buf, "glorkum %d %d %d", obj->oclass, typ, obj->spe); + break; } if (pluralize) Strcpy(buf, makeplural(buf)); @@ -2592,6 +2593,7 @@ const char *oldstr; || !BSTRCMPI(bp, p - 4, "nxes") /* lynxes */ || !BSTRCMPI(bp, p - 4, "ches") || !BSTRCMPI(bp, p - 4, "uses") /* lotuses */ + || !BSTRCMPI(bp, p - 4, "shes") /* splashes [of venom] */ || !BSTRCMPI(bp, p - 4, "sses") /* priestesses */ || !BSTRCMPI(bp, p - 5, "atoes") /* tomatoes */ || !BSTRCMPI(bp, p - 7, "dingoes") diff --git a/util/makedefs.c b/util/makedefs.c index 12bf8009c..f113b0ae9 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makedefs.c $NHDT-Date: 1594347789 2020/07/10 02:23:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ +/* NetHack 3.6 makedefs.c $NHDT-Date: 1595627153 2020/07/24 21:45:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -2091,8 +2091,18 @@ do_objs() break; } /*FALLTHRU*/ + case VENOM_CLASS: + /* fall-through from gem class is ok; objects[] used to have + { "{acid,blinding} venom", "splash of venom" } + but those have been changed to + { "splash of {acid,blinding} venom", "splash of venom" } + so strip the extra "splash of " off to keep same macros */ + if (!strncmp(objnam, "SPLASH_OF_", 10)) + objnam += 10; + /*FALLTHRU*/ default: Fprintf(ofp, "#define\t"); + break; } if (prefix >= 0) Fprintf(ofp, "%s\t%d\n", limit(objnam, prefix), i); From f66b6458789e0f55ffaeb979557a161e9662cb75 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 24 Jul 2020 17:39:48 -0700 Subject: [PATCH 024/708] couple of comment typos --- doc/fixes37.0 | 4 ++-- src/insight.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 6dc8c6919..95fa0b92d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.254 $ $NHDT-Date: 1595627151 2020/07/24 21:45:51 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.255 $ $NHDT-Date: 1595637572 2020/07/25 00:39:32 $ General Fixes and Modified Features ----------------------------------- @@ -225,7 +225,7 @@ if a mind flayer's psychic blast targetted a hidden monster, feedback named the monster but it wasn't brought out of hiding hero poly'd into a mind flayer who used #monster to emit a psychic blast was able to harm mindless monsters with it -some hero attacks that should have gotten a skill bonus or penalty weren't +some hero attacks that should have gotten a skill bonus or penalty didn't change internal name of " venom" to "splash of venom" singularize "splashes" to "splash" instead of "splashe" diff --git a/src/insight.c b/src/insight.c index 021d06753..16d30d96f 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1595282650 2020/07/20 22:04:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1595637572 2020/07/25 00:39:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1023,7 +1023,7 @@ int final; if (iflags.tux_penalty && !Upolyd) { (void) enlght_combatinc("to hit", -g.urole.spelarmr, final, buf); /* if from_what() ever gets extended from wizard mode to normal - play, it could be adapted to handled this */ + play, it could be adapted to handle this */ Sprintf(eos(buf), " due to your %s", suit_simple_name(uarm)); you_have(buf, ""); } From 84ccc144511ad0d77b40bfbf70c759bcf27c1ced Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 24 Jul 2020 18:25:54 -0700 Subject: [PATCH 025/708] wizhelp update Update the help menu entry for wizard mode commands to reflect the recent change to #wizrumorcheck. This messes up the formatting a bit (by introducing a continuation line) but the no longer precise command name warrants it. --- dat/wizhelp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dat/wizhelp b/dat/wizhelp index bc8a4715c..4e68fef66 100644 --- a/dat/wizhelp +++ b/dat/wizhelp @@ -22,7 +22,8 @@ Debug-Mode Quick Reference: #wizborn == show monster birth/death/geno/extinct stats #wizintrinsic == set selected intrinsic timeouts #wizmakemap == recreate the current dungeon level -#wizrumorcheck == validate first and last rumor for true and false set +#wizrumorcheck == validate rumor indexing and show first, second, and last + random engravings, epitaphs, and hallucinatory monsters #wizsmell == smell a monster #wizwhere == show dungeon placement of all special levels #wmode == show wall modes From 6973e637763679d3007d3f3cd46ea8ae2afc229b Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 25 Jul 2020 02:21:32 -0700 Subject: [PATCH 026/708] venom vs tiles tiles2x11 didn't complain about the tile definitions of the renamed objects. It seems to me that all processors of win/share/*.txt ought to be sharing the same code instead of apparently rolling their own. (Maybe the issue was issuing diagnostic messages rather than noticing the name mismatches? I haven't looked.) --- doc/fixes37.0 | 4 +++- win/share/objects.txt | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 95fa0b92d..e24f9302c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.255 $ $NHDT-Date: 1595637572 2020/07/25 00:39:32 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ $NHDT-Date: 1595668889 2020/07/25 09:21:29 $ General Fixes and Modified Features ----------------------------------- @@ -292,6 +292,8 @@ if a monster removed a corpse from an ice box, the corpse would never rot away monster creation on quest levels could make genocided creatures enabling wizard mode 'sanity_check' option would complain about invalid mhpmax value for level N monsters created with a d8 value of 1 for all N d8's +some versions of tiles processing (not X11's) complained about the rename of + "{acid,blinding} venom" to "splash of {acid,blinding} venom" tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display diff --git a/win/share/objects.txt b/win/share/objects.txt index 6cc337be3..094c7c14a 100644 --- a/win/share/objects.txt +++ b/win/share/objects.txt @@ -8692,7 +8692,7 @@ Z = (195, 195, 195) ...........PP.PA ............AA.. } -# tile 456 (splash of venom / blinding venom) +# tile 456 (splash of venom / splash of blinding venom) { ................ ................ @@ -8711,7 +8711,7 @@ Z = (195, 195, 195) ................ ................ } -# tile 457 (splash of venom / acid venom) +# tile 457 (splash of venom / splash of acid venom) { ................ ................ From c37882d16b6ade4504ac1f2aae2fe828875a4a86 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Jul 2020 11:41:58 -0400 Subject: [PATCH 027/708] x11 utility tile name comparisons were checking against unitialized data --- win/X11/tile2x11.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/win/X11/tile2x11.c b/win/X11/tile2x11.c index 774b6e636..762f95ba2 100644 --- a/win/X11/tile2x11.c +++ b/win/X11/tile2x11.c @@ -22,6 +22,9 @@ unsigned char tile_bytes[TILE_X * TILE_Y * (MAX_GLYPH + TILES_PER_ROW)]; unsigned char *curr_tb = tile_bytes; unsigned char x11_colormap[MAXCOLORMAPSIZE][3]; +extern void NDECL(monst_globals_init); +extern void NDECL(objects_globals_init); + /* Look up the given pixel and return its colormap index. */ static unsigned char pix_to_colormap(pix) @@ -187,6 +190,10 @@ char **argv; exit(1); } + /* without this, the comparisons check uninitialized data and won't pass */ + objects_globals_init(); + monst_globals_init(); + fp = fopen(OUTNAME, "w"); if (!fp) { Fprintf(stderr, "can't open output file\n"); From 694fe2f16198ac75f4f5b96ee6aa4340d12b33d6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 25 Jul 2020 11:42:59 -0400 Subject: [PATCH 028/708] allow checking tile2x11 utility build and execution on Windows - this doesn't depend on building with X11 or linking with X11. --- sys/winnt/Makefile.msc | 69 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 22 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 629213b47..4cb968c8b 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -190,6 +190,7 @@ MSWIN = ..\win\win32 # window port files (win32) WCURSES = ..\win\curses # window port files (curses) WSHR = ..\win\share # Tile support files QT = ..\win\Qt # QT support files +X11 = ..\win\X11 # X11 support files # # Object directory. @@ -1361,6 +1362,30 @@ $(O)tile2bmp.o: $(WSHR)\tile2bmp.c $(HACK_H) $(TILE_H) $(MSWSYS)\win32api.h $(O)til2bm32.o: $(WSHR)\tile2bmp.c $(HACK_H) $(TILE_H) $(MSWSYS)\win32api.h @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DPACKED_FILE /DTILE_X=32 /DTILE_Y=32 /Fo$@ $(WSHR)\tile2bmp.c +$(U)tile2x11.exe: $(O)tile2x11.o $(O)tiletext.o $(O)tiletxt.o $(O)alloc.o \ + $(O)panic.o $(O)monst.o $(O)objects.o + @echo Linking $(@:\=/) + @$(link) $(lflagsBuild) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ @<<$(@B).lnk + $(O)tile2x11.o + $(O)tiletext.o + $(O)tiletxt.o + $(O)drawing.o + $(O)monst.o + $(O)objects.o + $(O)alloc.o + $(O)panic.o +<< + +$(O)tile2x11.o: $(X11)\tile2x11.c $(HACK_H) $(TILE_H) $(INCL)\tile2x11.h + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DPACKED_FILE /Fo$@ $(X11)\tile2x11.c + +$(SRC)\x11tiles: $(U)tile2x11.exe $(WSHR)\monsters.txt $(WSHR)\objects.txt \ + $(WSHR)\other.txt \ + $(WSHR)\monsters.txt + $(U)tile2x11 $(WSHR)\monsters.txt $(WSHR)\objects.txt \ + $(WSHR)\other.txt \ + -grayscale $(WSHR)\monsters.txt + #=============================================================================== # PDCurses #=============================================================================== @@ -1735,31 +1760,31 @@ $(O)cursmesg.o: ..\win\curses\cursmesg.c $(HACK_H) $(INCL)\wincurs.h \ $(O)cursinvt.o: ..\win\curses\cursinvt.c $(HACK_H) $(INCL)\wincurs.h \ ..\win\curses\cursinvt.h # @$(cc) $(cflagsBuild) -Fo$@ ..\win\curses\cursinvt.c -#$(O)Window.o: ..\win\X11\Window.c $(INCL)\xwindowp.h $(INCL)\xwindow.h \ +#$(O)Window.o: $(X11)\Window.c $(INCL)\xwindowp.h $(INCL)\xwindow.h \ # $(CONFIG_H) $(INCL)\lint.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\Window.c -$(O)dialogs.o: ..\win\X11\dialogs.c $(CONFIG_H) $(INCL)\lint.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\dialogs.c -$(O)winX.o: ..\win\X11\winX.c $(HACK_H) $(INCL)\winX.h $(INCL)\dlb.h \ - $(INCL)\xwindow.h ..\win\X11\nh72icon ..\win\X11\nh56icon \ - ..\win\X11\nh32icon -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winX.c -$(O)winmap.o: ..\win\X11\winmap.c $(INCL)\xwindow.h $(HACK_H) $(INCL)\dlb.h \ +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\Window.c +$(O)dialogs.o: $(X11)\dialogs.c $(CONFIG_H) $(INCL)\lint.h +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\dialogs.c +$(O)winX.o: $(X11)\winX.c $(HACK_H) $(INCL)\winX.h $(INCL)\dlb.h \ + $(INCL)\xwindow.h $(X11)\nh72icon $(X11)\nh56icon \ + $(X11)\nh32icon +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winX.c +$(O)winmap.o: $(X11)\winmap.c $(INCL)\xwindow.h $(HACK_H) $(INCL)\dlb.h \ $(INCL)\winX.h $(INCL)\tile2x11.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winmap.c -$(O)winmenu.o: ..\win\X11\winmenu.c $(HACK_H) $(INCL)\winX.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winmenu.c -$(O)winmesg.o: ..\win\X11\winmesg.c $(INCL)\xwindow.h $(HACK_H) $(INCL)\winX.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winmesg.c -$(O)winmisc.o: ..\win\X11\winmisc.c $(HACK_H) $(INCL)\func_tab.h \ +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winmap.c +$(O)winmenu.o: $(X11)\winmenu.c $(HACK_H) $(INCL)\winX.h +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winmenu.c +$(O)winmesg.o: $(X11)\winmesg.c $(INCL)\xwindow.h $(HACK_H) $(INCL)\winX.h +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winmesg.c +$(O)winmisc.o: $(X11)\winmisc.c $(HACK_H) $(INCL)\func_tab.h \ $(INCL)\winX.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winmisc.c -$(O)winstat.o: ..\win\X11\winstat.c $(HACK_H) $(INCL)\winX.h $(INCL)\xwindow.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winstat.c -$(O)wintext.o: ..\win\X11\wintext.c $(HACK_H) $(INCL)\winX.h $(INCL)\xwindow.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\wintext.c -$(O)winval.o: ..\win\X11\winval.c $(HACK_H) $(INCL)\winX.h -# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ ..\win\X11\winval.c +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winmisc.c +$(O)winstat.o: $(X11)\winstat.c $(HACK_H) $(INCL)\winX.h $(INCL)\xwindow.h +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winstat.c +$(O)wintext.o: $(X11)\wintext.c $(HACK_H) $(INCL)\winX.h $(INCL)\xwindow.h +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\wintext.c +$(O)winval.o: $(X11)\winval.c $(HACK_H) $(INCL)\winX.h +# @$(cc) $(cflagsBuild) $(X11CFLAGS) -Fo$@ $(X11)\winval.c $(O)tile.o: $(SRC)\tile.c $(HACK_H) #cppregex.o: ..\sys\share\cppregex.cpp # $(CXX) $(CXXFLAGS) -Fo$@ ..\sys\share\cppregex.cpp From d7307f9ca5bfc3407f4f73608404530ca968b247 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 25 Jul 2020 19:45:50 -0700 Subject: [PATCH 029/708] Guidebook tweaks Fix at least one typo. Change a few quoted and/or italicized words to fixed width (tty) font. In the "Curses and Blessings" subsection, mention dropping objects onto altars and the terms "BUC" and "BUCX". --- doc/Guidebook.mn | 47 +++++++++++++++++++++++++++++------------------ doc/Guidebook.tex | 46 +++++++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 92149f78b..713d2cbaf 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.392 $ $NHDT-Date: 1594599425 2020/07/13 00:17:05 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.393 $ $NHDT-Date: 1595731545 2020/07/26 02:45:45 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "July 9, 2020 +.ds f2 "July 25, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1813,7 +1813,7 @@ 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. +with a \fIscroll of earth\fP. However, doing such things will lower your luck without any specific message given about that. See the \fIConduct\fP section for information about getting feedback for @@ -1876,10 +1876,12 @@ 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. .pg -Shopkeepers sometimes 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 shop where -it was obtained; other shopkeepers won't honor it. (If you happen to +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 shop +where it was obtained; other shopkeepers won't honor it. +(If you happen to find a \(lqcredit card\(rq in the dungeon, don't bother trying to use it in shops; shopkeepers will not accept it.) .pg @@ -1901,7 +1903,7 @@ 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 were outside the shop. .lp * 2 -While the shopkeeper watches you like a hawk, he will generally ignore +While the shopkeeper watches you like a hawk, he or she will generally ignore any other customers. .lp * 2 If a shop is \(lqclosed for inventory,\(rq it will not open of its own accord. @@ -2140,8 +2142,8 @@ to discard some of what you're carrying or collapse under its weight. .pg NetHack will tell you how badly you have loaded yourself. If you are encumbered, one of the conditions -\(lq\fIBurdened\fP\(rq, \(lq\fIStressed\fP\(rq, \(lq\fIStrained\fP\(rq, -\(lq\fIOvertaxed\fP\(rq or \(lq\fIOverloaded\fP\(rq will be +\f(CRBurdened\fP, \f(CRStressed\fP, \f(CRStrained\fP, +\f(CROvertaxed\fP, or \f(CROverloaded\fP will be shown on the bottom line status display. .pg When you pick up an object, it is assigned an inventory letter. Many @@ -2177,9 +2179,10 @@ 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. .pg -Objects can also be blessed. Blessed items usually work better or -more beneficially than normal uncursed items. For example, a blessed -weapon will do more damage against demons. +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. .pg Objects which are neither cursed nor blessed are referred to as uncursed. They could just as easily have been described as unblessed, but the @@ -2189,20 +2192,28 @@ that what you will. .pg 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 +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. .pg An item with unknown status will be reported in your inventory with no prefix. An item which you know the state of will be distinguished in your inventory -by the presence of the word \(lqcursed\(rq, \(lquncursed\(rq or -\(lqblessed\(rq in the description of the item. -In some cases \(lquncursed\(rq will be omitted as being redundant when +by the presence of the word \f(CRcursed\fP, \f(CRuncursed\fP, or +\f(CRblessed\fP in the description of the item. +In some cases \f(CRuncursed\fP will be omitted as being redundant when enough other information is displayed. The .op implicit_uncursed -option can be used to control this; toggle it off to have \(lquncursed\(rq +option can be used to control this; toggle it off to have \f(CRuncursed\fP be displayed even when that can be deduced from other attributes. +.pg +Sometimes the bless or curse state of objects is referred to as their +\(lq\f(CRBUC\fP\(rq attribute, for Blessed, Uncursed, or Cursed state, +or \(lq\f(CRBUCX\fP\(rq for Blessed, Uncursed, Cursed, or unknown. +(The term \fIbeatitude\fP is occasionally used as well.) .hn 2 Weapons (\(oq)\(cq) .pg diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 64edc17e7..a2c542bd9 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{July 9, 2020} +\date{July 25, 2020} \maketitle @@ -1959,7 +1959,7 @@ 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. +with a {\it scroll of earth}. However, doing such things will lower your luck without any specific message given about that. See the {\it Conduct\/} section for information about getting feedback for @@ -2028,10 +2028,12 @@ claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. %.pg -Shopkeepers sometimes 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 shop where -it was obtained; other shopkeepers won't honor it. (If you happen to +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 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.) @@ -2060,7 +2062,7 @@ A shopkeeper treats the spot immediately inside the door as if it were outside the shop. %.lp \(bu 2 \item[$\bullet$] -While the shopkeeper watches you like a hawk, he will generally ignore +While the shopkeeper watches you like a hawk, he or she will generally ignore any other customers. %.lp \(bu 2 \item[$\bullet$] @@ -2324,8 +2326,8 @@ to discard some of what you're carrying or collapse under its weight. %.pg {\it NetHack\/} will tell you how badly you have loaded yourself. If you are encumbered, one of the conditions -``{\it Burdened\/}'', ``{\it Stressed\/}'', ``{\it Strained\/}'', -``{\it Overtaxed\/}'' or ``{\it Overloaded\/}'' will be +{\tt Burdened}, {\tt Stressed}, {\tt Strained}, +{\tt Overtaxed}, or {\tt Overloaded} will be shown on the bottom line status display. %.pg @@ -2366,9 +2368,10 @@ less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. %.pg -Objects can also be blessed. Blessed items usually work better or -more beneficially than normal uncursed items. For example, a blessed -weapon will do more damage against demons. +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. %.pg Objects which are neither cursed nor blessed are referred to as uncursed. @@ -2379,22 +2382,31 @@ half full versus glass half empty'' situation; make of that what you will. %.pg 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 +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. %.pg An item with unknown status will be reported in your inventory with no prefix. An item which you know the state of will be distinguished 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 +by the presence of the word {\tt cursed}, {\tt uncursed} or +{\tt blessed} in the description of the item. +In some cases {\tt uncursed} will be omitted as being redundant when enough other information is displayed. The {\it implicit\verb+_+uncursed\/} -option can be used to control this; toggle it off to have ``uncursed'' +option can be used to control this; toggle it off to have {\tt uncursed} be displayed even when that can be deduced from other attributes. +%.pg +Sometimes the bless or curse state of objects is referred to as their +``{\tt BUC}'' attribute, for Blessed, Uncursed, or Cursed state, +or ``{\tt BUCX}'' for Blessed, Uncursed, Cursed, or unknown. +(The term {\it beatitude\/} is occasionally used as well.) + %.hn 2 \subsection*{Weapons (`{\tt )}')} From d3ee8a771736aac5f15352f9f2d30c70000a4969 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sat, 25 Jul 2020 23:24:04 -0400 Subject: [PATCH 030/708] This is cron-daily v1-Jan-20-2020. guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 2040 ++++++++++++++++++++++----------------------- 1 file changed, 1020 insertions(+), 1020 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 3bd5af125..f81e2b7bb 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - July 9, 2020 + July 25, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -786,7 +786,7 @@ Di - examine your inventory before dropping anything. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -984,7 +984,7 @@ hand and it will generally be less effective than when shot. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1050,7 +1050,7 @@ from normal play to "explore mode", also known as "discovery - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1182,7 +1182,7 @@ not have a name, only other stacks with no name are - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1248,7 +1248,7 @@ Dip an object into something. Autocompletes. Default key - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1314,7 +1314,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1380,7 +1380,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1446,7 +1446,7 @@ it. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1512,7 +1512,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1578,7 +1578,7 @@ Show bare map without displaying monsters, objects, or - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1644,7 +1644,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1710,7 +1710,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1776,7 +1776,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1842,7 +1842,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1908,7 +1908,7 @@ attempt is made to open (when unlocked) or unlock (when locked) - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -1974,7 +1974,7 @@ send you to a different level but behave differently. Some - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2040,7 +2040,7 @@ scribed below). Monsters are only active on the current level; - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2085,7 +2085,7 @@ will usually claim ownership without offering any compensation. You'll have to buy it back if you want to reclaim it. - Shopkeepers sometimes run out of money. When that happens, + 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 shop where it was obtained; other shopkeepers @@ -2106,7 +2106,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2125,8 +2125,8 @@ * 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 will generally - ignore any other customers. + * While the shopkeeper watches you like a hawk, he or she will + generally ignore any other customers. * If a shop is "closed for inventory," it will not open of its own accord. @@ -2172,7 +2172,7 @@ on the map. Setting this option to true will describe such - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2238,7 +2238,7 @@ when angered. Remember: discretion is the better part of valor. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2304,7 +2304,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2370,7 +2370,7 @@ pends on your strength and your constitution. The stronger and - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2389,9 +2389,9 @@ 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", "Overtaxed" or "Overloaded" will be shown - on the bottom line status display. + If you are encumbered, one of the conditions Burdened, Stressed, + Strained, Overtaxed, or Overloaded will be shown on the bottom + line status display. When you pick up an object, it is assigned an inventory let- ter. Many commands that operate on objects must ask you to find @@ -2427,16 +2427,16 @@ chantments that make them less effective in combat. Other cursed objects may act poorly or detrimentally in other ways. - Objects can also be blessed. Blessed items usually work - better or more beneficially than normal uncursed items. For ex- - ample, a blessed weapon will do more damage against demons. + 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 uncursed. They could just as easily have been described as - unblessed, but the uncursed designation is what you will see + as uncursed. They could just as easily have been described as - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2446,25 +2446,31 @@ - within the game. A "glass half full versus glass half empty" + 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. + 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. An item with unknown status will be reported in your inven- tory with no prefix. An item which you know the state of will be distinguished 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 + cursed, uncursed, or blessed in the description of the item. In + some cases uncursed will be omitted as being redundant when enough other information is displayed. The implicit_uncursed op- - tion can be used to control this; toggle it off to have "un- - cursed" be displayed even when that can be deduced from other at- - tributes. + tion can be used to control 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 "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term + beatitude is occasionally used as well.) 7.2. Weapons (`)') @@ -2494,15 +2500,9 @@ factors. Among them are: type of weapon, quality of weapon (en- chantment and/or erosion), experience level, strength, dexterity, encumbrance, and proficiency (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 - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2512,6 +2512,12 @@ + 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 @@ -2559,16 +2565,10 @@ quiver sack, or have at the ready) when the inventory slot used for `Q' runs out. - Some characters have the ability to fire a volley of multi- - ple items in a single turn. 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 - NetHack 3.7 July 9, 2020 + + NetHack 3.7 July 25, 2020 @@ -2578,18 +2578,25 @@ - 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 example, "2f" (or "n2f" if using num- - ber_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 speci- - fied. Once the volley is in motion, all of the items will travel - in the same direction; if the first ones kill a monster, the oth- - ers can still continue beyond that spot. + Some characters have the ability to fire a volley of multi- + ple items in a single turn. 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 wield- + ing 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 lim- + it the number of shots by using a numeric prefix before the `t' + or `f' command. For 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 shoot- + ing 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.2.2. Weapon proficiency @@ -2625,16 +2632,9 @@ 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 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 your to- - tal overall skills, so you need to actively choose which skills - to enhance and which to ignore. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2644,6 +2644,14 @@ + 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 your to- + tal overall skills, so you need to actively choose which skills + to enhance and which to ignore. + 7.2.3. Two-Weapon combat Some characters can use two weapons at once. Setting things @@ -2691,16 +2699,8 @@ 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 armor: - Dragon scale mail 1 - Plate mail, Crystal plate mail 3 - Bronze plate mail, Splint mail, - Banded mail, Dwarvish mithril-coat 4 - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2710,6 +2710,12 @@ + Here is a list of the armor class values provided by suits + of armor: + Dragon scale mail 1 + Plate mail, Crystal plate mail 3 + Bronze plate mail, Splint mail, + Banded mail, Dwarvish mithril-coat 4 Chain mail, Elven mithril-coat 5 Scale mail, Orcish chain mail 6 Ring mail, Studded leather armor, @@ -2757,16 +2763,10 @@ 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 usual- - ly 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 + protected. Food stored in ice boxes or tins ("cans") will - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2776,6 +2776,12 @@ + 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 what you eat." Some character roles and some monsters are vegetarian. Veg- @@ -2824,15 +2830,9 @@ 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. - - The command to drink a potion is `q' (quaff). - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2842,6 +2842,11 @@ + things to throw (`t') 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). + 7.7. Wands (`/') Wands usually have multiple magical charges. Some types of @@ -2891,14 +2896,9 @@ worn cannot be removed. When worn gloves aren't cursed, you don't have to manually take them off before putting on or remov- ing 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). - `A', `W', and `T' can also be used; see Amulets. - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2908,6 +2908,11 @@ + to avoid unnecessary tedium. + + The commands to use rings are `P' (put on) and `R' (remove). + `A', `W', and `T' can also be used; see Amulets. + 7.9. Spellbooks (`+') Spellbooks are tomes of mighty magic. When studied with the @@ -2958,13 +2963,8 @@ estimate of how strongly it is remembered. The `Z' (cast) com- mand casts a spell. - 7.10. Tools (`(') - Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -2974,6 +2974,10 @@ + 7.10. Tools (`(') + + Tools are miscellaneous objects with various purposes. Some + tools have a limited number of uses, akin to wand charges. For example, lamps burn out after a while. Other tools are contain- ers, which objects can be placed into or taken out of. @@ -3024,13 +3028,9 @@ shown as likely candidates in a prompt for choosing what to wear or take off. - 7.12. 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. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3040,6 +3040,10 @@ + 7.12. 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 gems increase your score if you bring them with you when you exit. @@ -3090,13 +3094,9 @@ cation 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 ex- - ception is that if the object gets covered by the "remembered, - unseen monster" marker. When that marker is later removed after - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3106,6 +3106,10 @@ + more--perhaps a monster has picked it up or it has rotted away-- + until you can see or feel that location again. One notable ex- + ception is that if the object gets covered 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, @@ -3156,13 +3160,9 @@ (`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 - foodless conducts. This includes tripe rations, the corpses or - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3172,6 +3172,10 @@ + observe a vegetarian diet. + + Eating any kind of meat violates the vegetarian, vegan, and + foodless 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 polymorphed is treated as if you ate the creature's @@ -3222,13 +3226,9 @@ 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. - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3238,6 +3238,9 @@ + 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 men- tioned there, the goal is to push boulders into pits and/or holes @@ -3289,12 +3292,9 @@ necessarily in the order in which you might accomplish them. - Attained rank title . - Shop - Entered a shop. - Temple - Entered a temple. - Mines - Entered the Gnomish Mines. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3304,6 +3304,9 @@ + Shop - Entered a shop. + Temple - Entered a temple. + Mines - Entered the Gnomish Mines. Town - Entered Mine Town. Oracle - Consulted the Oracle of Delphi. Novel - Read a passage from a Discworld Novel. @@ -3354,13 +3357,10 @@ dies. Blind and Nudist are also conducts, and they can only be en- - abled by setting the correspondingly named option in NETHACKOP- - TIONS or run-time configuration file prior to game start. In the - case of Blind, the option also enforces the conduct. They aren't - really significant accomplishments unless/until you make + abled by setting the correspondingly named option in - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3370,7 +3370,10 @@ - substantial progress into the dungeon. + NETHACKOPTIONS or run-time configuration file prior to game + start. In the case of Blind, the option also enforces the con- + duct. They aren't really significant accomplishments unless/un- + til you make substantial progress into the dungeon. 9. Options @@ -3421,12 +3424,9 @@ You can use different configuration statements in the file, some of which can be used multiple times. In general, the state- ments are written in capital letters, followed by an equals sign, - followed by settings particular to that statement. - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3436,6 +3436,8 @@ + followed by settings particular to that statement. + Here is a list of allowed statements: OPTIONS @@ -3487,12 +3489,10 @@ extended command. Prefix the command with "!" to disable the autocompletion for that command. - Example: - - AUTOCOMPLETE=zap,!annotate - NetHack 3.7 July 9, 2020 + + NetHack 3.7 July 25, 2020 @@ -3502,6 +3502,10 @@ + Example: + + AUTOCOMPLETE=zap,!annotate + AUTOPICKUP_EXCEPTION Set exceptions to the pickup_types option. See the "Configur- ing Autopickup Exceptions" section. @@ -3552,13 +3556,9 @@ SYMBOLS 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: - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3568,6 +3568,10 @@ + "Modifying NetHack Symbols" section. + + Example: + # replace small punctuation (tick marks) with digits SYMBOLS=S_boulder:0,S_golem:7 @@ -3618,13 +3622,9 @@ 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 shell), or the pair of commands - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3634,6 +3634,11 @@ + % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" + + 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" $ export NETHACKOPTIONS @@ -3684,13 +3689,8 @@ Automatically dig if you are wielding a digging tool and moving into a place that can be dug (default false). Persistent. - autoopen - Walking into a closed door attempts to open it (default true). - Persistent. - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3700,6 +3700,10 @@ + autoopen + Walking into a closed door attempts to open it (default true). + Persistent. + autopickup Automatically pick up things onto which you move (default on). Persistent. See pickup_types to refine the behavior. @@ -3749,14 +3753,10 @@ Allows looking at things on the screen by navigating the mouse over them and clicking the right mouse button (default off). - cmdassist - Have the game provide some additional command assistance for - new players if it detects some anticipated mistakes (default - on). - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3766,6 +3766,11 @@ + cmdassist + 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 creatures (default on). Persistent. @@ -3814,15 +3819,10 @@ (for example "disclose:yi na +v -g o") The example sets inven- tory to prompt and default to yes, attributes to prompt and de- - fault to no, vanquished to disclose without prompting, genocid- - ed 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 by traps and each other as well as by you. And the + fault to no, vanquished to disclose without prompting, - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3832,63 +3832,63 @@ - dungeon overview shows all levels you had visited but does not - reveal things about them that you hadn't discovered. + 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 by traps and each other as well as by you. And the dun- + geon overview shows all levels you had visited but does not re- + veal things about them that you hadn't discovered. dogname 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 + Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit + tional 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 avail- - able commands (on) or just the subset of commands which have + able commands (on) or just the subset of commands which have traditionally been considered extended ones (off). female - An obsolete synonym for "gender:female". Cannot be set with + An obsolete synonym for "gender:female". Cannot be set with the `O' command. fixinv - An object's inventory letter sticks to it when it's dropped - (default on). If this is off, dropping an object shifts all + 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 inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a + 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 - "fruit:mango") (default "slime mold"). Basically a nostalgic - whimsy that NetHack uses from time to time. You should set - this to something you find more appetizing than slime mold. - Apples, oranges, pears, bananas, and melons already exist in + 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 something 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 - specify just the first letter. Although you can still denote + Your starting gender (gender:male or gender:female). You may + specify just the first letter. Although you can still denote your gender using the "male" and "female" options, the "gender" - option will take precedence. The default is to randomly pick - an appropriate gender. If you prefix the value with `!' or - "no", you will exclude that gender from being picked randomly. + option will take precedence. The default is to randomly pick + an appropriate gender. If you prefix the value with `!' or + "no", you will exclude that gender from being picked randomly. 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 de- - fault). Gold is never blessed or cursed, but it is not de- - scribed as "uncursed" even when the implicit_uncursed option is - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3898,63 +3898,63 @@ + 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 de- + fault). Gold is never blessed or cursed, but it is not de- + scribed as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with + If more information is available for an object looked at with the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the "More info?" prompt, but it also + ing help off makes just looking at things faster, since you + aren't interrupted with the "More info?" prompt, but it also means that you might miss some interesting and/or important in- formation. Persistent. 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. Same as "#herecmdmenu" and "#therecmdmenu" com- + When using a windowport that supports mouse and clicking on + yourself or next to you, show a menu of possible actions for + the location. Same as "#herecmdmenu" and "#therecmdmenu" com- mands. hilite_pet - Visually distinguish pets from similar animals (default off). - The behavior of this option depends on the type of windowing + 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 + is often used; with tiles, generally displays a heart symbol near pets. - With the curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option + With the curses interface, the petattr option controls how to + 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 + 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 + 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. Only - available for TTY and Windows GUI, and only when statushilites + Show a hit point bar graph behind your name and title. Only + available for TTY and Windows GUI, and only when statushilites is on. horsename - Name your starting horse (for example "horsename:Trigger"). + Name your starting horse (for example "horsename:Trigger"). Cannot be set with the `O' command. ignintr Ignore interrupt signals, including breaks (default off). Per- sistent. - implicit_uncursed - Omit "uncursed" from object descriptions when it can be deduced - from other aspects of the description (default on). Persis- - tent. - - If you use menu coloring, you may want to turn this off. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -3964,63 +3964,63 @@ + implicit_uncursed + Omit "uncursed" from object descriptions when it can be deduced + from other aspects of the description (default on). Persis- + tent. + + If you use menu coloring, you may want to turn this off. + legacy Display an introductory message when starting the game (default on). Persistent. lit_corridor - Show corridor squares seen by night vision or a light source + Show corridor squares seen by night vision or a light source held by 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 + 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 + 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 de- - scribed when covered by one or more objects (default off). + Give feedback when walking onto various dungeon features such + as stairs, fountains, or altars which are ordinarily only de- + scribed when covered by one or more objects (default off). Persistent. mention_walls - Give feedback when walking against a wall (default off). Per- + Give feedback when walking against a wall (default off). Per- sistent. menucolors - Enable coloring menu lines (default off). See "Configuring + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for 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 + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for 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 interest, but then displays a menu of matching ob- - jects 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. Partial skips the ob- - ject class filtering and immediately displays a menu of all ob- - jects. Persistent. - - menu_deselect_all - Menu character accelerator to deselect all items in a menu. - Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. + jects 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. Partial skips the - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4030,9 +4030,16 @@ + object class filtering and immediately displays a menu of all + objects. Persistent. + + menu_deselect_all + Menu character accelerator to deselect all items in a menu. + Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. + menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- fault `\'. menu_first_page @@ -4040,34 +4047,34 @@ Implemented by the Amiga, Gem and tty ports. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Values - are "none", "bold", "dim", "underline", "blink", or "inverse". + Controls how the headings in a menu are highlighted. Values + are "none", "bold", "dim", "underline", "blink", or "inverse". Not all ports can actually display all types. menu_invert_all - Menu character accelerator to invert all items in a menu. Im- + Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `@'. menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `~'. menu_last_page - Menu character accelerator to jump to the last page in a menu. + Menu character accelerator to jump to the last page in a menu. Implemented by the Amiga, Gem and tty ports. Default `|'. menu_next_page - Menu character accelerator to goto the next menu page. Imple- + Menu character accelerator to goto the next menu page. Imple- mented by the Amiga, Gem and tty ports. Default `>'. menu_objsyms - Show object symbols in menu headings in menus where the object + Show object symbols in menu headings in menus where the object symbols act as menu accelerators (default off). menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- fault on) menu_previous_page @@ -4075,18 +4082,11 @@ plemented by the Amiga, Gem and tty ports. Default `<'. menu_search - Menu character accelerator to search for a menu item. Imple- + Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default `:'. - menu_select_all - Menu character accelerator to select all items in a menu. Im- - plemented by the Amiga, Gem, X11 and tty ports. Default `.'. - menu_select_page - Menu character accelerator to select all items on this page of - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4096,7 +4096,13 @@ - a menu. Implemented by the Amiga, Gem and tty ports. Default + menu_select_all + Menu character accelerator to select all items in a menu. Im- + plemented by the Amiga, Gem, X11 and tty ports. Default `.'. + + menu_select_page + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `,'. monpolycontrol @@ -4104,24 +4110,24 @@ off). Debug mode only. mouse_support - Allow use of the mouse for input and travel. Valid settings + Allow use of the mouse for input and travel. Valid settings are: 0 - disabled 1 - enabled and make OS adjustments to support mouse use 2 - like 1 but does not make any OS adjustments - Omitting a value is the same as specifying 1 and negating + Omitting a value is the same as specifying 1 and negating mouse_support is the same as specifying 0. msghistory - The number of top line messages to keep (and be able to recall + 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. - Currently it is only supported for tty (all four choices) and - for curses (`f' and `r' choices, default `r'). The possible + Allows you to change the way recalled messages are displayed. + Currently 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); @@ -4129,30 +4135,24 @@ 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 + For backward compatibility, no value needs to be specified + (which defaults to "full"), or it can be negated (which defaults to "single"). 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 + 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. Cannot + -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. 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 this with the `O' command. - - nudist - Start the character with no armor (default false). Persistent. - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4162,11 +4162,16 @@ + setting this with the `O' command. + + nudist + Start the character with no armor (default false). Persistent. + null Send padding nulls to the terminal (default on). Persistent. number_pad - Use digit keys instead of letters to move (default 0 or off). + Use digit keys instead of letters to move (default 0 or off). Valid settings are: 0 - move by letters; "yuhjklbn" @@ -4176,49 +4181,44 @@ 4 - combines 3 with 2; phone layout plus MS-DOS compatibility -1 - by letters but use `z' to go northwest, `y' to zap wands - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 2 and 4 are for compatibility with MS-DOS or old + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 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 accommo- - date some QWERTZ keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a + date some QWERTZ keyboards 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' + 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 containing the symbols for the various object types. Any omit- ted 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_confirma- + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma- tion:pray. - Confirm - for any prompts which are set to require "yes" - rather than `y', also require "no" to reject in- + Confirm - for any prompts which are set to require "yes" + rather than `y', also require "no" to reject in- stead of accepting any non-yes response as no quit - require "yes" rather than `y' to confirm quitting - the game or switching into non-scoring explore + the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying - (not useful in normal play; applies to explore + 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 - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attack- + attack - require "yes" rather than `y' to confirm attack- ing a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking - a wand; - eating - require "yes" rather than `y' to confirm whether - to continue eating; - Were-change - require "yes" rather than `y' to confirm changing - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4228,29 +4228,34 @@ - form due to lycanthropy when hero has polymorph + wand-break - require "yes" rather than `y' to confirm breaking + a wand; + 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 + pray - require `y' to confirm an attempt to pray rather than immediately praying; on by default; - Remove - require selection from inventory for `R' and `T' - commands even when wearing just one applicable + Remove - require selection from inventory for `R' and `T' + commands even when wearing just one applicable item. all - turn on all of the above. - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use "paranoid_confirmation:none". To keep it enabled while setting - any of the others, include it in the list, such as "para- + any of the others, include it in the list, such as "para- noid_confirmation:attack pray Remove". perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. petattr - Specifies one or more text highlighting attributes to use when - showing pets on the map. Effectively a superset of the + Specifies one or more text highlighting attributes to use when + showing pets on the map. Effectively a superset of the hilite_pet boolean option. Curses interface only; value is one or more of the following letters. @@ -4264,27 +4269,22 @@ l - Left line indicator r - Right line indicator - Some of those choices might not work, particularly the final - three, depending upon terminal hardware or terminal emulation + Some of those choices might not work, particularly the final + three, depending upon terminal hardware or terminal emulation software. - Currently multiple highlight-style letters can be combined by - simply stringing them together (for example, "bk"), but in the - future they might require being separated by plus signs (such - as "b+k", which works already). When using the `n' choice, it - should be specified on its own, not in combination with any of + Currently multiple highlight-style letters can be combined by + simply stringing them together (for example, "bk"), but in the + future they might require being separated by plus signs (such + as "b+k", which works already). When using the `n' choice, it + should be specified on its own, not in combination with any of the other letters. 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". If the choice is not allowed for the role - you are currently playing, it will be silently ignored. For - example, "horse" will only be honored when playing a knight. + Specify the type of your initial pet, if you are playing a - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4294,17 +4294,22 @@ + 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". If the choice is not allowed for the role + you are currently playing, it will be silently ignored. For + example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. (Default `S'). Persistent. 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 + 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 @@ -4314,43 +4319,38 @@ sistent. 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 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. + 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 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. playmode - Values are "normal", "explore", or "debug". Allows selection - of explore mode (also known as discovery mode) or debug mode + 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 + 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 it when not allowed or not possible re- + entirely. Requesting it when not allowed or not possible re- sults in explore mode instead. Default is normal play. pushweapon - Using the `w' (wield) command when already wielding something - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the + Using the `w' (wield) command when already wielding something + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. quick_farsight - When set, usually prevents the "you sense your surroundings" - message where play pauses to allow you to browse the map when- + When set, usually prevents the "you sense your surroundings" + message where play pauses to allow you to browse the map when- ever clairvoyance randomly activates. Some situations, such as - being underwater or engulfed, ignore this option. It does not - affect the clairvoyance spell where pausing to examine revealed - objects or monsters is less intrusive. Default is off. Per- - sistent. + being underwater or engulfed, ignore this option. It does not - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4360,39 +4360,43 @@ + affect the clairvoyance spell where pausing to examine revealed + objects or monsters is less intrusive. Default is off. Per- + sistent. + race Selects your race (for example, "race:human"). Default is ran- - dom. If you prefix the value with `!' or "no", you will ex- + dom. If you prefix the value with `!' or "no", you will ex- clude that race from being picked randomly. Cannot be set with the `O' command. Persistent. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (de- + Make the space bar a synonym for the `.' (#wait) command (de- fault off). Persistent. role - Pick your type of character (for example "role:Samurai"); syn- - onym for "character". See "name" for an alternate method of - specifying your role. Normally only the first letter of the - value is examined; `r' is an exception with "Rogue", "Ranger", + Pick your type of character (for example "role:Samurai"); syn- + onym for "character". See "name" for an alternate method of + specifying your role. Normally only the first letter of the + value is examined; `r' is an exception with "Rogue", "Ranger", and "random" values. If you prefix the value with `!' or "no", - you will exclude that role from being picked randomly. Cannot + you will exclude that role from being picked randomly. Cannot be set with the `O' command. Persistent. roguesymset - This option may be used to select one of the named symbol sets - found within "symbols" to alter the symbols displayed on the + This option may be used to select one of the named symbol sets + found within "symbols" to alter the symbols displayed on the screen on the rogue level. rlecomp When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has + 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 - control+direction and so forth, or via the travel command or + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -4401,22 +4405,18 @@ crawl - like walk, but pause briefly after each step. This option only affects the game's screen display, not the ac- - tual results of moving. The default is "run"; versions prior - to 3.4.1 used "teleport" only. Whether or not the effect is + tual 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. Persistent. safe_pet - Prevent you from (knowingly) attacking your pets (default on). + Prevent you from (knowingly) attacking your pets (default on). Persistent. - sanity_check - Evaluate monsters, objects, and map prior to each turn (default - off). Debug mode only. - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4426,9 +4426,13 @@ + sanity_check + 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 + 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. @@ -4437,9 +4441,9 @@ off). Persistent. showrace - Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4451,38 +4455,34 @@ sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + 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, + 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. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. sparkle Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- + hit by an attack to which it is resistant (default on). Per- sistent. standout Boldface monsters and "--More--" (default off). Persistent. statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. See "Configuring Status Hilites" for further information. - status_updates - Allow updates to the status lines at the bottom of the screen - (default true). - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4492,25 +4492,29 @@ + status_updates + 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 + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (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 "symset:default" to explicitly select the default + 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 "symset:default" to explicitly select the default symbols. time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface only; "X11" interface always uses a timer based delay. The de- fault is on if configured into the program.) Persistent. @@ -4520,35 +4524,31 @@ toptenwin Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map win- - dow. Does not affect traveling via the `_' ("#travel") com- + ed moves if you make inadvertent mouse clicks on the map win- + dow. Does not affect traveling via the `_' ("#travel") com- mand. Persistent. verbose - Provide more commentary during the game (default on). Persis- + Provide more commentary during the game (default on). Persis- tent. whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. - The possible settings are: - - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4558,6 +4558,8 @@ + The possible settings are: + c - compass ("east" or "3s" or "2n,4w"); f - full compass ("east" or "3south" or "2north,4west"); m - map (map column x=0 is not used); @@ -4570,40 +4572,40 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possi- + through next and previous targets, allows filtering the possi- ble 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 + 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 + Filtering can also be changed when getting a location with the "getpos.filter" key. whatis_menu - When getting a location on the map, and using a key to cycle + 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. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement + 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 de- + select which one to use, such as "tty" or "X11" (default de- pends 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 op- - tions. For multiple lines in a configuration file, that would - be the first non-comment line. For a comma-separated list in + When used, it should be the first option set since its value + might enable or disable the availability of various other op- + tions. 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 option in the list. @@ -4612,9 +4614,7 @@ off). Debug mode only. - - - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4625,35 +4625,35 @@ zerocomp - When writing out a save file, perform zero-comp compression of - the contents. Not all ports support zero-comp compression. It + 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 + 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 adjust- - ing 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 + 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 adjust- + ing 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. Some options - are dynamic and can be specified during the game with the `O' + 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, + 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, + Where to align or place the status window (top, bottom, left, or right). ascii_map - If NetHack can, it should display an ascii character map if it + If NetHack can, it should display an ascii character map if it can. color @@ -4661,8 +4661,8 @@ monsters, objects, and dungeon features. eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to your terminal (default off). font_map @@ -4670,7 +4670,7 @@ map window. font_menu - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -4680,7 +4680,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4695,45 +4695,45 @@ status window. font_text - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for text windows. font_size_map - If NetHack can, it should use this size font for the map win- + If NetHack can, it should use this size font for the map win- dow. 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 + 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 + 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. fullscreen - If NetHack can, it should try and display on the entire screen + If NetHack can, it should try and display on the entire screen rather than in a window. guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- terface only; default is on. large_font If NetHack can, it should use a large font. map_mode - If NetHack can, it should display the map in the manner speci- + If NetHack can, it should display the map in the manner speci- fied. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog @@ -4741,12 +4741,12 @@ preload_tiles If NetHack can, it should preload tiles into memory. For exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4759,21 +4759,21 @@ memory. (default on). Cannot be set with the `O' command. scroll_amount - If NetHack can, it should scroll the display by this number of + If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- dow. selectsaved - If NetHack can, it should display a menu of existing saved + If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to + Display an onscreen keyboard. Handhelds are most likely to support this option. splash_screen @@ -4781,27 +4781,27 @@ 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). Curses and tty + Number of lines for traditional below-the-map status display. + Acceptable values are 2 and 3 (default is 2). Curses and tty interfaces only. term_cols and term_rows - Curses interface only. Number of columns and rows to use for + Curses interface only. Number of columns and rows to use for the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. + ified but will settle for smaller sizes if they are too big. Default is the current window size. tiled_map If NetHack can, it should display a tiled map if it can. 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. tile_height - Specify the preferred height of each tile in a tile capable + Specify the preferred height of each tile in a tile capable port. tile_width @@ -4812,7 +4812,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4823,42 +4823,42 @@ use_inverse - If NetHack can, it should display inverse when the game speci- + If NetHack can, it should display inverse when the game speci- fies it. vary_msgcount - If NetHack can, it should display this number of messages at a + 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 in- + Whether to draw boxes around the map, status area, message + area, and persistent inventory window if enabled. Curses in- terface only. Acceptable values are 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) (default) - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns + (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 for align_status set to left or right.) windowcolors - If NetHack can, it should display windows with the specified + If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- text). wraptext @@ -4867,18 +4867,18 @@ 9.6. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be set with the `O' command. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4894,23 +4894,23 @@ altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). flush @@ -4923,28 +4923,28 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of + (Win32 tty NetHack only). May be used to alter the value of keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally - going to be returned. You can use multiple subkeyvalue state- - ments in the configuration file if needed. Cannot be set with + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally + going to be returned. You can use multiple subkeyvalue state- + ments in the configuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause + tect", "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -4954,43 +4954,43 @@ - hardware. Setting "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 of those modes works. Cannot be set + hardware. Setting "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 of those modes works. Cannot be set with the `O' command. video_height - Set the VGA mode resolution height (MS-DOS only, with + Set the VGA mode resolution height (MS-DOS only, with video:vesa) video_width - Set the VGA mode resolution width (MS-DOS only, with + 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 bright.cyan. Cannot be set with the `O' + 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 (de- fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the `O' command. 9.7. Regular Expressions - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -4999,18 +4999,18 @@ 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 + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as a pattern to match against the singular form of the description of an object at your location. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5020,19 +5020,19 @@ - In addition, some characters are treated specially if they oc- + In addition, some characters are treated specially if they oc- cur 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 + 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 save and then restore your game. autopickup_ex- + 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 save and then restore your game. autopickup_ex- ception rules and not saved with the game. Here are some examples: @@ -5041,17 +5041,17 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - 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 ex- + 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 ex- clusion of items known to be cursed from autopickup. 9.9. 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 + 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"), or a three-digit decimal ASCII code. @@ -5062,21 +5062,21 @@ BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a key by using "nothing" as the extended command to bind - to. You can also bind the "", "", and "" + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- + The menu control or accelerator keys can also be rebound via + OPTIONS lines in the configuration file. You cannot bind ob- ject symbols into menu accelerators. Special command keys - Below are the special commands you can rebind. Some of them + Below are the special commands you can rebind. Some of them - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5086,13 +5086,13 @@ - can be bound to same keys with no problems, others are in the - same "context", and if bound to same keys, only one of those - commands will be available. Special command can only be bound + can be bound to same keys with no problems, others are in the + same "context", 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 + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. doinv @@ -5102,19 +5102,19 @@ Prefix key to force fight a direction. Default is `F'. fight.numpad - Prefix key to force fight a direction. With number_pad only. + Prefix key to force fight a direction. With number_pad only. Default is `-'. getdir.help - When asked for a direction, the key to show the help. Default + When asked for a direction, the key to show the help. Default is `?'. getdir.self - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `.'. getdir.self2 - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `s'. getpos.autodescribe @@ -5126,23 +5126,23 @@ esting thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest interesting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door + When asked for a location, the key to go to next closest door or doorway. Default is `d'. getpos.door.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest door or doorway. Default is `D'. getpos.help - When asked for a location, the key to show help. Default is + When asked for a location, the key to show help. Default is `?'. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5153,52 +5153,52 @@ getpos.mon.next - When asked for a location, the key to go to next closest mon- + When asked for a location, the key to go to next closest mon- ster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest monster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest ob- + When asked for a location, the key to go to next closest ob- ject. Default is `o'. getpos.obj.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest object. Default is `O'. getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- stead. 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 + 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 + 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 + When asked for a location, the key to choose the location, and possibly ask for more info. Default is `.'. getpos.pick.once - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. getpos.pick.quick When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- + asking for more info, and exit the location asking loop. De- fault is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self @@ -5208,7 +5208,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5219,23 +5219,23 @@ getpos.unexplored.next - When asked for a location, the key to go to next closest unex- + When asked for a location, the key to go to next closest unex- plored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest unexplored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target + When asked for a location, the key to go to show valid target locations. Default is `$'. getpos.valid.next - When asked for a location, the key to go to next closest valid + When asked for a location, the key to go to next closest valid location. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest valid location. Default is `Z'. nopickup @@ -5245,7 +5245,7 @@ Key to redraw the screen. Default is `^R'. redraw.numpad - Key to redraw the screen. With number_pad only. Default is + Key to redraw the screen. With number_pad only. Default is `^L'. repeat @@ -5258,11 +5258,11 @@ Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad - Prefix key to run towards a direction. With number_pad only. + Prefix key to run towards a direction. With number_pad only. Default is `5'. rush @@ -5274,7 +5274,7 @@ area, when the message matches a user-defined pattern. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5284,7 +5284,7 @@ - In general, the configuration file entries to describe the + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5297,50 +5297,50 @@ 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 mes- + norep - show the message once, but not again if no other mes- sage is shown in between. - Here's an example of message types using NetHack's internal + 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 + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when 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 + 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 pat- + color - the color to use for lines matching the pat- tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, + ing 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, gray, orange, light-green, yellow, light-blue, light- + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, light-green, yellow, light-blue, light- - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5350,63 +5350,63 @@ - magenta, light-cyan, and white. And no-color, the default - foreground color, which isn't necessarily the same as any of + magenta, light-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, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- + 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 line will be shown in red color and under- lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu + uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message 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 + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + 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 3.6); pattern - the pattern to match; sound file - the sound file to play; - volume - the volume to be set while playing the sound + volume - the volume to be set while playing the sound file; - sound index - optional; the index corresponding to a sound + sound index - optional; the index corresponding to a sound file. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5421,7 +5421,7 @@ 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5429,8 +5429,8 @@ 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 + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -5438,33 +5438,33 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground 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, blink, - and inverse. "Normal" is a synonym for "none"; they should not + Allowed attributes are none, bold, dim, underline, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. @@ -5472,7 +5472,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5482,7 +5482,7 @@ - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5493,16 +5493,16 @@ 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 condition- + 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 condition- ally displayed depending upon your other option settings. - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. @@ -5511,34 +5511,34 @@ * "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 + * "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 val- - ue 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 val- + ue 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 val- ue, 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 be- - tween 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 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 corresponding maxi- - mum field. Percentage highlight rules are also allowed + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- - perience level to the start of the next level. So if + perience level to the start of the next level. So if - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5548,32 +5548,32 @@ - 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 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 lev- - el, but a rule for =100% is allowed and matches the spe- + el, but a rule for =100% is allowed and matches the spe- cial case of being exactly 1 experience 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, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only match when strictly above or below. * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". For title, only the role's rank title is tested; + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- + The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: @@ -5593,18 +5593,18 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5614,13 +5614,13 @@ - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols @@ -5670,7 +5670,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5736,7 +5736,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5802,7 +5802,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5846,29 +5846,29 @@ Notes: * 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 en- + space character, except for S_pet_override and S_hero_override + which don't have any default value and can only be used if en- abled 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 de- - pict. So S_rock is only used for boulders and not used at all + * 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 de- + pict. So S_rock is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. Be certain to + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. Be certain to - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5878,48 +5878,48 @@ - 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 charac- + 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 charac- ter 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 + 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 location of items on the screen. - 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 message handler", your NetHack has been compiled + 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 message 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 environment variable NETHACK_MSGHANDLER + and other POSIX systems, define MSGHANDLER to enable it. To use + the capability, set the environment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task somewhat daunting. Included within the "symbols" file of all of- ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- abled in the sysconf file. - The most crucial settings to make the game more accessible + The most crucial settings to make the game more accessible are: symset:NHAccess Load a symbol set appropriate for use by blind players. roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional @@ -5929,12 +5929,12 @@ 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 + 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. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -5945,43 +5945,43 @@ autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip - When targeting with cursor and using fast-move, skip the same + When targeting with cursor and using fast-move, skip the same glyphs 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 in- + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. 9.16. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed + 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. @@ -5989,18 +5989,18 @@ SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS = A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in + space. The first format in the list will written as well as + read. The second format will be read only if no save file in - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6010,35 +6010,35 @@ - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- + SUPPORT = A string explaining how to get local support (no de- fault value). - RECOVER = A string explaining how to recover a game on this + 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, WIZ- + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6047,26 +6047,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6077,7 +6077,7 @@ DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6093,46 +6093,46 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on + 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 + 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 + 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 + 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 all your gold, but if + 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 + 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 + 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 paltry cost of not getting on the high score + "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 game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The + ing in initial inventory; switching during play does not. The - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6142,63 +6142,63 @@ - other benefits of explore mode are left for the trepid reader to + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 + vide god-like powers 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 par- - ticular 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 + For some systems, the player must be logged in under a par- + ticular 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. 12. Credits - 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 + 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 Dungeons of Doom, by Ken Arromdee. NetHack is the product of literally scores of people's work. - Main events in the course of the game development are described + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting + Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming Hack into a very different game. He published the Hack - source code for use on UNIX systems by posting that to Usenet + forming 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 ver- sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 1.0.3 in July of 1985. Usenet newsgroup net.games.hack - (later renamed rec.games.hack, eventually replaced by + nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion numbers, not contemporary NetHack ones). - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6208,63 +6208,63 @@ - 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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. Along with various other Dungeoneers, they continued - to enhance the PC, Macintosh, and Amiga ports through the later + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6277,60 +6277,60 @@ NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 + Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor 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 ob- + 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6341,62 +6341,62 @@ During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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 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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6406,37 +6406,37 @@ - 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 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 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 plat- + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows 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 + 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 + 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 af- @@ -6445,24 +6445,24 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 + velopment 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 - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6472,63 +6472,63 @@ - and never used in an official NetHack release. An announcement + and never used in an official NetHack release. An announcement was posted on the NetHack Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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. - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6539,20 +6539,20 @@ In early May 2019, another 320 bug fixes along with some en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6564,19 +6564,19 @@ 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6594,7 +6594,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 @@ -6634,7 +6634,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6660,7 +6660,7 @@ - NetHack 3.7 July 9, 2020 + NetHack 3.7 July 25, 2020 From 0fe9905cf83327c06b5c6c907427d908cc2ba9a9 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 26 Jul 2020 07:46:07 -0700 Subject: [PATCH 031/708] rocks vs unicorns A reddit thread mentioned that throwing rocks at unicorns behaved the same as throwing gems at them: not treated as an attack and if teleporting away is allowed, they will. Change to treat shooting gems and glass at unicorns with a sling as an attack rather than as just giving the gem or piece of glass to them, and treat throwing or shooting rocks and gray stones as an attack too. If picked up by blind hero while not yet seen, gems and glass format as "gem" and rocks and gray stones format as "stone" so the player can always tell the difference. Forgetting to unwield a sling before interacting with a unicorn is on the player's head. --- doc/fixes37.0 | 3 ++- src/dothrow.c | 31 ++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index e24f9302c..72352f307 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ $NHDT-Date: 1595668889 2020/07/25 09:21:29 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.257 $ $NHDT-Date: 1595774758 2020/07/26 14:45:58 $ General Fixes and Modified Features ----------------------------------- @@ -228,6 +228,7 @@ hero poly'd into a mind flayer who used #monster to emit a psychic blast was some hero attacks that should have gotten a skill bonus or penalty didn't change internal name of " venom" to "splash of venom" singularize "splashes" to "splash" instead of "splashe" +treat slinging gems and tossing or slinging stones at unicorns as attacks Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/dothrow.c b/src/dothrow.c index 1e6930c8e..f5d93cd37 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1584398443 2020/03/16 22:40:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.184 $ */ +/* NetHack 3.6 dothrow.c $NHDT-Date: 1595774758 2020/07/26 14:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.187 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1611,7 +1611,13 @@ register struct obj *obj; /* g.thrownobj or g.kickedobj or uwep */ tmp += 1000; /* Guaranteed hit */ } - if (obj->oclass == GEM_CLASS && is_unicorn(mon->data)) { + /* 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 + 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()) { if (mon->msleeping || !mon->mcanmove) { tmiss(obj, mon, FALSE); return 0; @@ -1628,8 +1634,8 @@ register struct obj *obj; /* g.thrownobj or g.kickedobj or uwep */ at leader... (kicked artifact is ok too; HMON_APPLIED could occur if quest artifact polearm or grapnel ever gets added) */ if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) { - /* AIS: changes to wakeup() means that it's now less inappropriate here - than it used to be, but the manual version works just as well */ + /* AIS: changes to wakeup() means that it's now less inappropriate + here than it used to be, but manual version works just as well */ mon->msleeping = 0; mon->mstrategy &= ~STRAT_WAITMASK; @@ -1823,15 +1829,16 @@ gem_accept(mon, obj) register struct monst *mon; register struct obj *obj; { + static NEARDATA const char + nogood[] = " is not interested in your junk.", + acceptgift[] = " accepts your gift.", + maybeluck[] = " hesitatingly", + noluck[] = " graciously", + addluck[] = " gratefully"; char buf[BUFSZ]; boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type); boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE; int ret = 0; - static NEARDATA const char nogood[] = " is not interested in your junk."; - static NEARDATA const char acceptgift[] = " accepts your gift."; - static NEARDATA const char maybeluck[] = " hesitatingly"; - static NEARDATA const char noluck[] = " graciously"; - static NEARDATA const char addluck[] = " gratefully"; Strcpy(buf, Monnam(mon)); mon->mpeaceful = 1; @@ -1851,7 +1858,8 @@ register struct obj *obj; Strcat(buf, nogood); goto nopick; } - /* making guesses */ + + /* making guesses */ } else if (has_oname(obj) || objects[obj->otyp].oc_uname) { if (is_gem) { if (is_buddy) { @@ -1865,7 +1873,8 @@ register struct obj *obj; Strcat(buf, nogood); goto nopick; } - /* value completely unknown to @ */ + + /* value completely unknown to @ */ } else { if (is_gem) { if (is_buddy) { From fae75f5930bf8e7707a31b019f7fe415c6705cdd Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 26 Jul 2020 11:13:43 -0700 Subject: [PATCH 032/708] troll corpse revival Prevent corpses left by cancelled trolls from reviving. Their revival is an innate ability but is clearly a magical one, so make that be subject to cancellation magic. Change existing corpses that are scheduled to revive to rot instead if they get cancelled as objects. Rider corpses are excluded. Uncancel an ice troll whose corpse is put into an ice box. Commit e9f53ab7f677656be530bf30c65bc3ff14d0c467 at the end of May to fix corpses taken out of ice boxes by monsters changed removing corpses from ice boxes by anybody to always give them rot-away timers, even for trolls. Make an exception for ice troll corpses: give those revive timers instead. --- doc/fixes37.0 | 6 +++++- src/mkobj.c | 7 ++++++- src/pickup.c | 24 +++++++++++++++++------- src/zap.c | 15 ++++++++++++++- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 72352f307..574729ed2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.257 $ $NHDT-Date: 1595774758 2020/07/26 14:45:58 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.258 $ $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ General Fixes and Modified Features ----------------------------------- @@ -229,6 +229,10 @@ some hero attacks that should have gotten a skill bonus or penalty didn't change internal name of " venom" to "splash of venom" singularize "splashes" to "splash" instead of "splashe" treat slinging gems and tossing or slinging stones at unicorns as attacks +give rot-away timer instead of revive timer to corpses of cancelled trolls +switch revive timer to rot-away timer if a troll corpse gets cancelled +uncancel an ice troll if its corpse is put into an ice box; give corpse a + revive timer if later taken out Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mkobj.c b/src/mkobj.c index b439461b4..4d5b5cc03 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1593306908 2020/06/28 01:15:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1516,6 +1516,10 @@ unsigned corpstatflags; if (!ptr) ptr = mtmp->data; + + /* don't give a revive timer to a cancelled troll's corpse */ + if (mtmp->mcan && !is_rider(ptr)) + otmp->norevive = 1; } /* when 'ptr' is non-null it comes from our caller or from 'mtmp'; @@ -1639,6 +1643,7 @@ boolean copyof; /* Never insert this returned pointer into mon chains! */ mnew = mtmp; } + mnew->data = &mons[mnew->mnum]; } return mnew; } diff --git a/src/pickup.c b/src/pickup.c index bd17ab0f9..38ced3f1a 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1590870789 2020/05/30 20:33:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1595787212 2020/07/26 18:13:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2351,9 +2351,14 @@ register struct obj *obj; if (Icebox && !age_is_relative(obj)) { obj->age = g.monstermoves - obj->age; /* actual age */ /* stop any corpse timeouts when frozen */ - if (obj->otyp == CORPSE && obj->timed) { - (void) stop_timer(ROT_CORPSE, obj_to_any(obj)); - (void) stop_timer(REVIVE_MON, obj_to_any(obj)); + if (obj->otyp == CORPSE) { + if (obj->timed) { + (void) stop_timer(ROT_CORPSE, obj_to_any(obj)); + (void) stop_timer(REVIVE_MON, obj_to_any(obj)); + } + /* if this is the corpse of a cancelled ice troll, uncancel it */ + if (obj->corpsenm == PM_ICE_TROLL && has_omonst(obj)) + OMONST(obj)->mcan = 0; } } else if (Is_mbag(g.current_container) && mbag_explodes(obj, 0)) { /* explicitly mention what item is triggering the explosion */ @@ -2362,7 +2367,7 @@ register struct obj *obj; /* did not actually insert obj yet */ if (was_unpaid) addtobill(obj, FALSE, FALSE, TRUE); - if (obj->otyp == BAG_OF_HOLDING) /* putting bag of holding into another */ + if (obj->otyp == BAG_OF_HOLDING) /* one bag of holding into another */ do_boh_explosion(obj, (obj->where == OBJ_FLOOR)); obfree(obj, (struct obj *) 0); /* if carried, shop goods will be flagged 'unpaid' and obfree() will @@ -2489,8 +2494,13 @@ struct obj *obj; if (!age_is_relative(obj)) { obj->age = g.monstermoves - obj->age; /* actual age */ if (obj->otyp == CORPSE) { - /* start a rot-away timer but not a troll's revive timer */ - obj->norevive = 1; + struct monst *m = get_mtraits(obj, FALSE); + boolean iceT = m ? (m->data == &mons[PM_ICE_TROLL]) + : (obj->corpsenm == PM_ICE_TROLL); + + /* start a revive timer if this corpse is for an ice troll, + otherwise start a rot-away timer (even for other trolls) */ + obj->norevive = iceT ? 0 : 1; start_corpse_timeout(obj); } } diff --git a/src/zap.c b/src/zap.c index 35bdfd6bb..50c1e0e32 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1593772051 2020/07/03 10:27:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ +/* NetHack 3.6 zap.c $NHDT-Date: 1595787213 2020/07/26 18:13:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.345 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1152,6 +1152,19 @@ register struct obj *obj; break; } } + /* cancelling a troll's corpse prevents it from reviving (on its own; + does not affect undead turning induced revival) */ + if (obj->otyp == CORPSE && obj->timed + && !is_rider(&mons[obj->corpsenm])) { + anything a = *obj_to_any(obj); + long timout = peek_timer(REVIVE_MON, &a); + + if (timout) { + (void) stop_timer(REVIVE_MON, &a); + (void) start_timer(timout, TIMER_OBJECT, ROT_CORPSE, &a); + } + } + unbless(obj); uncurse(obj); return; From 3cc82cbbe707887d134cbc13d2aab8205e5c5e72 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 27 Jul 2020 09:20:12 -0700 Subject: [PATCH 033/708] venom bit I looked for places where changing "{blinding,acid} venom" into "splash of {blinding,acid} venom" might make messages become too verbose. Turns out to have been unnecessary work because the full name won't be used unless you get a venom object in inventory and formally identify it. Wizard mode, or bones from wizard mode, is necessary for that to happen so the possibility can be ignored. [The name change is still useful for wizard mode wishing though.] Many messages use hard-coded "venom" instead of xname() so won't be affected even if such identification takes place. However, thitmon() was producing |The is hit by the splash of venom. |The splash of venom blinds the . which seems rather redundant even without the longer full object name. So change the second message to be generated as |The venom blinds the . It also shortens "cream pie" in first line to "pie" in second one. --- src/mthrowu.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/mthrowu.c b/src/mthrowu.c index e7340a04b..712dbfc01 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mthrowu.c $NHDT-Date: 1586567393 2020/04/11 01:09:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.99 $ */ +/* NetHack 3.6 mthrowu.c $NHDT-Date: 1595866809 2020/07/27 16:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -425,7 +425,14 @@ boolean verbose; /* give message(s) even when you can't see what happened */ : AT_WEAP), otmp)) { if (vis && mtmp->mcansee) - pline("%s is blinded by %s.", Monnam(mtmp), the(xname(otmp))); + /* shorten object name to reduce redundancy in the + two message [first via hit() above] sequence: + "The {splash of venom,cream pie} hits ." + " is blinded by the {venom,pie}." */ + pline("%s is blinded by %s.", Monnam(mtmp), + the((otmp->oclass == VENOM_CLASS) ? "venom" + : (otmp->otyp == CREAM_PIE) ? "pie" + : xname(otmp))); /* catchall; not used */ mtmp->mcansee = 0; tmp = (int) mtmp->mblinded + rnd(25) + 20; if (tmp > 127) From c8ad99fcdf118597b1846bd865cb0d88b195e3cb Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 28 Jul 2020 08:18:39 -0400 Subject: [PATCH 034/708] add fixes37.7 entry for f664e83 gone portal --- doc/fixes37.0 | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 574729ed2..351b66114 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -276,6 +276,7 @@ grammar for messages about a monster removing items from a container was bad some new status conditions didn't always update when they should fix flipping non-existent stairs and ladders (github #311) fix door created into random wall or position opening into solid wall +handle gone portal when going back in quest 'use_inverse' option was accidentally made Windows-only; change it back to being more general; change its default to True change inconsistent achievement spelling of "Mine Town" to "Minetown" From 0a575befcc45cf438ebeee93043bb97ef2c08448 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 28 Jul 2020 13:10:11 -0700 Subject: [PATCH 035/708] identify tweaks Give better feedback if reading a scroll of identify when it is the only item in inventory (making that empty when scroll is used up). Reading a cursed scroll of identify used to always ID 1 item besides itself. Change it to behave like confused identify--only identifying itself--if read when the scroll hasn't been discovered yet. Same as before when scroll has already been discovered: identify 1 item. --- src/read.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/read.c b/src/read.c index 5ff54c5cb..0963806b6 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1592875138 2020/06/23 01:18:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.198 $ */ +/* NetHack 3.6 read.c $NHDT-Date: 1595966992 2020/07/28 20:09:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.199 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1345,34 +1345,36 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ break; case SCR_IDENTIFY: /* known = TRUE; -- handled inline here */ - /* use up the scroll first, before makeknown() performs a - perm_invent update; also simplifies empty invent check */ + /* use up the scroll first, before learnscrolltyp() -> makeknown() + performs perm_invent update; also simplifies empty invent check */ useup(sobj); sobj = 0; /* it's gone */ - if (confused) + /* scroll just identifies itself for any scroll read while confused + or for cursed scroll read without knowing identify yet */ + if (confused || (scursed && !already_known)) You("identify this as an identify scroll."); - else if (!already_known || !g.invent) - /* force feedback now if invent became - empty after using up this scroll */ + else if (!already_known) pline("This is an identify scroll."); if (!already_known) (void) learnscrolltyp(SCR_IDENTIFY); + if (confused || (scursed && !already_known)) + break; /*FALLTHRU*/ case SPE_IDENTIFY: - cval = 1; - if (sblessed || (!scursed && !rn2(5))) { - cval = rn2(5); - /* note: if cval==0, identify all items */ - if (cval == 1 && sblessed && Luck > 0) - ++cval; - } - if (g.invent && !confused) { + if (g.invent) { + cval = 1; + if (sblessed || (!scursed && !rn2(5))) { + cval = rn2(5); + /* note: if cval==0, identify all items */ + if (cval == 1 && sblessed && Luck > 0) + ++cval; + } identify_pack(cval, !already_known); - } else if (otyp == SPE_IDENTIFY) { - /* when casting a spell we know we're not confused, - so inventory must be empty (another message has - already been given above if reading a scroll) */ - pline("You're not carrying anything to be identified."); + } else { + /* spell cast with inventory empty or scroll read when it's + the only item leaving empty inventory after being used up */ + pline("You're not carrying anything%s to be identified.", + (otyp == SCR_IDENTIFY) ? " else" : ""); } break; case SCR_CHARGING: From 79275629fc3b587f7e9a57a24575fbb91a9d920f Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 28 Jul 2020 19:31:14 -0700 Subject: [PATCH 036/708] Qt tinkering After installing qt511-qtbase and qt511-qtmultimedia from macports on my OSX 10.11 system (there is a qt513 but it requires OSX 10.12), I can build the Qt interface with hints/macosx10.10-qt by overriding QTDIR. It doesn't actually need the extra CFLAGS, and without those I wonder whether the multimedia package is needed either, but I've left them in. I have changed them to not be passed to the C sources though, just the C++ ones. I haven't tried combining with X11 or adding curses. --- sys/unix/Makefile.src | 4 ++-- sys/unix/hints/macosx10.10-qt | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 6b1da0794..60283236f 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1588776919 2020/05/06 14:55:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ +# NetHack 3.6 Makefile.src $NHDT-Date: 1595989869 2020/07/29 02:31:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -179,7 +179,7 @@ LIBS += -lm # 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 # the C++ libraries linked in. -CXXFLAGS = $(CFLAGS) -I. -I$(QTDIR)/include +CXXFLAGS = $(CFLAGS) -I. -I$(QTDIR)/include $(QTCXXFLAGS) CXX ?= g++ MOC ?= moc #LINK=g++ diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index 759703a5b..bb3773336 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.11 $NHDT-Date: 1595085485 2020/07/18 15:18:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ +# NetHack 3.6 macosx10.11 $NHDT-Date: 1595989870 2020/07/29 02:31:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -31,7 +31,10 @@ WANT_DEFAULT=Qt # A) set QTDIR either here or in the environment to point to the Qt5 # library installation root. (Qt2 or Qt3 will not work.) ifdef WANT_WIN_QT +# Qt installed via homebrew QTDIR=$(shell brew --prefix)/opt/qt +# Qt installed via macports (qt511 package; 5.13 requires OSX 10.12 or later) +#QTDIR=/opt/local/libexec/qt5 endif # WANT_WIN_QT # 2. Is this a build for a binary that will be shared among different users @@ -121,8 +124,8 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT CFLAGS += -DQT_GRAPHICS -DNOUSER_SOUNDS -CFLAGS += -Wno-deprecated-declarations -CFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) +QTCXXFLAGS += -Wno-deprecated-declarations +QTCXXFLAGS += $(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) LINK=$(CXX) WINSRC += $(WINQTSRC) From 5ce74c7bd5d885e5b1d38a084b8a2c8032708e6a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 29 Jul 2020 09:17:45 -0700 Subject: [PATCH 037/708] Qt extended command selection Qt's implementation of '#' puts up a rectangular grid of buttons containing command names from the alphabetized extcmdlist[]: | # ? adjust annotate | apply attributes autopickup call | cast ... When 3.6 put all commands into that list, the hardcoded 4 columns resulted in so many rows that the grid wouldn't fit on the screen (at least not on my smallish laptop screen). There's no scrollbar so the commands beyond "takeoff" were inaccessible off the bottom. Warning messages from within Qt were issued to stderr complaining about trying to render something off the screen (once each time the '#' command grid was generated). It was also including wizard mode commands when not in wizard mode. Suppress those when they're not applicable, and change the grid to use 6 columns then and 8 for wizard mode. The appropriate amount ought to be calculated on the fly but these values work ok with the current command list. (On my screen; if something smaller is used, the original problem could come back, just not as severe as before.) Having an alphabetized list go across rows instead of down columns feels counter-intuitive so transpose the grid. | # autopickup ... | ? call | adjust cast | annotate ... | apply [Having another button next to that lets the user switch back and forth between the two orientations could be worthwhile. A full-fledged wc/wc2 option for that doesn't seem warranted.] The commands can be selected by typing their names as an alternative to mouse click. The input widget supports but lacked handling for so add that. When typing a command by its name, a new grid showing only matching candidates gets displayed so that you can switch back to mouse input. It looks pretty bad but does work as intended. I didn't touch that; however, it looks different now due to the columns-vs-rows change. The menu after picking "?" looks worse. It assumes a fixed width font and tries to align things in two columns with spaces, but the result when using a variable width font is ugly. This makes no attempt to address that. --- doc/fixes37.0 | 9 +++++- win/Qt/qt_xcmd.cpp | 71 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 351b66114..ec4a8f2b8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.258 $ $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ +$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.260 $ $NHDT-Date: 1596039461 2020/07/29 16:17:41 $ General Fixes and Modified Features ----------------------------------- @@ -322,6 +322,13 @@ curses: for vertical status, line up conditions in columns; usually two but msdos: add -DSTATUES_LOOK_LIKE_MONSTERS to Makefile1.cross so the VESA mode can display statue glyphs Qt: quit if can't load tiles file instead of continuing and then segfaulting +Qt: use more columns for extended command selection dialog so that the number + of rows needed doesn't result in some commands being unaccessible +Qt: suppress wizard mode commands from '#' handling when not in wizard mode +Qt: organize extended command selection grid by columns instead of by rows + (first N entries down left column, next N entries down 2nd column, &c) +Qt: when selecting an extended command by typing its name, support + (aka ) in addition to to go back a character tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 4eb9ac4a5..448f66dfe 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -34,6 +34,14 @@ namespace nethack_qt_ { void centerOnMain(QWidget *); // end temporary +static inline bool +interesting_command(unsigned indx) +{ + return (!(extcmdlist[indx].flags & CMD_NOT_AVAILABLE) + /* 'wizard' is #undef'd above [why?] so rely on its internals */ + && (flags.debug || !(extcmdlist[indx].flags & WIZMODECMD))); +} + NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : QDialog(parent) { @@ -51,24 +59,56 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : QGroupBox *grid=new QGroupBox("Extended commands",this); l->addWidget(grid); - int i; - int butw=50; + unsigned i, j, ncmds = 0; + int butw = 50; QFontMetrics fm = fontMetrics(); - for (i=0; extcmdlist[i].ef_txt; i++) { - butw = std::max(butw,30+fm.width(extcmdlist[i].ef_txt)); + for (i = 0; extcmdlist[i].ef_txt; ++i) { + if (interesting_command(i)) { + ++ncmds; + butw = std::max(butw, 30 + fm.width(extcmdlist[i].ef_txt)); + } } - int ncols=4; + + /* 'ncols' should be calculated to fit (or enable a vertical scrollbar + when its so big it forces too many rows, if GroupBox supports that); + it used to be hardcoded 4 but after every command became accessible + as an extended command, that resulted in so many rows that some of + the buttoms were chopped off at the bottom of the grid */ + unsigned ncols = !flags.debug ? 6 : 8, + nrows = (ncmds + ncols - 1) / ncols; + /* + * Choose grid layout. This ought to selected via a button that can + * be used to toggle the setting back and forth. + * + * by row vs by column + * a b a e + * c d b f + * e f c g + * g d + * + * Prior to 3.7, it was always by-row, but by-column is more natural + * for an alphabetized list. + */ + bool by_column = true; QVBoxLayout* bl = new QVBoxLayout(grid); bl->addSpacing(fm.height()); QGridLayout* gl = new QGridLayout(); bl->addLayout(gl); - for (i=0; extcmdlist[i].ef_txt; i++) { - QPushButton* pb=new QPushButton(extcmdlist[i].ef_txt, grid); - pb->setMinimumSize(butw,pb->sizeHint().height()); - group->addButton(pb, i+1); - gl->addWidget(pb,i/ncols,i%ncols); - buttons.append(pb); + for (i = j = 0; extcmdlist[i].ef_txt; ++i) { + if (interesting_command(i)) { + QPushButton *pb = new QPushButton(extcmdlist[i].ef_txt, grid); + pb->setMinimumSize(butw, pb->sizeHint().height()); + group->addButton(pb, i + 1); + if (by_column) + /* 0..R-1 down first column, R..2*R-1 down second column,...*/ + gl->addWidget(pb, j % nrows, j / nrows); + else + /* 0..C-1 across first row, C..2*C-1 across second row, ... */ + gl->addWidget(pb, j / ncols, j % ncols); + buttons.append(pb); + ++j; + } } group->addButton(can, 0); connect(group,SIGNAL(buttonPressed(int)),this,SLOT(done(int))); @@ -90,7 +130,7 @@ void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) { reject(); } - else if (text == "\b") + else if (text == "\b" || text == "\177") { QString promptstr = prompt->text(); if (promptstr != "#") @@ -104,6 +144,8 @@ void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) unsigned matches = 0; unsigned match = 0; for (unsigned i=0; extcmdlist[i].ef_txt; i++) { + if (!interesting_command(i)) + continue; if (QString(extcmdlist[i].ef_txt).startsWith(typedstr)) { ++matches; if (matches >= 2) @@ -136,6 +178,11 @@ int NetHackQtExtCmdRequestor::get() return result()-1; } +/* + * FIXME: + * This looks terrible. [Possibly a difference between initial + * implementation using Qt2 and the current Qt version?] + */ // Enable only buttons that match the current prompt string void NetHackQtExtCmdRequestor::enableButtons() { From 00d1e729da5b67c686a4b661be46cea71ddc7652 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 29 Jul 2020 11:10:01 -0700 Subject: [PATCH 038/708] more mind flayer vs headless target Recently combat between monster mind flayer and headless monster was changed to skip extra tentable-for-drain_intelligence attacks after hitting with one for no effect. Do the same for monster mind flayer against headless poly'd hero and for hero poly'd into mind flayer versus headless monster. As before, it only applies to additional actions during the current attack. As soon as the attack is over, the ineffectiveness of intelligence drain upon target is forgotten. --- src/mhitu.c | 10 ++++++++-- src/uhitm.c | 10 +++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/mhitu.c b/src/mhitu.c index aaf3fb280..3e3953da6 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitu.c $NHDT-Date: 1593306907 2020/06/28 01:15:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ +/* NetHack 3.6 mhitu.c $NHDT-Date: 1596046195 2020/07/29 18:09:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -622,6 +622,8 @@ register struct monst *mtmp; return (foo == 1); } + g.skipdrin = FALSE; /* [see mattackm(mhitm.c)] */ + for (i = 0; i < NATTK; i++) { sum[i] = 0; if (i > 0 && foundyou /* previous attack might have moved hero */ @@ -630,7 +632,9 @@ register struct monst *mtmp; mon_currwep = (struct obj *)0; mattk = getmattk(mtmp, &g.youmonst, i, sum, &alt_attk); if ((u.uswallow && mattk->aatyp != AT_ENGL) - || (skipnonmagc && mattk->aatyp != AT_MAGC)) + || (skipnonmagc && mattk->aatyp != AT_MAGC) + || (g.skipdrin && mattk->aatyp == AT_TENT + && mattk->adtyp == AD_DRIN)) continue; switch (mattk->aatyp) { @@ -1185,6 +1189,8 @@ register struct attack *mattk; hitmsg(mtmp, mattk); if (defends(AD_DRIN, uwep) || !has_head(g.youmonst.data)) { You("don't seem harmed."); + /* attacker should skip remaining AT_TENT+AD_DRIN attacks */ + g.skipdrin = TRUE; /* Not clear what to do for green slimes */ break; } diff --git a/src/uhitm.c b/src/uhitm.c index 2bbe579a4..6cef240dc 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1595621524 2020/07/24 20:12:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.238 $ */ +/* NetHack 3.6 uhitm.c $NHDT-Date: 1596046196 2020/07/29 18:09:56 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -1979,6 +1979,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (g.notonhead || !has_head(pd)) { pline("%s doesn't seem harmed.", Monnam(mdef)); + /* hero should skip remaining AT_TENT+AD_DRIN attacks + because they'll be just as harmless as this one (and also + to reduce verbosity) */ + g.skipdrin = TRUE; tmp = 0; if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) { if (!Slimed) { @@ -2445,9 +2449,13 @@ register struct monst *mon; } multi_claw = (multi_claw > 1); /* switch from count to yes/no */ + g.skipdrin = FALSE; /* [see mattackm(mhitm.c)] */ + for (i = 0; i < NATTK; i++) { /* sum[i] = 0; -- now done above */ mattk = getmattk(&g.youmonst, mon, i, sum, &alt_attk); + if (g.skipdrin && mattk->aatyp == AT_TENT && mattk->adtyp == AD_DRIN) + continue; weapon = 0; switch (mattk->aatyp) { case AT_WEAP: From 827e40705df095b9c06b30f10ed1dca6cf2f4ba4 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 29 Jul 2020 18:23:54 -0700 Subject: [PATCH 039/708] X11+Qt vs config.h This lets combined X11 and Qt compile cleanly (when set up with hints/macosx10.10-qt and built with 'make WANT_WIN_X11=1 USE_XPM=1') but linking fails at present. (It can't find X11 library routines despite specifying the same -L/opt/X11/lib that X11 without Qt uses. The C++ linker is being used but the code that calls those routines is compiled as C, not C++ so name mangling shouldn't be an issue.) --- include/config.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/include/config.h b/include/config.h index 7083a09bf..7d54ceda3 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 config.h $NHDT-Date: 1594169990 2020/07/08 00:59:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ +/* NetHack 3.6 config.h $NHDT-Date: 1596072230 2020/07/30 01:23:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -58,7 +58,6 @@ /* #define CURSES_GRAPHICS *//* Curses interface - Karl Garrison*/ /* #define X11_GRAPHICS */ /* X11 interface */ /* #define QT_GRAPHICS */ /* Qt interface */ -/* #define GNOME_GRAPHICS */ /* Gnome interface */ /* #define MSWIN_GRAPHICS */ /* Windows NT, CE, Graphics */ /* @@ -103,16 +102,24 @@ #ifndef NOUSER_SOUNDS #define USER_SOUNDS /* Use sounds */ #endif +#ifndef USE_XPM #define USE_XPM /* Use XPM format for images (required) */ +#endif +#ifndef GRAPHIC_TOMBSTONE #define GRAPHIC_TOMBSTONE /* Use graphical tombstone (rip.ppm) */ +#endif #ifndef DEFAULT_WINDOW_SYS #define DEFAULT_WINDOW_SYS "Qt" #endif #endif #ifdef GNOME_GRAPHICS +#ifndef USE_XPM #define USE_XPM /* Use XPM format for images (required) */ +#endif +#ifndef GRAPHIC_TOMBSTONE #define GRAPHIC_TOMBSTONE /* Use graphical tombstone (rip.ppm) */ +#endif #ifndef DEFAULT_WINDOW_SYS #define DEFAULT_WINDOW_SYS "Gnome" #endif @@ -125,9 +132,11 @@ #define HACKDIR "\\nethack" #endif +#ifdef TTY_GRAPHICS #ifndef DEFAULT_WINDOW_SYS #define DEFAULT_WINDOW_SYS "tty" #endif +#endif #ifdef CURSES_GRAPHICS #ifndef DEFAULT_WINDOW_SYS @@ -146,8 +155,10 @@ */ /* # define USE_XPM */ /* Disable if you do not have the XPM library */ #ifdef USE_XPM +#ifndef GRAPHIC_TOMBSTONE #define GRAPHIC_TOMBSTONE /* Use graphical tombstone (rip.xpm) */ #endif +#endif #ifndef DEFAULT_WC_TILED_MAP #define DEFAULT_WC_TILED_MAP /* Default to tiles */ #endif From 5a072c420230291387a58c802498441379554889 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 30 Jul 2020 06:20:11 -0700 Subject: [PATCH 040/708] hints tinkering For macosx10.10-qt, move the linker specification to one spot. Should be no change in behavior. --- sys/unix/hints/macosx10.10-qt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index bb3773336..c5cafa09a 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.11 $NHDT-Date: 1595989870 2020/07/29 02:31:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.59 $ +# NetHack 3.6 macosx10.10-qt $NHDT-Date: 1596115204 2020/07/30 13:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -67,6 +67,12 @@ CXX=clang++ -std=gnu++11 # You shouldn't need to change anything below here. # +ifdef WANT_WIN_QT +LINK = $(CXX) +else +LINK = $(CC) +endif + #CFLAGS+=-W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so @@ -91,7 +97,6 @@ endif WINSRC = WINOBJ0 = WINLIB = -LINK = $(CC) VARDATND = ifdef WANT_WIN_TTY @@ -127,7 +132,6 @@ CFLAGS += -DQT_GRAPHICS -DNOUSER_SOUNDS QTCXXFLAGS += -Wno-deprecated-declarations QTCXXFLAGS += $(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) -LINK=$(CXX) WINSRC += $(WINQTSRC) WINOBJ0 += $(WINQTOBJ) VARDATND0 = nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm From 7f1420558ac2bd548040e66c0ba5b6f22c94aeca Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 30 Jul 2020 06:25:43 -0700 Subject: [PATCH 041/708] lua on Unix tinkering The base Makefile hasn't been using the '+=' construct, so take out the one used for lua (post 3.6.6). Only the 'Sysunix' target has been tested. --- sys/unix/Makefile.src | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 60283236f..1e0ad2842 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1595989869 2020/07/29 02:31:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ +# NetHack 3.6 Makefile.src $NHDT-Date: 1596115531 2020/07/30 13:25:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -49,7 +49,7 @@ SHELL=/bin/sh # for UNIX systems SYSSRC = ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixmain.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c -SYSOBJ = ioctl.o unixmain.o unixtty.o unixunix.o unixres.o ../lib/lua/liblua.a +SYSOBJ = ioctl.o unixmain.o unixtty.o unixunix.o unixres.o # # for Systos # SYSSRC = ../sys/atari/tos.c ../sys/share/pcmain.c ../sys/share/pcsys.c \ @@ -173,9 +173,6 @@ SYSOBJ = ioctl.o unixmain.o unixtty.o unixunix.o unixres.o ../lib/lua/liblua.a #CFLAGS = -O -I../include #LFLAGS = -# -lm required by lua -LIBS += -lm - # 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 # the C++ libraries linked in. @@ -447,6 +444,9 @@ AT = $(AT_V$(QUIETCC)) MAKEDEFS = ../util/makedefs +# -lm required by lua +LUALIB = ../lib/lua/liblua.a -lm + # timestamp files to reduce `make' overhead and shorten .o dependency lists CONFIG_H = ../src/config.h-t HACK_H = ../src/hack.h-t @@ -550,32 +550,33 @@ $(GAME): $(SYSTEM) Sysunix: $(HOBJ) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) $(LUALIB) @touch Sysunix Sys3B2: $(HOBJ) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) -lmalloc + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) -lmalloc @touch Sys3B2 Sysatt: $(HOBJ) Makefile @echo "Loading $(GAME)." - $(AT)$(LD) $(LFLAGS) /lib/crt0s.o /lib/shlib.ifile -o $(GAME) $(HOBJ) + $(AT)$(LD) $(LFLAGS) /lib/crt0s.o /lib/shlib.ifile -o $(GAME) $(HOBJ) \ + $(LUALIB) @touch Sysatt Systos: $(HOBJ) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) @touch Systos SysV-AT: DUMB.Setup $(HOBJ) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) @touch SysV-AT SysBe: $(HOBJ) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) $(LUALIB) @xres -o $(GAME) ../win/BeOS/nethack.rsrc @mimeset -f $(GAME) @touch SysBe From c96a9ff389fe93ec2f134a9f3d65c89dec362dec Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 30 Jul 2020 08:19:06 -0700 Subject: [PATCH 042/708] Qt menus font This greatly improves the '?' choice when using the '#' prefix to select an extended command. It isn't perfect, because the layout (using spaces to pad the first column so that the second one lines up) produces at least one line where is so long that it wraps, and instead of | | that selectable menu entries have, the continuation is | | (made slightly worse by the fact that is indented a little and isn't. This affects the aesthetics of all NHW_MENU windows, not just the one that desparately needed help. Maybe the core should send some hint on a menu or text window by menu or text window basis about whether or not fixed-width font is preferable to variable one. --- win/Qt/qt_menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index fb7e391e4..405a982b8 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -214,7 +214,7 @@ void NetHackQtMenuWindow::EndMenu(const QString& p) int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) { - QFont tablefont(qt_settings->normalFont()); + QFont tablefont(qt_settings->normalFixedFont()); table->setFont(tablefont); table->setRowCount(itemcount); From 8ca0834eb2cd23e7d5902dbcdf49ca9e2ca7f2d4 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 30 Jul 2020 08:58:57 -0700 Subject: [PATCH 043/708] Qt pick-none menu vs [cancel] Qt menus have [ok][cancel][all][none][other stuff] buttons across the top but it was disabling [cancel] for inventory viewing and other pick-none menus. Enable that so that [cancel] is a viable alternative to typing ESC or clicking on [ok] for dismissing the menu without picking anything. --- doc/fixes37.0 | 5 ++++- win/Qt/qt_menu.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index ec4a8f2b8..cc9312a41 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.260 $ $NHDT-Date: 1596039461 2020/07/29 16:17:41 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.261 $ $NHDT-Date: 1596124734 2020/07/30 15:58:54 $ General Fixes and Modified Features ----------------------------------- @@ -329,6 +329,9 @@ Qt: organize extended command selection grid by columns instead of by rows (first N entries down left column, next N entries down 2nd column, &c) Qt: when selecting an extended command by typing its name, support (aka ) in addition to to go back a character +Qt: switch to fixed-width font for menus +Qt: don't disable [cancel] button when viewing inventory or other pick-none + menus; ESC works to dismiss those and [cancel] should be the same tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 405a982b8..2f4d41762 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -222,7 +222,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) how=h; ok->setEnabled(how!=PICK_ONE);ok->setDefault(how!=PICK_ONE); - cancel->setEnabled(how!=PICK_NONE); + cancel->setEnabled(true); all->setEnabled(how==PICK_ANY); none->setEnabled(how==PICK_ANY); invert->setEnabled(how==PICK_ANY); From c64049306d6b52c7b0589bda8c47e10cb7608cfd Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 30 Jul 2020 19:25:57 -0700 Subject: [PATCH 044/708] candy bar wrappers Adopt the suggestion that candy bar stacks which get split should keep the same wrapper text for both halves of the stack. The patch stuck with using obj->o_id to manage the wrapper which prior to the patch wasn't a factor in merging and splitting. Switch to obj->spe instead, comparable to tin varities, so mergability is already taken care of. End of game disclosure tacks on T-shirt text to formatted items. Do the same for candy bar wrappers. --- doc/fixes37.0 | 5 ++++- include/extern.h | 4 +++- include/obj.h | 3 ++- src/mkobj.c | 8 +++++++- src/objnam.c | 21 ++++++++++++++++--- src/read.c | 52 +++++++++++++++++++++++++++++++++++++----------- 6 files changed, 74 insertions(+), 19 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index cc9312a41..53bc1b2c8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.261 $ $NHDT-Date: 1596124734 2020/07/30 15:58:54 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.262 $ $NHDT-Date: 1596162338 2020/07/31 02:25:38 $ General Fixes and Modified Features ----------------------------------- @@ -233,6 +233,9 @@ give rot-away timer instead of revive timer to corpses of cancelled trolls switch revive timer to rot-away timer if a troll corpse gets cancelled uncancel an ice troll if its corpse is put into an ice box; give corpse a revive timer if later taken out +splitting a stack of candy bars gave new wrapper text depending upon the + obj->o_id value assigned; keep existing text for both halves of stack + (side-effect: separate candy bars usually won't merge anymore) Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 873b2e632..cb198ff18 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1594168620 2020/07/08 00:37:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.851 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1596162339 2020/07/31 02:25:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.852 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2157,6 +2157,8 @@ E long NDECL(random); E void FDECL(learnscroll, (struct obj *)); E char *FDECL(tshirt_text, (struct obj *, char *)); +E const char *FDECL(candy_wrapper_text, (struct obj *)); +E void FDECL(assign_candy_wrapper, (struct obj *)); E int NDECL(doread); E boolean FDECL(is_chargeable, (struct obj *)); E void FDECL(recharge, (struct obj *, int)); diff --git a/include/obj.h b/include/obj.h index bdf7945cb..3feabe688 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 obj.h $NHDT-Date: 1590870784 2020/05/30 20:33:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 3.6 obj.h $NHDT-Date: 1596162340 2020/07/31 02:25:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -44,6 +44,7 @@ struct obj { number of charges for wand or charged tool ( >= -1 ); number of candles attached to candelabrum; marks your eggs, tin variety and spinach tins; + candy bar wrapper index; Schroedinger's Box (1) or royal coffers for a court (2); tells which fruit a fruit is; special for uball and amulet; diff --git a/src/mkobj.c b/src/mkobj.c index 4d5b5cc03..13e86e034 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1595787211 2020/07/26 18:13:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1596162341 2020/07/31 02:25:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -836,6 +836,12 @@ boolean artif; case KELP_FROND: otmp->quan = (long) rnd(2); break; + case CANDY_BAR: + /* set otmp->spe */ + assign_candy_wrapper(otmp); + break; + default: + break; } if (Is_pudding(otmp)) { otmp->quan = 1L; /* for emphasis; glob quantity is always 1 */ diff --git a/src/objnam.c b/src/objnam.c index 4dc8c585b..cbc539f20 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1595627152 2020/07/24 21:45:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.303 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1596162343 2020/07/31 02:25:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -718,10 +718,25 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ if (pluralize) Strcpy(buf, makeplural(buf)); - if (obj->otyp == T_SHIRT && g.program_state.gameover) { + /* maybe give some extra information which isn't shown during play */ + if (g.program_state.gameover) { + const char *lbl; char tmpbuf[BUFSZ]; - Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf)); + /* disclose without breaking illiterate conduct, but mainly tip off + players who aren't aware that something readable is present */ + switch (obj->otyp) { + case T_SHIRT: + Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf)); + break; + case CANDY_BAR: + lbl = candy_wrapper_text(obj); + if (*lbl) + Sprintf(eos(buf), " labeled \"%s\"", lbl); + break; + default: + break; + } } if (has_oname(obj) && dknown) { diff --git a/src/read.c b/src/read.c index 0963806b6..ac022be4c 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1595966992 2020/07/28 20:09:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.199 $ */ +/* NetHack 3.6 read.c $NHDT-Date: 1596162345 2020/07/31 02:25:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.200 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -178,6 +178,39 @@ char *buf; return erode_obj_text(apron, buf); } +static const char *candy_wrappers[] = { + "", /* (none -- should never happen) */ + "Apollo", /* Lost */ + "Moon Crunchy", /* South Park */ + "Snacky Cake", "Chocolate Nuggie", "The Small Bar", + "Crispy Yum Yum", "Nilla Crunchie", "Berry Bar", + "Choco Nummer", "Om-nom", /* Cat Macro */ + "Fruity Oaty", /* Serenity */ + "Wonka Bar", /* Charlie and the Chocolate Factory */ +}; + +/* return the text of a candy bar's wrapper */ +const char * +candy_wrapper_text(obj) +struct obj *obj; +{ + /* modulo operation is just bullet proofing; 'spe' is already in range */ + return candy_wrappers[obj->spe % SIZE(candy_wrappers)]; +} + +/* assign a wrapper to a candy bar stack */ +void +assign_candy_wrapper(obj) +struct obj *obj; +{ + if (obj->otyp == CANDY_BAR) { + /* skips candy_wrappers[0] */ + obj->spe = 1 + rn2(SIZE(candy_wrappers) - 1); + } + return; +} + +/* the 'r' command; read a scroll or spell book or various other things */ int doread() { @@ -299,22 +332,17 @@ doread() u.uconduct.literate++; return 1; } else if (scroll->otyp == CANDY_BAR) { - static const char *wrapper_msgs[] = { - "Apollo", /* Lost */ - "Moon Crunchy", /* South Park */ - "Snacky Cake", "Chocolate Nuggie", "The Small Bar", - "Crispy Yum Yum", "Nilla Crunchie", "Berry Bar", - "Choco Nummer", "Om-nom", /* Cat Macro */ - "Fruity Oaty", /* Serenity */ - "Wonka Bar" /* Charlie and the Chocolate Factory */ - }; + const char *wrapper = candy_wrapper_text(scroll); if (Blind) { You_cant("feel any Braille writing."); return 0; } - pline("The wrapper reads: \"%s\".", - wrapper_msgs[scroll->o_id % SIZE(wrapper_msgs)]); + if (!*wrapper) { + pline("The candy bar's wrapper is blank."); + return 0; + } + pline("The wrapper reads: \"%s\".", wrapper); u.uconduct.literate++; return 1; } else if (scroll->oclass != SCROLL_CLASS From 922321b2511f09734afbfd18ba87b3d3badf6577 Mon Sep 17 00:00:00 2001 From: copperwater Date: Thu, 30 Jul 2020 23:07:30 -0400 Subject: [PATCH 045/708] Add instructions to zero mextra struct pointer in mextra documentation It doesn't mention anywhere that newmextra() is responsible for initializing struct mextra with null pointers to the various sub-structs. So, when one follows the instructions and doesn't know or remember to do this, they'll get segfaults when something tries to read the uninitialized pointer to their new struct. --- include/mextra.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/mextra.h b/include/mextra.h index 9ceee2fb2..ca42f2bb7 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -56,6 +56,8 @@ * struct or data during a restore. * 10. Adjust savemon() in src/save.c to deal with your * struct or data during a save. + * 11. Zero out the pointer to your struct in newmextra() in + * src/makemon.c. */ /*** From 6b7979fa72304e6d7d3afe6e558a82bb066c516c Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 08:31:09 -0400 Subject: [PATCH 046/708] add note to zero out new mextra and oextra fields Closes #375 --- include/mextra.h | 18 +++++++++--------- include/obj.h | 14 ++++++++------ 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/include/mextra.h b/include/mextra.h index ca42f2bb7..50546787b 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -19,7 +19,9 @@ * file. * 3. Add a referencing macro at bottom of this file after the mextra * struct (see MNAME, EGD, EPRI, ESHK, EMIN, or EDOG for examples). - * 4. Create a newXX(mtmp) function and possibly a free_XX(mtmp) + * 4. Zero out the pointer to your struct in newmextra() in + * src/makemon.c. + * 5. Create a newXX(mtmp) function and possibly a free_XX(mtmp) * function in an appropriate new or existing source file and add * a prototype for it to include/extern.h. * @@ -39,7 +41,7 @@ * } * } * - * 5. Consider adding a new makemon flag MM_XX flag to include/hack.h + * 6. Consider adding a new makemon flag MM_XX flag to include/hack.h * and a corresponding change to makemon() if you require your * structure to be added at monster creation time. Initialize your * struct after a successful return from makemon(). @@ -47,17 +49,15 @@ * src/makemon.c: if (mmflags & MM_XX) newXX(mtmp); * your new code: mon = makemon(&mons[mnum], x, y, MM_XX); * - * 6. Adjust size_monst() in src/cmd.c appropriately. - * 7. Adjust dealloc_mextra() in src/mon.c to clean up + * 7. Adjust size_monst() in src/cmd.c appropriately. + * 8. Adjust dealloc_mextra() in src/mon.c to clean up * properly during monst deallocation. - * 8. Adjust copy_mextra() in src/mon.c to make duplicate + * 9. Adjust copy_mextra() in src/mon.c to make duplicate * copies of your struct or data on another monst struct. - * 9. Adjust restmon() in src/restore.c to deal with your + * 10. Adjust restmon() in src/restore.c to deal with your * struct or data during a restore. - * 10. Adjust savemon() in src/save.c to deal with your + * 11. Adjust savemon() in src/save.c to deal with your * struct or data during a save. - * 11. Zero out the pointer to your struct in newmextra() in - * src/makemon.c. */ /*** diff --git a/include/obj.h b/include/obj.h index 3feabe688..703f82792 100644 --- a/include/obj.h +++ b/include/obj.h @@ -389,7 +389,9 @@ struct obj { * 4. Add a testing macro after the set of referencing macros * (see has_oname(), has_omonst(), has_omailcmd(), and has_omin(), * for examples). - * 5. Create newXX(otmp) function and possibly free_XX(otmp) function + * 5. Zero out the pointer to your struct in newmoextra() in + * src/mkobj.c. + * 6. Create newXX(otmp) function and possibly free_XX(otmp) function * in an appropriate new or existing source file and add a prototype * for it to include/extern.h. The majority of these are currently * located in mkobj.c for convenience. @@ -410,14 +412,14 @@ struct obj { * } * } * - * 6. Adjust size_obj() in src/cmd.c appropriately. - * 7. Adjust dealloc_oextra() in src/mkobj.c to clean up + * 7. Adjust size_obj() in src/cmd.c appropriately. + * 8. Adjust dealloc_oextra() in src/mkobj.c to clean up * properly during obj deallocation. - * 8. Adjust copy_oextra() in src/mkobj.c to make duplicate + * 9. Adjust copy_oextra() in src/mkobj.c to make duplicate * copies of your struct or data onto another obj struct. - * 9. Adjust restobj() in src/restore.c to deal with your + * 10. Adjust restobj() in src/restore.c to deal with your * struct or data during a restore. - * 10. Adjust saveobj() in src/save.c to deal with your + * 11. Adjust saveobj() in src/save.c to deal with your * struct or data during a save. */ From 33acf59ee715e64af42c50d3e55b56b31a747947 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 08:37:51 -0400 Subject: [PATCH 047/708] merge and evolve PR #375 Closes #375 --- doc/fixes37.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 53bc1b2c8..fa8ca4296 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -521,4 +521,6 @@ removed MFLOPPY conditional code get rid of 3.6.1 workaround needed to retain compatibility with 3.6.0 bones files after fix for 3.3.0 through 3.6.0 bug for invalid 'bonesid' designation in bones of quest levels +add an additional note to mextra.h and obj.h comments that reminds people to + zero out added mextra and oextra fields in the appropriate function From f153c1f0d12f96afbd3a7ff6872e586240414857 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 08:42:40 -0400 Subject: [PATCH 048/708] typo fix in include/obj.h comment --- include/obj.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/obj.h b/include/obj.h index 703f82792..cbb5f7003 100644 --- a/include/obj.h +++ b/include/obj.h @@ -389,7 +389,7 @@ struct obj { * 4. Add a testing macro after the set of referencing macros * (see has_oname(), has_omonst(), has_omailcmd(), and has_omin(), * for examples). - * 5. Zero out the pointer to your struct in newmoextra() in + * 5. Zero out the pointer to your struct in newoextra() in * src/mkobj.c. * 6. Create newXX(otmp) function and possibly free_XX(otmp) function * in an appropriate new or existing source file and add a prototype From 8b2750ab603ddd2d0bff910513e7bc9ab2bb4860 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 09:42:17 -0400 Subject: [PATCH 049/708] lower the code upkeep for mextra and oextra pointer additions --- include/mextra.h | 4 ++-- include/obj.h | 4 ++-- src/makemon.c | 18 +++++++++++------- src/mkobj.c | 14 ++++++++++---- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/include/mextra.h b/include/mextra.h index 50546787b..9d87a8181 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -19,8 +19,8 @@ * file. * 3. Add a referencing macro at bottom of this file after the mextra * struct (see MNAME, EGD, EPRI, ESHK, EMIN, or EDOG for examples). - * 4. Zero out the pointer to your struct in newmextra() in - * src/makemon.c. + * 4. If your new field isn't a pointer and requires a special value + * on initialization, add code to init_mextra() in src/makemon.c * 5. Create a newXX(mtmp) function and possibly a free_XX(mtmp) * function in an appropriate new or existing source file and add * a prototype for it to include/extern.h. diff --git a/include/obj.h b/include/obj.h index cbb5f7003..ad54580ad 100644 --- a/include/obj.h +++ b/include/obj.h @@ -389,8 +389,8 @@ struct obj { * 4. Add a testing macro after the set of referencing macros * (see has_oname(), has_omonst(), has_omailcmd(), and has_omin(), * for examples). - * 5. Zero out the pointer to your struct in newoextra() in - * src/mkobj.c. + * 5. If your new field isn't a pointer and requires a special value + * on initialization, add code to init_oextra() in src/mkobj.c. * 6. Create newXX(otmp) function and possibly free_XX(otmp) function * in an appropriate new or existing source file and add a prototype * for it to include/extern.h. The majority of these are currently diff --git a/src/makemon.c b/src/makemon.c index 09b082ed8..12f03431a 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1038,19 +1038,23 @@ int mndx; } } +static const struct mextra zeromextra = { DUMMY }; + +static void +init_mextra(mex) +struct mextra *mex; +{ + *mex = zeromextra; + mex->mcorpsenm = NON_PM; +} + struct mextra * newmextra() { struct mextra *mextra; mextra = (struct mextra *) alloc(sizeof(struct mextra)); - mextra->mname = 0; - mextra->egd = 0; - mextra->epri = 0; - mextra->eshk = 0; - mextra->emin = 0; - mextra->edog = 0; - mextra->mcorpsenm = NON_PM; + init_mextra(mextra); return mextra; } diff --git a/src/mkobj.c b/src/mkobj.c index 13e86e034..4b3411a6a 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -67,16 +67,22 @@ static const struct icp hellprobs[] = { { 20, WEAPON_CLASS }, { 8, RING_CLASS }, { 4, AMULET_CLASS } }; +static const struct oextra zerooextra = { DUMMY }; + +static void +init_oextra(oex) +struct oextra *oex; +{ + *oex = zerooextra; +} + struct oextra * newoextra() { struct oextra *oextra; oextra = (struct oextra *) alloc(sizeof (struct oextra)); - oextra->oname = 0; - oextra->omonst = 0; - oextra->omailcmd = 0; - oextra->omid = 0; + init_oextra(oextra); return oextra; } From 63575059489c799b902e504fdd270617790052a8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 10:00:14 -0400 Subject: [PATCH 050/708] makemon and mkobj follow-up initialization bit --- src/makemon.c | 2 +- src/mkobj.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/makemon.c b/src/makemon.c index 12f03431a..d09518bb1 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1038,7 +1038,7 @@ int mndx; } } -static const struct mextra zeromextra = { DUMMY }; +static const struct mextra zeromextra = DUMMY; static void init_mextra(mex) diff --git a/src/mkobj.c b/src/mkobj.c index 4b3411a6a..d46ed924c 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -67,7 +67,7 @@ static const struct icp hellprobs[] = { { 20, WEAPON_CLASS }, { 8, RING_CLASS }, { 4, AMULET_CLASS } }; -static const struct oextra zerooextra = { DUMMY }; +static const struct oextra zerooextra = DUMMY; static void init_oextra(oex) From e524fc4fc806859c895d3110155c91084683020a Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 10:57:20 -0400 Subject: [PATCH 051/708] clarify what was meant by "special" in a comment --- include/mextra.h | 2 +- include/obj.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mextra.h b/include/mextra.h index 9d87a8181..a8e06784e 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -19,7 +19,7 @@ * file. * 3. Add a referencing macro at bottom of this file after the mextra * struct (see MNAME, EGD, EPRI, ESHK, EMIN, or EDOG for examples). - * 4. If your new field isn't a pointer and requires a special value + * 4. If your new field isn't a pointer and requires a non-zero value * on initialization, add code to init_mextra() in src/makemon.c * 5. Create a newXX(mtmp) function and possibly a free_XX(mtmp) * function in an appropriate new or existing source file and add diff --git a/include/obj.h b/include/obj.h index ad54580ad..9ff6bdc71 100644 --- a/include/obj.h +++ b/include/obj.h @@ -389,7 +389,7 @@ struct obj { * 4. Add a testing macro after the set of referencing macros * (see has_oname(), has_omonst(), has_omailcmd(), and has_omin(), * for examples). - * 5. If your new field isn't a pointer and requires a special value + * 5. If your new field isn't a pointer and requires a non-zero value * on initialization, add code to init_oextra() in src/mkobj.c. * 6. Create newXX(otmp) function and possibly free_XX(otmp) function * in an appropriate new or existing source file and add a prototype From 3388fd5887d99942d6ea83165eae2f89aa0ebf8d Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 31 Jul 2020 12:53:34 -0700 Subject: [PATCH 052/708] Qt comment tidbit A recenly added comment used "its" where "it's" was intended. Instead of just adding an apostrophe, rewrite the clause. --- win/Qt/qt_xcmd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 448f66dfe..3bb3a4f92 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -70,7 +70,7 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : } /* 'ncols' should be calculated to fit (or enable a vertical scrollbar - when its so big it forces too many rows, if GroupBox supports that); + when resulting 'nrows' is too big, if GroupBox supports that); it used to be hardcoded 4 but after every command became accessible as an extended command, that resulted in so many rows that some of the buttoms were chopped off at the bottom of the grid */ From 97cc68955328dddc3d565e68b5dfb39c5fe92c43 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 31 Jul 2020 13:14:09 -0700 Subject: [PATCH 053/708] tin identification Tin handling code used tin->cknown to indicate that the variety (soup, deep fried, pureed, &c) was known, but neither object identification nor end of game disclosure was setting cknown for that type of object. ^I behaves as if cknown is set, so the problem was hidden during times when anyone was likely to be paying attention. --- doc/fixes37.0 | 4 +++- include/extern.h | 3 ++- include/obj.h | 5 +++-- src/end.c | 5 ++--- src/invent.c | 19 ++++++++++++++++--- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index fa8ca4296..c45b6e268 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.262 $ $NHDT-Date: 1596162338 2020/07/31 02:25:38 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ $NHDT-Date: 1596226446 2020/07/31 20:14:06 $ General Fixes and Modified Features ----------------------------------- @@ -236,6 +236,8 @@ uncancel an ice troll if its corpse is put into an ice box; give corpse a splitting a stack of candy bars gave new wrapper text depending upon the obj->o_id value assigned; keep existing text for both halves of stack (side-effect: separate candy bars usually won't merge anymore) +describing tin variety (deep fried, pureed, &c) relied on the 'contents known' + flag but object identification wasn't setting obj->cknown for tins Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index cb198ff18..3c2d94dda 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1596162339 2020/07/31 02:25:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.852 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1596226441 2020/07/31 20:14:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.853 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1044,6 +1044,7 @@ E int FDECL(ggetobj, (const char *, int (*)(OBJ_P), int, BOOLEAN_P, unsigned *)); E int FDECL(askchain, (struct obj **, const char *, int, int (*)(OBJ_P), int (*)(OBJ_P), int, const char *)); +E void FDECL(set_cknown_lknown, (struct obj *)); E void FDECL(fully_identify_obj, (struct obj *)); E int FDECL(identify, (struct obj *)); E int FDECL(count_unidentified, (struct obj *)); diff --git a/include/obj.h b/include/obj.h index 9ff6bdc71..39f6c67a5 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 obj.h $NHDT-Date: 1596162340 2020/07/31 02:25:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.6 obj.h $NHDT-Date: 1596226442 2020/07/31 20:14:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -106,7 +106,8 @@ struct obj { Bitfield(in_use, 1); /* for magic items before useup items */ Bitfield(bypass, 1); /* mark this as an object to be skipped by bhito() */ - Bitfield(cknown, 1); /* contents of container assumed to be known */ + Bitfield(cknown, 1); /* for containers (including statues): the contents + * are known; also applicable to tins */ Bitfield(lknown, 1); /* locked/unlocked status is known */ /* 4 free bits */ diff --git a/src/end.c b/src/end.c index a33e9ef07..fa6295b8b 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 end.c $NHDT-Date: 1583190253 2020/03/02 23:04:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.208 $ */ +/* NetHack 3.6 end.c $NHDT-Date: 1596226442 2020/07/31 20:14:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.210 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1315,8 +1315,7 @@ int how; for (obj = g.invent; obj; obj = obj->nobj) { discover_object(obj->otyp, TRUE, FALSE); obj->known = obj->bknown = obj->dknown = obj->rknown = 1; - if (Is_container(obj) || obj->otyp == STATUE) - obj->cknown = obj->lknown = 1; + set_cknown_lknown(obj); /* set flags when applicable */ /* we resolve Schroedinger's cat now in case of both disclosure and dumplog, where the 50:50 chance for live cat has to be the same both times */ diff --git a/src/invent.c b/src/invent.c index 0e0ccec8f..e33740ace 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1590343765 2020/05/24 18:09:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1596226443 2020/07/31 20:14:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2315,6 +2315,20 @@ int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P)); * Object identification routines: */ +/* set the cknown and lknown flags on an object if they're applicable */ +void +set_cknown_lknown(obj) +struct obj *obj; +{ + if (Is_container(obj) || obj->otyp == STATUE) + obj->cknown = obj->lknown = 1; + else if (obj->otyp == TIN) + obj->cknown = 1; + /* TODO? cknown might be extended to candy bar, where it would mean that + wrapper's text was known which in turn indicates candy bar's content */ + return; +} + /* make an object actually be identified; no display updating */ void fully_identify_obj(otmp) @@ -2324,8 +2338,7 @@ struct obj *otmp; if (otmp->oartifact) discover_artifact((xchar) otmp->oartifact); otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; - if (Is_container(otmp) || otmp->otyp == STATUE) - otmp->cknown = otmp->lknown = 1; + set_cknown_lknown(otmp); /* set otmp->{cknown,lknown} if applicable */ if (otmp->otyp == EGG && otmp->corpsenm != NON_PM) learn_egg_type(otmp->corpsenm); } From 1d2a5aed375f81e63dab71fef2ca008adb93ea0b Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 31 Jul 2020 16:59:34 -0400 Subject: [PATCH 054/708] adjust note wording in mkobj.c and makemon.c --- doc/fixes37.0 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c45b6e268..cb9670fed 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -524,5 +524,6 @@ get rid of 3.6.1 workaround needed to retain compatibility with 3.6.0 bones files after fix for 3.3.0 through 3.6.0 bug for invalid 'bonesid' designation in bones of quest levels add an additional note to mextra.h and obj.h comments that reminds people to - zero out added mextra and oextra fields in the appropriate function + appropriately init new fields if they need to initialize to something + other than zero From dcf5d7d68ec0dbd8516e164b606206f01c99745d Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 31 Jul 2020 14:30:55 -0700 Subject: [PATCH 055/708] Qt+X11 on OSX Using hints/macosx10.10-qt, | make QTDIR={path} WANT_WIN_X11=1 USE_XPM=1 now builds a combined tty+Qt+X11 binary. Linking the X11 code works a lot better when the Makefile tells the linker where the X11 libraries are.... This reconciles some of the differences between macosx10.10 and macosx10.10-qt but there are still lots more (including lack of WANT_WIN_CURSES in the latter). And now 10.10 has differences with the half dozen or so other macosx10.* hints. --- sys/unix/hints/macosx10.10 | 25 +++++++++++++++++++------ sys/unix/hints/macosx10.10-qt | 13 ++++++++++++- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/sys/unix/hints/macosx10.10 b/sys/unix/hints/macosx10.10 index 279a15ec3..f4c2989f0 100644 --- a/sys/unix/hints/macosx10.10 +++ b/sys/unix/hints/macosx10.10 @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.11 $NHDT-Date: 1566346603 2019/08/21 00:16:43 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.53 $ +# NetHack 3.6 macosx10.11 $NHDT-Date: 1596231041 2020/07/31 21:30:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -59,6 +59,7 @@ GAMEGRP = games #WANT_SOURCE_INSTALL=1 CC=gcc +CXX=g++ # At the moment this is just for debugging, but in the future it could be # useful for other things. Requires SYSCF and an ANSI compiler. @@ -68,8 +69,23 @@ CC=gcc # You shouldn't need to change anything below here. # +ifdef WANT_WIN_QT +LINK = $(CXX) +else +LINK = $(CC) +endif + #CFLAGS+=-W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN -CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN -ansi -pedantic -Wno-long-long +CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN +ifndef WANT_WIN_QT +# these are normally used when compiling nethack's core +CFLAGS+=-ansi -pedantic -Wno-long-long +# but -ansi -pendantic forces C90 sematics and win/Qt/qt_*.cpp trigger +#In file included from .../qt5/include/QtCore/qglobal.h:105: +#.../qt5/include/QtCore/qcompilerdetection.h:561:6: +# error Qt requires a C++11 compiler and yours does not seem to be that. +# so we suppress them when the build includes Qt +endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. #CFLAGS+=-Wunreachable-code @@ -110,9 +126,9 @@ WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm # -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 ); +CFLAGS += -DX11_GRAPHICS # separate from CFLAGS so that we don't pass it to every file X11CFLAGS = -I/opt/X11/include -CFLAGS += -DX11_GRAPHICS # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XPM @@ -129,7 +145,6 @@ endif # WANT_WIN_X11 ifdef WANT_WIN_QT CFLAGS += -DQT_GRAPHICS -DNOUSER_SOUNDS CFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4 -LINK=g++ WINSRC += $(WINQTSRC) WINLIB += $(WINQTLIB) $(LIBXPM) WINLIB += -framework Carbon -framework QuickTime -lz -framework OpenGL @@ -149,8 +164,6 @@ ifndef QTDIR $(error QTDIR not defined in the environment or Makefile) endif # QTDIR # XXX make sure QTDIR points to something reasonable -else # !WANT_WIN_QT -LINK=$(CC) endif # !WANT_WIN_QT ifdef WANT_SHARE_INSTALL diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index c5cafa09a..25466cf4c 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.10-qt $NHDT-Date: 1596115204 2020/07/30 13:20:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ +# NetHack 3.6 macosx10.10-qt $NHDT-Date: 1596231050 2020/07/31 21:30:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.61 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -75,6 +75,15 @@ endif #CFLAGS+=-W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN +ifndef WANT_WIN_QT +# these are normally used when compiling nethack's core +CFLAGS+=-ansi -pedantic -Wno-long-long +# but -ansi -pendantic forces C90 sematics and win/Qt/qt_*.cpp trigger +#In file included from .../qt5/include/QtCore/qglobal.h:105: +#.../qt5/include/QtCore/qcompilerdetection.h:561:6: +# error Qt requires a C++11 compiler and yours does not seem to be that. +# so we suppress them when the build includes Qt +endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. #CFLAGS+=-Wunreachable-code @@ -109,7 +118,9 @@ CFLAGS += -DNOTTYGRAPHICS endif # !WANT_WIN_TTY ifdef WANT_WIN_X11 +WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +# -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 ); CFLAGS += -DX11_GRAPHICS # separate from CFLAGS so that we don't pass it to every file From 308e7ededd0b1cc1932553a1ea26c3c06a6f784d Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 31 Jul 2020 16:05:35 -0700 Subject: [PATCH 056/708] Qt status conditions The status lines are out of date. This brings status conditions up to 3.6.0 level: adding Stoned, Slimed, Strangled, Deaf, Levitating, Flying, Riding. It also reorders a few things: put encumbrance after hunger, put Confused after Stunned, and Blind after Hallucinating. Also renames Sick to FoodPois and Ill to TermIll. So, the portion of status devoted to conditions is now (left to right on one line): Satiated/[omitted]/Hungry/Weak/Fainting/Fainted, [omitted]/Burdened/Stressed/Strained/Overtaxed/Overloaded, Stone, Slime, Strngl, FoodPois, TermIll, Stun, Conf, Hallu, Blind, Deaf, Lev, Fly, Ride. It's actually two lines. The upper line has a 40x40 or so icon (aka tile, defined in qt_xpms.h rather than a data file) above the corresponding text on the lower line. I created a blank icon and used it for all the added conditions. At some point someone with artistic talent will need to draw a bunch of things. --- doc/fixes37.0 | 3 +- win/Qt/qt_stat.cpp | 157 ++++++++++++++++++++++++++++++++------------- win/Qt/qt_stat.h | 28 ++++++-- win/Qt/qt_xpms.h | 52 +++++++++++++++ 4 files changed, 186 insertions(+), 54 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index cb9670fed..a5b90b73c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ $NHDT-Date: 1596226446 2020/07/31 20:14:06 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ $NHDT-Date: 1596236728 2020/07/31 23:05:28 $ General Fixes and Modified Features ----------------------------------- @@ -337,6 +337,7 @@ Qt: when selecting an extended command by typing its name, support Qt: switch to fixed-width font for menus Qt: don't disable [cancel] button when viewing inventory or other pick-none menus; ESC works to dismiss those and [cancel] should be the same +Qt: bring status conditions up to 3.6 levels but new ones lack pictures tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 2ed28612e..22fb2f6a5 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -57,13 +57,20 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : time(this,"Time"), score(this,"Score"), hunger(this,""), - confused(this,"Confused"), - sick_fp(this,"Sick"), - sick_il(this,"Ill"), - blind(this,""), - stunned(this,"Stunned"), - hallu(this,"Hallu"), encumber(this,""), + stoned(this,"Stone"), + slimed(this,"Slime"), + strngld(this,"Strngl"), + sick_fp(this,"FoodPois"), + sick_il(this,"TermIll"), + stunned(this,"Stun"), + confused(this,"Conf"), + hallu(this,"Hallu"), + blind(this,""), + deaf(this,"Deaf"), + lev(this,"Lev"), + fly(this,"Fly"), + ride(this,"Ride"), hline1(this), hline2(this), hline3(this), @@ -84,19 +91,26 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : p_satiated = QPixmap(satiated_xpm); p_hungry = QPixmap(hungry_xpm); - p_confused = QPixmap(confused_xpm); - p_sick_fp = QPixmap(sick_fp_xpm); - p_sick_il = QPixmap(sick_il_xpm); - p_blind = QPixmap(blind_xpm); - p_stunned = QPixmap(stunned_xpm); - p_hallu = QPixmap(hallu_xpm); - p_encumber[0] = QPixmap(slt_enc_xpm); p_encumber[1] = QPixmap(mod_enc_xpm); p_encumber[2] = QPixmap(hvy_enc_xpm); p_encumber[3] = QPixmap(ext_enc_xpm); p_encumber[4] = QPixmap(ovr_enc_xpm); + p_stoned = QPixmap(blank_xpm); // placeholder icon + p_slimed = QPixmap(blank_xpm); // placeholder icon + p_strngld = QPixmap(blank_xpm); // placeholder icon + p_sick_fp = QPixmap(sick_fp_xpm); + p_sick_il = QPixmap(sick_il_xpm); + p_stunned = QPixmap(stunned_xpm); + p_confused = QPixmap(confused_xpm); + p_hallu = QPixmap(hallu_xpm); + p_blind = QPixmap(blind_xpm); + p_deaf = QPixmap(blank_xpm); // placeholder icon + p_lev = QPixmap(blank_xpm); // placeholder icon + p_fly = QPixmap(blank_xpm); // placeholder icon + p_ride = QPixmap(blank_xpm); // placeholder icon + str.setIcon(p_str); dex.setIcon(p_dex); con.setIcon(p_con); @@ -106,15 +120,21 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : align.setIcon(p_neutral); hunger.setIcon(p_hungry); + encumber.setIcon(p_encumber[0]); - confused.setIcon(p_confused); + stoned.setIcon(p_stoned); + slimed.setIcon(p_slimed); + strngld.setIcon(p_strngld); sick_fp.setIcon(p_sick_fp); sick_il.setIcon(p_sick_il); - blind.setIcon(p_blind); stunned.setIcon(p_stunned); + confused.setIcon(p_confused); hallu.setIcon(p_hallu); - - encumber.setIcon(p_encumber[0]); + blind.setIcon(p_blind); + deaf.setIcon(p_deaf); + lev.setIcon(p_lev); + fly.setIcon(p_fly); + ride.setIcon(p_ride); hline1.setFrameStyle(QFrame::HLine|QFrame::Sunken); hline2.setFrameStyle(QFrame::HLine|QFrame::Sunken); @@ -156,13 +176,20 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : QHBoxLayout *statbox = new QHBoxLayout(); statbox->addWidget(&align); statbox->addWidget(&hunger); - statbox->addWidget(&confused); + statbox->addWidget(&encumber); + statbox->addWidget(&stoned); + statbox->addWidget(&slimed); + statbox->addWidget(&strngld); statbox->addWidget(&sick_fp); statbox->addWidget(&sick_il); - statbox->addWidget(&blind); statbox->addWidget(&stunned); + statbox->addWidget(&confused); statbox->addWidget(&hallu); - statbox->addWidget(&encumber); + statbox->addWidget(&blind); + statbox->addWidget(&deaf); + statbox->addWidget(&lev); + statbox->addWidget(&fly); + statbox->addWidget(&ride); statbox->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); vbox->addLayout(statbox); setLayout(vbox); @@ -195,13 +222,20 @@ void NetHackQtStatusWindow::doUpdate() time.setFont(normal); score.setFont(normal); hunger.setFont(normal); - confused.setFont(normal); + encumber.setFont(normal); + stoned.setFont(normal); + slimed.setFont(normal); + strngld.setFont(normal); sick_fp.setFont(normal); sick_il.setFont(normal); - blind.setFont(normal); stunned.setFont(normal); + confused.setFont(normal); hallu.setFont(normal); - encumber.setFont(normal); + blind.setFont(normal); + deaf.setFont(normal); + lev.setFont(normal); + fly.setFont(normal); + ride.setFont(normal); updateStats(); } @@ -288,13 +322,20 @@ void NetHackQtStatusWindow::resizeEvent(QResizeEvent*) iw=width()/9; align.setGeometry(x,y,iw,lh); x+=iw; hunger.setGeometry(x,y,iw,lh); x+=iw; - confused.setGeometry(x,y,iw,lh); x+=iw; + encumber.setGeometry(x,y,iw,lh); x+=iw; + stoned.setGeometry(x,y,iw,lh); x+=iw; + slimed.setGeometry(x,y,iw,lh); x+=iw; + strngld.setGeometry(x,y,iw,lh); x+=iw; sick_fp.setGeometry(x,y,iw,lh); x+=iw; sick_il.setGeometry(x,y,iw,lh); x+=iw; - blind.setGeometry(x,y,iw,lh); x+=iw; stunned.setGeometry(x,y,iw,lh); x+=iw; + confused.setGeometry(x,y,iw,lh); x+=iw; hallu.setGeometry(x,y,iw,lh); x+=iw; - encumber.setGeometry(x,y,iw,lh); x+=iw; + blind.setGeometry(x,y,iw,lh); x+=iw; + deaf.setGeometry(x,y,iw,lh); x+=iw; + lev.setGeometry(x,y,iw,lh); x+=iw; + fly.setGeometry(x,y,iw,lh); x+=iw; + ride.setGeometry(x,y,iw,lh); x+=iw; x=0; y+=lh; #else // This is clumsy. But QLayout objects are proving balky. @@ -342,13 +383,20 @@ void NetHackQtStatusWindow::fadeHighlighting() score.dissipateHighlight(); hunger.dissipateHighlight(); - confused.dissipateHighlight(); + encumber.dissipateHighlight(); + stoned.dissipateHighlight(); + slimed.dissipateHighlight(); + strngld.dissipateHighlight(); sick_fp.dissipateHighlight(); sick_il.dissipateHighlight(); - blind.dissipateHighlight(); stunned.dissipateHighlight(); + confused.dissipateHighlight(); hallu.dissipateHighlight(); - encumber.dissipateHighlight(); + blind.dissipateHighlight(); + deaf.dissipateHighlight(); + lev.dissipateHighlight(); + fly.dissipateHighlight(); + ride.dissipateHighlight(); } /* @@ -361,7 +409,7 @@ void NetHackQtStatusWindow::fadeHighlighting() * * Information on the second line: * dlvl, gold, hp, power, ac, {level & exp or HD **} - * status (hunger, conf, halu, stun, sick, blind), time, encumbrance + * status (hunger, encumbrance, sick, stun, conf, halu, blind), time * * [**] HD is shown instead of level and exp if mtimedone is non-zero. */ @@ -398,14 +446,25 @@ void NetHackQtStatusWindow::updateStats() hunger.setLabel(hung); hunger.show(); } - if (Confusion) confused.show(); else confused.hide(); + const char *enc = enc_stat[near_capacity()]; + if (enc[0]==' ' || !enc[0]) { + encumber.hide(); + } else { + encumber.setIcon(p_encumber[near_capacity() - 1]); + encumber.setLabel(enc); + encumber.show(); + } + if (Stoned) stoned.show(); else stoned.hide(); + if (Slimed) slimed.show(); else slimed.hide(); + if (Strangled) strngld.show(); else strngld.hide(); if (Sick) { - if (u.usick_type & SICK_VOMITABLE) { + /* FoodPois or TermIll or both */ + if (u.usick_type & SICK_VOMITABLE) { /* food poisoning */ sick_fp.show(); } else { sick_fp.hide(); } - if (u.usick_type & SICK_NONVOMITABLE) { + if (u.usick_type & SICK_NONVOMITABLE) { /* terminally ill */ sick_il.show(); } else { sick_il.hide(); @@ -414,22 +473,21 @@ void NetHackQtStatusWindow::updateStats() sick_fp.hide(); sick_il.hide(); } + if (Stunned) stunned.show(); else stunned.hide(); + if (Confusion) confused.show(); else confused.hide(); + if (Hallucination) hallu.show(); else hallu.hide(); if (Blind) { blind.setLabel("Blind"); blind.show(); } else { blind.hide(); } - if (Stunned) stunned.show(); else stunned.hide(); - if (Hallucination) hallu.show(); else hallu.hide(); - const char* enc=enc_stat[near_capacity()]; - if (enc[0]==' ' || !enc[0]) { - encumber.hide(); - } else { - encumber.setIcon(p_encumber[near_capacity()-1]); - encumber.setLabel(enc); - encumber.show(); - } + if (Deaf) deaf.show(); else deaf.hide(); + // flying is blocked when levitating, so Lev and Fly are mutually exclusive + if (Levitation) lev.show(); else lev.hide(); + if (Flying) fly.show(); else fly.hide(); + if (u.usteed) ride.show(); else ride.hide(); + if (u.mtimedone) { buf = nh_capitalize_words(mons[u.umonnum].mname); } else { @@ -522,13 +580,20 @@ void NetHackQtStatusWindow::updateStats() score.highlightWhenChanging(); hunger.highlightWhenChanging(); - confused.highlightWhenChanging(); + encumber.highlightWhenChanging(); + stoned.highlightWhenChanging(); + slimed.highlightWhenChanging(); + strngld.highlightWhenChanging(); sick_fp.highlightWhenChanging(); sick_il.highlightWhenChanging(); - blind.highlightWhenChanging(); stunned.highlightWhenChanging(); + confused.highlightWhenChanging(); hallu.highlightWhenChanging(); - encumber.highlightWhenChanging(); + blind.highlightWhenChanging(); + deaf.highlightWhenChanging(); + lev.highlightWhenChanging(); + fly.highlightWhenChanging(); + ride.highlightWhenChanging(); } } diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index 73d7d8eca..0f50eb6de 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -48,15 +48,21 @@ private: QPixmap p_satiated; QPixmap p_hungry; + QPixmap p_encumber[5]; - QPixmap p_confused; + QPixmap p_stoned; + QPixmap p_slimed; + QPixmap p_strngld; QPixmap p_sick_fp; QPixmap p_sick_il; - QPixmap p_blind; QPixmap p_stunned; + QPixmap p_confused; QPixmap p_hallu; - - QPixmap p_encumber[5]; + QPixmap p_blind; + QPixmap p_deaf; + QPixmap p_lev; + QPixmap p_fly; + QPixmap p_ride; NetHackQtLabelledIcon name; NetHackQtLabelledIcon dlevel; @@ -80,13 +86,21 @@ private: NetHackQtLabelledIcon score; NetHackQtLabelledIcon hunger; - NetHackQtLabelledIcon confused; + NetHackQtLabelledIcon encumber; + + NetHackQtLabelledIcon stoned; + NetHackQtLabelledIcon slimed; + NetHackQtLabelledIcon strngld; NetHackQtLabelledIcon sick_fp; NetHackQtLabelledIcon sick_il; - NetHackQtLabelledIcon blind; NetHackQtLabelledIcon stunned; + NetHackQtLabelledIcon confused; NetHackQtLabelledIcon hallu; - NetHackQtLabelledIcon encumber; + NetHackQtLabelledIcon blind; + NetHackQtLabelledIcon deaf; + NetHackQtLabelledIcon lev; + NetHackQtLabelledIcon fly; + NetHackQtLabelledIcon ride; QFrame hline1; QFrame hline2; diff --git a/win/Qt/qt_xpms.h b/win/Qt/qt_xpms.h index 5667c13c0..2c842b84b 100644 --- a/win/Qt/qt_xpms.h +++ b/win/Qt/qt_xpms.h @@ -1,5 +1,57 @@ /* clang-format off */ /* XPM */ +static const char *blank_xpm[] = { +/* width height ncolors chars_per_pixel */ +"40 40 5 1", +/* colors */ +" c #000000", +". c None", +/* not used here */ +"X c #909090", +"o c #606060", +"O c #303030", +/* pixels */ +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................", +"........................................" +}; static const char *blind_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 5 1", From 9cb3fa9cf283e35946588b0eb48e64b6fec1fded Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Aug 2020 05:11:20 -0700 Subject: [PATCH 057/708] mon->mhpmax sanity check The check for mon's max HP being at least as high as its level turns out to be wishful thinking. Just disable it. Maybe we'll flag critters who got or gave up HP during cloning and let them be exceptions, then turn it back on, but not now. Or maybe reduce mon->m_lev when cloning. That would weaken them though. Keep the 1 extra HP that an earlier fix for this check gave to monsters who rolled the minimum possible value while being created (Nd8 that yielded N boosted to N+1, 1d4 for 1 boosted to 2). --- doc/fixes37.0 | 3 ++- src/mon.c | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a5b90b73c..c487cd8e8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ $NHDT-Date: 1596236728 2020/07/31 23:05:28 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.267 $ $NHDT-Date: 1596283876 2020/08/01 12:11:16 $ General Fixes and Modified Features ----------------------------------- @@ -303,6 +303,7 @@ if a monster removed a corpse from an ice box, the corpse would never rot away monster creation on quest levels could make genocided creatures enabling wizard mode 'sanity_check' option would complain about invalid mhpmax value for level N monsters created with a d8 value of 1 for all N d8's +disable that extra check because gremlim HP split after cloning triggers it some versions of tiles processing (not X11's) complained about the rename of "{acid,blinding} venom" to "splash of {acid,blinding} venom" diff --git a/src/mon.c b/src/mon.c index 901797938..eb4badc3e 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1594771374 2020/07/15 00:02:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1596283876 2020/08/01 12:11:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.342 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -56,6 +56,12 @@ const char *msg; mtmp->mnum, mndx, msg); mtmp->mnum = mndx; } +#if 0 /* + * Gremlims don't obey the (mhpmax >= m_lev) rule so disable + * this check, at least for the time being. We could skip it + * when the cloned flag is set, but the original gremlim would + * still be an issue. + */ /* check before DEADMONSTER() because dead monsters should still have sane mhpmax */ if (mtmp->mhpmax < 1 @@ -66,6 +72,7 @@ const char *msg; msg, (int) mtmp->m_lev, mtmp->m_id, fmt_ptr((genericptr_t) mtmp), mtmp->mhp, mtmp->mhpmax); +#endif if (DEADMONSTER(mtmp)) { #if 0 /* bad if not fmons list or if not vault guard */ From 22b4ed0be53076c267e6477d493de78938f47cb1 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Aug 2020 06:11:20 -0700 Subject: [PATCH 058/708] Lev vs Fly via #wizintrinsic I noticed that Qt status showed both Lev and Fly at the same time when they should be mutually exclusive (Levitation overrides Flying). I wasted a bunch of time trying to track down a Qt problem but it turned out to be a core issue. If Flying is set first (which won't happen if both are set in the same #wizinstrinsic operation), setting Levitation via #wizintrinsic was attempting to update the flag that indicates that Flying is blocked, but doing so too soon and failing. Setting Lev via other means while Fly was already set didn't have this problem so it wouldn't occur during normal play. Also, #timeout lists timed properties which can have a timeout value in normal play, then a separator, followed by properties that can only become timed due to #wizintrinsic. Move Displacement from the second group to the first now that it can be obtained as a timed value by eating a displacer beast corpse. --- doc/fixes37.0 | 6 +++++- src/cmd.c | 23 +++++++++++++---------- src/timeout.c | 5 +++-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c487cd8e8..1870fb7ac 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.267 $ $NHDT-Date: 1596283876 2020/08/01 12:11:16 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.268 $ $NHDT-Date: 1596287474 2020/08/01 13:11:14 $ General Fixes and Modified Features ----------------------------------- @@ -238,6 +238,8 @@ splitting a stack of candy bars gave new wrapper text depending upon the (side-effect: separate candy bars usually won't merge anymore) describing tin variety (deep fried, pureed, &c) relied on the 'contents known' flag but object identification wasn't setting obj->cknown for tins +wizard mode #wizintrinsic: setting Levitation wouldn't block Flying as + intended because the check for that was being made too soon Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -306,6 +308,8 @@ enabling wizard mode 'sanity_check' option would complain about invalid mhpmax disable that extra check because gremlim HP split after cloning triggers it some versions of tiles processing (not X11's) complained about the rename of "{acid,blinding} venom" to "splash of {acid,blinding} venom" +wizard mode #timeout changed to show timed Displacement in 'can be timed in + normal play' section instead of 'timed via #wizintrinsic only' section tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display diff --git a/src/cmd.c b/src/cmd.c index cc53f0915..7d51b6e47 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1587317999 2020/04/19 17:39:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.418 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1596287474 2020/08/01 13:11:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1564,6 +1564,9 @@ wiz_intrinsic(VOID_ARGS) continue; } if (p == FIRE_RES) { + /* FIRE_RES and properties beyond it (in the propertynames[] + ordering, not their numerical PROP values), can only be + set to timed values here so show a separator */ any.a_int = 0; add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "--", MENU_ITEMFLAGS_NONE); @@ -1642,23 +1645,23 @@ wiz_intrinsic(VOID_ARGS) } goto def_feedback; case GLIB: - /* slippery fingers applies to gloves if worn at the time - so persistent inventory might need updating */ + /* slippery fingers might need a persistent inventory update + so needs more than simple incr_itimeout() but we want + the pline() issued with that */ make_glib((int) newtimeout); - goto def_feedback; - case LEVITATION: - case FLYING: - float_vs_flight(); /*FALLTHRU*/ default: def_feedback: - pline("Timeout for %s %s %d.", propertynames[i].prop_name, - oldtimeout ? "increased by" : "set to", amt); if (p != GLIB) incr_itimeout(&u.uprops[p].intrinsic, amt); + g.context.botl = 1; /* have pline() do a status update */ + pline("Timeout for %s %s %d.", propertynames[i].prop_name, + oldtimeout ? "increased by" : "set to", amt); break; } - g.context.botl = 1; /* probably not necessary... */ + /* this has to be after incr_timeout() */ + if (p == LEVITATION || p == FLYING) + float_vs_flight(); } if (n >= 1) free((genericptr_t) pick_list); diff --git a/src/timeout.c b/src/timeout.c index d1494b73d..5dba34046 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1582925432 2020/02/28 21:30:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.112 $ */ +/* NetHack 3.6 timeout.c $NHDT-Date: 1596287475 2020/08/01 13:11:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.117 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -46,6 +46,8 @@ const struct propname { { DETECT_MONSTERS, "monster detection" }, { SEE_INVIS, "see invisible" }, { INVIS, "invisible" }, + { DISPLACED, "displaced" }, /* timed amount possible via eating a + * displacer beast corpse */ /* properties beyond here don't have timed values during normal play, so there's not much point in trying to order them sensibly; they're either on or off based on equipment, role, actions, &c */ @@ -70,7 +72,6 @@ const struct propname { { SEARCHING, "searching" }, { INFRAVISION, "infravision" }, { ADORNED, "adorned (+/- Cha)" }, - { DISPLACED, "displaced" }, { STEALTH, "stealthy" }, { AGGRAVATE_MONSTER, "monster aggravation" }, { CONFLICT, "conflict" }, From 427f8e42d85efad3a08e91a5d43df3048a08c3a5 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 1 Aug 2020 19:17:56 -0700 Subject: [PATCH 059/708] ^X vs hunger, encumbrance When hunger state is "not hungry" (so omitted from the status line), say so in the status section of ^X output. Mainly so that wizard mode can append the internal nutrition value without inserting an entire line that [previously] wouldn't be present in regular play. Show an internal value for encumbrance too, although that would be better if it also included some indication of the amount where the encumbrance state changes. Encumbrance is confusing and I didn't pursue that. --- include/you.h | 4 ++-- src/insight.c | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/you.h b/include/you.h index da85c9c21..76aae6a7f 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 you.h $NHDT-Date: 1593768079 2020/07/03 09:21:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 3.6 you.h $NHDT-Date: 1596334647 2020/08/02 02:17:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -359,7 +359,7 @@ struct you { char ushops_entered[5]; /* ditto, shops entered this turn */ char ushops_left[5]; /* ditto, shops exited this turn */ - int uhunger; /* refd only in eat.c and shk.c */ + int uhunger; /* refd only in eat.c and shk.c (also insight.c) */ unsigned uhs; /* hunger state - see eat.c */ struct prop uprops[LAST_PROP + 1]; diff --git a/src/insight.c b/src/insight.c index 16d30d96f..519a64be4 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1595637572 2020/07/25 00:39:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1596334662 2020/08/02 02:17:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -976,12 +976,18 @@ int final; } Strcpy(buf, hu_stat[u.uhs]); /* hunger status; omitted if "normal" */ mungspaces(buf); /* strip trailing spaces */ - if (*buf) { + /* status line doesn't show hunger when state is "not hungry", we do; + needed for wizard mode's reveal of u.uhunger but add it for everyone */ + if (!*buf) + Strcpy(buf, "not hungry"); + if (*buf) { /* (since "not hungry" was added, this will always be True) */ *buf = lowc(*buf); /* override capitalization */ if (!strcmp(buf, "weak")) Strcat(buf, " from severe hunger"); else if (!strncmp(buf, "faint", 5)) /* fainting, fainted */ Strcat(buf, " due to starvation"); + if (wizard) + Sprintf(eos(buf), " <%d>", u.uhunger); you_are(buf, ""); } /* encumbrance */ @@ -1007,6 +1013,8 @@ int final; adj = "not possible"; break; } + if (wizard) + Sprintf(eos(buf), " <%d>", inv_weight()); Sprintf(eos(buf), "; movement %s %s%s", !final ? "is" : "was", adj, (cap < OVERLOADED) ? " slowed" : ""); you_are(buf, ""); @@ -1014,7 +1022,10 @@ int final; /* last resort entry, guarantees Status section is non-empty (no longer needed for that purpose since weapon status added; still useful though) */ - you_are("unencumbered", ""); + Strcpy(buf, "unencumbered"); + if (wizard) + Sprintf(eos(buf), " <%d>", inv_weight()); + you_are(buf, ""); } /* current weapon(s) and corresponding skill level(s) */ weapon_insight(final); From 30da367b8055fc09f85c6ce0674702d233fd199a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 2 Aug 2020 10:59:50 -0700 Subject: [PATCH 060/708] udpate nethack's URL This was changed in the Guidebook and dat/history some time back but the value in the code was overlooked. Switch protocol from http to https and add trailing slash. --- include/hack.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/hack.h b/include/hack.h index 44ee8c4a5..a94407fcf 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.h $NHDT-Date: 1591178395 2020/06/03 09:59:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 3.6 hack.h $NHDT-Date: 1596391185 2020/08/02 17:59:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -561,6 +561,6 @@ enum optset_restrictions { #endif #define DEVTEAM_EMAIL "devteam@nethack.org" -#define DEVTEAM_URL "http://www.nethack.org" +#define DEVTEAM_URL "https://www.nethack.org/" #endif /* HACK_H */ From 09d9d002c7e3a2c9d1d0b422a9fb1eddca5fc6a1 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 2 Aug 2020 11:49:41 -0700 Subject: [PATCH 061/708] Qt's "about nethack" Update the 'about' popup to reflect current information. When I start Qt nethack on OSX 10.11, the horizontal application menu for nethack that's rendered across the top of the desktop won't respond to mouse clicks, not even if I click on nethack's title bar or inside its game window first. But if I give another application focus (which swaps top-edge menu to one for that other application) and then click on nethack's title bar to give focus back to nethack (which also swaps back to the top menu for it), clicking on that menu begins working. I have no idea what's going on there. Picking "nethack" in the application menu gives a pull down menu with "about nethack" as the first entry. When choosing that, the revised popup looks like | Qt NetHack is a version of NetHack | built using the Qt 5 GUI toolkit. | | This is NetHack 3.7.0-22 with Qt 5.11.3. | | NetHack's Qt interface originally developed by | Warwick Allison. | | Qt: | https://qt.io/ | NetHack: | https://www.nethack.org/ The line with Warwick's name is wrapping and I don't know how to make the popup wide enough to avoid that. The old edition had a "Homepage" URL for him instead of that sentence but the URL was out of date. It also had an obsolete URL for Qt and none at all for NetHack itself. --- win/Qt/qt_main.cpp | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 50a28828b..faf32e265 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -439,23 +439,44 @@ static const char * cast_c_xpm[] UNUSED = { static QString aboutMsg() { + char vbuf[BUFSZ]; QString msg; msg.sprintf( - "Qt NetHack is a version of NetHack built\n" + // format + "Qt NetHack is a version of NetHack\n" + "built using" // no newline #ifdef KDE - "using KDE and the Qt GUI toolkit.\n" + " KDE and" // ditto +#endif + " the Qt %d GUI toolkit.\n" + "\nThis is NetHack %s%s.\n" + "\nNetHack's Qt interface originally developed by Warwick Allison.\n" + "\n" +#if 0 + "Homepage:\n http://trolls.troll.no/warwick/nethack/\n" //obsolete +#endif +#ifdef KDE + "KDE:\n https://kde.org/\n" +#endif +#if 1 + "Qt:\n https://qt.io/\n" #else - "using the Qt GUI toolkit.\n" + "Qt:\n http://www.troll.no/\n" // obsolete #endif - "This is version %d.%d.%d\n\n" - "Homepage:\n http://trolls.troll.no/warwick/nethack/\n\n" -#ifdef KDE - "KDE:\n http://www.kde.org\n" + "NetHack:\n %s\n", + // arguments +#ifdef QT_VERSION_MAJOR + QT_VERSION_MAJOR, +#else + 5, // Qt version macro should exist; if not, assume Qt5 #endif - "Qt:\n http://www.troll.no", - VERSION_MAJOR, - VERSION_MINOR, - PATCHLEVEL); + version_string(vbuf), /* nethack version */ +#ifdef QT_VERSION_STR + " with Qt " QT_VERSION_STR, +#else + "", +#endif + DEVTEAM_URL); return msg; } From d3e77393abc3bee20cb05b6aaf896fa50f71d041 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 2 Aug 2020 12:18:11 -0700 Subject: [PATCH 062/708] fix github issue #376 - duplicate prompt When chatting to the quest leader to try to gain access to the rest of the quest, if your experience level is good enough but your alignment strength isn't, in wizard mode you'll get prompted about whether to have piety boosted. Normally you would answer 'y' and be able to go to lower quest levels. But if you answer 'n' you'll immediately be prompted a second time. Not because the no response didn't register but because the if/else-if/else logic checks twice for whether your alignment is inadequate and if you answered no the first time it will still be too low the second, with the first answer not carrying over. Fixes #376 --- doc/fixes37.0 | 5 ++++- src/quest.c | 8 +++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 1870fb7ac..9c56556d6 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.268 $ $NHDT-Date: 1596287474 2020/08/01 13:11:14 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ $NHDT-Date: 1596395887 2020/08/02 19:18:07 $ General Fixes and Modified Features ----------------------------------- @@ -240,6 +240,9 @@ describing tin variety (deep fried, pureed, &c) relied on the 'contents known' flag but object identification wasn't setting obj->cknown for tins wizard mode #wizintrinsic: setting Levitation wouldn't block Flying as intended because the check for that was being made too soon +chatting to the quest leader in wizard mode with sufficient experience level + and insufficient piety, player is asked whether alignment should be + boosted; answering 'n' resulted in being prompted a second time Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/quest.c b/src/quest.c index a74cdf41b..befe154b2 100644 --- a/src/quest.c +++ b/src/quest.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 quest.c $NHDT-Date: 1505170343 2017/09/11 22:52:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 3.6 quest.c $NHDT-Date: 1596395887 2020/08/02 19:18:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ @@ -277,6 +277,8 @@ chat_with_leader() /* Rule 5: You aren't yet acceptable - or are you? */ } else { + int purity = 0; + if (!Qstat(met_leader)) { qt_pager("leader_first"); Qstat(met_leader) = TRUE; @@ -293,10 +295,10 @@ chat_with_leader() qt_pager("badlevel"); exercise(A_WIS, TRUE); expulsion(FALSE); - } else if (is_pure(TRUE) < 0) { + } else if ((purity = is_pure(TRUE)) < 0) { com_pager("banished"); expulsion(TRUE); - } else if (is_pure(TRUE) == 0) { + } else if (purity == 0) { qt_pager("badalign"); if (Qstat(not_ready) == MAX_QUEST_TRIES) { qt_pager("leader_last"); From 357cb198eee418674c16e5c35cc7ddb7f5eb1850 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 2 Aug 2020 14:45:00 -0700 Subject: [PATCH 063/708] Qt 3 'about' Make the same change to outdated/win/Qt3/qt3_win.cpp for the "about nethack" popup that was just made to win/Qt/qt_main.cpp so that the out of date URLs won't be overlooked if the Qt 3 interface ever gets resurrected. Not tested and most likely will never matter. --- outdated/win/Qt3/qt3_win.cpp | 45 ++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/outdated/win/Qt3/qt3_win.cpp b/outdated/win/Qt3/qt3_win.cpp index f48c0d211..30b23370b 100644 --- a/outdated/win/Qt3/qt3_win.cpp +++ b/outdated/win/Qt3/qt3_win.cpp @@ -1,4 +1,4 @@ -// NetHack 3.6 qt_win.cpp $NHDT-Date: 1575917720 2019/12/09 18:55:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +// NetHack 3.6 qt_win.cpp $NHDT-Date: 1596404695 2020/08/02 21:44:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.91 $ // Copyright (c) Warwick Allison, 1999. // NetHack may be freely redistributed. See license for details. @@ -146,23 +146,44 @@ static const char nh_attribution[] = "
NetHack" static QString aboutMsg() { + char vbuf[BUFSZ]; QString msg; msg.sprintf( - "Qt NetHack is a version of NetHack built\n" + // format + "Qt NetHack is a version of NetHack\n" + "built using" // no newline #ifdef KDE - "using KDE and the Qt GUI toolkit.\n" + " KDE and" // ditto +#endif + " the Qt %d GUI toolkit.\n" + "\nThis is NetHack %s%s.\n" + "\nNetHack's Qt interface originally developed by Warwick Allison.\n" + "\n" +#if 0 + "Homepage:\n http://trolls.troll.no/warwick/nethack/\n" //obsolete +#endif +#ifdef KDE + "KDE:\n https://kde.org/\n" +#endif +#if 1 + "Qt:\n https://qt.io/\n" #else - "using the Qt GUI toolkit.\n" + "Qt:\n http://www.troll.no/\n" // obsolete #endif - "This is version %d.%d.%d\n\n" - "Homepage:\n http://trolls.troll.no/warwick/nethack/\n\n" -#ifdef KDE - "KDE:\n http://www.kde.org\n" + "NetHack:\n %s\n", + // arguments +#ifdef QT_VERSION_MAJOR + QT_VERSION_MAJOR, +#else + 3, // Qt version macro should exist; if not, assume Qt3 #endif - "Qt:\n http://www.troll.no", - VERSION_MAJOR, - VERSION_MINOR, - PATCHLEVEL); + version_string(vbuf), /* nethack version */ +#ifdef QT_VERSION_STR + " with Qt " QT_VERSION_STR, +#else + "", +#endif + DEVTEAM_URL); return msg; } From 08249963b24a6754eae45e75cad9658bd9eccbfd Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 2 Aug 2020 15:03:27 -0700 Subject: [PATCH 064/708] Qt menu fix The change to use fixed-width fonts for menus wasn't working optimally because the font got changed after menu construction had measured the necessary width and height amounts. ^X output, which uses a menu instead of a text window for tty's benefit (probably curses too; I don't remember), had a couple of lines which were wrapping unnecessarily. This fix avoids that, but the extra '+20' shouldn't be needed. Unfortunately lines in menus are effectively double-spaced, which looks bad, and I've no idea how to fix that. --- win/Qt/qt_menu.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 2f4d41762..aad4d5885 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -91,6 +91,11 @@ NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : prompt(0), counting(false) { + // 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()); + table->setFont(tablefont); + QGridLayout *grid = new QGridLayout(); table->setColumnCount(5); table->setFrameStyle(QFrame::Panel|QFrame::Sunken); @@ -134,7 +139,8 @@ NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : grid->setRowStretch(2, 1); setFocusPolicy(Qt::StrongFocus); table->setFocusPolicy(Qt::NoFocus); - connect(table, SIGNAL(cellClicked(int,int)), this, SLOT(cellToggleSelect(int,int))); + connect(table, SIGNAL(cellClicked(int,int)), + this, SLOT(cellToggleSelect(int,int))); setLayout(grid); } @@ -214,9 +220,6 @@ void NetHackQtMenuWindow::EndMenu(const QString& p) int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) { - QFont tablefont(qt_settings->normalFixedFont()); - table->setFont(tablefont); - table->setRowCount(itemcount); how=h; @@ -243,10 +246,18 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) std::vector col_widths; for (std::size_t i = 0; i < (size_t) itemlist.size(); ++i) { QStringList columns = itemlist[i].str.split("\t"); - if (!itemlist[i].Selectable() && columns.size() == 1) - { - // Nonselectable line with no column dividers + if (!itemlist[i].Selectable() && columns.size() == 1) { + // Nonselectable line with no column dividers. // Assume this is a section header + // or ordinary text (^X feedback, for instance) rendered in + // a menu because tty's paginated menus can be used to go + // backward, unlike text windows which can only go forward. + QTableWidgetItem *twi = table->item(i, 4); + if (twi) { + QString text = twi->text(); +#define MENU_WIDTH_SLOP 20 /* this should not be necessary */ + WidenColumn(4, fm.width(text) + MENU_WIDTH_SLOP); + } continue; } for (std::size_t j = 0U; j < (size_t) columns.size(); ++j) { From d39ae5ce79532418146217a0f36234d620c2fd26 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 2 Aug 2020 22:50:30 -0400 Subject: [PATCH 065/708] Support a build with tty,Qt,x11,curses on macOS Catalina 10.15 Assuming you have the prerequisite packages, You can specify the window ports to include on the make command line: make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 all Prequisites for window ports beyond tty: (some sample homebrew commands to obtain them shown but that is not the only way): xquartz for x11 support brew install xquartz Qt for Qt support brew install Qt --- src/sounds.c | 1 - sys/unix/hints/macOS.2020 | 470 ++++++++++++++++++++++++++++++++++++++ win/Qt/qt_bind.cpp | 2 +- 3 files changed, 471 insertions(+), 2 deletions(-) create mode 100755 sys/unix/hints/macOS.2020 diff --git a/src/sounds.c b/src/sounds.c index 2bdb8bbf1..41ee7117c 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1317,7 +1317,6 @@ const char *mapping; char filename[256]; char filespec[256]; int volume, idx = -1; - boolean toolong = FALSE; if (sscanf(mapping, "MESG \"%255[^\"]\"%*[\t ]\"%255[^\"]\" %d %d", text, filename, &volume, &idx) == 4 diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 new file mode 100755 index 000000000..eb5a3421a --- /dev/null +++ b/sys/unix/hints/macOS.2020 @@ -0,0 +1,470 @@ +# +# NetHack 3.6 macOS.2020 $NHDT-Date: 1573841535 2019/11/15 18:12:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. +# NetHack may be freely redistributed. See license for details. +# +#-PRE +# macOS X hints file +# Tested on: +# - MacOS Catalina 10.15 +# +# If this doesn't work for some other version of Mac OS X, make a new file for +# that OS, don't change this one. And let us know about it. +# Useful info: http://www.opensource.apple.com/darwinsource/index.html + +# +# This hints file supports tty, curses, x11, and Qt in the same binary, +# but: +# - You'll need to obtain and install XQuartz if you want X11 support. +# (Attempting to run X11.app will describe where to get it.) +# One possible way: brew install xquartz +# +# - You'll need to obtain and install Qt if you want Qt support +# One possible way: Brew install Qt +# +# - You'll need to obtain and install the ncurses development libraries +# if you want curses window port support. +# +# Assuming you have the prerequisite packages, You can specify the +# window ports to include on the make command line without requiring +# you to edit the Makefile: +# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 all +# +# This hints file can build several different types of installations. +# Edit the next section to match the type of build you need. + +# 1. Which window system(s) should be included in this binary? +WANT_WIN_TTY=1 +#WANT_WIN_CURSES=1 +#WANT_WIN_X11=1 +#WANT_WIN_QT=1 + +# 1a. What is the default window system? +WANT_DEFAULT=tty +#WANT_DEFAULT=curses +#WANT_DEFAULT=Qt +#WANT_DEFAULT=x11 + +# 1b. If you set WANT_WIN_QT, you need to +# A) set QTDIR either here or in the environment to point to the Qt5 +# library installation root. (Qt2, Qt3, Qt4 will not work) +# B) set XPMLIB to point to the Xpm library +ifdef WANT_WIN_QT +#QTDIR=/Developer/Qt +#LIBXPM= -L/opt/X11/lib -lXpm +QTDIR=$(shell brew --prefix)/opt/qt +# Qt installed via macports (qt511 package; 5.13 requires OSX 10.12 or later) +#QTDIR=/opt/local/libexec/qt5 +endif # WANT_WIN_QT + +# 2. Is this a build for a binary that will be shared among different users +# or will it be private to you? +# If it is shared: +# - it will be owned by the user and group listed +# - if the user does not exist, you MUST create it before installing +# NetHack +# - if the group does not exist, it will be created. +# NB: if the group already exists and is being used for something +# besides games, you probably want to specify a new group instead +# NB: the group will be created locally; if your computer is centrally +# administered this may not be what you (or your admin) want. +# Consider a non-shared install (WANT_SHARE_INSTALL=0) instead. +# - 'make install' must be run as "sudo make install" +# - 'make install' must be run as "sudo make install" +#WANT_SHARE_INSTALL=1 +GAMEUID = $(USER) +GAMEGRP = games +# build to run in the source tree - primarily for development. Build with "make all" +#WANT_SOURCE_INSTALL=1 + +# At the moment this is just for debugging, but in the future it could be +# useful for other things. Requires SYSCF and an ANSI compiler. +#WANT_WIN_CHAIN=1 + +ifdef WANT_WIN_QT +CC=clang +CXX=clang++ -std=gnu++11 +LINK= $(CXX) +#CC=gcc +#CXX=g++ +else +LINK = $(CC) +endif +#MOC = moc + +# +# You shouldn't need to change anything below here. +# + +ifndef WANT_DEFAULT +ifdef WANT_WIN_TTY +WANT_DEFAULT=tty +endif +endif + +ifndef WANT_DEFAULT +ifdef WANT_WIN_X11 +WANT_DEFAULT=x11 +endif +endif + +ifndef WANT_DEFAULT +ifdef WANT_WIN_CURSES +WANT_DEFAULT=curses +endif +endif + +ifndef WANT_DEFAULT +ifdef WANT_WIN_QT +WANT_DEFAULT=Qt +endif +endif + +CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN +ifndef WANT_WIN_QT +# these are normally used when compiling nethack's core +CFLAGS+=-ansi -pedantic -Wno-long-long +# but -ansi -pendantic forces C90 sematics and win/Qt/qt_*.cpp trigger +#In file included from .../qt5/include/QtCore/qglobal.h:105: +#.../qt5/include/QtCore/qcompilerdetection.h:561:6: +# error Qt requires a C++11 compiler and yours does not seem to be that. +# so we suppress them when the build includes Qt +endif +# As of LLVM build 2336.1.00, this gives dozens of spurious messages, so +# leave it out by default. +#CFLAGS+=-Wunreachable-code + +# XXX -g vs -O should go here, -I../include goes in the makefile +CFLAGS+=-g -I../include +# older binaries use NOCLIPPING, but that disables SIGWINCH +#CFLAGS+=-DNOCLIPPING +CFLAGS+= -DNOMAIL -DNOTPARMDECL -DHACKDIR=\"$(HACKDIR)\" +CFLAGS+= -DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB +CFLAGS+= -DGREPPATH=\"/usr/bin/grep\" + +ifdef WANT_WIN_CHAIN +CFLAGS+= -DWINCHAIN +HINTSRC=$(CHAINSRC) +HINTOBJ=$(CHAINOBJ) +endif # WANT_WIN_CHAIN + +WINSRC = +WINOBJ0 = +WINLIB = +WINLIB0 = +VARDATND = +VARDATND0 = +WINCURSESLIB=-lncurses + +ifdef WANT_WIN_TTY +WINSRC += $(WINTTYSRC) +WINOBJ0 += $(WINTTYOBJ) +WINLIB0 += $(WINCURSESLIB) +else # !WANT_WIN_TTY +CFLAGS += -DNOTTYGRAPHICS +endif # !WANT_WIN_TTY + +ifdef WANT_WIN_CURSES +CFLAGS += -DCURSES_GRAPHICS +WINSRC += $(WINCURSESSRC) +WINOBJ0 += $(WINCURSESOBJ) +WINLIB0 += $(WINCURSESLIB) +endif + +# prevent duplicates in WINLIB from WINLIB0 +WINLIB += $(sort $(WINLIB0)) + +ifdef WANT_WIN_X11 +USE_XPM=1 +WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 +VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +# -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 ); +CFLAGS += -DX11_GRAPHICS +# separate from CFLAGS so that we don't pass it to every file +X11CFLAGS = -I/opt/X11/include +# avoid repeated complaints about _X_NONNULL(args...) in +X11CFLAGS += -Wno-variadic-macros +ifdef USE_XPM +CFLAGS += -DUSE_XPM +WINX11LIB += -lXpm +VARDATND0 += rip.xpm +endif +WINSRC += $(WINX11SRC) +WINOBJ0 += $(WINX11OBJ) +WINLIB += $(WINX11LIB) +LFLAGS=-L/opt/X11/lib +endif # WANT_WIN_X11 + +ifdef WANT_WIN_QT +CFLAGS += -DQT_GRAPHICS +QTCXXFLAGS += -Wno-deprecated-declarations +QTCXXFLAGS += $(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) +WINSRC += $(WINQTSRC) +WINOBJ0 += $(WINQTOBJ) +VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm +# XXX if /Developer/qt exists and QTDIR not set, use that +ifndef QTDIR +$(error QTDIR not defined in the environment or Makefile) +endif # QTDIR +# XXX make sure QTDIR points to something reasonable +else # !WANT_WIN_QT +LINK=$(CC) +endif # !WANT_WIN_QT + +# prevent duplicate tile.o in WINOBJ +WINOBJ = $(sort $(WINOBJ0)) +# prevent duplicates in VARDATND if both X11 and Qt are being supported +VARDATND += $(sort $(VARDATND0)) + +ifdef WANT_SHARE_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 +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 +PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); . sys/unix/hints/macosx.sh group2 $(GAMEGRP); mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +else ifdef WANT_SOURCE_INSTALL +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: +MOREALL=$(MAKE) install +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +else # !WANT_SOURCE_INSTALL +PREFIX:=$(wildcard ~) +SHELLDIR=$(PREFIX)/bin +HACKDIR=$(PREFIX)/nethackdir +CHOWN=/usr/bin/true +CHGRP=/usr/bin/true +GAMEPERM = 0700 +VARFILEPERM = 0600 +VARDIRPERM = 0700 +ifdef WANT_WIN_X11 +# install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists +PREINSTALL= cp -n win/X11/nethack.rc ~/.nethackrc || true +endif # WANT_WIN_X11 +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +endif # !WANT_SOURCE_INSTALL + +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) + + +# ~/Library/Preferences/NetHack Defaults +# OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp +# OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt +# +# Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary +# package under the docs directory). + +#-POST +ifdef MAKEFILE_TOP +### +### Packaging +### +# Notes: +# 1) The Apple developer utilities must be installed in the default location. +# 2) Do a normal build before trying to package the game. +# 3) This matches the 3.4.3 Term package, but there are some things that +# should be changed. +# +# Packages that are being distributed must be signed by a Developer ID +# Installer certificate. Set DEVELOPER_CERT to the name of the certificate +# if you wish for your package to be signed for distribution. +# +# If building a package for signing, you must use sudo approriately. +# the binaries and package using sudo but you DO NOT use sudo to sign the +# package. If you use sudo to sign the package, it will fail. +# +# sudo make all +# sudo make build_tty_pkg +# make sign_tty_pkg +# + +ifdef WANT_WIN_TTY +DEVUTIL=/Developer/Applications/Utilities +SVS=$(shell $(NHSROOT)/util/makedefs --svs) +SVSDOT=$(shell $(NHSROOT)/util/makedefs --svs .) + +PKGROOT_UG = PKGROOT/$(PREFIX) +PKGROOT_UGLN = PKGROOT/$(HACKDIR) +PKGROOT_BIN = PKGROOT/$(SHELLDIR) + +#DEVELOPER_CERT = Developer ID Installer: Bart House +DEVELOPER_CERT = NONE + +spotless:: + rm -rf RESOURCES + rm -rf PKG + rm -rf PKGSCRIPTS + rm -rf PKGROOT + rm -f Info.plist + rm -f Distribution.xml + rm -f NetHack-*-mac-Term* + +build_tty_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_QT)) + -echo build_tty_pkg only works for a tty-only build + exit 1 +else + rm -rf NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + $(MAKE) build_package_root + rm -rf RESOURCES + mkdir RESOURCES + #enscript --language=rtf -o - < dat/license >RESOURCES/License.rtf + sys/unix/hints/macosx.sh descplist > RESOURCES/Description.plist + sys/unix/hints/macosx.sh infoplist > Info.plist + + mkdir PKGROOT/Applications + #osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + # win/macosx/NetHackRecover.applescript + #cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + osacompile -o PKGROOT/Applications/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl $(PKGROOT_UGLN) + + osacompile -o PKGROOT/Applications/NetHackTerm.app \ + win/macosx/NetHackTerm.applescript + + # XXX integrate into Makefile.doc + (cd doc; cat Guidebook.mn | ../util/makedefs --grep --input - --output - \ + | tbl tmac.n - | groff | pstopdf -i -o Guidebook.pdf) + cp doc/Guidebook.pdf $(PKGROOT_UG)/doc/NetHackGuidebook.pdf + + osacompile -o PKGROOT/Applications/NetHackGuidebook.app \ + win/macosx/NetHackGuidebook.applescript + + mkdir -p PKG + pkgbuild --root PKGROOT --identifier org.nethack.term --scripts PKGSCRIPTS PKG/NH-Term.pkg + productbuild --synthesize --product Info.plist --package PKG/NH-Term.pkg Distribution.xml + productbuild --distribution Distribution.xml --resources RESOURCES --package-path PKG NetHack-$(SVS)-mac-Term-unsigned.pkg +ifeq ($(DEVELOPER_CERT),NONE) + cp NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term-unsigned.dmg + @echo ------------------------------------------- + @echo PACKAGE IS NOT SIGNED FOR DISTRIBUTION!!!!! + @echo =========================================== +else + @echo "run 'make sign_tty_pkg' to complete package" +endif + +sign_tty_pkg: + productsign --timestamp=none --sign "$(DEVELOPER_CERT)" NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg || (echo "Package signing failed"; exit 1) + spctl -a -v --type install NetHack-$(SVS)-mac-Term.pkg || (echo "Package not signed properly"; exit 1) + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + +build_package_root: + cd src/.. # make sure we are at TOP + rm -rf PKGROOT + mkdir -p $(PKGROOT_UG)/lib $(PKGROOT_BIN) $(PKGROOT_UG)/man/man6 $(PKGROOT_UG)/doc $(PKGROOT_UGLN) + install -p src/nethack $(PKGROOT_BIN) + # XXX should this be called nethackrecover? + install -p util/recover $(PKGROOT_BIN) + install -p doc/nethack.6 $(PKGROOT_UG)/man/man6 + install -p doc/recover.6 $(PKGROOT_UG)/man/man6 + install -p doc/Guidebook $(PKGROOT_UG)/doc + install -p dat/nhdat $(PKGROOT_UGLN) + sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(PKGROOT_UGLN)/sysconf + cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN) +# XXX these files should be somewhere else for good Mac form + touch $(PKGROOT_UGLN)/perm $(PKGROOT_UGLN)/record $(PKGROOT_UGLN)/logfile $(PKGROOT_UGLN)/xlogfile + mkdir $(PKGROOT_UGLN)/save +# XXX what about a news file? + + mkdir -p PKGSCRIPTS + echo '#!/bin/sh' > PKGSCRIPTS/postinstall + echo dseditgroup -o create -r '"Games Group"' -s 3600 $(GAMEGRP) >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(HACKDIR)/* >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(HACKDIR)/* >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + echo chmod $(VARDIRPERM) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo chmod $(VARDIRPERM) $(HACKDIR)/save >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/license >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/nhdat >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/symbols >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/perm >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/record >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/logfile >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/xlogfile >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/sysconf >> PKGSCRIPTS/postinstall + echo chmod $(GAMEPERM) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo chmod $(EXEPERM) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + chmod 0775 PKGSCRIPTS/postinstall + +endif # end of build_tty_pkg +endif # WANT_WIN_TTY for packaging + +ifdef WANT_WIN_QT +# XXX untested and incomplete (see below) +build_qt_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_TTY)) + -echo build_qt_pkg only works for a qt-only build + exit 1 +else + $(MAKE) build_package_root + rm -rf NetHackQt + mkdir -p NetHackQt/NetHackQt.app/nethackdir/save + mkdir NetHackQt/Documentation + cp doc/Guidebook.txt doc/nethack.txt doc/recover.txt NetHackQt/Documentation + + osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + + mkdir -p NetHackQt/NetHackQt.app/Contents/Frameworks + cp $(QTDIR)/libqt-mt.3.dylib NetHackQt/NetHackQt.app/Contents/Frameworks + + mkdir NetHackQt/NetHackQt.app/Contents/MacOS + mv PKGROOT/nethack NetHackQt/NetHackQt.app/Contents/MacOS + + mv PKGROOT/lib/nethackdir NetHackQt/NetHackQt.app/nethackdir + +# XXX still missing: +#NetHackQt/NetHackQt.app +# /Contents +# Info.plist +# Resources/nethack.icns +#NetHackQt/Documentation +#NetHackQtRecover.txt +#NetHack Defaults.txt +#changes.patch XXX is this still needed? why isn't it part of the tree? +# doesn't go here + hdiutil create -verbose -srcfolder NetHackQt NetHack-$(SVS)-macosx-qt.dmg +endif # end of build_qt_pkg +endif # WANT_WIN_QT for packaging +endif # MAKEFILE_TOP diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 3f0c257fc..acf267eb7 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -805,7 +805,7 @@ struct window_procs Qt_procs = { #ifndef WIN32 #if defined(USER_SOUNDS) && !defined(QT_NO_SOUND) -extern "C" void play_usersound(const char* filename, int volume) +extern "C" void play_usersound(const char* filename, int volume UNUSED) #else extern "C" void play_usersound(const char* filename UNUSED, int volume UNUSED) #endif From 375c9c880edd8ef58423acaf3d5dd046ce4d5f52 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 2 Aug 2020 23:24:07 -0400 Subject: [PATCH 066/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Files b/Files index 881c2eaf2..499a00381 100644 --- a/Files +++ b/Files @@ -304,10 +304,10 @@ sys/unix/hints: (files for configuring UNIX NetHack versions) linux linux-chroot linux-minimal linux-qt4 linux-qt5 linux-x11 -macosx macosx.sh macosx10.5 -macosx10.7 macosx10.8 macosx10.10 -macosx10.10-qt macosx10.14 solaris -solaris-playground unix +macOS.2020 macosx macosx.sh +macosx10.5 macosx10.7 macosx10.8 +macosx10.10 macosx10.10-qt macosx10.14 +solaris solaris-playground unix sys/vms: (files for VMS version) From 02d616d8bcd3c180d2bfb4b8795819ddb21b79bf Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 3 Aug 2020 13:36:40 -0700 Subject: [PATCH 067/708] dat/Makefile spotless Testing some hints revisions resulted in some bafflement which turned out to be caused by 'make spotless' in the dat subdirectory not removing 'options'. It wasn't removing several other generated files either. That used to work but got clobbered when the lua special levels replaced levcomp and dgncomp. --- doc/fixes37.0 | 4 +++- sys/unix/Makefile.dat | 17 ++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9c56556d6..3b76a04f4 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ $NHDT-Date: 1596395887 2020/08/02 19:18:07 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ $NHDT-Date: 1596486996 2020/08/03 20:36:36 $ General Fixes and Modified Features ----------------------------------- @@ -318,6 +318,8 @@ tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display tty: previous change resulted in remnants of previous level being shown on new level after level change when S_unexplored is +Unix: after lua changes to Makefiles, 'make spotless' for dat subdirectory + left some generated data files which should have been deleted X11: was still initializing map to 'stone' instead of 'unexplored' after they became separate glyphs X11: for text map without color, add support for black&white ice; draw it in diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index 0508974e9..a264242ae 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -1,4 +1,4 @@ -# NetHack Datafiles Makefile.dat $NHDT-Date: 1447844574 2018/04/25 19:25:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.22 $ +# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -116,18 +116,21 @@ bogusmon: bogusmon.txt ../util/makedefs options: ../util/makedefs ../util/makedefs -v - +# these don't actually do anything useful now that levcomp and dngcomp are gone spec_levs: touch spec_levs - quest_levs: touch quest_levs # gitinfo.txt is optionally made by src/Makefile when creating date.h +# spec_levs and quest_levs are empty marker files to control 'make' actions clean: - -rm -f gitinfo.txt + -rm -f spec_levs quest_levs gitinfo.txt spotless: clean - -rm -f nhdat x11tiles beostiles pet_mark.xbm pilemark.xbm rip.xpm mapbg.xpm - -rm -f rip.img GEM_RSC.RSC title.img nh16.img NetHack.ad - -rm -f nhsplash.xpm nhtiles.bmp + -rm -f nhdat $(VARDAT) \ + x11tiles pet_mark.xbm pilemark.xbm rip.xpm mapbg.xpm \ + rip.img GEM_RSC.RSC title.img nh16.img NetHack.ad \ + nhsplash.xpm nhtiles.bmp beostiles + +#eof# From a968acb242e583e3dec84bf5d60f9582ea5cccb3 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 3 Aug 2020 14:10:35 -0700 Subject: [PATCH 068/708] hints/macOS.2020 Started out removing some trailing spaces and ended up making various substantive changes. Don't include tty by default since the sample make command shows how to enable it and there isn't any easy way to disable it other than not requesting it to begin with. (Due to using defined/not-defined rather than values in the 'if' directives, WANT_WIN_TTY=0 is the same as WANT_WIN_TTY=1 rather than it's inverse.) That resulted in all the interfaces starting commented out, so add some make code to make sure that at least one is enabled. If none, it silently enables tty. The sequence |CXX=compilerA |LINK=$(CXX) |#CXX=compilerB wouldn't work if 'make' substitutes immediately (I can't recall offhand whether it does) and the first CXX was commented out in order to uncomment the second one. The default CXX value would be used instead of the #CXX=foo one even if it was uncommented. Just move LINK= after it. Build logic has been tested. Final install and packaging for distribution have not (but weren't touched so shouldn't be affected). --- sys/unix/hints/macOS.2020 | 122 ++++++++++++++++++++++++-------------- 1 file changed, 79 insertions(+), 43 deletions(-) diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index eb5a3421a..dd0ffd5ee 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -1,14 +1,13 @@ -# -# NetHack 3.6 macOS.2020 $NHDT-Date: 1573841535 2019/11/15 18:12:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1596489016 2020/08/03 21:10:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # #-PRE # macOS X hints file # Tested on: -# - MacOS Catalina 10.15 +# - MacOS Catalina 10.15 # -# If this doesn't work for some other version of Mac OS X, make a new file for +# If this doesn't work for some other version of Mac OS X, make a new file for # that OS, don't change this one. And let us know about it. # Useful info: http://www.opensource.apple.com/darwinsource/index.html @@ -24,26 +23,37 @@ # # - You'll need to obtain and install the ncurses development libraries # if you want curses window port support. -# -# Assuming you have the prerequisite packages, You can specify the +# +# Assuming you have the prerequisite packages, You can specify the # window ports to include on the make command line without requiring # you to edit the Makefile: # make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 all +# in the src/ directory prior to 'make install' in the top directory. +# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use +# something other than tty as the default interface. # -# This hints file can build several different types of installations. -# Edit the next section to match the type of build you need. -# 1. Which window system(s) should be included in this binary? -WANT_WIN_TTY=1 +# This hints file can build several different interfaces and several +# types of installations (private, shared, source). +# Edit the section (1.) to control which interface(s). +# Edit the section (2.) to match the type of build you need. + +# 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 +# on the 'make' command line. If none are enabled, tty will be used. +#WANT_WIN_TTY=1 #WANT_WIN_CURSES=1 #WANT_WIN_X11=1 #WANT_WIN_QT=1 # 1a. What is the default window system? -WANT_DEFAULT=tty +# Exactly one of these can be manually uncommented and/or can be specified +# on the 'make' command line. If none is enabled, the first among +# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. +#WANT_DEFAULT=tty #WANT_DEFAULT=curses #WANT_DEFAULT=Qt -#WANT_DEFAULT=x11 +#WANT_DEFAULT=X11 # 1b. If you set WANT_WIN_QT, you need to # A) set QTDIR either here or in the environment to point to the Qt5 @@ -51,11 +61,14 @@ WANT_DEFAULT=tty # B) set XPMLIB to point to the Xpm library ifdef WANT_WIN_QT #QTDIR=/Developer/Qt -#LIBXPM= -L/opt/X11/lib -lXpm +# Qt installed via homebrew QTDIR=$(shell brew --prefix)/opt/qt -# Qt installed via macports (qt511 package; 5.13 requires OSX 10.12 or later) +# Qt installed via macports #QTDIR=/opt/local/libexec/qt5 endif # WANT_WIN_QT +ifndef LIBXPM +LIBXPM= -L/opt/X11/lib -lXpm +endif # 2. Is this a build for a binary that will be shared among different users # or will it be private to you? @@ -69,66 +82,89 @@ endif # WANT_WIN_QT # NB: the group will be created locally; if your computer is centrally # administered this may not be what you (or your admin) want. # Consider a non-shared install (WANT_SHARE_INSTALL=0) instead. -# - 'make install' must be run as "sudo make install" -# - 'make install' must be run as "sudo make install" +# - 'make install' must be run as "sudo make install" +# Note: 'make install' starts out be removing all files and subdirectories +# from the target destination. Use 'make update' instead if there is +# anything there that you want to keep such as the high scores file from +# a previous install. #WANT_SHARE_INSTALL=1 GAMEUID = $(USER) GAMEGRP = games -# build to run in the source tree - primarily for development. Build with "make all" +# build to run in the source tree - primarily for development. Build +# with "make all" #WANT_SOURCE_INSTALL=1 -# At the moment this is just for debugging, but in the future it could be -# useful for other things. Requires SYSCF and an ANSI compiler. -#WANT_WIN_CHAIN=1 - +# 3. miscellaneous: compiler selection; Qt5 requires C++11 ifdef WANT_WIN_QT CC=clang CXX=clang++ -std=gnu++11 -LINK= $(CXX) #CC=gcc -#CXX=g++ +#CXX=g++ -std=gnu++11 +LINK= $(CXX) else +# compiling C code only; CC and CXX defaults can be used +#CC= +#CXX= LINK = $(CC) endif #MOC = moc +# At the moment the 'chain' interface is just for debugging, but in the future +# it could be useful for other things. Requires SYSCF and an ANSI compiler. +#WANT_WIN_CHAIN=1 + # -# You shouldn't need to change anything below here. +# You shouldn't need to change anything below here (in the hints file; if +# you're reading this in Makefile augmented by hints, that may not be true). # +# Make sure that at least one interface aside from 'chain' is enabled. +ifndef WANT_WIN_TTY +ifndef WANT_WIN_CURSES +ifndef WANT_WIN_X11 +ifndef WANT_WIN_QT +WANT_WIN_TTY=1 +endif +endif +endif +endif + +# Make sure that a default interface is specified; this doesn't guarantee +# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but +# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. ifndef WANT_DEFAULT +# pick the first one enabled among { tty, curses, X11, Qt } ifdef WANT_WIN_TTY WANT_DEFAULT=tty -endif -endif - -ifndef WANT_DEFAULT -ifdef WANT_WIN_X11 -WANT_DEFAULT=x11 -endif -endif - -ifndef WANT_DEFAULT -ifdef WANT_WIN_CURSES +else +ifdef WANT_WIN_CURSES WANT_DEFAULT=curses -endif -endif - -ifndef WANT_DEFAULT -ifdef WANT_WIN_QT +else +ifdef WANT_WIN_X11 +WANT_DEFAULT=X11 +else +ifdef WANT_WIN_QT WANT_DEFAULT=Qt +else +# ? shouldn't be able to get here... +endif +endif +endif endif endif -CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -DGCC_WARN +CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ + -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings +CFLAGS+=-DGCC_WARN ifndef WANT_WIN_QT # these are normally used when compiling nethack's core CFLAGS+=-ansi -pedantic -Wno-long-long -# but -ansi -pendantic forces C90 sematics and win/Qt/qt_*.cpp trigger +# but -ansi forces -std=c90 for C or -std=c++98 for C++; +# win/Qt/qt_*.cpp compiled with C++98 semantics trigger #In file included from .../qt5/include/QtCore/qglobal.h:105: #.../qt5/include/QtCore/qcompilerdetection.h:561:6: # error Qt requires a C++11 compiler and yours does not seem to be that. -# so we suppress them when the build includes Qt +# so we suppress -ansi when the build includes Qt endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. From 2b8763c9fe041d0a3fe0adb33484d29cfc14d23a Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 3 Aug 2020 15:42:09 -0700 Subject: [PATCH 069/708] partial fix for 'msg_window' option processing options.c gave some unused variable warnings in the 'msg_window' parsing if compiled without having tty enabled. The 'msg_window' option should be available if either tty or curses is the interface in use, hidden otherwise. The code to parse it was included if TTY_GRAPHICS is enabled, so it worked in curses for a tty+curses binary but not curses without tty one. This fixes that. It is still displayed by 'O' when X11 or Qt is in use if the binary also supports tty or curses. I've left that as is. --- doc/fixes37.0 | 4 +++- src/options.c | 46 ++++++++++++++++++++++++++++------------------ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3b76a04f4..1c6f4e479 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ $NHDT-Date: 1596486996 2020/08/03 20:36:36 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ $NHDT-Date: 1596494524 2020/08/03 22:42:04 $ General Fixes and Modified Features ----------------------------------- @@ -314,6 +314,8 @@ some versions of tiles processing (not X11's) complained about the rename of wizard mode #timeout changed to show timed Displacement in 'can be timed in normal play' section instead of 'timed via #wizintrinsic only' section +curses: 'msg_window' option wasn't functional for curses unless the binary + also included tty support tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display tty: previous change resulted in remnants of previous level being shown on diff --git a/src/options.c b/src/options.c index 871fcf21e..6ff7859a4 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1594168619 2020/07/08 00:36:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.468 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1596494520 2020/08/03 22:42:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.469 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2079,6 +2079,13 @@ char *op; return optn_ok; } +/* whether the 'msg_window' option is used to control ^P behavior */ +#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) +#define PREV_MSGS 1 +#else +#define PREV_MSGS 0 +#endif + int optfn_msg_window(optidx, req, negated, opts, op) int optidx; @@ -2088,8 +2095,12 @@ char *opts; char *op; { int retval = optn_ok; -#ifdef TTY_GRAPHICS +#if PREV_MSGS int tmp; +#else + nhUse(optidx); + nhUse(negated); + nhUse(op); #endif if (req == do_init) { @@ -2098,8 +2109,8 @@ char *op; if (req == do_set) { /* msg_window:single, combo, full or reversed */ -/* allow option to be silently ignored by non-tty ports */ -#ifdef TTY_GRAPHICS + /* allow option to be silently ignored by non-tty ports */ +#if PREV_MSGS if (op == empty_optstr) { tmp = negated ? 's' : 'f'; } else { @@ -2111,16 +2122,10 @@ char *op; } switch (tmp) { case 's': /* single message history cycle (default if negated) */ - iflags.prevmsg_window = 's'; - break; - case 'c': /* combination: two singles, then full page */ - iflags.prevmsg_window = 'c'; - break; + case 'c': /* combination: first two as singles, then full page */ case 'f': /* full page (default if specified without argument) */ - iflags.prevmsg_window = 'f'; - break; - case 'r': /* full page (reversed) */ - iflags.prevmsg_window = 'r'; + case 'r': /* full page in reverse order (LIFO; default for curses) */ + iflags.prevmsg_window = (char) tmp; break; default: config_error_add("Unknown %s parameter '%s'", allopt[optidx].name, @@ -2134,11 +2139,16 @@ char *op; if (!opts) return optn_err; opts[0] = '\0'; -#ifdef TTY_GRAPHICS - Sprintf(opts, "%s", (iflags.prevmsg_window == 's') ? "single" - : (iflags.prevmsg_window == 'c') ? "combination" - : (iflags.prevmsg_window == 'f') ? "full" - : "reversed"); +#if PREV_MSGS + tmp = iflags.prevmsg_window; + if (WINDOWPORT("curses")) { + if (tmp == 's' || tmp == 'c') + tmp = iflags.prevmsg_window = 'r'; + } + Sprintf(opts, "%s", (tmp == 's') ? "single" + : (tmp == 'c') ? "combination" + : (tmp == 'f') ? "full" + : "reversed"); #endif return optn_ok; } From ac9ba384497879dd935bdf2aa86714dc2a35edd1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 3 Aug 2020 22:07:36 -0400 Subject: [PATCH 070/708] file header bump from "NetHack 3.6" to "NetHack 3.7" --- DEVEL/Developer.txt | 2 +- DEVEL/code_features.txt | 2 +- DEVEL/code_style.txt | 2 +- DEVEL/git_recipes.txt | 2 +- DEVEL/gitinfo.pl | 2 +- DEVEL/hooksdir/NHadd | 2 +- DEVEL/hooksdir/NHgithook.pm | 2 +- DEVEL/hooksdir/NHsubst | 6 +++--- DEVEL/hooksdir/NHtext | 2 +- DEVEL/hooksdir/applypatch-msg | 2 +- DEVEL/hooksdir/commit-msg | 2 +- DEVEL/hooksdir/post-checkout | 2 +- DEVEL/hooksdir/post-commit | 2 +- DEVEL/hooksdir/post-merge | 2 +- DEVEL/hooksdir/post-rewrite | 2 +- DEVEL/hooksdir/pre-applypatch | 2 +- DEVEL/hooksdir/pre-auto-gc | 2 +- DEVEL/hooksdir/pre-commit | 2 +- DEVEL/hooksdir/pre-push | 2 +- DEVEL/hooksdir/pre-rebase | 2 +- Files | 2 +- Porting | 2 +- 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/GENFILES | 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/bogusmon.txt | 2 +- dat/castle.lua | 2 +- dat/data.base | 4 ++-- dat/earth.lua | 2 +- dat/engrave.txt | 2 +- dat/epitaph.txt | 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/orcus.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/symbols | 2 +- dat/tower1.lua | 2 +- dat/tower2.lua | 2 +- dat/tower3.lua | 2 +- dat/tribute | 2 +- dat/valley.lua | 2 +- dat/water.lua | 2 +- dat/wizard1.lua | 2 +- dat/wizard2.lua | 2 +- dat/wizard3.lua | 2 +- doc/config.nh | 2 +- doc/tmac.nh | 2 +- doc/window.doc | 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/decl.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/func_tab.h | 2 +- include/hack.h | 2 +- include/integer.h | 2 +- include/lint.h | 2 +- include/mac-carbon.h | 2 +- include/mac-qt.h | 2 +- include/mac-term.h | 2 +- include/macpopup.h | 2 +- include/mactty.h | 2 +- include/macwin.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/monsym.h | 2 +- include/mttypriv.h | 2 +- include/ntconf.h | 2 +- include/obj.h | 2 +- include/objclass.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/skills.h | 2 +- include/sp_lev.h | 2 +- include/spell.h | 2 +- include/sys.h | 2 +- include/system.h | 2 +- include/tcap.h | 2 +- include/tile2x11.h | 2 +- include/tileset.h | 2 +- include/timeout.h | 2 +- include/tradstdc.h | 2 +- include/trampoli.h | 2 +- include/trap.h | 2 +- include/unixconf.h | 2 +- include/vision.h | 2 +- include/vmsconf.h | 2 +- include/winGnome.h | 2 +- include/winX.h | 2 +- include/winami.h | 2 +- include/wincurs.h | 2 +- include/wingem.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/cmd.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/eat.c | 2 +- src/end.c | 2 +- src/engrave.c | 2 +- src/exper.c | 2 +- src/explode.c | 2 +- src/extralev.c | 2 +- src/fountain.c | 2 +- src/hack.c | 2 +- src/hacklib.c | 2 +- src/light.c | 2 +- src/lock.c | 2 +- src/mail.c | 2 +- src/makemon.c | 2 +- src/mapglyph.c | 2 +- src/mcastu.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/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/o_init.c | 2 +- src/objects.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/rip.c | 2 +- src/rnd.c | 2 +- src/role.c | 2 +- src/save.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/steal.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/worm.c | 2 +- src/worn.c | 2 +- src/write.c | 2 +- src/zap.c | 2 +- sys/msdos/Install.dos | 6 +++--- sys/msdos/Makefile.GCC | 4 ++-- sys/msdos/msdos.c | 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/tile2bin.c | 4 ++-- sys/msdos/vesa.h | 2 +- sys/msdos/video.c | 2 +- sys/msdos/vidtxt.c | 2 +- sys/msdos/vidvga.c | 2 +- sys/share/Makefile.lib | 2 +- sys/share/cppregex.cpp | 4 ++-- sys/share/ioctl.c | 2 +- sys/share/nhlan.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/Makefile.doc | 2 +- sys/unix/Makefile.src | 2 +- sys/unix/Makefile.top | 2 +- sys/unix/Makefile.utl | 2 +- sys/unix/NewInstall.unx | 2 +- sys/unix/gitinfo.sh | 2 +- sys/unix/hints/linux | 2 +- sys/unix/hints/linux-minimal | 2 +- sys/unix/hints/linux-qt4 | 2 +- sys/unix/hints/linux-qt5 | 2 +- sys/unix/hints/linux-x11 | 2 +- sys/unix/hints/macosx | 2 +- sys/unix/hints/macosx.sh | 2 +- sys/unix/hints/macosx10.10 | 2 +- sys/unix/hints/macosx10.10-qt | 2 +- sys/unix/hints/macosx10.14 | 2 +- sys/unix/hints/macosx10.5 | 2 +- sys/unix/hints/macosx10.7 | 2 +- sys/unix/hints/macosx10.8 | 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 | 2 +- sys/unix/unixmain.c | 2 +- sys/unix/unixres.c | 2 +- sys/unix/unixunix.c | 2 +- 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/lev_lex.h | 2 +- sys/vms/oldcrtl.c | 2 +- sys/vms/sysconf | 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/winnt/.nethackrc.template | 2 +- sys/winnt/console.rc | 2 +- sys/winnt/nh340key.c | 2 +- sys/winnt/nhdefkey.c | 2 +- sys/winnt/nhraykey.c | 2 +- sys/winnt/nhsetup.bat | 2 +- sys/winnt/ntsound.c | 2 +- sys/winnt/nttty.c | 2 +- sys/winnt/stubs.c | 2 +- sys/winnt/win10.c | 2 +- sys/winnt/win10.h | 2 +- sys/winnt/win32api.h | 2 +- sys/winnt/windmain.c | 2 +- sys/winnt/winnt.c | 2 +- sys/winnt/winos.h | 2 +- util/dlb_main.c | 2 +- util/makedefs.c | 2 +- util/mdgrep.h | 2 +- util/mdgrep.pl | 10 +++++----- util/panic.c | 2 +- util/recover.c | 2 +- win/X11/Window.c | 2 +- win/X11/nh32icon | 2 +- win/X11/nh56icon | 2 +- win/X11/nh72icon | 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/cursdial.h | 2 +- win/curses/cursinit.c | 2 +- win/curses/cursinit.h | 2 +- win/curses/cursinvt.c | 2 +- win/curses/cursinvt.h | 2 +- win/curses/cursmain.c | 2 +- win/curses/cursmesg.c | 2 +- win/curses/cursmesg.h | 2 +- win/curses/cursmisc.c | 2 +- win/curses/cursmisc.h | 2 +- win/curses/cursstat.c | 2 +- win/curses/cursstat.h | 2 +- win/curses/curswins.c | 2 +- win/curses/curswins.h | 2 +- win/macosx/NetHackGuidebook.applescript | 2 +- win/macosx/NetHackRecover.applescript | 2 +- win/macosx/recover.pl | 2 +- win/share/bmptiles.c | 2 +- win/share/giftiles.c | 2 +- win/share/ppmwrite.c | 2 +- win/share/safeproc.c | 2 +- win/share/thintile.c | 2 +- win/share/tile.doc | 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/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/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 +- 482 files changed, 494 insertions(+), 494 deletions(-) diff --git a/DEVEL/Developer.txt b/DEVEL/Developer.txt index 7a588c203..ad4262bb6 100644 --- a/DEVEL/Developer.txt +++ b/DEVEL/Developer.txt @@ -4,7 +4,7 @@ |___/\___|\_/\___|_\___/ .__/\___|_| |_| -# NetHack 3.6 Developer.txt $NHDT-Date: 1524689668 2018/04/25 20:54:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.13 $ +# NetHack 3.7 Developer.txt $NHDT-Date: 1596498265 2020/08/03 23:44:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/code_features.txt b/DEVEL/code_features.txt index 4e89df7f5..25859a5f1 100644 --- a/DEVEL/code_features.txt +++ b/DEVEL/code_features.txt @@ -1,4 +1,4 @@ -# NetHack 3.6 code_features.txt $NHDT-Date: 1524689669 2018/04/25 20:54:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.3 $ +# NetHack 3.7 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. diff --git a/DEVEL/code_style.txt b/DEVEL/code_style.txt index 6946604e1..a62e1f9e9 100644 --- a/DEVEL/code_style.txt +++ b/DEVEL/code_style.txt @@ -1,4 +1,4 @@ -# NetHack 3.6 code_style.txt $NHDT-Date: 1524689669 2018/04/25 20:54:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 code_style.txt $NHDT-Date: 1596498264 2020/08/03 23:44:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ # Copyright (c) 2015 by Derek S. Ray # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/git_recipes.txt b/DEVEL/git_recipes.txt index 09f2344e3..e4ca94925 100644 --- a/DEVEL/git_recipes.txt +++ b/DEVEL/git_recipes.txt @@ -1,4 +1,4 @@ -# NetHack 3.6 git_recipes.txt $NHDT-Date: 1524689669 2018/04/25 20:54:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.9 $ +# NetHack 3.7 git_recipes.txt $NHDT-Date: 1596498266 2020/08/03 23:44:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ # Copyright (c) 2015 by Derek S. Ray # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/gitinfo.pl b/DEVEL/gitinfo.pl index 91f71e65e..f348f8e6e 100644 --- a/DEVEL/gitinfo.pl +++ b/DEVEL/gitinfo.pl @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 getinfo.pl $NHDT-Date: 1524689669 2018/04/25 20:54:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 getinfo.pl $NHDT-Date: 1596498266 2020/08/03 23:44:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ # Copyright (c) 2018 by Michael Allison # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/NHadd b/DEVEL/hooksdir/NHadd index 3e4b24b85..c4d6e547d 100644 --- a/DEVEL/hooksdir/NHadd +++ b/DEVEL/hooksdir/NHadd @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 NHadd $NHDT-Date: 1524689631 2018/04/25 20:53:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 NHadd $NHDT-Date: 1596498406 2020/08/03 23:46:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/NHgithook.pm b/DEVEL/hooksdir/NHgithook.pm index 0c64ab12f..c7c3456f5 100644 --- a/DEVEL/hooksdir/NHgithook.pm +++ b/DEVEL/hooksdir/NHgithook.pm @@ -1,5 +1,5 @@ # -# NetHack 3.6 NHgithook.pm $NHDT-Date: 1524689631 2018/04/25 20:53:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.6 $ +# NetHack 3.7 NHgithook.pm $NHDT-Date: 1596498406 2020/08/03 23:46:46 $ $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/DEVEL/hooksdir/NHsubst b/DEVEL/hooksdir/NHsubst index 45e8297e1..99621fc57 100755 --- a/DEVEL/hooksdir/NHsubst +++ b/DEVEL/hooksdir/NHsubst @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 NHsubst $NHDT-Date: 1524689631 2018/04/25 20:53:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.4 $ +# NetHack 3.7 NHsubst $NHDT-Date: 1596498407 2020/08/03 23:46:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -392,7 +392,7 @@ $TEST-Branch: theirs $ TEST 8: <<< d1 -/* NetHack 3.6 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ +/* NetHack 3.7 objnam.c $TEST-Date$ $TEST-Branch$:$TEST-Revision$ */ === -/* NetHack 3.6 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ +/* NetHack 3.7 objnam.c $TEST-Date: 1426977394 2015/03/21 22:36:34 $ $TEST-Branch: master $:$TEST-Revision: 1.108 $ */ >>> d3 diff --git a/DEVEL/hooksdir/NHtext b/DEVEL/hooksdir/NHtext index 44a70db42..8e0d9a9c2 100755 --- a/DEVEL/hooksdir/NHtext +++ b/DEVEL/hooksdir/NHtext @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 NHtext $NHDT-Date: 1524689631 2018/04/25 20:53:51 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.8 $ +# NetHack 3.7 NHtext $NHDT-Date: 1596498408 2020/08/03 23:46:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/applypatch-msg b/DEVEL/hooksdir/applypatch-msg index 4432174ab..2318186ed 100755 --- a/DEVEL/hooksdir/applypatch-msg +++ b/DEVEL/hooksdir/applypatch-msg @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 applypatch-msg $NHDT-Date: 1524689646 2018/04/25 20:54:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 applypatch-msg $NHDT-Date: 1596498405 2020/08/03 23:46:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/commit-msg b/DEVEL/hooksdir/commit-msg index 1f2ad49a2..e4befa0e5 100755 --- a/DEVEL/hooksdir/commit-msg +++ b/DEVEL/hooksdir/commit-msg @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 commit-msg $NHDT-Date: 1524689646 2018/04/25 20:54:06 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 commit-msg $NHDT-Date: 1596498405 2020/08/03 23:46:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/post-checkout b/DEVEL/hooksdir/post-checkout index c7fde4f18..d7e6c5724 100755 --- a/DEVEL/hooksdir/post-checkout +++ b/DEVEL/hooksdir/post-checkout @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 post-checkout $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 post-checkout $NHDT-Date: 1596498409 2020/08/03 23:46:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/post-commit b/DEVEL/hooksdir/post-commit index 309eec4ce..cb37b3800 100755 --- a/DEVEL/hooksdir/post-commit +++ b/DEVEL/hooksdir/post-commit @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 post-commit $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 post-commit $NHDT-Date: 1596498409 2020/08/03 23:46:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/post-merge b/DEVEL/hooksdir/post-merge index 6ca8dc532..a634f51ef 100755 --- a/DEVEL/hooksdir/post-merge +++ b/DEVEL/hooksdir/post-merge @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 post-merge $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 post-merge $NHDT-Date: 1596498410 2020/08/03 23:46:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/post-rewrite b/DEVEL/hooksdir/post-rewrite index 317eddea0..655c1a0cd 100755 --- a/DEVEL/hooksdir/post-rewrite +++ b/DEVEL/hooksdir/post-rewrite @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 post-rewrite $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 post-rewrite $NHDT-Date: 1596498411 2020/08/03 23:46:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/pre-applypatch b/DEVEL/hooksdir/pre-applypatch index f71d1fda3..3b57a6f53 100755 --- a/DEVEL/hooksdir/pre-applypatch +++ b/DEVEL/hooksdir/pre-applypatch @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 pre-applypatch $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 pre-applypatch $NHDT-Date: 1596498411 2020/08/03 23:46:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/pre-auto-gc b/DEVEL/hooksdir/pre-auto-gc index e1c39bebd..d1ab9b005 100755 --- a/DEVEL/hooksdir/pre-auto-gc +++ b/DEVEL/hooksdir/pre-auto-gc @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 pre-auto-gc $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 pre-auto-gc $NHDT-Date: 1596498412 2020/08/03 23:46:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/pre-commit b/DEVEL/hooksdir/pre-commit index 83dacdd41..bb5dbfe84 100755 --- a/DEVEL/hooksdir/pre-commit +++ b/DEVEL/hooksdir/pre-commit @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 pre-commit $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 pre-commit $NHDT-Date: 1596498413 2020/08/03 23:46:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/pre-push b/DEVEL/hooksdir/pre-push index d65dcbecb..c2639fa2e 100755 --- a/DEVEL/hooksdir/pre-push +++ b/DEVEL/hooksdir/pre-push @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 pre-push $NHDT-Date: 1524689632 2018/04/25 20:53:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 pre-push $NHDT-Date: 1596498413 2020/08/03 23:46:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/DEVEL/hooksdir/pre-rebase b/DEVEL/hooksdir/pre-rebase index e25f41cac..7f447a082 100755 --- a/DEVEL/hooksdir/pre-rebase +++ b/DEVEL/hooksdir/pre-rebase @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 pre-rebase $NHDT-Date: 1524689633 2018/04/25 20:53:53 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 pre-rebase $NHDT-Date: 1596498414 2020/08/03 23:46:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/Files b/Files index 499a00381..48c7a040b 100644 --- a/Files +++ b/Files @@ -1,4 +1,4 @@ -This is a listing of all files in a full NetHack 3.6 distribution, organized +This is a listing of all files in a full NetHack 3.7 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. diff --git a/Porting b/Porting index 7d4d5153a..3f5a99d8e 100644 --- a/Porting +++ b/Porting @@ -266,6 +266,6 @@ by code within the game itself. That was done to facilitate cross-compiling of NetHack on one platform for game execution on another. -# NetHack 3.6 Porting $NHDT-Date: 1594155866 2020/07/07 21:04:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +# NetHack 3.7 Porting $NHDT-Date: 1596498144 2020/08/03 23:42:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ # Copyright (c) 2005 by Michael Allison # NetHack may be freely redistributed. See license for details. diff --git a/dat/Arc-fila.lua b/dat/Arc-fila.lua index 2e2dc1578..786d37e86 100644 --- a/dat/Arc-fila.lua +++ b/dat/Arc-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 8b3f1d257..d4ec17464 100644 --- a/dat/Arc-filb.lua +++ b/dat/Arc-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 4f48ec516..ba3a00555 100644 --- a/dat/Arc-goal.lua +++ b/dat/Arc-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 374deb595..31776ac52 100644 --- a/dat/Arc-loca.lua +++ b/dat/Arc-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 9292d40ca..5f759b575 100644 --- a/dat/Arc-strt.lua +++ b/dat/Arc-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Arch.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 dda6d9ca7..dca44c6cf 100644 --- a/dat/Bar-fila.lua +++ b/dat/Bar-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 6978f32a3..4da533632 100644 --- a/dat/Bar-filb.lua +++ b/dat/Bar-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 31754a4c0..79b9b587e 100644 --- a/dat/Bar-goal.lua +++ b/dat/Bar-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 df1e7d8aa..41680ca28 100644 --- a/dat/Bar-loca.lua +++ b/dat/Bar-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 17be92208..79df053e7 100644 --- a/dat/Bar-strt.lua +++ b/dat/Bar-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Barb.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 5220b4eb3..50b518833 100644 --- a/dat/Cav-fila.lua +++ b/dat/Cav-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 5bc5ad4ac..812b6b786 100644 --- a/dat/Cav-filb.lua +++ b/dat/Cav-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 98919b04f..698147fd2 100644 --- a/dat/Cav-goal.lua +++ b/dat/Cav-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 e3b970948..8406a5dd6 100644 --- a/dat/Cav-loca.lua +++ b/dat/Cav-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 eae5c35d1..1dfe83628 100644 --- a/dat/Cav-strt.lua +++ b/dat/Cav-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Caveman.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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/GENFILES b/dat/GENFILES index 1a49c97a2..eaf994740 100755 --- a/dat/GENFILES +++ b/dat/GENFILES @@ -1,5 +1,5 @@ #!/usr/bin/perl -# NetHack 3.6 GENFILES $NHDT-Date: 1550799147 2019/02/22 01:32:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.0 $ +# NetHack 3.7 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/Hea-fila.lua b/dat/Hea-fila.lua index 03f52245f..5046818d0 100644 --- a/dat/Hea-fila.lua +++ b/dat/Hea-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 293437006..5d67d817e 100644 --- a/dat/Hea-filb.lua +++ b/dat/Hea-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 48d6fbae4..fd0203908 100644 --- a/dat/Hea-goal.lua +++ b/dat/Hea-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 fdc432471..7723bdbf5 100644 --- a/dat/Hea-loca.lua +++ b/dat/Hea-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 665c73097..1a2f64acc 100644 --- a/dat/Hea-strt.lua +++ b/dat/Hea-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 Healer.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 79866a692..b02df405e 100644 --- a/dat/Kni-fila.lua +++ b/dat/Kni-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 49d14e661..31afecf30 100644 --- a/dat/Kni-filb.lua +++ b/dat/Kni-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 577355937..70709e9ce 100644 --- a/dat/Kni-goal.lua +++ b/dat/Kni-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 20aed41f5..6c9480b26 100644 --- a/dat/Kni-loca.lua +++ b/dat/Kni-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 8feba3489..7d43f61c4 100644 --- a/dat/Kni-strt.lua +++ b/dat/Kni-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Knight.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 d0e36ad2c..9a2129ee5 100644 --- a/dat/Mon-fila.lua +++ b/dat/Mon-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ +-- NetHack 3.7 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ -- 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 a6fbdd5b1..4c5f7d23c 100644 --- a/dat/Mon-filb.lua +++ b/dat/Mon-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ +-- NetHack 3.7 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ -- 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 d339e323d..26a715238 100644 --- a/dat/Mon-goal.lua +++ b/dat/Mon-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ +-- NetHack 3.7 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ -- 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 2436a33da..927b770ec 100644 --- a/dat/Mon-loca.lua +++ b/dat/Mon-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ +-- NetHack 3.7 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ -- 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 a71975d5f..ae1ad77d0 100644 --- a/dat/Mon-strt.lua +++ b/dat/Mon-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ +-- NetHack 3.7 Monk.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ -- 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 6df964f60..65bd61ee2 100644 --- a/dat/Pri-fila.lua +++ b/dat/Pri-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 060afd246..b3bc7e33d 100644 --- a/dat/Pri-filb.lua +++ b/dat/Pri-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 5de237d20..ba47c03f0 100644 --- a/dat/Pri-goal.lua +++ b/dat/Pri-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 ab2cc2f3d..9ebd55300 100644 --- a/dat/Pri-loca.lua +++ b/dat/Pri-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 70d8444e6..3b4be1ac7 100644 --- a/dat/Pri-strt.lua +++ b/dat/Pri-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Priest.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 2ef3e476c..e604310c3 100644 --- a/dat/Ran-fila.lua +++ b/dat/Ran-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 8f19cd06f..a91bfd579 100644 --- a/dat/Ran-filb.lua +++ b/dat/Ran-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 b32c5add4..9e9215a18 100644 --- a/dat/Ran-goal.lua +++ b/dat/Ran-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 c9af3f1f3..4aec9449c 100644 --- a/dat/Ran-loca.lua +++ b/dat/Ran-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 66ea5028a..69004ebb6 100644 --- a/dat/Ran-strt.lua +++ b/dat/Ran-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 Ranger.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 b21be7db9..d89bbaf98 100644 --- a/dat/Rog-fila.lua +++ b/dat/Rog-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 b21be7db9..d89bbaf98 100644 --- a/dat/Rog-filb.lua +++ b/dat/Rog-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 3fa505c25..351ec307a 100644 --- a/dat/Rog-goal.lua +++ b/dat/Rog-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 ef5b399ea..fa151dbb2 100644 --- a/dat/Rog-loca.lua +++ b/dat/Rog-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 b7e97e63a..58f27f696 100644 --- a/dat/Rog-strt.lua +++ b/dat/Rog-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Rogue.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 642b79fa1..e93278391 100644 --- a/dat/Sam-fila.lua +++ b/dat/Sam-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 640f4b17b..60611d4c3 100644 --- a/dat/Sam-filb.lua +++ b/dat/Sam-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 ce7215a0a..ce766f80b 100644 --- a/dat/Sam-goal.lua +++ b/dat/Sam-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 ccad8e260..45ccd7ece 100644 --- a/dat/Sam-loca.lua +++ b/dat/Sam-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 108f28f61..ec865ab5d 100644 --- a/dat/Sam-strt.lua +++ b/dat/Sam-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Samurai.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 112caf4ed..8a8af769c 100644 --- a/dat/Tou-fila.lua +++ b/dat/Tou-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 4dccad5b0..ad2a8ae9f 100644 --- a/dat/Tou-filb.lua +++ b/dat/Tou-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 b1fb941ed..5cf5abd6f 100644 --- a/dat/Tou-goal.lua +++ b/dat/Tou-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 f82f5072f..d32a7911f 100644 --- a/dat/Tou-loca.lua +++ b/dat/Tou-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 8ca3f6a76..60891c8c4 100644 --- a/dat/Tou-strt.lua +++ b/dat/Tou-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +-- NetHack 3.7 Tourist.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ -- 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 bf7cb2e86..ad3dc282d 100644 --- a/dat/Val-fila.lua +++ b/dat/Val-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ +-- NetHack 3.7 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ -- 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 e779ed564..84bb73987 100644 --- a/dat/Val-filb.lua +++ b/dat/Val-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ +-- NetHack 3.7 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ -- 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 d92917039..4971822cf 100644 --- a/dat/Val-goal.lua +++ b/dat/Val-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ +-- NetHack 3.7 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ -- 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 a5817ebea..ab0f15181 100644 --- a/dat/Val-loca.lua +++ b/dat/Val-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ +-- NetHack 3.7 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ -- 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 5bb9fce57..dbce2280d 100644 --- a/dat/Val-strt.lua +++ b/dat/Val-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ +-- NetHack 3.7 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ -- 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 61c78d75b..e11b50340 100644 --- a/dat/Wiz-fila.lua +++ b/dat/Wiz-fila.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 41eae6c47..2fff8cba5 100644 --- a/dat/Wiz-filb.lua +++ b/dat/Wiz-filb.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 5673410c6..c243da4f7 100644 --- a/dat/Wiz-goal.lua +++ b/dat/Wiz-goal.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 288660ca7..6acc15da6 100644 --- a/dat/Wiz-loca.lua +++ b/dat/Wiz-loca.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 19478b249..fdc9ae531 100644 --- a/dat/Wiz-strt.lua +++ b/dat/Wiz-strt.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 Wizard.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- 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 ba925c86a..b8e0fd936 100644 --- a/dat/air.lua +++ b/dat/air.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ +-- NetHack 3.7 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ -- 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 a8b73b8a4..e8f1ffaf6 100644 --- a/dat/asmodeus.lua +++ b/dat/asmodeus.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 5a3a70286..7085eba78 100644 --- a/dat/astral.lua +++ b/dat/astral.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ +-- NetHack 3.7 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ -- 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 107c98719..d75e6e3a2 100644 --- a/dat/baalz.lua +++ b/dat/baalz.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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/bogusmon.txt b/dat/bogusmon.txt index 7179c8b11..40f7a507e 100644 --- a/dat/bogusmon.txt +++ b/dat/bogusmon.txt @@ -1,4 +1,4 @@ -# NetHack 3.6 bogusmon.txt $NHDT-Date: 1574387024 2019/11/22 01:43:44 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.8 $ +# NetHack 3.7 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/castle.lua b/dat/castle.lua index fa798f3f9..4c614f550 100644 --- a/dat/castle.lua +++ b/dat/castle.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 castle.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ +-- NetHack 3.7 castle.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/data.base b/dat/data.base index b4ada5b50..66f32e68a 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1,5 +1,5 @@ -# NetHack 3.6 data.base -# $NHDT-Date: 1590711596 2020/05/29 00:19:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.96 $ +# NetHack 3.7 data.base +# $NHDT-Date: 1596498239 2020/08/03 23:43:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ # Copyright (c) 1994, 1995, 1996 by the NetHack Development Team # Copyright (c) 1994 by Boudewijn Wayers # NetHack may be freely redistributed. See license for details. diff --git a/dat/earth.lua b/dat/earth.lua index 62cb6da32..521da3d10 100644 --- a/dat/earth.lua +++ b/dat/earth.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ +-- NetHack 3.7 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- Copyright (c) 1992,1993 by Izchak Miller, David Cohrs, -- and Timo Hakulinen diff --git a/dat/engrave.txt b/dat/engrave.txt index 222d1e5a9..ff473b610 100644 --- a/dat/engrave.txt +++ b/dat/engrave.txt @@ -1,4 +1,4 @@ -# NetHack 3.6 engrave.txt $NHDT-Date: 1581206725 2020/02/09 00:05:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 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 $ # 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 d35ba5441..a8fbb3266 100644 --- a/dat/epitaph.txt +++ b/dat/epitaph.txt @@ -1,4 +1,4 @@ -# NetHack 3.6 epitaph.txt $NHDT-Date: 1524689580 2018/04/25 20:53:00 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.3 $ +# NetHack 3.7 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/fakewiz1.lua b/dat/fakewiz1.lua index 856ac3161..6576176e2 100644 --- a/dat/fakewiz1.lua +++ b/dat/fakewiz1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 d8f73abb3..f34d00af0 100644 --- a/dat/fakewiz2.lua +++ b/dat/fakewiz2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 105ca0fd0..babe6e15f 100644 --- a/dat/fire.lua +++ b/dat/fire.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ +-- NetHack 3.7 endgame.des $NHDT-Date: 1546303680 2019/01/01 00:48:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.14 $ -- 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 588290cc1..98bc89bde 100644 --- a/dat/juiblex.lua +++ b/dat/juiblex.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 aa5ca4888..c1b4c204b 100644 --- a/dat/knox.lua +++ b/dat/knox.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 knox.des $NHDT-Date: 1547343821 2019/01/13 01:43:41 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 knox.des $NHDT-Date: 1547343821 2019/01/13 01:43:41 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.13 $ -- 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 591e404d2..63a471904 100644 --- a/dat/medusa-1.lua +++ b/dat/medusa-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$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-2.lua b/dat/medusa-2.lua index 17c2893ff..4b03631e7 100644 --- a/dat/medusa-2.lua +++ b/dat/medusa-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$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-3.lua b/dat/medusa-3.lua index efc860ae5..221cb8172 100644 --- a/dat/medusa-3.lua +++ b/dat/medusa-3.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$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 73f6df286..c5f8e206d 100644 --- a/dat/medusa-4.lua +++ b/dat/medusa-4.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 medusa.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$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/minefill.lua b/dat/minefill.lua index ca23a8da6..74911c39d 100644 --- a/dat/minefill.lua +++ b/dat/minefill.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 7fce31a28..30e1a23d7 100644 --- a/dat/minend-1.lua +++ b/dat/minend-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 ced2b11f6..469310d19 100644 --- a/dat/minend-2.lua +++ b/dat/minend-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 92be571b1..b5d7abfda 100644 --- a/dat/minend-3.lua +++ b/dat/minend-3.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 39460ead3..8558662b9 100644 --- a/dat/minetn-1.lua +++ b/dat/minetn-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 7081021e6..258f62a57 100644 --- a/dat/minetn-2.lua +++ b/dat/minetn-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 b4ff7fb06..cd979739f 100644 --- a/dat/minetn-3.lua +++ b/dat/minetn-3.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.25 $ -- 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 cc4dc7611..49325239d 100644 --- a/dat/minetn-4.lua +++ b/dat/minetn-4.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ -- 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 baade6a41..5faac05a1 100644 --- a/dat/minetn-5.lua +++ b/dat/minetn-5.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ -- 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 6de06d11a..7e3c88131 100644 --- a/dat/minetn-6.lua +++ b/dat/minetn-6.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ -- 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 16bca3ae1..4526b9225 100644 --- a/dat/minetn-7.lua +++ b/dat/minetn-7.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ +-- NetHack 3.7 mines.des $NHDT-Date: 1548631704 2019/01/27 23:28:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ -- 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/orcus.lua b/dat/orcus.lua index ac5b940bf..b04247491 100644 --- a/dat/orcus.lua +++ b/dat/orcus.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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/sanctum.lua b/dat/sanctum.lua index 45aa0b361..c99eff81d 100644 --- a/dat/sanctum.lua +++ b/dat/sanctum.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 b281975b5..f38667960 100644 --- a/dat/soko1-1.lua +++ b/dat/soko1-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 9a8002852..48305895e 100644 --- a/dat/soko1-2.lua +++ b/dat/soko1-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 9934819f7..b9d043853 100644 --- a/dat/soko2-1.lua +++ b/dat/soko2-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 bb931c15f..ed64954d8 100644 --- a/dat/soko2-2.lua +++ b/dat/soko2-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 cec5eec8b..2a0826e0f 100644 --- a/dat/soko3-1.lua +++ b/dat/soko3-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 fa15d8ba6..461635d8d 100644 --- a/dat/soko3-2.lua +++ b/dat/soko3-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 3257986de..5629a7a5d 100644 --- a/dat/soko4-1.lua +++ b/dat/soko4-1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 e9df5c050..2cea6235f 100644 --- a/dat/soko4-2.lua +++ b/dat/soko4-2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 sokoban.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- Copyright (c) 1998-1999 by Kevin Hugo -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/symbols b/dat/symbols index 06aa31f66..9b9f9c72e 100644 --- a/dat/symbols +++ b/dat/symbols @@ -1,4 +1,4 @@ -# NetHack 3.6 symbols $NHDT-Date: 1572892906 2019/11/04 18:41:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.21 $ +# NetHack 3.7 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/dat/tower1.lua b/dat/tower1.lua index dcd84f1f6..a5ee95f55 100644 --- a/dat/tower1.lua +++ b/dat/tower1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 tower.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 tower.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 0376ec51c..793257844 100644 --- a/dat/tower2.lua +++ b/dat/tower2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 tower.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 tower.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- 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 345c5a9c2..6a601908a 100644 --- a/dat/tower3.lua +++ b/dat/tower3.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 tower.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +-- NetHack 3.7 tower.des $NHDT-Date: 1432512784 2015/05/25 00:13:04 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ -- Copyright (c) 1989 by Jean-Christophe Collet -- NetHack may be freely redistributed. See license for details. -- diff --git a/dat/tribute b/dat/tribute index e1596bc49..67fbd93d8 100644 --- a/dat/tribute +++ b/dat/tribute @@ -1,4 +1,4 @@ -# NetHack 3.6 tribute $NHDT-Date: 1590695417 2020/05/28 19:50:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.88 $ +# NetHack 3.7 tribute $NHDT-Date: 1596498255 2020/08/03 23:44:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ # 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/dat/valley.lua b/dat/valley.lua index adcd4e80f..f283cb415 100644 --- a/dat/valley.lua +++ b/dat/valley.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 gehennom.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 fdf6a5586..8b1ba9365 100644 --- a/dat/water.lua +++ b/dat/water.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 endgame.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +-- NetHack 3.7 endgame.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ -- 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 26dfd5839..3a40d6ae9 100644 --- a/dat/wizard1.lua +++ b/dat/wizard1.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 9bcd4ab3b..d9fd181a0 100644 --- a/dat/wizard2.lua +++ b/dat/wizard2.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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 a7b53a340..60e9dd014 100644 --- a/dat/wizard3.lua +++ b/dat/wizard3.lua @@ -1,4 +1,4 @@ --- NetHack 3.6 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ +-- NetHack 3.7 yendor.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ -- 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/doc/config.nh b/doc/config.nh index 437158250..484a2930e 100644 --- a/doc/config.nh +++ b/doc/config.nh @@ -1,4 +1,4 @@ -# NetHack 3.6 config.nh $NHDT-Date: 1524689547 2018/04/25 20:52:27 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 config.nh $NHDT-Date: 1596498144 2020/08/03 23:42:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ # Copyright (c) 2016 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. # Sample config file for NetHack 3.6 diff --git a/doc/tmac.nh b/doc/tmac.nh index 5a1bd0a60..473f33a38 100644 --- a/doc/tmac.nh +++ b/doc/tmac.nh @@ -1,4 +1,4 @@ -.\" NetHack 3.6 tmac.nh $NHDT-Date: $ $NHDT-Branch: $:$NHDT-Revision: $ +.\" NetHack 3.7 tmac.nh $NHDT-Date: $ $NHDT-Branch: $:$NHDT-Revision: $ . .\" Miscellaneous tmac.n-style macros specifically for nethack's Guidebook. .\" diff --git a/doc/window.doc b/doc/window.doc index 73caf9322..1f376a5bd 100644 --- a/doc/window.doc +++ b/doc/window.doc @@ -1,4 +1,4 @@ -NetHack 3.6 window.doc $NHDT-Date: 1433901374 2015/06/10 01:56:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.42 $ +NetHack 3.7 window.doc $NHDT-Date: 1596498145 2020/08/03 23:42:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.58 $ Introduction diff --git a/include/align.h b/include/align.h index 47ad97f5d..9e3e658ff 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 align.h $NHDT-Date: 1432512779 2015/05/25 00:12:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 align.h $NHDT-Date: 1596498525 2020/08/03 23:48:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* 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 4e5193f55..b10d75160 100644 --- a/include/artifact.h +++ b/include/artifact.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 artifact.h $NHDT-Date: 1433050871 2015/05/31 05:41:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 artifact.h $NHDT-Date: 1596498526 2020/08/03 23:48:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* 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 d7b8f250c..d3a5e7ab2 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 artilist.h $NHDT-Date: 1564351548 2019/07/28 22:05:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.7 artilist.h $NHDT-Date: 1596498526 2020/08/03 23:48:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ /* 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 ecd29ab38..b3a5d82e7 100644 --- a/include/attrib.h +++ b/include/attrib.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 attrib.h $NHDT-Date: 1432512779 2015/05/25 00:12:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 c91d76db6..89ca4f2df 100644 --- a/include/botl.h +++ b/include/botl.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 botl.h $NHDT-Date: 1562187996 2019/07/03 21:06:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 3.7 botl.h $NHDT-Date: 1596498528 2020/08/03 23:48:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.34 $ */ /* 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 b05ae6d73..4b9f8a1cf 100644 --- a/include/color.h +++ b/include/color.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 color.h $NHDT-Date: 1432512776 2015/05/25 00:12:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.7 color.h $NHDT-Date: 1596498528 2020/08/03 23:48:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ */ /* 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 7d54ceda3..bbcd4b112 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 config.h $NHDT-Date: 1596072230 2020/07/30 01:23:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */ +/* NetHack 3.7 config.h $NHDT-Date: 1596498529 2020/08/03 23:48:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */ /* 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 172de10b1..986a710c1 100644 --- a/include/config1.h +++ b/include/config1.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 config1.h $NHDT-Date: 1594169991 2020/07/08 00:59:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 3.7 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 e2bd9b49f..fe7b3ab72 100644 --- a/include/context.h +++ b/include/context.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 context.h $NHDT-Date: 1580434522 2020/01/31 01:35:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ */ +/* NetHack 3.7 context.h $NHDT-Date: 1596498530 2020/08/03 23:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ /* 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 e800fb876..9c066db26 100644 --- a/include/coord.h +++ b/include/coord.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 coord.h $NHDT-Date: 1432512778 2015/05/25 00:12:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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/decl.h b/include/decl.h index a626a76e0..b4f7f0dc1 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.h $NHDT-Date: 1594730609 2020/07/14 12:43:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1596498532 2020/08/03 23:48:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.240 $ */ /* 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/dgn_file.h b/include/dgn_file.h index 442905cfb..dc3422391 100644 --- a/include/dgn_file.h +++ b/include/dgn_file.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 dgn_file.h $NHDT-Date: 1432512780 2015/05/25 00:13:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 7813c008a..272ed163d 100644 --- a/include/display.h +++ b/include/display.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 display.h $NHDT-Date: 1559994621 2019/06/08 11:50:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.7 display.h $NHDT-Date: 1596498533 2020/08/03 23:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ /* 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 e8b9fd253..4f5934b55 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 dlb.h $NHDT-Date: 1432512780 2015/05/25 00:13:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 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 26508a184..83ea0015c 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 dungeon.h $NHDT-Date: 1593953333 2020/07/05 12:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 3.7 dungeon.h $NHDT-Date: 1596498535 2020/08/03 23:48:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ */ /* 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 86f6fcdb8..f16c66ec1 100644 --- a/include/engrave.h +++ b/include/engrave.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 engrave.h $NHDT-Date: 1432512777 2015/05/25 00:12:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 3c2d94dda..77d4c6d5e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1596226441 2020/07/31 20:14:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.853 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1596498536 2020/08/03 23:48:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.854 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/func_tab.h b/include/func_tab.h index 79daef1de..84539c559 100644 --- a/include/func_tab.h +++ b/include/func_tab.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 func_tab.h $NHDT-Date: 1543797823 2018/12/03 00:43:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 func_tab.h $NHDT-Date: 1596498537 2020/08/03 23:48:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* 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 a94407fcf..ae66209e6 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.h $NHDT-Date: 1596391185 2020/08/02 17:59:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ +/* NetHack 3.7 hack.h $NHDT-Date: 1596498538 2020/08/03 23:48:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ /* 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/integer.h b/include/integer.h index 322c2f5e3..5aca4ca22 100644 --- a/include/integer.h +++ b/include/integer.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 integer.h $NHDT-Date: 1551901047 2019/03/06 19:37:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.7 $ */ +/* NetHack 3.7 integer.h $NHDT-Date: 1596498539 2020/08/03 23:48:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ */ /* 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 93a33776b..66ad73d72 100644 --- a/include/lint.h +++ b/include/lint.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 lint.h $NHDT-Date: 1524689514 2018/04/25 20:51:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.5 $ */ +/* NetHack 3.7 lint.h $NHDT-Date: 1596498539 2020/08/03 23:48:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ */ /* Copyright (c) 2016 by Robert Patrick Rankin */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/mac-carbon.h b/include/mac-carbon.h index da53c622a..b773c732f 100644 --- a/include/mac-carbon.h +++ b/include/mac-carbon.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mac-carbon.h $NHDT-Date: 1432512777 2015/05/25 00:12:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ +/* NetHack 3.7 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/include/mac-qt.h b/include/mac-qt.h index 96e406b4d..429106c92 100644 --- a/include/mac-qt.h +++ b/include/mac-qt.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mac-qt.h $NHDT-Date: 1432512776 2015/05/25 00:12:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ +/* NetHack 3.7 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/include/mac-term.h b/include/mac-term.h index 9f4ba462f..8bef72d0b 100644 --- a/include/mac-term.h +++ b/include/mac-term.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mac-term.h $NHDT-Date: 1432512775 2015/05/25 00:12:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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/include/macpopup.h b/include/macpopup.h index 491592b1f..873af3cc6 100644 --- a/include/macpopup.h +++ b/include/macpopup.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 macpopup.h $NHDT-Date: 1432512781 2015/05/25 00:13:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 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/include/mactty.h b/include/mactty.h index 086aa050f..7f84747bc 100644 --- a/include/mactty.h +++ b/include/mactty.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mactty.h $NHDT-Date: 1447755970 2015/11/17 10:26:10 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 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/include/macwin.h b/include/macwin.h index b1ea4a2f1..8dad9ea57 100644 --- a/include/macwin.h +++ b/include/macwin.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 macwin.h $NHDT-Date: 1447755970 2015/11/17 10:26:10 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 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/include/mail.h b/include/mail.h index 3b7772b8c..4b3ec2d05 100644 --- a/include/mail.h +++ b/include/mail.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mail.h $NHDT-Date: 1524689515 2018/04/25 20:51:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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 a8e06784e..0ade0adf7 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mextra.h $NHDT-Date: 1574722861 2019/11/25 23:01:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.7 mextra.h $NHDT-Date: 1596498545 2020/08/03 23:49:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ /* 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 18259c70c..a49f13262 100644 --- a/include/mfndpos.h +++ b/include/mfndpos.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mfndpos.h $NHDT-Date: 1432512776 2015/05/25 00:12:56 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 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 ec512a5c9..fd10be51b 100644 --- a/include/micro.h +++ b/include/micro.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 micro.h $NHDT-Date: 1524689515 2018/04/25 20:51:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 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 6bc6204ef..e7bd874ea 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkroom.h $NHDT-Date: 1560851014 2019/06/18 09:43:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 3.7 mkroom.h $NHDT-Date: 1596498547 2020/08/03 23:49:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ /* 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 1eb848fe7..a836f3eab 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 monattk.h $NHDT-Date: 1432512775 2015/05/25 00:12:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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 abff12a2c..db9d83d92 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.h $NHDT-Date: 1586178708 2020/04/06 13:11:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ +/* NetHack 3.7 mondata.h $NHDT-Date: 1596498548 2020/08/03 23:49:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.44 $ */ /* 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 b343791b0..a243dc8a4 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 monflag.h $NHDT-Date: 1590879610 2020/05/30 23:00:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.7 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 722805680..eaecd34a7 100644 --- a/include/monst.h +++ b/include/monst.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 monst.h $NHDT-Date: 1559994623 2019/06/08 11:50:23 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.7 monst.h $NHDT-Date: 1596498550 2020/08/03 23:49:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.42 $ */ /* 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/monsym.h b/include/monsym.h index 68737fd83..e09a0b55d 100644 --- a/include/monsym.h +++ b/include/monsym.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 monsym.h $NHDT-Date: 1547428769 2019/01/14 01:19:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 monsym.h $NHDT-Date: 1596498550 2020/08/03 23:49:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) 2016 by Pasi Kallinen */ /* NetHack may be freely redistributed. See license for details. */ /* Monster symbols and creation information rev 1.0 */ diff --git a/include/mttypriv.h b/include/mttypriv.h index e07813709..5fc90abc4 100644 --- a/include/mttypriv.h +++ b/include/mttypriv.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 mttypriv.h $NHDT-Date: 1432512780 2015/05/25 00:13:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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/include/ntconf.h b/include/ntconf.h index 7b7edb407..5f86971d4 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 ntconf.h $NHDT-Date: 1447424077 2015/11/13 14:14:37 $ $NHDT-Branch: master $:$NHDT-Revision: 1.48 $ */ +/* NetHack 3.7 ntconf.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/obj.h b/include/obj.h index 39f6c67a5..d6577da91 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 obj.h $NHDT-Date: 1596226442 2020/07/31 20:14:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 3.7 obj.h $NHDT-Date: 1596498552 2020/08/03 23:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ /* 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 031d8595e..cdfc9b625 100644 --- a/include/objclass.h +++ b/include/objclass.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 objclass.h $NHDT-Date: 1578895344 2020/01/13 06:02:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 3.7 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/pcconf.h b/include/pcconf.h index 6f1ad2b48..c0c4786a0 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcconf.h $NHDT-Date: 1593953338 2020/07/05 12:48:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 3.7 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 b22269e68..5125f1339 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 permonst.h $NHDT-Date: 1539804913 2018/10/17 19:35:13 $ $NHDT-Branch: keni-makedefsm $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 permonst.h $NHDT-Date: 1596498555 2020/08/03 23:49:15 $ $NHDT-Branch: NetHack-3.7 $:$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/prop.h b/include/prop.h index 570f3f2fa..889ada22f 100644 --- a/include/prop.h +++ b/include/prop.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 prop.h $NHDT-Date: 1570566360 2019/10/08 20:26:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 3.7 prop.h $NHDT-Date: 1596498555 2020/08/03 23:49:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ /* 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 0042de7f0..710af02d9 100644 --- a/include/quest.h +++ b/include/quest.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 quest.h $NHDT-Date: 1432512779 2015/05/25 00:12:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 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 efbf253d5..cd5cb3b63 100644 --- a/include/rect.h +++ b/include/rect.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 rect.h $NHDT-Date: 1432512778 2015/05/25 00:12:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 dd1534fc2..1303c7099 100644 --- a/include/region.h +++ b/include/region.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 region.h $NHDT-Date: 1432512779 2015/05/25 00:12:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.7 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 e5322b2ee..3f06e9d83 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 rm.h $NHDT-Date: 1589064684 2020/05/09 22:51:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 3.7 rm.h $NHDT-Date: 1596498558 2020/08/03 23:49:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ /* 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/skills.h b/include/skills.h index a7cdb5256..1862238c6 100644 --- a/include/skills.h +++ b/include/skills.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 skills.h $NHDT-Date: 1547255911 2019/01/12 01:18:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.7 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/sp_lev.h b/include/sp_lev.h index 4104d51c9..d68250b02 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.h $NHDT-Date: 1580434523 2020/01/31 01:35:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 3.7 sp_lev.h $NHDT-Date: 1596498560 2020/08/03 23:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ /* 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 8bf50715e..479283458 100644 --- a/include/spell.h +++ b/include/spell.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 spell.h $NHDT-Date: 1432512780 2015/05/25 00:13:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 spell.h $NHDT-Date: 1596498560 2020/08/03 23:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright 1986, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/sys.h b/include/sys.h index afb1fc865..ef794e747 100644 --- a/include/sys.h +++ b/include/sys.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 sys.h $NHDT-Date: 1449296291 2015/12/05 06:18:11 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.27 $ */ +/* NetHack 3.7 sys.h $NHDT-Date: 1596498561 2020/08/03 23:49:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.36 $ */ /* Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/system.h b/include/system.h index 3906e68e4..07c639574 100644 --- a/include/system.h +++ b/include/system.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 system.h $NHDT-Date: 1574825213 2019/11/27 03:26:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 3.7 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/include/tcap.h b/include/tcap.h index f3f28a95e..508d9432e 100644 --- a/include/tcap.h +++ b/include/tcap.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 tcap.h $NHDT-Date: 1432512774 2015/05/25 00:12:54 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 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 802cbd853..3ca57315e 100644 --- a/include/tile2x11.h +++ b/include/tile2x11.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 tile2x11.h $NHDT-Date: 1524689515 2018/04/25 20:51:55 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 tile2x11.h $NHDT-Date: 1596498563 2020/08/03 23:49:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* 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 997766434..92f40be9d 100644 --- a/include/tileset.h +++ b/include/tileset.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 tileset.h $NHDT-Date: 1457207052 2016/03/05 19:44:12 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.0 $ */ +/* NetHack 3.7 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 0ac85a3c8..5cad4388a 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.h $NHDT-Date: 1564269131 2019/07/27 23:12:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 timeout.h $NHDT-Date: 1596498564 2020/08/03 23:49:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright 1994, Dean Luick */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/tradstdc.h b/include/tradstdc.h index 12a0d4afe..65fea90b0 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 tradstdc.h $NHDT-Date: 1555361295 2019/04/15 20:48:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.36 $ */ +/* NetHack 3.7 tradstdc.h $NHDT-Date: 1596498565 2020/08/03 23:49:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */ /* 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/trampoli.h b/include/trampoli.h index f6c8cec5a..344dacc93 100644 --- a/include/trampoli.h +++ b/include/trampoli.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 trampoli.h $NHDT-Date: 1433806581 2015/06/08 23:36:21 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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/include/trap.h b/include/trap.h index f422c7764..8d08143b2 100644 --- a/include/trap.h +++ b/include/trap.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 trap.h $NHDT-Date: 1547255912 2019/01/12 01:18:32 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 3.7 trap.h $NHDT-Date: 1596498566 2020/08/03 23:49:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ /* 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 1d3d636b0..abc69ee84 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixconf.h $NHDT-Date: 1555361298 2019/04/15 20:48:18 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.42 $ */ +/* NetHack 3.7 unixconf.h $NHDT-Date: 1596498567 2020/08/03 23:49:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* 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 8b2b0090c..7d1f651b6 100644 --- a/include/vision.h +++ b/include/vision.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 vision.h $NHDT-Date: 1559994624 2019/06/08 11:50:24 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 vision.h $NHDT-Date: 1596498568 2020/08/03 23:49:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* 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 4fc219c2e..4c17d6151 100644 --- a/include/vmsconf.h +++ b/include/vmsconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmsconf.h $NHDT-Date: 1555361299 2019/04/15 20:48:19 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 3.7 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/winGnome.h b/include/winGnome.h index 0c2483a78..93bbbeb13 100644 --- a/include/winGnome.h +++ b/include/winGnome.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winGnome.h $NHDT-Date: 1432512782 2015/05/25 00:13:02 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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/include/winX.h b/include/winX.h index 60c4e8d58..7cf1c2885 100644 --- a/include/winX.h +++ b/include/winX.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winX.h $NHDT-Date: 1457079196 2016/03/04 08:13:16 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 3.7 winX.h $NHDT-Date: 1596498574 2020/08/03 23:49:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ */ /* 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 ccc3c1e16..77932cc67 100644 --- a/include/winami.h +++ b/include/winami.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winami.h $NHDT-Date: 1432512780 2015/05/25 00:13:00 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 9ae069a22..ad7be2083 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wincurs.h */ +/* NetHack 3.7 wincurs.h */ /* Copyright (c) Karl Garrison, 2010. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/include/wingem.h b/include/wingem.h index 8d1edf2be..6a0a517f7 100644 --- a/include/wingem.h +++ b/include/wingem.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wingem.h $NHDT-Date: 1433806582 2015/06/08 23:36:22 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 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/include/winprocs.h b/include/winprocs.h index 6506c9af0..fa6652c05 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winprocs.h $NHDT-Date: 1567213890 2019/08/31 01:11:30 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.50 $ */ +/* NetHack 3.7 winprocs.h $NHDT-Date: 1596498572 2020/08/03 23:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.56 $ */ /* 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 a13fe5226..702d8dece 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintty.h $NHDT-Date: 1594169998 2020/07/08 00:59:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ +/* NetHack 3.7 wintty.h $NHDT-Date: 1596498572 2020/08/03 23:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.44 $ */ /* 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 d85485aeb..534421f2c 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintype.h $NHDT-Date: 1549327486 2019/02/05 00:44:46 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.19 $ */ +/* NetHack 3.7 wintype.h $NHDT-Date: 1596498573 2020/08/03 23:49:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ /* 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 8b9cfa0d3..e05e94ae3 100644 --- a/include/xwindow.h +++ b/include/xwindow.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 xwindow.h $NHDT-Date: 1432512775 2015/05/25 00:12:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 74f8e4ac0..10ee0b815 100644 --- a/include/xwindowp.h +++ b/include/xwindowp.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 xwindowp.h $NHDT-Date: 1432512779 2015/05/25 00:12:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 76aae6a7f..0d1761a19 100644 --- a/include/you.h +++ b/include/you.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 you.h $NHDT-Date: 1596334647 2020/08/02 02:17:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 3.7 you.h $NHDT-Date: 1596498576 2020/08/03 23:49:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.48 $ */ /* 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 c7bce068c..ff26d3e03 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 youprop.h $NHDT-Date: 1579655025 2020/01/22 01:03:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 3.7 youprop.h $NHDT-Date: 1596498577 2020/08/03 23:49:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ /* 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 2d22937a8..eb17b82e0 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 allmain.c $NHDT-Date: 1593953342 2020/07/05 12:49:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.144 $ */ +/* NetHack 3.7 allmain.c $NHDT-Date: 1596498146 2020/08/03 23:42:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.145 $ */ /* 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 c6944aba4..a1792e1f9 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 alloc.c $NHDT-Date: 1454376505 2016/02/02 01:28:25 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.16 $ */ +/* NetHack 3.7 alloc.c $NHDT-Date: 1596498147 2020/08/03 23:42:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.18 $ */ /* 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 c1e31010e..849d11004 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 apply.c $NHDT-Date: 1593614972 2020/07/01 14:49:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.325 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1596498148 2020/08/03 23:42:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ /* 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 bb808e8c6..990be7b43 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 artifact.c $NHDT-Date: 1593611274 2020/07/01 13:47:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.158 $ */ +/* NetHack 3.7 artifact.c $NHDT-Date: 1596498149 2020/08/03 23:42:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ /* 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 eb069a1f0..551992bf7 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 attrib.c $NHDT-Date: 1579655026 2020/01/22 01:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 3.7 attrib.c $NHDT-Date: 1596498149 2020/08/03 23:42:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* 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 9005f3900..7bc78dd07 100644 --- a/src/ball.c +++ b/src/ball.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 ball.c $NHDT-Date: 1573940835 2019/11/16 21:47:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.44 $ */ +/* NetHack 3.7 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 90d29fd60..ca5a818cc 100644 --- a/src/bones.c +++ b/src/bones.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 bones.c $NHDT-Date: 1595006054 2020/07/17 17:14:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ +/* NetHack 3.7 bones.c $NHDT-Date: 1596498151 2020/08/03 23:42:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.103 $ */ /* 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 2dfaa11b9..f27714091 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 botl.c $NHDT-Date: 1585647484 2020/03/31 09:38:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.187 $ */ +/* NetHack 3.7 botl.c $NHDT-Date: 1596498152 2020/08/03 23:42:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ /* 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/cmd.c b/src/cmd.c index 7d51b6e47..c9ee5115b 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1596287474 2020/08/01 13:11:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.420 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1596498153 2020/08/03 23:42:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.421 $ */ /* 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/dbridge.c b/src/dbridge.c index ad2b85db8..fd234e801 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dbridge.c $NHDT-Date: 1503355815 2017/08/21 22:50:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.39 $ */ +/* NetHack 3.7 dbridge.c $NHDT-Date: 1596498153 2020/08/03 23:42:33 $ $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/src/decl.c b/src/decl.c index b57b7ba7f..5d528df33 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 decl.c $NHDT-Date: 1594730611 2020/07/14 12:43:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.215 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1596498154 2020/08/03 23:42:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.216 $ */ /* 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 427adbe23..3fa2ae9ca 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 detect.c $NHDT-Date: 1586815085 2020/04/13 21:58:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ */ +/* NetHack 3.7 detect.c $NHDT-Date: 1596498155 2020/08/03 23:42:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ /* 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 ad565aac7..05369498f 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dig.c $NHDT-Date: 1584350347 2020/03/16 09:19:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 3.7 dig.c $NHDT-Date: 1596498156 2020/08/03 23:42:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */ /* 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 482e9f901..7445486dd 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 display.c $NHDT-Date: 1587248921 2020/04/18 22:28:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.131 $ */ +/* NetHack 3.7 display.c $NHDT-Date: 1596498156 2020/08/03 23:42:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ /* 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 8d4439894..a2bb28bdb 100644 --- a/src/dlb.c +++ b/src/dlb.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dlb.c $NHDT-Date: 1446975464 2015/11/08 09:37:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.7 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 8f13dd2ad..f4415b251 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do.c $NHDT-Date: 1593953347 2020/07/05 12:49:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ */ +/* NetHack 3.7 do.c $NHDT-Date: 1596498158 2020/08/03 23:42:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ */ /* 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 27bf9f0fa..2725f4955 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_name.c $NHDT-Date: 1590904090 2020/05/31 05:48:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1596498162 2020/08/03 23:42:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ /* 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 28be5050a..f3a157c81 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1592951498 2020/06/23 22:31:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.133 $ */ +/* NetHack 3.7 do_wear.c $NHDT-Date: 1596498163 2020/08/03 23:42:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ /* 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 a19167794..44ef538ff 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dog.c $NHDT-Date: 1554580624 2019/04/06 19:57:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.85 $ */ +/* NetHack 3.7 dog.c $NHDT-Date: 1596498159 2020/08/03 23:42:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.103 $ */ /* 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 90faaad60..ad24f9674 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dogmove.c $NHDT-Date: 1557094801 2019/05/05 22:20:01 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 3.7 dogmove.c $NHDT-Date: 1596498159 2020/08/03 23:42:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.91 $ */ /* 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 a0ffff9f4..5564c84c5 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dokick.c $NHDT-Date: 1582155880 2020/02/19 23:44:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.153 $ */ +/* NetHack 3.7 dokick.c $NHDT-Date: 1596498160 2020/08/03 23:42:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.155 $ */ /* 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 f5d93cd37..18e3a77d1 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dothrow.c $NHDT-Date: 1595774758 2020/07/26 14:45:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.187 $ */ +/* NetHack 3.7 dothrow.c $NHDT-Date: 1596498161 2020/08/03 23:42:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */ /* 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 7d9932e19..6ea864b9f 100644 --- a/src/drawing.c +++ b/src/drawing.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 drawing.c $NHDT-Date: 1588778111 2020/05/06 15:15:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 3.7 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 f376e5237..935a32088 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dungeon.c $NHDT-Date: 1580607225 2020/02/02 01:33:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.124 $ */ +/* NetHack 3.7 dungeon.c $NHDT-Date: 1596498164 2020/08/03 23:42:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.133 $ */ /* 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/eat.c b/src/eat.c index de5e698b6..a4a670df1 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 eat.c $NHDT-Date: 1590971980 2020/06/01 00:39:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.230 $ */ +/* NetHack 3.7 eat.c $NHDT-Date: 1596498165 2020/08/03 23:42:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.231 $ */ /* 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 fa6295b8b..b41136009 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 end.c $NHDT-Date: 1596226442 2020/07/31 20:14:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.210 $ */ +/* NetHack 3.7 end.c $NHDT-Date: 1596498166 2020/08/03 23:42:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.211 $ */ /* 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 f78545329..09ddfcc48 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 engrave.c $NHDT-Date: 1589827569 2020/05/18 18:46:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ */ +/* NetHack 3.7 engrave.c $NHDT-Date: 1596498167 2020/08/03 23:42:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ /* 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 f7e426db4..de4404ab4 100644 --- a/src/exper.c +++ b/src/exper.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 exper.c $NHDT-Date: 1562114352 2019/07/03 00:39:12 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.33 $ */ +/* NetHack 3.7 exper.c $NHDT-Date: 1596498167 2020/08/03 23:42:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ /* 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 c44baa261..469eaeff2 100644 --- a/src/explode.c +++ b/src/explode.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 explode.c $NHDT-Date: 1589322381 2020/05/12 22:26:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.7 explode.c $NHDT-Date: 1596498168 2020/08/03 23:42:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ */ /* 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 b3a19504d..4e03acac0 100644 --- a/src/extralev.c +++ b/src/extralev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 extralev.c $NHDT-Date: 1446975468 2015/11/08 09:37:48 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 extralev.c $NHDT-Date: 1596498169 2020/08/03 23:42:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ /* Copyright 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/fountain.c b/src/fountain.c index 14b5a5a9f..f5be392dd 100644 --- a/src/fountain.c +++ b/src/fountain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 fountain.c $NHDT-Date: 1583926845 2020/03/11 11:40:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.7 fountain.c $NHDT-Date: 1596498170 2020/08/03 23:42:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/hack.c b/src/hack.c index 81ed3c38e..583689adf 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hack.c $NHDT-Date: 1585993266 2020/04/04 09:41:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.254 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1596498171 2020/08/03 23:42:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.267 $ */ /* 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 60f1dfd76..3600ec798 100644 --- a/src/hacklib.c +++ b/src/hacklib.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 hacklib.c $NHDT-Date: 1578137629 2020/01/04 11:33:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.80 $ */ +/* NetHack 3.7 hacklib.c $NHDT-Date: 1596498172 2020/08/03 23:42:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* Copyright (c) Robert Patrick Rankin, 1991 */ diff --git a/src/light.c b/src/light.c index bcf797b55..d3fce655e 100644 --- a/src/light.c +++ b/src/light.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 light.c $NHDT-Date: 1559994625 2019/06/08 11:50:25 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 3.7 light.c $NHDT-Date: 1596498173 2020/08/03 23:42:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ /* 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 892bacb1e..ceb430941 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 lock.c $NHDT-Date: 1578297245 2020/01/06 07:54:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ +/* NetHack 3.7 lock.c $NHDT-Date: 1596498173 2020/08/03 23:42:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.99 $ */ /* 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 a6ec5ddc6..423673420 100644 --- a/src/mail.c +++ b/src/mail.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mail.c $NHDT-Date: 1568508711 2019/09/15 00:51:51 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 3.7 mail.c $NHDT-Date: 1596498174 2020/08/03 23:42:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* 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 d09518bb1..3af9524ba 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makemon.c $NHDT-Date: 1594771378 2020/07/15 00:02:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.174 $ */ +/* NetHack 3.7 makemon.c $NHDT-Date: 1596498176 2020/08/03 23:42:56 $ $NHDT-Branch: NetHack-3.7 $:$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/mapglyph.c b/src/mapglyph.c index 91e827e17..291a11f36 100644 --- a/src/mapglyph.c +++ b/src/mapglyph.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mapglyph.c $NHDT-Date: 1587110793 2020/04/17 08:06:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 3.7 mapglyph.c $NHDT-Date: 1596498176 2020/08/03 23:42:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/mcastu.c b/src/mcastu.c index bc1000fbe..e53195f72 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mcastu.c $NHDT-Date: 1590904092 2020/05/31 05:48:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.7 mcastu.c $NHDT-Date: 1596498177 2020/08/03 23:42:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.68 $ */ /* 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/mhitm.c b/src/mhitm.c index 50db4ba43..37cf537eb 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitm.c $NHDT-Date: 1594730614 2020/07/14 12:43:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ +/* NetHack 3.7 mhitm.c $NHDT-Date: 1596498178 2020/08/03 23:42:58 $ $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/mhitu.c b/src/mhitu.c index 3e3953da6..ddfc45453 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mhitu.c $NHDT-Date: 1596046195 2020/07/29 18:09:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ +/* NetHack 3.7 mhitu.c $NHDT-Date: 1596498179 2020/08/03 23:42:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */ /* 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 03706027a..03f0b27c0 100644 --- a/src/minion.c +++ b/src/minion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 minion.c $NHDT-Date: 1583688543 2020/03/08 17:29:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ */ +/* NetHack 3.7 minion.c $NHDT-Date: 1596498180 2020/08/03 23:43:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.55 $ */ /* 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 007262ea0..7f316b8db 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mklev.c $NHDT-Date: 1587291592 2020/04/19 10:19:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.85 $ */ +/* NetHack 3.7 mklev.c $NHDT-Date: 1596498181 2020/08/03 23:43:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ /* 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 d6fa6dc0d..96e97a333 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkmap.c $NHDT-Date: 1432512767 2015/05/25 00:12:47 $ $NHDT-Branch: master $:$NHDT-Revision: 1.16 $ */ +/* NetHack 3.7 mkmap.c $NHDT-Date: 1596498181 2020/08/03 23:43:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ /* 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 014bdd3fd..ae8e7636b 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkmaze.c $NHDT-Date: 1577674536 2019/12/30 02:55:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ +/* NetHack 3.7 mkmaze.c $NHDT-Date: 1596498182 2020/08/03 23:43:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.114 $ */ /* 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 d46ed924c..6c3d8b4a9 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1596162341 2020/07/31 02:25:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */ +/* NetHack 3.7 mkobj.c $NHDT-Date: 1596498183 2020/08/03 23:43:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.186 $ */ /* 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 d41b74b39..7fb8874fe 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkroom.c $NHDT-Date: 1446887530 2015/11/07 09:12:10 $ $NHDT-Branch: master $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.7 mkroom.c $NHDT-Date: 1596498184 2020/08/03 23:43:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ /* 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 eb4badc3e..2a81379e7 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1596283876 2020/08/01 12:11:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.342 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1596498185 2020/08/03 23:43:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.343 $ */ /* 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 4e0ba2d0a..d84ce949a 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1581803740 2020/02/15 21:55:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ +/* NetHack 3.7 mondata.c $NHDT-Date: 1596498186 2020/08/03 23:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ /* 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 fe70cbd69..87af97796 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monmove.c $NHDT-Date: 1594727747 2020/07/14 11:55:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */ +/* NetHack 3.7 monmove.c $NHDT-Date: 1596498186 2020/08/03 23:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */ /* 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 9b8961636..8173aea04 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 monst.c $NHDT-Date: 1587502224 2020/04/21 20:50:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.73 $ */ +/* NetHack 3.7 monst.c $NHDT-Date: 1596498187 2020/08/03 23:43:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ /* 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 13a44ed35..80b995b5d 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mplayer.c $NHDT-Date: 1550524564 2019/02/18 21:16:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 3.7 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 712dbfc01..4bae7d788 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mthrowu.c $NHDT-Date: 1595866809 2020/07/27 16:20:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 3.7 mthrowu.c $NHDT-Date: 1596498189 2020/08/03 23:43:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ /* 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 0bae9b866..424a444c5 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 muse.c $NHDT-Date: 1594630714 2020/07/13 08:58:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */ +/* NetHack 3.7 muse.c $NHDT-Date: 1596498190 2020/08/03 23:43:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ /* 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 86a49b85a..dd84b98c6 100644 --- a/src/music.c +++ b/src/music.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 music.c $NHDT-Date: 1578252632 2020/01/05 19:30:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.7 music.c $NHDT-Date: 1596498191 2020/08/03 23:43:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/o_init.c b/src/o_init.c index 8bce36391..1ea5085c4 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 o_init.c $NHDT-Date: 1545383615 2018/12/21 09:13:35 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.25 $ */ +/* NetHack 3.7 o_init.c $NHDT-Date: 1596498193 2020/08/03 23:43:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.43 $ */ /* 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 771178eed..782e8019f 100644 --- a/src/objects.c +++ b/src/objects.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objects.c $NHDT-Date: 1595627151 2020/07/24 21:45:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ +/* NetHack 3.7 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/pager.c b/src/pager.c index 83856f30c..7a6acebd3 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pager.c $NHDT-Date: 1588778117 2020/05/06 15:15:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1596498194 2020/08/03 23:43:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.189 $ */ /* 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 38ced3f1a..ad6644dfb 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1595787212 2020/07/26 18:13:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ */ +/* NetHack 3.7 pickup.c $NHDT-Date: 1596498195 2020/08/03 23:43:15 $ $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/pline.c b/src/pline.c index 16594654f..cc03ebd44 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pline.c $NHDT-Date: 1549327495 2019/02/05 00:44:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.73 $ */ +/* NetHack 3.7 pline.c $NHDT-Date: 1596498196 2020/08/03 23:43:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.96 $ */ /* 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 b6e22bc7a..fbfe59fd1 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 polyself.c $NHDT-Date: 1594727748 2020/07/14 11:55:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.154 $ */ +/* NetHack 3.7 polyself.c $NHDT-Date: 1596498197 2020/08/03 23:43:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.155 $ */ /* 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 c07d96cab..0785ebb1f 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1581810073 2020/02/15 23:41:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */ +/* NetHack 3.7 potion.c $NHDT-Date: 1596498197 2020/08/03 23:43:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ /* 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 e0f104601..f6ce19b1a 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pray.c $NHDT-Date: 1584872363 2020/03/22 10:19:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */ +/* NetHack 3.7 pray.c $NHDT-Date: 1596498198 2020/08/03 23:43:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.144 $ */ /* 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 1b5bd3824..f73cedbaf 100644 --- a/src/priest.c +++ b/src/priest.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 priest.c $NHDT-Date: 1578895348 2020/01/13 06:02:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ +/* NetHack 3.7 priest.c $NHDT-Date: 1596498199 2020/08/03 23:43:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ /* 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 befe154b2..5ca4ec0d7 100644 --- a/src/quest.c +++ b/src/quest.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 quest.c $NHDT-Date: 1596395887 2020/08/02 19:18:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ */ +/* NetHack 3.7 quest.c $NHDT-Date: 1596498200 2020/08/03 23:43:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/questpgr.c b/src/questpgr.c index 9f21301d2..bfae12d0c 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 questpgr.c $NHDT-Date: 1590314765 2020/05/24 10:06:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ */ +/* NetHack 3.7 questpgr.c $NHDT-Date: 1596498201 2020/08/03 23:43:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ */ /* Copyright 1991, M. Stephenson */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/read.c b/src/read.c index ac022be4c..fb2c1ced1 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 read.c $NHDT-Date: 1596162345 2020/07/31 02:25:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.200 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1596498202 2020/08/03 23:43:22 $ $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/rect.c b/src/rect.c index 9f462fcc6..1ae311898 100644 --- a/src/rect.c +++ b/src/rect.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 rect.c $NHDT-Date: 1432512774 2015/05/25 00:12:54 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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 9dfe9150d..771217bd9 100644 --- a/src/region.c +++ b/src/region.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 region.c $NHDT-Date: 1579655029 2020/01/22 01:03:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ */ +/* NetHack 3.7 region.c $NHDT-Date: 1596498203 2020/08/03 23:43:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */ /* Copyright (c) 1996 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/src/rip.c b/src/rip.c index 6b5fdb097..2996d21a2 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 rip.c $NHDT-Date: 1488788514 2017/03/06 08:21:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 3.7 rip.c $NHDT-Date: 1596498204 2020/08/03 23:43:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ /* 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 2a1e92bcf..6b5d46006 100644 --- a/src/rnd.c +++ b/src/rnd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 rnd.c $NHDT-Date: 1524689470 2018/04/25 20:51:10 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.18 $ */ +/* NetHack 3.7 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 a31700369..98854f3dc 100644 --- a/src/role.c +++ b/src/role.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 role.c $NHDT-Date: 1589326676 2020/05/12 23:37:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.7 role.c $NHDT-Date: 1596498206 2020/08/03 23:43:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ */ /* 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/save.c b/src/save.c index 3e7964cd4..c3864d5b0 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 save.c $NHDT-Date: 1593953359 2020/07/05 12:49:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 3.7 save.c $NHDT-Date: 1596498207 2020/08/03 23:43:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.160 $ */ /* 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/shk.c b/src/shk.c index bd91495d4..2c7852d10 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shk.c $NHDT-Date: 1571436007 2019/10/18 22:00:07 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.171 $ */ +/* NetHack 3.7 shk.c $NHDT-Date: 1596498208 2020/08/03 23:43:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.189 $ */ /* 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 7460eb8ba..fe9a0d989 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shknam.c $NHDT-Date: 1587024023 2020/04/16 08:00:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.54 $ */ +/* NetHack 3.7 shknam.c $NHDT-Date: 1596498209 2020/08/03 23:43:29 $ $NHDT-Branch: NetHack-3.7 $:$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/src/sit.c b/src/sit.c index 8d26e2db8..ee6e9679b 100644 --- a/src/sit.c +++ b/src/sit.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sit.c $NHDT-Date: 1559670609 2019/06/04 17:50:09 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.61 $ */ +/* NetHack 3.7 sit.c $NHDT-Date: 1596498210 2020/08/03 23:43:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ /* 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 41ee7117c..806d25129 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sounds.c $NHDT-Date: 1593651682 2020/07/02 01:01:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ +/* NetHack 3.7 sounds.c $NHDT-Date: 1596498211 2020/08/03 23:43:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ /* 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 b85c4ab75..d49d68579 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sp_lev.c $NHDT-Date: 1585569501 2020/03/30 11:58:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ +/* NetHack 3.7 sp_lev.c $NHDT-Date: 1596498212 2020/08/03 23:43:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ /* 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 b805dffbe..4b509c61c 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 spell.c $NHDT-Date: 1593614134 2020/07/01 14:35:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ */ +/* NetHack 3.7 spell.c $NHDT-Date: 1596498211 2020/08/03 23:43:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ */ /* 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 4d4b2235e..7ce86a9ce 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steal.c $NHDT-Date: 1591196090 2020/06/03 14:54:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 3.7 steal.c $NHDT-Date: 1596498213 2020/08/03 23:43:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.84 $ */ /* 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/symbols.c b/src/symbols.c index f8b0cf457..fccec4576 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 symbols.c $NHDT-Date: 1588776075 2020/05/06 14:41:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 3.7 symbols.c $NHDT-Date: 1596498214 2020/08/03 23:43:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* 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 63a48ab7d..8ef533980 100644 --- a/src/sys.c +++ b/src/sys.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 sys.c $NHDT-Date: 1575665952 2019/12/06 20:59:12 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 3.7 sys.c $NHDT-Date: 1596498215 2020/08/03 23:43:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ */ /* 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 a29808b00..9f291af99 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 teleport.c $NHDT-Date: 1586384219 2020/04/08 22:16:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.122 $ */ +/* NetHack 3.7 teleport.c $NHDT-Date: 1596498216 2020/08/03 23:43:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.126 $ */ /* 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 5dba34046..fb24b87f0 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1596287475 2020/08/01 13:11:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.117 $ */ +/* NetHack 3.7 timeout.c $NHDT-Date: 1596498217 2020/08/03 23:43:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ */ /* 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 da418bf69..284d31ef5 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 topten.c $NHDT-Date: 1593771616 2020/07/03 10:20:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ */ +/* NetHack 3.7 topten.c $NHDT-Date: 1596498218 2020/08/03 23:43:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.73 $ */ /* 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 8ac35c51a..ec6e8f565 100644 --- a/src/track.c +++ b/src/track.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 track.c $NHDT-Date: 1432512769 2015/05/25 00:12:49 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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 72fd27d59..c2e30afd5 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 trap.c $NHDT-Date: 1593768051 2020/07/03 09:20:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.361 $ */ +/* NetHack 3.7 trap.c $NHDT-Date: 1596498220 2020/08/03 23:43:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.362 $ */ /* 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 4b0e9f74a..de375a308 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 u_init.c $NHDT-Date: 1578855627 2020/01/12 19:00:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.7 u_init.c $NHDT-Date: 1596498222 2020/08/03 23:43:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ /* 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 6cef240dc..4a0b6f7e7 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 uhitm.c $NHDT-Date: 1596046196 2020/07/29 18:09:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.239 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1596498221 2020/08/03 23:43:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.240 $ */ /* 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 129177f31..a15e4eff6 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vault.c $NHDT-Date: 1549921171 2019/02/11 21:39:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 3.7 vault.c $NHDT-Date: 1596498223 2020/08/03 23:43:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ /* 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 3d3ae6999..049b92137 100644 --- a/src/version.c +++ b/src/version.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 version.c $NHDT-Date: 1575161965 2019/12/01 00:59:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ */ +/* NetHack 3.7 version.c $NHDT-Date: 1596498224 2020/08/03 23:43:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */ /* 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 2d9f8bd24..45cd1fe9b 100644 --- a/src/vision.c +++ b/src/vision.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vision.c $NHDT-Date: 1448013598 2015/11/20 09:59:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.27 $ */ +/* NetHack 3.7 vision.c $NHDT-Date: 1596498225 2020/08/03 23:43:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ /* 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 faaadc0b9..a785f4fbf 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 weapon.c $NHDT-Date: 1579648295 2020/01/21 23:11:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */ +/* NetHack 3.7 weapon.c $NHDT-Date: 1596498226 2020/08/03 23:43:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ /* 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 8b1350a8e..c441ad6d1 100644 --- a/src/were.c +++ b/src/were.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 were.c $NHDT-Date: 1550524568 2019/02/18 21:16:08 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 3.7 were.c $NHDT-Date: 1596498227 2020/08/03 23:43:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.25 $ */ /* 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 2382a0e3c..5d5b04b94 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wield.c $NHDT-Date: 1586178709 2020/04/06 13:11:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ +/* NetHack 3.7 wield.c $NHDT-Date: 1596498228 2020/08/03 23:43:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* 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 0632a09b3..03bc1e592 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 windows.c $NHDT-Date: 1575245096 2019/12/02 00:04:56 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ */ +/* NetHack 3.7 windows.c $NHDT-Date: 1596498228 2020/08/03 23:43:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.75 $ */ /* 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 a2b5d4f31..a0b267682 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wizard.c $NHDT-Date: 1585361057 2020/03/28 02:04:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ +/* NetHack 3.7 wizard.c $NHDT-Date: 1596498229 2020/08/03 23:43:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.68 $ */ /* 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/worm.c b/src/worm.c index dab10f926..7deb90cb6 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 worm.c $NHDT-Date: 1591178400 2020/06/03 10:00:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ +/* NetHack 3.7 worm.c $NHDT-Date: 1596498230 2020/08/03 23:43:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ /* 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 918a3b143..de97f2b7f 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 worn.c $NHDT-Date: 1550524569 2019/02/18 21:16:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.56 $ */ +/* NetHack 3.7 worn.c $NHDT-Date: 1596498231 2020/08/03 23:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ /* 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 28d916f48..326713886 100644 --- a/src/write.c +++ b/src/write.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 write.c $NHDT-Date: 1573346194 2019/11/10 00:36:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.7 write.c $NHDT-Date: 1596498232 2020/08/03 23:43:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" diff --git a/src/zap.c b/src/zap.c index 50c1e0e32..049090edc 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 zap.c $NHDT-Date: 1595787213 2020/07/26 18:13:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.345 $ */ +/* NetHack 3.7 zap.c $NHDT-Date: 1596498233 2020/08/03 23:43:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.346 $ */ /* 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/Install.dos b/sys/msdos/Install.dos index b3ac0abd7..c70975b5b 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.6 on a DOS system + NetHack 3.7 on a DOS system ====================================================== (or, How to make PC NetHack 3.6) - Last revision: $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ + Last revision: $NHDT-Date: 1596498267 2020/08/03 23:44:27 $ -Credit for a runnable full PC NetHack 3.6 goes to the PC Development team +Credit for a runnable full PC NetHack 3.7 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 57e1f0c93..bd04dc986 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -1,6 +1,6 @@ -# NetHack 3.6 Makefile.GCC $NHDT-Date: 1594155873 2020/07/07 21:04:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ +# NetHack 3.7 Makefile.GCC $NHDT-Date: 1596498268 2020/08/03 23:44:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ # Copyright (c) NetHack PC Development Team 1996-2019. -# PC NetHack 3.6 Makefile for djgpp V2 +# PC NetHack 3.7 Makefile for djgpp V2 # # Gnu gcc compiler for msdos (djgpp) # Requires Gnu Make utility (V3.79.1 or greater) supplied with djgpp diff --git a/sys/msdos/msdos.c b/sys/msdos/msdos.c index c3230140e..0892566b9 100644 --- a/sys/msdos/msdos.c +++ b/sys/msdos/msdos.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 msdos.c $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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 f07acd0c6..224c031d6 100644 --- a/sys/msdos/pckeys.c +++ b/sys/msdos/pckeys.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pckeys.c $NHDT-Date: 1501465420 2017/07/31 01:43:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 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 7df6d9881..b7c7d7e4f 100644 --- a/sys/msdos/pctiles.c +++ b/sys/msdos/pctiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pctiles.c $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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/pctiles.h b/sys/msdos/pctiles.h index e56812371..7fb7f7e3b 100644 --- a/sys/msdos/pctiles.h +++ b/sys/msdos/pctiles.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 pctiles.h $NHDT-Date: 1457207040 2016/03/05 19:44:00 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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 cfe45c1eb..1b21c652f 100644 --- a/sys/msdos/pcvideo.h +++ b/sys/msdos/pcvideo.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcvideo.h $NHDT-Date: 1457207040 2016/03/05 19:44:00 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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 97e023b6e..8907278b2 100644 --- a/sys/msdos/portio.h +++ b/sys/msdos/portio.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 portio.h $NHDT-Date: 1432512791 2015/05/25 00:13:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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/setup.bat b/sys/msdos/setup.bat index 8c16863ae..41e213587 100755 --- a/sys/msdos/setup.bat +++ b/sys/msdos/setup.bat @@ -1,5 +1,5 @@ @echo off -REM NetHack 3.6 setup.bat $NHDT-Date: 1432512792 2015/05/25 00:13:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ +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 Copyright (c) NetHack PC Development Team 1990 - 2019 REM NetHack may be freely redistributed. See license for details. diff --git a/sys/msdos/tile2bin.c b/sys/msdos/tile2bin.c index 5d10248e4..a0b415291 100644 --- a/sys/msdos/tile2bin.c +++ b/sys/msdos/tile2bin.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 tile2bin.c $NHDT-Date: 1457207041 2016/03/05 19:44:01 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 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. */ @@ -191,7 +191,7 @@ char *argv[]; tibheader.compiler = OTHER_COMP; #endif - strncpy(tibheader.ident, "NetHack 3.6 MSDOS Port binary tile file", 80); + strncpy(tibheader.ident, "NetHack 3.7 MSDOS Port binary tile file", 80); strncpy(tibheader.timestamp, asctime(newtime), 24); tibheader.timestamp[25] = '\0'; tibheader.tilecount = tilecount; diff --git a/sys/msdos/vesa.h b/sys/msdos/vesa.h index 1184a42ca..3056b07a0 100644 --- a/sys/msdos/vesa.h +++ b/sys/msdos/vesa.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 vesa.h $NHDT-Date: 1507161296 2017/10/04 23:54:56 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.0 $ */ +/* NetHack 3.7 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/msdos/video.c b/sys/msdos/video.c index 21b400152..0ab576f14 100644 --- a/sys/msdos/video.c +++ b/sys/msdos/video.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 video.c $NHDT-Date: 1554215931 2019/04/02 14:38:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 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 6dd23832b..90c4cc44e 100644 --- a/sys/msdos/vidtxt.c +++ b/sys/msdos/vidtxt.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vidtxt.c $NHDT-Date: 1457207043 2016/03/05 19:44:03 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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 768f8d619..a9962019a 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vidvga.c $NHDT-Date: 1457207044 2016/03/05 19:44:04 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.18 $ */ +/* NetHack 3.7 vidvga.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.25 $ */ /* Copyright (c) NetHack PC Development Team 1995 */ /* NetHack may be freely redistributed. See license for details. */ /* diff --git a/sys/share/Makefile.lib b/sys/share/Makefile.lib index 1774a45ba..8118a1af7 100644 --- a/sys/share/Makefile.lib +++ b/sys/share/Makefile.lib @@ -1,4 +1,4 @@ -# NetHack 3.6 Makefile.lib $NHDT-Date: 1432512788 2015/05/25 00:13:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ +# NetHack 3.7 Makefile.lib $NHDT-Date: 1596498281 2020/08/03 23:44:41 $ $NHDT-Branch: NetHack-3.7 $:$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 cba44b88a..c3ce58ced 100644 --- a/sys/share/cppregex.cpp +++ b/sys/share/cppregex.cpp @@ -1,5 +1,5 @@ -/* NetHack 3.6 cppregex.cpp */ -/* $NHDT-Date: 1524684157 2018/04/25 19:22:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 cppregex.cpp */ +/* $NHDT-Date: 1596498279 2020/08/03 23:44:39 $ $NHDT-Branch: NetHack-3.7 $:$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 8b2c91712..b391c1f07 100644 --- a/sys/share/ioctl.c +++ b/sys/share/ioctl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 ioctl.c $NHDT-Date: 1520099308 2018/03/03 17:48:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.7 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/nhlan.c b/sys/share/nhlan.c index 970c35fbc..f3e75e360 100644 --- a/sys/share/nhlan.c +++ b/sys/share/nhlan.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nhlan.c $NHDT-Date: 1432512786 2015/05/25 00:13:06 $ $NHDT-Branch: master $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 nhlan.c $NHDT-Date: 1596498282 2020/08/03 23:44:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Michael Allison, 1997 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index e73a2427b..704da8d2c 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcmain.c $NHDT-Date: 1593953369 2020/07/05 12:49:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.120 $ */ +/* NetHack 3.7 pcmain.c $NHDT-Date: 1596498282 2020/08/03 23:44:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ /* 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 f191d1f25..0282c7a49 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcsys.c $NHDT-Date: 1593953370 2020/07/05 12:49:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.41 $ */ +/* NetHack 3.7 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 cd7d65588..75e38e9ab 100644 --- a/sys/share/pctty.c +++ b/sys/share/pctty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pctty.c $NHDT-Date: 1432512787 2015/05/25 00:13:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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 8956ba3bc..2ea4e38dd 100644 --- a/sys/share/pcunix.c +++ b/sys/share/pcunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pcunix.c $NHDT-Date: 1432512787 2015/05/25 00:13:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.34 $ */ +/* NetHack 3.7 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 cb3d58455..0d688d330 100644 --- a/sys/share/pmatchregex.c +++ b/sys/share/pmatchregex.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pmatchregex.c $NHDT-Date: 1544482890 2018/12/10 23:01:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.2 $ */ +/* NetHack 3.7 pmatchregex.c $NHDT-Date: 1596498285 2020/08/03 23:44:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ */ /* 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 0b4ba218d..d681a5b9a 100644 --- a/sys/share/posixregex.c +++ b/sys/share/posixregex.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 posixregex.c $NHDT-Date: 1434446947 2015/06/16 09:29:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.5 $ */ +/* NetHack 3.7 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 b47f41815..75ce78151 100644 --- a/sys/share/tclib.c +++ b/sys/share/tclib.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 tclib.c $NHDT-Date: 1432512788 2015/05/25 00:13:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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 3196f3b3d..cc6a088ca 100644 --- a/sys/share/unixtty.c +++ b/sys/share/unixtty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixtty.c $NHDT-Date: 1570652308 2019/10/09 20:18:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.26 $ */ +/* NetHack 3.7 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/Makefile.doc b/sys/unix/Makefile.doc index 35666a5cc..d1c3c1831 100644 --- a/sys/unix/Makefile.doc +++ b/sys/unix/Makefile.doc @@ -1,5 +1,5 @@ # NetHack Documentation Makefile. -# NetHack 3.6 Makefile.doc $NHDT-Date: 1581732920 2020/02/15 02:15:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ +# NetHack 3.7 Makefile.doc $NHDT-Date: 1596498290 2020/08/03 23:44:50 $ $NHDT-Branch: NetHack-3.7 $:$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/Makefile.src b/sys/unix/Makefile.src index 1e0ad2842..278f4bbde 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.6 Makefile.src $NHDT-Date: 1596115531 2020/07/30 13:25:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.105 $ +# NetHack 3.7 Makefile.src $NHDT-Date: 1596498291 2020/08/03 23:44:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 9070d60e8..a9c0f81cb 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -1,5 +1,5 @@ # NetHack Top-level Makefile. -# NetHack 3.6 Makefile.top $NHDT-Date: 1594155882 2020/07/07 21:04:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1596498292 2020/08/03 23:44:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ # 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 987e4d447..2674596f4 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -1,5 +1,5 @@ # Makefile for NetHack's utility programs. -# NetHack 3.6 Makefile.utl $NHDT-Date: 1588776926 2020/05/06 14:55:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ +# NetHack 3.7 Makefile.utl $NHDT-Date: 1596498292 2020/08/03 23:44:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index ee929c347..5d607c4cd 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -45,6 +45,6 @@ If you are using the traditional configuration system, see Install.unx. 5. If it all worked, you're done. If something went wrong, see Install.unx for information about the settings the hints file tried to automate. -# NetHack 3.6 NewInstall.unx $NHDT-Date: 1524689458 2018/04/25 20:50:58 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 NewInstall.unx $NHDT-Date: 1596498295 2020/08/03 23:44:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/gitinfo.sh b/sys/unix/gitinfo.sh index 9ab309f84..d087272a2 100755 --- a/sys/unix/gitinfo.sh +++ b/sys/unix/gitinfo.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 gitinfo.sh $NHDT-Date: 1524689450 2018/04/25 20:50:50 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 gitinfo.sh $NHDT-Date: 1596498289 2020/08/03 23:44:49 $ $NHDT-Branch: NetHack-3.7 $:$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/linux b/sys/unix/hints/linux index 47260f78c..48ab631c1 100644 --- a/sys/unix/hints/linux +++ b/sys/unix/hints/linux @@ -1,5 +1,5 @@ # -# NetHack 3.6 linux $NHDT-Date: 1589828478 2020/05/18 19:01:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ +# NetHack 3.7 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/sys/unix/hints/linux-minimal b/sys/unix/hints/linux-minimal index 0582792d9..003d69fe1 100644 --- a/sys/unix/hints/linux-minimal +++ b/sys/unix/hints/linux-minimal @@ -1,5 +1,5 @@ # -# NetHack 3.6 linux $NHDT-Date: 1589828479 2020/05/18 19:01:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1 $ +# NetHack 3.7 linux $NHDT-Date: 1596498416 2020/08/03 23:46:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) Patric Mueller # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/linux-qt4 b/sys/unix/hints/linux-qt4 index 33abfbc84..3ef04923d 100644 --- a/sys/unix/hints/linux-qt4 +++ b/sys/unix/hints/linux-qt4 @@ -1,5 +1,5 @@ # -# NetHack 3.6 linux-qt4 $NHDT-Date: 1589828479 2020/05/18 19:01:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.28 $ +# NetHack 3.7 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/sys/unix/hints/linux-qt5 b/sys/unix/hints/linux-qt5 index 1ee188568..945384baf 100644 --- a/sys/unix/hints/linux-qt5 +++ b/sys/unix/hints/linux-qt5 @@ -1,5 +1,5 @@ # -# NetHack 3.6 linux-qt5 $NHDT-Date: 1589828480 2020/05/18 19:01:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ +# NetHack 3.7 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/sys/unix/hints/linux-x11 b/sys/unix/hints/linux-x11 index 0f186e3f0..64dc9c235 100644 --- a/sys/unix/hints/linux-x11 +++ b/sys/unix/hints/linux-x11 @@ -1,5 +1,5 @@ # -# NetHack 3.6 linux-x11 $NHDT-Date: 1589828480 2020/05/18 19:01:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.25 $ +# NetHack 3.7 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/sys/unix/hints/macosx b/sys/unix/hints/macosx index 573473249..c74742396 100644 --- a/sys/unix/hints/macosx +++ b/sys/unix/hints/macosx @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx $NHDT-Date: 1566346603 2019/08/21 00:16:43 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.20 $ +# NetHack 3.7 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/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index c6cf10c31..fe096410b 100755 --- a/sys/unix/hints/macosx.sh +++ b/sys/unix/hints/macosx.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 macosx.sh $NHDT-Date: 1517231957 2018/01/29 13:19:17 $ $NHDT-Branch: githash $:$NHDT-Revision: 1.20 $ +# NetHack 3.7 macosx.sh $NHDT-Date: 1596498420 2020/08/03 23:47:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/macosx10.10 b/sys/unix/hints/macosx10.10 index f4c2989f0..262a8af33 100644 --- a/sys/unix/hints/macosx10.10 +++ b/sys/unix/hints/macosx10.10 @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.11 $NHDT-Date: 1596231041 2020/07/31 21:30:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.57 $ +# NetHack 3.7 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/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index 25466cf4c..f23452672 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.10-qt $NHDT-Date: 1596231050 2020/07/31 21:30:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.61 $ +# NetHack 3.7 macosx10.10-qt $NHDT-Date: 1596498421 2020/08/03 23:47:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/hints/macosx10.14 b/sys/unix/hints/macosx10.14 index e43b5f19d..79454a7ae 100644 --- a/sys/unix/hints/macosx10.14 +++ b/sys/unix/hints/macosx10.14 @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.14 $NHDT-Date: 1573841535 2019/11/15 18:12:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.60 $ +# NetHack 3.7 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/sys/unix/hints/macosx10.5 b/sys/unix/hints/macosx10.5 index 3cbe335be..b4a5def41 100644 --- a/sys/unix/hints/macosx10.5 +++ b/sys/unix/hints/macosx10.5 @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.5 $NHDT-Date: 1566346606 2019/08/21 00:16:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.32 $ +# NetHack 3.7 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/sys/unix/hints/macosx10.7 b/sys/unix/hints/macosx10.7 index 4937c64dc..e307e0ec8 100644 --- a/sys/unix/hints/macosx10.7 +++ b/sys/unix/hints/macosx10.7 @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.7 $NHDT-Date: 1566346606 2019/08/21 00:16:46 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.36 $ +# NetHack 3.7 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/sys/unix/hints/macosx10.8 b/sys/unix/hints/macosx10.8 index a6e9c4d3c..0961bb198 100644 --- a/sys/unix/hints/macosx10.8 +++ b/sys/unix/hints/macosx10.8 @@ -1,5 +1,5 @@ # -# NetHack 3.6 macosx10.8 $NHDT-Date: 1566346607 2019/08/21 00:16:47 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.38 $ +# NetHack 3.7 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/sys/unix/hints/solaris b/sys/unix/hints/solaris index 2140330dd..9d02d4bd3 100644 --- a/sys/unix/hints/solaris +++ b/sys/unix/hints/solaris @@ -1,5 +1,5 @@ # -# NetHack 3.6 unix $NHDT-Date: 1554411633 2019/04/04 21:00:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.0 $ +# NetHack 3.7 unix $NHDT-Date: 1596498426 2020/08/03 23:47:06 $ $NHDT-Branch: NetHack-3.7 $:$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 5e51df6f2..b44bccf27 100644 --- a/sys/unix/hints/solaris-playground +++ b/sys/unix/hints/solaris-playground @@ -1,5 +1,5 @@ # -# NetHack 3.6 unix $NHDT-Date: 1554411633 2019/04/04 21:00:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.0 $ +# NetHack 3.7 unix $NHDT-Date: 1596498427 2020/08/03 23:47:07 $ $NHDT-Branch: NetHack-3.7 $:$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 bd2ef8684..b761757ea 100644 --- a/sys/unix/hints/unix +++ b/sys/unix/hints/unix @@ -1,5 +1,5 @@ # -# NetHack 3.6 unix $NHDT-Date: 1432512813 2015/05/25 00:13:33 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ +# NetHack 3.7 unix $NHDT-Date: 1596498428 2020/08/03 23:47:08 $ $NHDT-Branch: NetHack-3.7 $:$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 4c003d639..478aa70cc 100755 --- a/sys/unix/mkmkfile.sh +++ b/sys/unix/mkmkfile.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 mkmkfile.sh $NHDT-Date: 1432512788 2015/05/25 00:13:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $ +# NetHack 3.7 mkmkfile.sh $NHDT-Date: 1596498293 2020/08/03 23:44:53 $ $NHDT-Branch: NetHack-3.7 $:$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/nethack.sh b/sys/unix/nethack.sh index 2c2b62cdf..9ce743494 100755 --- a/sys/unix/nethack.sh +++ b/sys/unix/nethack.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 nethack.sh $NHDT-Date: 1552425075 2019/03/12 21:11:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.20 $ +# NetHack 3.7 nethack.sh $NHDT-Date: 1596498294 2020/08/03 23:44:54 $ $NHDT-Branch: NetHack-3.7 $:$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 043bf90d4..69595fd00 100755 --- a/sys/unix/setup.sh +++ b/sys/unix/setup.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.6 setup.sh $NHDT-Date: 1432512789 2015/05/25 00:13:09 $ $NHDT-Branch: master $:$NHDT-Revision: 1.14 $ +# NetHack 3.7 setup.sh $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$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 71e786f43..c62852522 100644 --- a/sys/unix/sysconf +++ b/sys/unix/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.6 sysconf $NHDT-Date: 1589575728 2020/05/15 20:48:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ +# NetHack 3.7 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. # diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 59f8d9edf..87e255064 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixmain.c $NHDT-Date: 1589326677 2020/05/12 23:37:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ +/* NetHack 3.7 unixmain.c $NHDT-Date: 1596498297 2020/08/03 23:44:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ /* 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 cd0954a1f..f44cd2cc5 100644 --- a/sys/unix/unixres.c +++ b/sys/unix/unixres.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixres.c $NHDT-Date: 1432512788 2015/05/25 00:13:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 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 546c9a185..9364200f5 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 unixunix.c $NHDT-Date: 1432512788 2015/05/25 00:13:08 $ $NHDT-Branch: master $:$NHDT-Revision: 1.22 $ */ +/* NetHack 3.7 unixunix.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-3.7 $:$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/sys/vms/Makefile.dat b/sys/vms/Makefile.dat index 11e7e41c6..efe363297 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.6 Makefile.dat $NHDT-Date: 1542388601 2018/11/16 17:16:41 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.10 $ +# NetHack 3.7 Makefile.dat $NHDT-Date: 1596498300 2020/08/03 23:45:00 $ $NHDT-Branch: NetHack-3.7 $:$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 624f5ea0a..d728620d4 100644 --- a/sys/vms/Makefile.doc +++ b/sys/vms/Makefile.doc @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for the [Unix] documentation. -# NetHack 3.6 Makefile.doc $NHDT-Date: 1524689428 2018/04/25 20:50:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.9 $ +# NetHack 3.7 Makefile.doc $NHDT-Date: 1596498301 2020/08/03 23:45:01 $ $NHDT-Branch: NetHack-3.7 $:$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 7fb33e2b7..9149a985f 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for building nethack itself. -# NetHack 3.6 Makefile.src $NHDT-Date: 1594155889 2020/07/07 21:04:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.50 $ +# NetHack 3.7 Makefile.src $NHDT-Date: 1596498302 2020/08/03 23:45:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ # 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 2bdb2c951..c12946959 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.6 Makefile.top $NHDT-Date: 1524689428 2018/04/25 20:50:28 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1596498303 2020/08/03 23:45:03 $ $NHDT-Branch: NetHack-3.7 $:$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 713a37995..651223aa1 100644 --- a/sys/vms/Makefile.utl +++ b/sys/vms/Makefile.utl @@ -1,5 +1,5 @@ # NetHack Makefile (VMS) - for utility programs. -# NetHack 3.6 Makefile.utl $NHDT-Date: 1542388602 2018/11/16 17:16:42 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.16 $ +# NetHack 3.7 Makefile.utl $NHDT-Date: 1596498303 2020/08/03 23:45:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ # Copyright (c) 2011 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. diff --git a/sys/vms/lev_lex.h b/sys/vms/lev_lex.h index 31a923f42..2198df851 100644 --- a/sys/vms/lev_lex.h +++ b/sys/vms/lev_lex.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 lev_lex.h $NHDT-Date: 1432512790 2015/05/25 00:13:10 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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/sys/vms/oldcrtl.c b/sys/vms/oldcrtl.c index 40a30127b..43bbd815a 100644 --- a/sys/vms/oldcrtl.c +++ b/sys/vms/oldcrtl.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 oldcrtl.c $NHDT-Date: 1432512789 2015/05/25 00:13:09 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */ +/* NetHack 3.7 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/sysconf b/sys/vms/sysconf index b4ffd357b..16ce0c684 100644 --- a/sys/vms/sysconf +++ b/sys/vms/sysconf @@ -1,4 +1,4 @@ -# NetHack 3.6 sysconf $NHDT-Date: 1524689429 2018/04/25 20:50:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 sysconf $NHDT-Date: 1596498305 2020/08/03 23:45:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.4 $ # Copyright (c) 2015 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. # diff --git a/sys/vms/vmsfiles.c b/sys/vms/vmsfiles.c index 89e6aff4a..02602d147 100644 --- a/sys/vms/vmsfiles.c +++ b/sys/vms/vmsfiles.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmsfiles.c $NHDT-Date: 1449801740 2015/12/11 02:42:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 vmsfiles.c $NHDT-Date: 1596498306 2020/08/03 23:45:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* 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 989775687..4e2eaf06f 100644 --- a/sys/vms/vmsmail.c +++ b/sys/vms/vmsmail.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmsmail.c $NHDT-Date: 1449801741 2015/12/11 02:42:21 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 vmsmail.c $NHDT-Date: 1596498307 2020/08/03 23:45:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ /* 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 f4631557c..18657be9f 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmsmain.c $NHDT-Date: 1449801742 2015/12/11 02:42:22 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.7 vmsmain.c $NHDT-Date: 1596498307 2020/08/03 23:45:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ /* 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 8cb266cc7..6da4ed3f5 100644 --- a/sys/vms/vmsmisc.c +++ b/sys/vms/vmsmisc.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmsmisc.c $NHDT-Date: 1524689429 2018/04/25 20:50:29 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 vmsmisc.c $NHDT-Date: 1596498308 2020/08/03 23:45:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.12 $ */ /* 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 a04928839..e26e7db8d 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmstty.c $NHDT-Date: 1449801743 2015/12/11 02:42:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 3.7 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 2eec83b01..e6f2fca07 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 vmsunix.c $NHDT-Date: 1449801743 2015/12/11 02:42:23 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.7 vmsunix.c $NHDT-Date: 1596498310 2020/08/03 23:45:10 $ $NHDT-Branch: NetHack-3.7 $:$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/sys/winnt/.nethackrc.template b/sys/winnt/.nethackrc.template index b2bacbd7f..053e48358 100644 --- a/sys/winnt/.nethackrc.template +++ b/sys/winnt/.nethackrc.template @@ -1,4 +1,4 @@ -# NetHack 3.6 defaults.nh $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.32 $ +# NetHack 3.7 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/winnt/console.rc b/sys/winnt/console.rc index 427079ede..c2019cd7c 100644 --- a/sys/winnt/console.rc +++ b/sys/winnt/console.rc @@ -1,4 +1,4 @@ -/* NetHack 3.6 console.rc $NHDT-Date: 1575245149 2019/12/02 00:05:49 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.7 console.rc $NHDT-Date: 1596498311 2020/08/03 23:45:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Yitzhak Sapir, 2002. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/nh340key.c b/sys/winnt/nh340key.c index a4faa80c1..348bd89e8 100644 --- a/sys/winnt/nh340key.c +++ b/sys/winnt/nh340key.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nh340key.c $NHDT-Date: 1432512793 2015/05/25 00:13:13 $ $NHDT-Branch: master $:$NHDT-Revision: 1.12 $ */ +/* NetHack 3.7 nh340key.c $NHDT-Date: 1596498312 2020/08/03 23:45:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) NetHack PC Development Team 2003 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/nhdefkey.c b/sys/winnt/nhdefkey.c index acbb75990..32b7c95dd 100644 --- a/sys/winnt/nhdefkey.c +++ b/sys/winnt/nhdefkey.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nhdefkey.c $NHDT-Date: 1432512793 2015/05/25 00:13:13 $ $NHDT-Branch: master $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.7 nhdefkey.c $NHDT-Date: 1596498313 2020/08/03 23:45:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ */ /* Copyright (c) NetHack PC Development Team 2003 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/nhraykey.c b/sys/winnt/nhraykey.c index 7ce4e0e50..5bd9e3ead 100644 --- a/sys/winnt/nhraykey.c +++ b/sys/winnt/nhraykey.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nhraykey.c $NHDT-Date: 1457207047 2016/03/05 19:44:07 $ $NHDT-Branch: chasonr $:$NHDT-Revision: 1.16 $ */ +/* NetHack 3.7 nhraykey.c $NHDT-Date: 1596498314 2020/08/03 23:45:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) NetHack PC Development Team 2003 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/nhsetup.bat b/sys/winnt/nhsetup.bat index 25ac9fee7..7f65ac88f 100755 --- a/sys/winnt/nhsetup.bat +++ b/sys/winnt/nhsetup.bat @@ -1,4 +1,4 @@ -@REM NetHack 3.6 nhsetup.bat $NHDT-Date: 1554784485 2019/04/09 04:34:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.37 $ */ +@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 Copyright (c) NetHack PC Development Team 1993-2019 @REM NetHack may be freely redistributed. See license for details. @REM Win32 setup batch file, see Install.nt for details diff --git a/sys/winnt/ntsound.c b/sys/winnt/ntsound.c index c8ec07450..69450b748 100644 --- a/sys/winnt/ntsound.c +++ b/sys/winnt/ntsound.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 ntsound.c $NHDT-Date: 1432512794 2015/05/25 00:13:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 ntsound.c $NHDT-Date: 1596498316 2020/08/03 23:45:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.13 $ */ /* Copyright (c) NetHack PC Development Team 1993 */ /* NetHack may be freely redistributed. See license for details. */ /* */ diff --git a/sys/winnt/nttty.c b/sys/winnt/nttty.c index 6b1a7ea64..c1f1a0f70 100644 --- a/sys/winnt/nttty.c +++ b/sys/winnt/nttty.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 nttty.c $NHDT-Date: 1554215932 2019/04/02 14:38:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.99 $ */ +/* NetHack 3.7 nttty.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/winnt/stubs.c b/sys/winnt/stubs.c index 805298305..7e7fe01f6 100644 --- a/sys/winnt/stubs.c +++ b/sys/winnt/stubs.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 stubs.c $NHDT-Date: 1524689357 2018/04/25 20:49:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 3.7 stubs.c $NHDT-Date: 1596498317 2020/08/03 23:45:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ /* Copyright (c) 2015 by Michael Allison */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/win10.c b/sys/winnt/win10.c index 9791bbec6..80542574e 100644 --- a/sys/winnt/win10.c +++ b/sys/winnt/win10.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 win10.c $NHDT-Date: 1432512810 2015/05/25 00:13:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.7 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/winnt/win10.h b/sys/winnt/win10.h index 517843b87..fd9c9a895 100644 --- a/sys/winnt/win10.h +++ b/sys/winnt/win10.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 win10.h $NHDT-Date: 1432512810 2015/05/25 00:13:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.7 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/winnt/win32api.h b/sys/winnt/win32api.h index 469b8dc96..3d59fa30c 100644 --- a/sys/winnt/win32api.h +++ b/sys/winnt/win32api.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 win32api.h $NHDT-Date: 1432516197 2015/05/25 01:09:57 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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/winnt/windmain.c b/sys/winnt/windmain.c index 357c8e38b..a18999a78 100644 --- a/sys/winnt/windmain.c +++ b/sys/winnt/windmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 windmain.c $NHDT-Date: 1543465755 2018/11/29 04:29:15 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 3.7 windmain.c $NHDT-Date: 1596498320 2020/08/03 23:45:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.157 $ */ /* Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index bd0d2cf48..cc314ef07 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 winnt.c $NHDT-Date: 1524321419 2018/04/21 14:36:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 3.7 winnt.c $NHDT-Date: 1596498321 2020/08/03 23:45:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.64 $ */ /* Copyright (c) NetHack PC Development Team 1993, 1994 */ /* NetHack may be freely redistributed. See license for details. */ diff --git a/sys/winnt/winos.h b/sys/winnt/winos.h index 39a4b408e..55300bda0 100644 --- a/sys/winnt/winos.h +++ b/sys/winnt/winos.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 winos.h $NHDT-Date: 1524321419 2018/04/21 14:36:59 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.30 $ */ +/* NetHack 3.7 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/dlb_main.c b/util/dlb_main.c index 120de616c..2a32124dc 100644 --- a/util/dlb_main.c +++ b/util/dlb_main.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 dlb_main.c $NHDT-Date: 1570258542 2019/10/05 06:55:42 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.13 $ */ +/* NetHack 3.7 dlb_main.c $NHDT-Date: 1596498258 2020/08/03 23:44:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* 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 f113b0ae9..8b5179c1b 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makedefs.c $NHDT-Date: 1595627153 2020/07/24 21:45:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */ +/* NetHack 3.7 makedefs.c $NHDT-Date: 1596498258 2020/08/03 23:44:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.184 $ */ /* 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 382da338c..dfdd9790f 100644 --- a/util/mdgrep.h +++ b/util/mdgrep.h @@ -1,5 +1,5 @@ /* - * NetHack 3.6 mdgrep.h $NHDT-Date: 1432512785 2015/05/25 00:13:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ + * NetHack 3.7 mdgrep.h $NHDT-Date: 1596498259 2020/08/03 23:44:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ * Copyright (c) Kenneth Lorber, Kensington, Maryland, 2008 * NetHack may be freely redistributed. See license for details. * diff --git a/util/mdgrep.pl b/util/mdgrep.pl index 8a4cd8d36..72eb7b567 100644 --- a/util/mdgrep.pl +++ b/util/mdgrep.pl @@ -1,5 +1,5 @@ #!perl -# NetHack 3.6 mdgrep.pl $NHDT-Date: 1593953364 2020/07/05 12:49:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.19 $ +# NetHack 3.7 mdgrep.pl $NHDT-Date: 1596498260 2020/08/03 23:44:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.20 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -54,17 +54,17 @@ $outfile = "mdgrep.h"; sub start_file { - ($rev) = ('$NHDT-Revision: 1.19 $') =~ m/: (.*) .$/; - my $date = '$NHDT-Date: 1593953366 2020/07/05 12:49:26 $'; + ($rev) = ('$NHDT-Revision: 1.20 $') =~ m/: (.*) .$/; + my $date = '$NHDT-Date: 1596498261 2020/08/03 23:44:21 $'; my $branch = '$NHDT-Branch: NetHack-3.7 $'; - my $revision = '$NHDT-Revision: 1.19 $'; + my $revision = '$NHDT-Revision: 1.20 $'; open(OUT, ">$outfile") || die "open $outfile: $!"; # NB: Date and Revision below will be modified when mdgrep.h is written to # git - this is correct (but it means you must commit changes to mdgrep.pl # before generating mdgrep.h and committing that file). print OUT < Date: Mon, 3 Aug 2020 22:41:35 -0400 Subject: [PATCH 071/708] more file header "NetHack 3.6" to "NetHack 3.7" --- doc/Guidebook.tex | 2 +- sys/msdos/Install.dos | 4 ++-- sys/msdos/msdoshlp.txt | 2 +- sys/winnt/porthelp | 6 +++--- win/win32/vs2017/NetHackPackage.appxmanifest | 6 +++--- win/win32/vs2017/Package.StoreAssociation.xml | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index a2c542bd9..47b79d3c4 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1,5 +1,5 @@ \documentstyle[titlepage,longtable]{article} -% NetHack 3.6 Guidebook.tex $NHDT-Date: 1431192762 2015/12/16 17:32:42 $ $NHDT-Branch: master $:$NHDT-Revision: 1.60 $ */ +% NetHack 3.7 Guidebook.tex $NHDT-Date: 1431192762 2015/12/16 17:32:42 $ $NHDT-Branch: master $:$NHDT-Revision: 1.60 $ */ %+% we're still limping along in LaTeX 2.09 compatibility mode %-%\documentclass{article} %-%\usepackage{hyperref} % before longtable diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index c70975b5b..ba96764a0 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -5,8 +5,8 @@ Instructions for compiling and installing NetHack 3.7 on a DOS system ====================================================== - (or, How to make PC NetHack 3.6) - Last revision: $NHDT-Date: 1596498267 2020/08/03 23:44:27 $ + (or, How to make PC NetHack 3.7) + Last revision: $NHDT-Date: 1596508786 2020/08/04 02:39:46 $ Credit for a runnable full PC NetHack 3.7 goes to the PC Development team of Paul Winner, Kevin Smolkowski, Michael Allison, Yitzhak Sapir, Bill Dyer, diff --git a/sys/msdos/msdoshlp.txt b/sys/msdos/msdoshlp.txt index cad9a17fb..441f3bb61 100644 --- a/sys/msdos/msdoshlp.txt +++ b/sys/msdos/msdoshlp.txt @@ -1,4 +1,4 @@ - MSDOS specific help file for NetHack 3.6 + MSDOS specific help file for NetHack 3.7 (Last Revision: December 4, 1999) Copyright (c) NetHack PC Development Team 1993-1999. diff --git a/sys/winnt/porthelp b/sys/winnt/porthelp index 3f553739e..a251e14b5 100644 --- a/sys/winnt/porthelp +++ b/sys/winnt/porthelp @@ -1,7 +1,7 @@ - Microsoft Windows specific help file for NetHack 3.6 - Copyright (c) NetHack PC Development Team 1993-2002. + Microsoft Windows specific help file for NetHack 3.7 + Copyright (c) NetHack PC Development Team 1993-2020. NetHack may be freely distributed. See license for details. - (Last Revision: March 16, 2003) + (Last Revision: August 8, 2020) This file details specifics for NetHack built for Windows 95, 98, NT, Me, 2000, and XP. Users of really early 16-bit Windows versions should diff --git a/win/win32/vs2017/NetHackPackage.appxmanifest b/win/win32/vs2017/NetHackPackage.appxmanifest index 12b8d3ad1..54140a413 100644 --- a/win/win32/vs2017/NetHackPackage.appxmanifest +++ b/win/win32/vs2017/NetHackPackage.appxmanifest @@ -2,7 +2,7 @@ - NetHack 3.6 + NetHack 3.7 NetHack DevTeam Images\StoreLogo.png @@ -15,7 +15,7 @@ - + @@ -26,4 +26,4 @@ - \ No newline at end of file + diff --git a/win/win32/vs2017/Package.StoreAssociation.xml b/win/win32/vs2017/Package.StoreAssociation.xml index 1200895f3..24422d2fd 100644 --- a/win/win32/vs2017/Package.StoreAssociation.xml +++ b/win/win32/vs2017/Package.StoreAssociation.xml @@ -363,11 +363,11 @@ 30485NetHackDevTeam.NetHack3.6 - NetHack 3.6 + NetHack 3.7 30485NetHackDevTeam.NetHackBeta - \ No newline at end of file + From ac8bc414bca0f43d3122499cfee8e20362625806 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Mon, 3 Aug 2020 22:24:08 -0400 Subject: [PATCH 072/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Files b/Files index 48c7a040b..499a00381 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 3.6 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. From ef5aeba16748e262aa92c9e4cdb625d6c24e3fc5 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 4 Aug 2020 12:00:17 -0700 Subject: [PATCH 073/708] interface feedback by #version When there was only one supported interface included in the program, feedback of |Supported windowing system: |"tty" (traditional text with optional line-drawing) was missing the intended final period. When there were more than one, the clause describing the default could be preceded by a spurious space. |Supported windowing systems: |"tty" (traditional text with optional line-drawing) and "Qt" , with a |default of "tty". There was a fixup for " , " but it only worked as intended when that was on the last line, not when the default's text spanned lines. This adds description of "Windows GUI" to the mswin entry. X11 could have its formal name "The X Windows System" as the description but I didn't add that since it just seems like extra verbosity. Apparently Qt doesn't stand for anything else so still has no extra description. --- src/mdlib.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index d42ee02b8..59b94b459 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mdlib.c $NHDT-Date: 1593953352 2020/07/05 12:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ */ +/* NetHack 3.7 mdlib.c $NHDT-Date: 1596567095 2020/08/04 18:51:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -63,7 +63,9 @@ static char *FDECL(bannerc_string, (char *, const char *)); static int FDECL(case_insensitive_comp, (const char *, const char *)); static void NDECL(make_version); static char *FDECL(eos, (char *)); +#if 0 static char *FDECL(mdlib_strsubst, (char *, const char *, const char *)); +#endif #endif /* MAKEDEFS_C || FOR_RUNTIME */ #if !defined(MAKEDEFS_C) && defined(WIN32) extern int GUILaunched; @@ -118,6 +120,11 @@ static struct win_info window_opts[] = { #ifdef QT_GRAPHICS /* too vague; there are multiple incompatible versions */ { "Qt", "Qt", TRUE }, #endif +#ifdef MSWIN_GRAPHICS /* win32 */ + { "mswin", "Windows GUI", TRUE }, +#endif + +#if 0 /* remainder have been retired */ #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ { "Gnome", "Gnome", TRUE }, #endif @@ -130,12 +137,10 @@ static struct win_info window_opts[] = { #ifdef GEM_GRAPHICS /* defunct Atari interface */ { "Gem", "Gem", TRUE }, #endif -#ifdef MSWIN_GRAPHICS /* win32 */ - { "mswin", "mswin", TRUE }, -#endif #ifdef BEOS_GRAPHICS /* unmaintained/defunct */ { "BeOS", "BeOS InterfaceKit", TRUE }, #endif +#endif /* 0 => retired */ { 0, 0, FALSE } }; @@ -345,6 +350,7 @@ char *str; return str; } +#if 0 static char * mdlib_strsubst(bp, orig, replacement) char *bp; @@ -363,6 +369,7 @@ const char *orig, *replacement; } return bp; } +#endif static char save_bones_compat_buf[BUFSZ]; @@ -615,8 +622,7 @@ int *length_p; /* in/out */ } else { Sprintf(eos(optbuf), " "), (*length_p)++; } - Sprintf(eos(optbuf), - "%s", str), *length_p += (int) strlen(str); + Sprintf(eos(optbuf), "%s", str), *length_p += (int) strlen(str); str += strlen(str) + (word ? 1 : 0); } } @@ -694,23 +700,24 @@ build_options() Sprintf(eos(buf), " (%s)", window_opts[i].name); /* * 1 : foo. - * 2 : foo and bar (note no period; comes from 'with default' below) - * 3+: for, bar, and quux + * 2 : foo and bar, + * 3+: for, bar, and quux, + * + * 2+ will be followed by " with a default of..." */ - if (cnt != (winsyscnt - 1)) { - Strcat(buf, (winsyscnt == 1) ? "." /* no 'default' */ - : (winsyscnt == 2 && cnt == 0) ? " and" - : (cnt == winsyscnt - 2) ? ", and" - : ","); - } + Strcat(buf, (winsyscnt == 1) ? "." /* no 'default' */ + : (winsyscnt == 2 && cnt == 0) ? " and" + : (cnt == winsyscnt - 2) ? ", and" + : ","); opt_out_words(buf, &length); cnt++; } if (cnt > 1) { - Sprintf(buf, ", with a default of \"%s\".", defwinsys); + /* loop ended with a comma; opt_out_words() will insert a space */ + Sprintf(buf, "with a default of \"%s\".", defwinsys); opt_out_words(buf, &length); } - (void) mdlib_strsubst(optbuf, " , ", ", "); + opttext[idxopttext] = strdup(optbuf); if (idxopttext < (MAXOPT - 1)) idxopttext++; From 5bd3c15ebc8b8d255c148486c64fa9142e067673 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 4 Aug 2020 16:07:04 -0400 Subject: [PATCH 074/708] macOS.2020 tweak Eliminate the use of WINLIB0 and the use of sort for clearing of duplicate strings within it. --- sys/unix/hints/macOS.2020 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index dd0ffd5ee..e02026563 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -19,7 +19,7 @@ # One possible way: brew install xquartz # # - You'll need to obtain and install Qt if you want Qt support -# One possible way: Brew install Qt +# One possible way: brew install Qt # # - You'll need to obtain and install the ncurses development libraries # if you want curses window port support. @@ -187,15 +187,14 @@ endif # WANT_WIN_CHAIN WINSRC = WINOBJ0 = WINLIB = -WINLIB0 = VARDATND = VARDATND0 = -WINCURSESLIB=-lncurses +WINCURSESLIB = ifdef WANT_WIN_TTY WINSRC += $(WINTTYSRC) WINOBJ0 += $(WINTTYOBJ) -WINLIB0 += $(WINCURSESLIB) +WINCURSESLIB = -lncurses else # !WANT_WIN_TTY CFLAGS += -DNOTTYGRAPHICS endif # !WANT_WIN_TTY @@ -204,11 +203,12 @@ ifdef WANT_WIN_CURSES CFLAGS += -DCURSES_GRAPHICS WINSRC += $(WINCURSESSRC) WINOBJ0 += $(WINCURSESOBJ) -WINLIB0 += $(WINCURSESLIB) +WINCURSESLIB = -lncurses endif -# prevent duplicates in WINLIB from WINLIB0 -WINLIB += $(sort $(WINLIB0)) +ifdef WINCURSESLIB +WINLIB += $(WINCURSESLIB) +endif ifdef WANT_WIN_X11 USE_XPM=1 From e426f99d259fb439212af236a923779ba56041e0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 5 Aug 2020 08:49:58 -0400 Subject: [PATCH 075/708] Use the more detailed version info on Qt --- win/Qt/qt_main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index faf32e265..7662639ef 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -470,7 +470,7 @@ aboutMsg() #else 5, // Qt version macro should exist; if not, assume Qt5 #endif - version_string(vbuf), /* nethack version */ + getversionstring(vbuf), /* nethack version */ #ifdef QT_VERSION_STR " with Qt " QT_VERSION_STR, #else From b8b4fc70daa261b0fb1bf65818997e1cf0be1f8e Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 5 Aug 2020 10:55:10 -0700 Subject: [PATCH 076/708] more Qt "about nethack" The presence of longer lines has made the 'about' box become wider so combine the first two short lines into one longer one. Switching to the longer nethack version string resulted in "This is NetHack MacOSX Nethack ..." so remove the initial "NetHack" from the 'about' box's format string. That version string also includes a final period; strip that off since "with Qt 5.x.y." follows it to end the sentence. Still some issues: The application menu has first entry "nethack" which ought to be capitalized but I haven't been able to figure out how to accomplish that. Some code in qt_main.cpp tries to add an extra instance of "about NetHack" to the game window's "Help" menu but it doesn't show up. --- win/Qt/qt_main.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 7662639ef..ce0954d2e 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -439,18 +439,23 @@ static const char * cast_c_xpm[] UNUSED = { static QString aboutMsg() { - char vbuf[BUFSZ]; + char *p, vbuf[BUFSZ]; + /* nethack's getversionstring() includes a final period + but we're using it mid-sentence so strip period off */ + if ((p = strrchr(getversionstring(vbuf), '.')) != 0 && *(p + 1) == '\0') + *p = '\0'; QString msg; msg.sprintf( // format - "Qt NetHack is a version of NetHack\n" - "built using" // no newline + "Qt NetHack is a version of NetHack built using" // no newline #ifdef KDE - " KDE and" // ditto + " KDE and" // ditto #endif - " the Qt %d GUI toolkit.\n" - "\nThis is NetHack %s%s.\n" - "\nNetHack's Qt interface originally developed by Warwick Allison.\n" + " the Qt %d GUI toolkit.\n" // short Qt version + "\n" + "This is %s%s.\n" // long nethack version and full Qt version + "\n" + "NetHack's Qt interface originally developed by Warwick Allison.\n" "\n" #if 0 "Homepage:\n http://trolls.troll.no/warwick/nethack/\n" //obsolete @@ -463,14 +468,14 @@ aboutMsg() #else "Qt:\n http://www.troll.no/\n" // obsolete #endif - "NetHack:\n %s\n", + "NetHack:\n %s\n", // DEVTEAM_URL // arguments #ifdef QT_VERSION_MAJOR QT_VERSION_MAJOR, #else 5, // Qt version macro should exist; if not, assume Qt5 #endif - getversionstring(vbuf), /* nethack version */ + vbuf, // nethack version #ifdef QT_VERSION_STR " with Qt " QT_VERSION_STR, #else From be3edcd097986d560ea2ba2aaabaa66b4169fe31 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 5 Aug 2020 11:10:57 -0700 Subject: [PATCH 077/708] some qt_main.cpp formatting cleanup --- win/Qt/qt_main.cpp | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index ce0954d2e..241c7a801 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -827,7 +827,8 @@ public: const QMimeSource* data(const QString& abs_name) const { const QMimeSource* r = 0; - if ( (NetHackMimeSourceFactory*)this == Q3MimeSourceFactory::defaultFactory() ) + if ( (NetHackMimeSourceFactory *) this + == Q3MimeSourceFactory::defaultFactory() ) r = Q3MimeSourceFactory::data(abs_name); else r = Q3MimeSourceFactory::defaultFactory()->data(abs_name); @@ -1006,51 +1007,59 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) const char* d = g.Cmd.dirchars; switch (event->key()) { - case Qt::Key_Up: + case Qt::Key_Up: if ( dirkey == d[0] ) dirkey = d[1]; else if ( dirkey == d[4] ) dirkey = d[3]; else dirkey = d[2]; - break; case Qt::Key_Down: + break; + case Qt::Key_Down: if ( dirkey == d[0] ) dirkey = d[7]; else if ( dirkey == d[4] ) dirkey = d[5]; else dirkey = d[6]; - break; case Qt::Key_Left: + break; + case Qt::Key_Left: if ( dirkey == d[2] ) dirkey = d[1]; else if ( dirkey == d[6] ) dirkey = d[7]; else dirkey = d[0]; - break; case Qt::Key_Right: + break; + case Qt::Key_Right: if ( dirkey == d[2] ) dirkey = d[3]; else if ( dirkey == d[6] ) dirkey = d[5]; else dirkey = d[4]; - break; case Qt::Key_PageUp: + break; + case Qt::Key_PageUp: dirkey = 0; if (message) message->Scroll(0,-1); - break; case Qt::Key_PageDown: + break; + case Qt::Key_PageDown: dirkey = 0; if (message) message->Scroll(0,+1); - break; case Qt::Key_Space: + break; + case Qt::Key_Space: if ( flags.rest_on_space ) { event->ignore(); return; } - case Qt::Key_Enter: + case Qt::Key_Enter: if ( map ) map->clickCursor(); - break; default: + break; + default: dirkey = 0; event->ignore(); + break; } } @@ -1080,8 +1089,10 @@ void NetHackQtMainWindow::closeEvent(QCloseEvent* e) void NetHackQtMainWindow::ShowIfReady() { if (message && map && status) { - QWidget* hp = qt_compact_mode ? static_cast(stack) : static_cast(hsplitter); - QWidget* vp = qt_compact_mode ? static_cast(stack) : static_cast(vsplitter); + QWidget* hp = qt_compact_mode ? static_cast(stack) + : static_cast(hsplitter); + QWidget* vp = qt_compact_mode ? static_cast(stack) + : static_cast(vsplitter); message->Widget()->setParent(hp); map->Widget()->setParent(vp); status->Widget()->setParent(hp); From f4cee951ca5e5cd00d66595b9cda7b28a79f2bb1 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 5 Aug 2020 11:26:25 -0700 Subject: [PATCH 078/708] ^X on MacOSX Qt Add Michael's fix for control+x. The enum name of the argument suggests that option+x should have been sending control characters but that wasn't the case for me. Before this fix, both control+x and option+x behaved like dead keys, not transmitting anything for nethack to use. After this fix, control+x sends ^X as desired but option+x is still dead. --- doc/fixes37.0 | 3 ++- win/Qt/qt_main.cpp | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 1c6f4e479..7dcf64596 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ $NHDT-Date: 1596494524 2020/08/03 22:42:04 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.272 $ $NHDT-Date: 1596651973 2020/08/05 18:26:13 $ General Fixes and Modified Features ----------------------------------- @@ -350,6 +350,7 @@ Qt: switch to fixed-width font for menus Qt: don't disable [cancel] button when viewing inventory or other pick-none menus; ESC works to dismiss those and [cancel] should be the same Qt: bring status conditions up to 3.6 levels but new ones lack pictures +Qt: fix control key on OSX tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 241c7a801..4968fc7bf 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -520,6 +520,11 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : QCoreApplication::setOrganizationName("The NetHack DevTeam"); QCoreApplication::setOrganizationDomain("nethack.org"); QCoreApplication::setApplicationName("NetHack"); +#ifdef MACOSX + /* without this, neither control+x nor option+x do anything; + with it, control+x is ^X and option+x still does nothing */ + QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); +#endif setWindowTitle("Qt NetHack"); if ( qt_compact_mode ) From addebf7090e53bb661263f2cd11a6766c99e505c Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 5 Aug 2020 11:34:56 -0700 Subject: [PATCH 079/708] Qt "close window" debacle on OSX Prevent an infinite loop that occurred if player clicked on the close window button and then tried to cancel out of that in the dialog it brings up. I don't know whether Qt interface on platforms other than OSX need this but they're getting it. The choices are changed from "Save" or "Cancel" to "Save and exit" or "Quit without saving". Since save allows subsequent restore, not being able to cancel out of the application shutdown should only be an inconvenience. Unresolved issues: I don't know whether there's any other way to bring up that dialog, where Cancel might be a viable choice. If so, handling that might be tricky. Quit should definitely be available as an alterative to Save, but that type of dialog doesn't seem to allow more than two choices. Picking "nethack" from application menu and then "quit nethack" from the resulting pull down menu results in executing nethack's help command (the '?' menu) and then just resumes play. --- doc/fixes37.0 | 7 ++++++- win/Qt/qt_main.cpp | 40 ++++++++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 7dcf64596..970889489 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.272 $ $NHDT-Date: 1596651973 2020/08/05 18:26:13 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.273 $ $NHDT-Date: 1596652492 2020/08/05 18:34:52 $ General Fixes and Modified Features ----------------------------------- @@ -351,6 +351,11 @@ Qt: don't disable [cancel] button when viewing inventory or other pick-none menus; ESC works to dismiss those and [cancel] should be the same Qt: bring status conditions up to 3.6 levels but new ones lack pictures Qt: fix control key on OSX +Qt: clicking on the window's Close button brought up a dialog offering + choices of "Save" and "Cancel"; picking Cancel sent nethack into an + infinite loop with complaints about Qt's event loop already being + active; change dialog: offer "Save and exit" or "Quit without saving" + with no opportunity to try to back out of the Close operation tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 4968fc7bf..975917e4d 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1071,21 +1071,33 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) void NetHackQtMainWindow::closeEvent(QCloseEvent* e) { if ( g.program_state.something_worth_saving ) { - switch ( QMessageBox::information( this, "NetHack", - "This will end your NetHack session", - "&Save", "&Cancel", 0, 1 ) ) - { - case 0: - // See dosave() function - if (dosave0()) { - u.uhp = -1; - NetHackQtBind::qt_exit_nhwindows(0); - nh_terminate(EXIT_SUCCESS); - } - break; - case 1: - break; // ignore the event + int ok = 0; + /* this used to offer "Save" and "Cancel" + but cancel (ignoring the close attempt) won't work + if user has clicked on the window's Close button */ + int act = QMessageBox::information(this, "NetHack", + "This will end your NetHack session", + "&Save and exit", "&Quit without saving", 0, 1); + switch (act) { + case 0: + // See dosave() function + ok = dosave0(); + break; + case 1: + // quit -- bypass the prompting preformed by done2() + ok = 1; + g.program_state.stopprint++; + done(QUIT); + /*NOTREACHED*/ + break; + case 2: + // cancel -- no longer an alternative + break; // ignore the event } + /* if !ok, we should try to continue, but we don't... */ + u.uhp = -1; + NetHackQtBind::qt_exit_nhwindows(0); + nh_terminate(EXIT_SUCCESS); } else { e->accept(); } From 318a56669d6bbbe32d81be1a1c80ace9ea33fff3 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 5 Aug 2020 12:48:12 -0700 Subject: [PATCH 080/708] augment Qt Info menu Add ^X (as "Attributes (extended status)") to the "Info" drop down menu, also Overview, and Annotate. Attributes and Overview work, Annotate results in running southeast. Existing entries Conduct, Adjust, and Skills execute nethack's '?' command so I didn't bother holding back on adding Annotate. Other existing entries (Inventory, Discoveries, Spells, and Name) work. If there's any sort of pattern involved, I'm not seeing it. The Game menu has "Save", which shows up and works, but that's supposed to be followed by "Quit" which doesn't show up when the menu is used. This doesn't attempt to deal with that. Command+q keystroke, which should close the application, behaves the same as previously mentioned "quit nethack" in nethack menu: runs nethack's '?' command and then resumes play. --- doc/fixes37.0 | 4 +++- win/Qt/qt_main.cpp | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 970889489..d23b99349 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.273 $ $NHDT-Date: 1596652492 2020/08/05 18:34:52 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.274 $ $NHDT-Date: 1596656886 2020/08/05 19:48:06 $ General Fixes and Modified Features ----------------------------------- @@ -356,6 +356,8 @@ Qt: clicking on the window's Close button brought up a dialog offering infinite loop with complaints about Qt's event loop already being active; change dialog: offer "Save and exit" or "Quit without saving" with no opportunity to try to back out of the Close operation +Qt: add 3.6 status fields Stone, Slime, Strngl, Deaf, Lev, Fly, Ride +Qt: add Attributes, Overview, and Annotate to the "Info" pull down menu tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 975917e4d..0f6870b9d 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -631,12 +631,15 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { help, 0, 1}, { info, "Inventory", 3, ddoinv}, + { info, "Attributes (extended status)", 3, doattributes }, + { info, "Overview", 3, dooverview }, { info, "Conduct", 3, doconduct}, { info, "Discoveries", 3, dodiscovered}, { info, "List/reorder spells", 3, dovspell}, - { info, "Adjust letters", 2, doorganize}, + { info, "Adjust inventory letters", 2, doorganize }, { info, 0, 3}, { info, "Name object or creature", 3, docallcmd}, + { info, "Annotate level", 2, donamelevel }, { info, 0, 3}, { info, "Skills", 3, enhance_weapon_skill}, From 2392832f22dee46b773fc37a87c1f5bec0e5d019 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 6 Aug 2020 15:57:05 -0700 Subject: [PATCH 081/708] END-CHOOSE directive for .nethackrc Add an optional way to terminate the last section after a CHOOSE directive in the run-time options file so that it's possible to revert to common options. If no END-CHOOSE directive is present then the last CHOOSE section continues until the end of the file. (All existing uses of CHOOSE already behave that way.) Change the Guidebook to refer to OPTIONS=x, AUTOPICKUP_EXCEPTION=y, CHOOSE=z, and so on as "directives" rather than "statements". It just feels like a better fit. --- doc/Guidebook.mn | 37 +++++++++++++-------- doc/Guidebook.tex | 34 ++++++++++++------- doc/fixes37.0 | 7 +++- src/files.c | 85 ++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 122 insertions(+), 41 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 713d2cbaf..dfa15732b 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.393 $ $NHDT-Date: 1595731545 2020/07/26 02:45:45 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.394 $ $NHDT-Date: 1596754607 2020/08/06 22:56:47 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "July 25, 2020 +.ds f2 "August 5, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -3138,16 +3138,16 @@ Any line beginning with \(oq[\(cq and ending in \(oq]\(cq is considered a section marker. The text between the square brackets is the section name. Lines after a section marker belong to that section, and are -ignored unless a CHOOSE statement was used to select that section. +ignored unless a CHOOSE directive was used to select that section. Section names are case insensitive. .pg -You can use different configuration statements in the file, some +You can use different configuration directives in the file, some of which can be used multiple times. -In general, the statements are +In general, the directives are written in capital letters, followed by an equals sign, followed by -settings particular to that statement. +settings particular to that directive. .pg -Here is a list of allowed statements: +Here is a list of allowed directives: .lp OPTIONS There are two types of options, boolean and compound options. Boolean options toggle a setting on or off, while compound options @@ -3155,8 +3155,8 @@ take more diverse values. Prefix a boolean option with \(lqno\(rq or \(oq!\(cq 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 statements, and multiple options -separated by commas in a single OPTIONS statement. +You can specify multiple OPTIONS directives, and multiple options +separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) .lp "" Example: @@ -3220,7 +3220,8 @@ Example: .ed .lp CHOOSE Chooses at random one of the comma-separated parameters as an active -section name. Lines in other sections are ignored. +section name. +Lines in other sections are ignored. .lp "" Example: .sd @@ -3231,8 +3232,18 @@ CHOOSE=char A,char B OPTIONS=role:arc,race:dwa,align:law,gender:fem [char B] OPTIONS=role:wiz,race:elf,align:cha,gender:mal +END-CHOOSE +OPTIONS=!rest_on_space .ft \" revert to previous font .ed +.lp END-CHOOSE +An optional way to terminate CHOOSE. +.\" use of the \% prefix prevents END-CHOOSE from being hyphenated across +.\" line boundary despite its hyphen; needed for the plain text output to +.\" avoid splitting the directive name +You can place an \%END-CHOOSE directive after the last CHOOSE section in +order to follow that with other options which are common to all sections. +Otherwise the last section extends to the end of the options file. .lp MENUCOLOR Highlight menu lines with different colors. See the \(lqConfiguring Menu Colors\(rq section. @@ -3342,10 +3353,10 @@ to that shell), or the pair of commands in \fIsh\fP, \fIksh\fP, or \fIbash\fP. .pg The NETHACKOPTIONS value is effectively the same as a single OPTIONS -statement in a configuration file. +directive in a configuration file. The \(lqOPTIONS=\(rq prefix is implied and comma separated options are processed from right to left. -Other types of configuration statements such as BIND or MSGTYPE are +Other types of configuration directives such as BIND or MSGTYPE are not allowed. .pg Instead of a comma-separated list of options, @@ -4338,7 +4349,7 @@ May be used to alter the value of keystrokes that the operating system returns to NetHack to help compensate 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 statements in the configuration file +You can use multiple subkeyvalue assignments in the configuration file if needed. Cannot be set with the \(oqO\(cq command. .lp video diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 47b79d3c4..14c3cd843 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{July 25, 2020} +\date{August 5, 2020} \maketitle @@ -3359,18 +3359,18 @@ Any line in the configuration file starting with `{\tt \#}' is treated as a comm Empty lines are ignored. Any line beginning with `{\tt [}' and ending in `{\tt ]}' is considered a section marker. The text between the square brackets is the section name. Lines after a section marker belong to that section, and are -ignored unless a CHOOSE -statement was used to select that section. +ignored unless a CHOOSE -directive was used to select that section. Section names are case insensitive. %.pg -You can use different configuration statements in the file, some +You can use different configuration directives in the file, some of which can be used multiple times. -In general, the statements are +In general, the directives are written in capital letters, followed by an equals sign, followed by -settings particular to that statement. +settings particular to that directive. %.pg -Here is a list of allowed statements: +Here is a list of allowed directives: %.lp \blist{} @@ -3381,8 +3381,8 @@ 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 statements, and multiple options -separated by commas in a single OPTIONS statement. +You can specify multiple OPTIONS directives, and multiple options +separated by commas in a single OPTIONS directive. (Comma separated options are processed from right to left.) %.lp "" @@ -3461,7 +3461,8 @@ Example: %.lp \item[\bb{CHOOSE}] Chooses at random one of the comma-separated parameters as an active -section name. Lines in other sections are ignored. +section name. +Lines in other sections are ignored. %.lp "" Example: @@ -3473,9 +3474,18 @@ Example: OPTIONS=role:arc,race:dwa,align:law,gender:fem [char B] OPTIONS=role:wiz,race:elf,align:cha,gender:mal + END-CHOOSE + OPTIONS=!rest_on_space \end{verbatim} %.ed +%.lp +\item[\bb{END-CHOOSE}] +An optional way to terminate CHOOSE. +You can place an END-CHOOSE directive after the last CHOOSE section in +order to follow that with other options which are common to all sections. +Otherwise the last section extends to the end of the options file. + %.lp \item[\bb{MENUCOLOR}] Highlight menu lines with different colors. @@ -3592,10 +3602,10 @@ to that shell), or the pair of commands %.pg The NETHACKOPTIONS value is effectively the same as a single OPTIONS -statement in a configuration file. +directive in a configuration file. The ``OPTIONS='' prefix is implied and comma separated options are processed from right to left. -Other types of configuration statements such as BIND or MSGTYPE are +Other types of configuration directives such as BIND or MSGTYPE are not allowed. %.pg @@ -4745,7 +4755,7 @@ returns to {\it NetHack\/} to help compensate for international keyboard issues. OPTIONS=subkeyvalue:171/92 will return 92 to {\it NetHack\/}, if 171 was originally going to be returned. -You can use multiple subkeyvalue statements in the configuration file +You can use multiple subkeyvalue assignments in the configuration file if needed. Cannot be set with the `{\tt O}' command. %.lp diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d23b99349..35fb1fec0 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.274 $ $NHDT-Date: 1596656886 2020/08/05 19:48:06 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.275 $ $NHDT-Date: 1596754606 2020/08/06 22:56:46 $ General Fixes and Modified Features ----------------------------------- @@ -459,6 +459,11 @@ add 'Sokoban' conduct, tracking the number of times the special Sokoban rules reduce verbosity when a mind flayer attacks a headless monster; when a tentacle-to-head attack hits but fails to accomplish anything skip remaining attacks (mind flayer has 3, master mind flayer has 5) +add END-CHOOSE directive for run-time config file; CHOOSE section1,section2 + followed by [section1] ... [section2] ... forced all the rest of the + file to be part of the last section; that still works the same but + END-CHOOSE can be used to terminate the last section and revert to + common options for the remainder of the file Platform- and/or Interface-Specific New Features diff --git a/src/files.c b/src/files.c index 690f88580..b79c2a913 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 files.c $NHDT-Date: 1595006057 2020/07/17 17:14:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.316 $ */ +/* NetHack 3.7 files.c $NHDT-Date: 1596754598 2020/08/06 22:56:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.317 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -163,7 +163,8 @@ static void FDECL(adjust_prefix, (char *, int)); static boolean FDECL(config_error_nextline, (const char *)); static void NDECL(free_config_sections); static char *FDECL(choose_random_part, (char *, CHAR_P)); -static boolean FDECL(is_config_section, (const char *)); +static char *FDECL(is_config_section, (char *)); +static boolean FDECL(is_end_of_sections, (const char *)); static boolean FDECL(handle_config_section, (char *)); static char *FDECL(find_optparam, (const char *)); static void FDECL(parseformat, (int *, char *)); @@ -2258,7 +2259,7 @@ int prefixid; /* Choose at random one of the sep separated parts from str. Mangles str. */ static char * -choose_random_part(str,sep) +choose_random_part(str, sep) char *str; char sep; { @@ -2310,29 +2311,78 @@ free_config_sections() } } -static boolean +/* check for " [ anything-except-bracket-or-empty ] # arbitrary-comment" + with spaces optional; returns pointer to "anything-except..." (with + trailing " ] #..." stripped) if ok, otherwise Null */ +static char * is_config_section(str) -const char *str; +char *str; /* trailing spaces will be stripped, ']' too iff result is good */ { - const char *a = rindex(str, ']'); + char *a, *c, *z; - return (a && *str == '[' && *(a+1) == '\0' && (int)(a - str) > 0); + /* remove any spaces at start and end; won't significantly interfere + with echoing the string in a config error message, if warranted */ + a = trimspaces(str); + /* first character should be open square bracket; set pointer past it */ + if (*a++ != '[') + return (char *) 0; + /* last character should be close bracket, ignoring any comment */ + z = index(a, ']'); + if (!z || z == a) + return (char *) 0; + for (c = z + 1; *c && *c != '#'; ++c) + continue; + if (*c && *c != '#') + return (char *) 0; + /* we now know that result is good; there won't be a config error + message so we can modify the input string */ + *z = '\0'; + /* 'a' points past '[' and the string ends where ']' was; remove any + spaces between '[' and choice-start and between choice-end and ']' */ + return trimspaces(a); +} + +static boolean +is_end_of_sections(buf) +const char *buf; +{ + /* "END-CHOOSE"; bypass match_optname()/match_varname(); + accepts "ENDCHOOSE", "END CHOOSE", "END-CHOOSE", "END_CHOOSE" */ + if (!strncmpi(buf, "END", 3) && buf[3]) { + boolean sep = index(" -_", buf[3]) != 0; + + if (!strcmpi(&buf[sep ? 4 : 3], "CHOOSE")) { + if (!g.config_section_current) + config_error_add("END-CHOOSE when not in a CHOOSE section"); + return TRUE; + } + } + return FALSE; } static boolean handle_config_section(buf) char *buf; { - if (is_config_section(buf)) { - char *send; - if (g.config_section_current) { + boolean was_in_section = (g.config_section_current != 0); + char *sect = is_config_section(buf); + + if (sect) { + if (g.config_section_current) free(g.config_section_current); + /* is_config_section() removed brackets from 'sect' */ + if (!g.config_section_chosen) { + config_error_add("Section \"[%s]\" without CHOOSE", sect); + return TRUE; } - g.config_section_current = dupstr(&buf[1]); - send = rindex(g.config_section_current, ']'); - *send = '\0'; + g.config_section_current = dupstr(sect); debugpline1("set config section: '%s'", g.config_section_current); return TRUE; + } else if (is_end_of_sections(buf)) { + if (was_in_section) + debugpline0("unset config section"); + free_config_sections(); + return TRUE; } if (g.config_section_current) { @@ -2386,6 +2436,12 @@ char *origbuf; but spaces, one of them will be kept even though it leads/trails) */ mungspaces(buf); + /* "END-CHOOSE" doesn't have a value so we need to check for it + before checking for that; if found here, is_end_of_sections() + will report a config_error */ + if (is_end_of_sections(buf)) + return FALSE; + /* find the '=' or ':' */ bufp = find_optparam(buf); if (!bufp) { @@ -2670,8 +2726,7 @@ char *origbuf; retval = FALSE; #endif } else if (match_varname(buf, "WARNINGS", 5)) { - (void) get_uchars(bufp, translate, FALSE, WARNCOUNT, - "WARNINGS"); + (void) get_uchars(bufp, translate, FALSE, WARNCOUNT, "WARNINGS"); assign_warnings(translate); } else if (match_varname(buf, "ROGUESYMBOLS", 4)) { if (!parsesymbols(bufp, ROGUESET)) { From daf6294ad7341cb849d3c5709f7b5ce3c4ede455 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 6 Aug 2020 22:18:11 -0400 Subject: [PATCH 082/708] from cron-daily --- Files | 2 +- doc/Guidebook.txt | 2712 +++++++++++++++++++++++---------------------- 2 files changed, 1390 insertions(+), 1324 deletions(-) diff --git a/Files b/Files index 499a00381..48c7a040b 100644 --- a/Files +++ b/Files @@ -1,4 +1,4 @@ -This is a listing of all files in a full NetHack 3.6 distribution, organized +This is a listing of all files in a full NetHack 3.7 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. diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index f81e2b7bb..4f352bf4d 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - July 25, 2020 + August 5, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -786,7 +786,7 @@ Di - examine your inventory before dropping anything. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -984,7 +984,7 @@ hand and it will generally be less effective than when shot. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1050,7 +1050,7 @@ from normal play to "explore mode", also known as "discovery - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1182,7 +1182,7 @@ not have a name, only other stacks with no name are - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1248,7 +1248,7 @@ Dip an object into something. Autocompletes. Default key - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1314,7 +1314,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1380,7 +1380,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1446,7 +1446,7 @@ it. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1512,7 +1512,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1578,7 +1578,7 @@ Show bare map without displaying monsters, objects, or - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1644,7 +1644,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1710,7 +1710,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1776,7 +1776,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1842,7 +1842,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1908,7 +1908,7 @@ attempt is made to open (when unlocked) or unlock (when locked) - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -1974,7 +1974,7 @@ send you to a different level but behave differently. Some - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2040,7 +2040,7 @@ scribed below). Monsters are only active on the current level; - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2106,7 +2106,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2172,7 +2172,7 @@ on the map. Setting this option to true will describe such - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2238,7 +2238,7 @@ when angered. Remember: discretion is the better part of valor. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2304,7 +2304,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2370,7 +2370,7 @@ pends on your strength and your constitution. The stronger and - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2436,7 +2436,7 @@ as uncursed. They could just as easily have been described as - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2502,7 +2502,7 @@ encumbrance, and proficiency (see below). The monster's armor - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2568,7 +2568,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2634,7 +2634,7 @@ boost your training towards the next skill level (unless you've - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2700,7 +2700,7 @@ protection in NetHack. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2766,7 +2766,7 @@ protected. Food stored in ice boxes or tins ("cans") will - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2832,7 +2832,7 @@ is the bane of the undead, so potions of holy water are good - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2898,7 +2898,7 @@ ing a ring and then re-wear them after. That's done implicitly - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -2964,7 +2964,7 @@ mand casts a spell. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3030,7 +3030,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3096,7 +3096,7 @@ map. That remains the case even if it is not actually there any - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3162,7 +3162,7 @@ and candy bars), and lumps of royal jelly. Monks are expected to - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3228,7 +3228,7 @@ The identity of scrolls and spellbooks (and knowledge of spells) - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3294,7 +3294,7 @@ - Attained rank title . - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3360,7 +3360,7 @@ abled by setting the correspondingly named option in - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3418,15 +3418,15 @@ Any line beginning with `[' and ending in `]' is considered a section marker. The text between the square brackets is the section name. Lines after a section marker belong to that sec- - tion, and are ignored unless a CHOOSE statement was used to se- + tion, and are ignored unless a CHOOSE directive was used to se- lect that section. Section names are case insensitive. - You can use different configuration statements in the file, - some of which can be used multiple times. In general, the state- - ments are written in capital letters, followed by an equals sign, + You can use different configuration directives in the file, + some of which can be used multiple times. In general, the direc- + tives are written in capital letters, followed by an equals sign, - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3436,9 +3436,9 @@ - followed by settings particular to that statement. + followed by settings particular to that directive. - Here is a list of allowed statements: + Here is a list of allowed directives: OPTIONS There are two types of options, boolean and compound options. @@ -3447,8 +3447,8 @@ "no" or `!' to turn it off. For compound options, the option name and value are separated by a colon. Some options are per- sistent, and apply only to new games. You can specify multiple - OPTIONS statements, and multiple options separated by commas in - a single OPTIONS statement. (Comma separated options are pro- + OPTIONS directives, and multiple options separated by commas in + a single OPTIONS directive. (Comma separated options are pro- cessed from right to left.) Example: @@ -3492,7 +3492,7 @@ - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3522,7 +3522,7 @@ CHOOSE Chooses at random one of the comma-separated parameters as an - active section name. Lines in other sections are ignored. + active section name. Lines in other sections are ignored. Example: @@ -3532,6 +3532,15 @@ OPTIONS=role:arc,race:dwa,align:law,gender:fem [char B] OPTIONS=role:wiz,race:elf,align:cha,gender:mal + END-CHOOSE + OPTIONS=!rest_on_space + + END-CHOOSE + An optional way to terminate CHOOSE. You can place an + END-CHOOSE directive after the last CHOOSE section in order to + follow that with other options which are common to all sec- + tions. Otherwise the last section extends to the end of the + options file. MENUCOLOR Highlight menu lines with different colors. See the "Configur- @@ -3546,19 +3555,10 @@ BOLS below. SOUND - Define a sound mapping. See the "Configuring User Sounds" sec- - tion. - - SOUNDDIR - Define the directory that contains the sound files. See the - "Configuring 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 + Define a sound mapping. See the "Configuring User Sounds" - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3568,6 +3568,15 @@ + section. + + SOUNDDIR + Define the directory that contains the sound files. See the + "Configuring 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 NetHack Symbols" section. Example: @@ -3612,19 +3621,10 @@ 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" be- - fore 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 ter- - minated 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 fruit is set to "lime", you would enter the command + option to the list, and turn it off by typing a `!' or "no" - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3634,6 +3634,15 @@ + 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 ter- + minated 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 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 @@ -3645,9 +3654,9 @@ in sh, ksh, or bash. The NETHACKOPTIONS value is effectively the same as a single - OPTIONS statement in a configuration file. The "OPTIONS=" prefix + 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 statements such as BIND or + to left. Other types of configuration directives such as BIND or MSGTYPE are not allowed. Instead of a comma-separated list of options, NETHACKOPTIONS @@ -3680,17 +3689,8 @@ ment from being picked randomly. Cannot be set with the `O' command. Persistent. - autodescribe - Automatically describe the terrain under cursor when asked to - get a location on the map (default true). The whatis_coord op- - tion controls 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 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3700,6 +3700,15 @@ + autodescribe + Automatically describe the terrain under cursor when asked to + get a location on the map (default true). The whatis_coord op- + tion controls 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. + autoopen Walking into a closed door attempts to open it (default true). Persistent. @@ -3745,18 +3754,9 @@ Synonym for "role" to pick the type of your character (for ex- ample "character:Monk"). See role for more details. - checkpoint - Save game state after each level change, for possible recovery - after program crash (default on). Persistent. - - clicklook - Allows looking at things on the screen by navigating the mouse - over them and clicking the right mouse button (default off). - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3766,6 +3766,14 @@ + checkpoint + Save game state after each level change, for possible recovery + after program crash (default on). Persistent. + + clicklook + Allows looking at things on the screen by navigating the mouse + over them and clicking the right mouse button (default off). + cmdassist Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default @@ -3812,17 +3820,9 @@ answering `y' rather than `a', will default to showing monsters in the traditional order, from high level to low level. - Omitted categories are implicitly added with `n' prefix. Spec- - ified 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 inven- - tory to prompt and default to yes, attributes to prompt and de- - fault to no, vanquished to disclose without prompting, - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3832,11 +3832,18 @@ - genocided to not disclose and not prompt, conduct to implicitly - prompt and default to no, and overview to disclose without - prompting. + Omitted categories are implicitly added with `n' prefix. Spec- + ified 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. - Note that the vanquished monsters list includes all monsters + (for example "disclose:yi na +v -g o") The example sets inven- + tory to prompt and default to yes, attributes to prompt and de- + fault to no, vanquished to disclose without prompting, genocid- + ed 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 by traps and each other as well as by you. And the dun- geon overview shows all levels you had visited but does not re- veal things about them that you hadn't discovered. @@ -3846,49 +3853,42 @@ set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of + Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit + tional 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 avail- - able commands (on) or just the subset of commands which have + able commands (on) or just the subset of commands which have traditionally been considered extended ones (off). female - An obsolete synonym for "gender:female". Cannot be set with + An obsolete synonym for "gender:female". Cannot be set with the `O' command. fixinv - An object's inventory letter sticks to it when it's dropped - (default on). If this is off, dropping an object shifts all + 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 inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a + 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 - "fruit:mango") (default "slime mold"). Basically a nostalgic - whimsy that NetHack uses from time to time. You should set - this to something you find more appetizing than slime mold. - Apples, oranges, pears, bananas, and melons already exist in + 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 something 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 - specify just the first letter. Although you can still denote - your gender using the "male" and "female" options, the "gender" - option will take precedence. The default is to randomly pick - an appropriate gender. If you prefix the value with `!' or - "no", you will exclude that gender from being picked randomly. - Cannot be set with the `O' command. Persistent. + Your starting gender (gender:male or gender:female). You may - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3898,63 +3898,63 @@ + specify just the first letter. Although you can still denote + your gender using the "male" and "female" options, the "gender" + option will take precedence. The default is to randomly pick + an appropriate gender. If you prefix the value with `!' or + "no", you will exclude that gender from being picked randomly. + 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 de- - fault). Gold is never blessed or cursed, but it is not de- + 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 de- + fault). Gold is never blessed or cursed, but it is not de- scribed as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with + If more information is available for an object looked at with the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the "More info?" prompt, but it also + ing help off makes just looking at things faster, since you + aren't interrupted with the "More info?" prompt, but it also means that you might miss some interesting and/or important in- formation. Persistent. 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. Same as "#herecmdmenu" and "#therecmdmenu" com- + When using a windowport that supports mouse and clicking on + yourself or next to you, show a menu of possible actions for + the location. Same as "#herecmdmenu" and "#therecmdmenu" com- mands. hilite_pet - Visually distinguish pets from similar animals (default off). - The behavior of this option depends on the type of windowing + 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 + is often used; with tiles, generally displays a heart symbol near pets. - With the curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option + With the curses interface, the petattr option controls how to + 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 + 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 + 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. Only - available for TTY and Windows GUI, and only when statushilites + Show a hit point bar graph behind your name and title. Only + available for TTY and Windows GUI, and only when statushilites is on. horsename - Name your starting horse (for example "horsename:Trigger"). - Cannot be set with the `O' command. - - ignintr - Ignore interrupt signals, including breaks (default off). Per- - sistent. + Name your starting horse (for example "horsename:Trigger"). - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -3964,9 +3964,15 @@ + Cannot be set with the `O' command. + + ignintr + Ignore interrupt signals, including breaks (default off). Per- + sistent. + implicit_uncursed Omit "uncursed" from object descriptions when it can be deduced - from other aspects of the description (default on). Persis- + from other aspects of the description (default on). Persis- tent. If you use menu coloring, you may want to turn this off. @@ -3976,51 +3982,45 @@ on). Persistent. lit_corridor - Show corridor squares seen by night vision or a light source + Show corridor squares seen by night vision or a light source held by 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 + 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 + 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 de- - scribed when covered by one or more objects (default off). + Give feedback when walking onto various dungeon features such + as stairs, fountains, or altars which are ordinarily only de- + scribed when covered by one or more objects (default off). Persistent. mention_walls - Give feedback when walking against a wall (default off). Per- + Give feedback when walking against a wall (default off). Per- sistent. menucolors - Enable coloring menu lines (default off). See "Configuring + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for 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 interest, but then displays a menu of matching ob- - jects 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. Partial skips the + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for early versions; it + consists of a prompt for object class characters, followed by - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4030,16 +4030,22 @@ - object class filtering and immediately displays a menu of all - objects. Persistent. + an object-by-object prompt for all items matching the selected + object class(es). Combination starts with a prompt for object + class(es) of interest, but then displays a menu of matching ob- + jects 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. Partial skips the ob- + ject class filtering and immediately displays a menu of all ob- + jects. Persistent. menu_deselect_all - Menu character accelerator to deselect all items in a menu. + Menu character accelerator to deselect all items in a menu. Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- fault `\'. menu_first_page @@ -4047,46 +4053,40 @@ Implemented by the Amiga, Gem and tty ports. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Values - are "none", "bold", "dim", "underline", "blink", or "inverse". + Controls how the headings in a menu are highlighted. Values + are "none", "bold", "dim", "underline", "blink", or "inverse". Not all ports can actually display all types. menu_invert_all - Menu character accelerator to invert all items in a menu. Im- + Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `@'. menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `~'. menu_last_page - Menu character accelerator to jump to the last page in a menu. + Menu character accelerator to jump to the last page in a menu. Implemented by the Amiga, Gem and tty ports. Default `|'. menu_next_page - Menu character accelerator to goto the next menu page. Imple- + Menu character accelerator to goto the next menu page. Imple- mented by the Amiga, Gem and tty ports. Default `>'. menu_objsyms - Show object symbols in menu headings in menus where the object + Show object symbols in menu headings in menus where the object symbols act as menu accelerators (default off). menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- fault on) - menu_previous_page - Menu character accelerator to goto the previous menu page. Im- - plemented by the Amiga, Gem and tty ports. Default `<'. - - menu_search - Menu character accelerator to search for a menu item. Imple- - mented by the Amiga, Gem, X11 and tty ports. Default `:'. - NetHack 3.7 July 25, 2020 + + NetHack 3.7 August 5, 2020 @@ -4096,13 +4096,21 @@ + menu_previous_page + Menu character accelerator to goto the previous menu page. Im- + plemented by the Amiga, Gem and tty ports. Default `<'. + + menu_search + Menu character accelerator to search for a menu item. Imple- + mented by the Amiga, Gem, X11 and tty ports. Default `:'. + menu_select_all - Menu character accelerator to select all items in a menu. Im- + Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `.'. menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `,'. monpolycontrol @@ -4110,24 +4118,24 @@ off). Debug mode only. mouse_support - Allow use of the mouse for input and travel. Valid settings + Allow use of the mouse for input and travel. Valid settings are: 0 - disabled 1 - enabled and make OS adjustments to support mouse use 2 - like 1 but does not make any OS adjustments - Omitting a value is the same as specifying 1 and negating + Omitting a value is the same as specifying 1 and negating mouse_support is the same as specifying 0. msghistory - The number of top line messages to keep (and be able to recall + 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. - Currently it is only supported for tty (all four choices) and - for curses (`f' and `r' choices, default `r'). The possible + Allows you to change the way recalled messages are displayed. + Currently 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); @@ -4135,24 +4143,16 @@ 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 + For backward compatibility, no value needs to be specified + (which defaults to "full"), or it can be negated (which defaults to "single"). 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 one will be automatically chosen. 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 + Set your character's name (defaults to your user name). You + can also set your character's role by appending a dash and one - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4162,6 +4162,14 @@ + 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. 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 this with the `O' command. nudist @@ -4171,7 +4179,7 @@ Send padding nulls to the terminal (default on). Persistent. number_pad - Use digit keys instead of letters to move (default 0 or off). + Use digit keys instead of letters to move (default 0 or off). Valid settings are: 0 - move by letters; "yuhjklbn" @@ -4181,44 +4189,36 @@ 4 - combines 3 with 2; phone layout plus MS-DOS compatibility -1 - by letters but use `z' to go northwest, `y' to zap wands - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 2 and 4 are for compatibility with MS-DOS or old + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 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 accommo- - date some QWERTZ keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a + date some QWERTZ keyboards 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' + 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 containing the symbols for the various object types. Any omit- ted 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_confirma- + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma- tion:pray. - Confirm - for any prompts which are set to require "yes" - rather than `y', also require "no" to reject in- + Confirm - for any prompts which are set to require "yes" + rather than `y', also require "no" to reject in- stead of accepting any non-yes response as no 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 useful in normal play; applies to explore - mode); - bones - require "yes" rather than `y' to confirm saving - bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attack- - ing a peaceful monster; + the game or switching into non-scoring explore - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4228,34 +4228,42 @@ + mode; + 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 data when dying in debug mode; + attack - require "yes" rather than `y' to confirm attack- + ing a peaceful monster; wand-break - require "yes" rather than `y' to confirm breaking a wand; - eating - require "yes" rather than `y' to confirm whether + 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 + form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather + pray - require `y' to confirm an attempt to pray rather than immediately praying; on by default; - Remove - require selection from inventory for `R' and `T' - commands even when wearing just one applicable + Remove - require selection from inventory for `R' and `T' + commands even when wearing just one applicable item. all - turn on all of the above. - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use "paranoid_confirmation:none". To keep it enabled while setting - any of the others, include it in the list, such as "para- + any of the others, include it in the list, such as "para- noid_confirmation:attack pray Remove". perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. petattr - Specifies one or more text highlighting attributes to use when - showing pets on the map. Effectively a superset of the + Specifies one or more text highlighting attributes to use when + showing pets on the map. Effectively a superset of the hilite_pet boolean option. Curses interface only; value is one or more of the following letters. @@ -4269,22 +4277,14 @@ l - Left line indicator r - Right line indicator - Some of those choices might not work, particularly the final - three, depending upon terminal hardware or terminal emulation + Some of those choices might not work, particularly the final + three, depending upon terminal hardware or terminal emulation software. - Currently multiple highlight-style letters can be combined by - simply stringing them together (for example, "bk"), but in the - future they might require being separated by plus signs (such - as "b+k", which works already). When using the `n' choice, it - should be specified on its own, not in combination with any of - the other letters. - - pettype - Specify the type of your initial pet, if you are playing a - NetHack 3.7 July 25, 2020 + + NetHack 3.7 August 5, 2020 @@ -4294,22 +4294,31 @@ - character class that uses multiple types of pets; or choose to - have no initial pet at all. Possible values are "cat", "dog", + Currently multiple highlight-style letters can be combined by + simply stringing them together (for example, "bk"), but in the + future they might require being separated by plus signs (such + as "b+k", which works already). When using the `n' choice, it + should be specified on its own, not in combination with any of + the other letters. + + 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". If the choice is not allowed for the role - you are currently playing, it will be silently ignored. For - example, "horse" will only be honored when playing a knight. + you are currently playing, it will be silently ignored. For + example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. (Default `S'). Persistent. 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 + 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 @@ -4319,38 +4328,29 @@ sistent. 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 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. + 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 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. playmode - Values are "normal", "explore", or "debug". Allows selection - of explore mode (also known as discovery mode) or debug mode + 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 + 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 it when not allowed or not possible re- + entirely. Requesting it when not allowed or not possible re- sults in explore mode instead. Default is normal play. pushweapon - Using the `w' (wield) command when already wielding something - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the - applied item to become wielded. Persistent. - - quick_farsight - When set, usually prevents the "you sense your surroundings" - message where play pauses to allow you to browse the map when- - ever clairvoyance randomly activates. Some situations, such as - being underwater or engulfed, ignore this option. It does not + Using the `w' (wield) command when already wielding something - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4360,43 +4360,52 @@ + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the + applied item to become wielded. Persistent. + + quick_farsight + When set, usually prevents the "you sense your surroundings" + message where play pauses to allow you to browse the map when- + ever clairvoyance randomly activates. Some situations, such as + being underwater or engulfed, ignore this option. It does not affect the clairvoyance spell where pausing to examine revealed - objects or monsters is less intrusive. Default is off. Per- + objects or monsters is less intrusive. Default is off. Per- sistent. race Selects your race (for example, "race:human"). Default is ran- - dom. If you prefix the value with `!' or "no", you will ex- + dom. If you prefix the value with `!' or "no", you will ex- clude that race from being picked randomly. Cannot be set with the `O' command. Persistent. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (de- + Make the space bar a synonym for the `.' (#wait) command (de- fault off). Persistent. role - Pick your type of character (for example "role:Samurai"); syn- - onym for "character". See "name" for an alternate method of - specifying your role. Normally only the first letter of the - value is examined; `r' is an exception with "Rogue", "Ranger", + Pick your type of character (for example "role:Samurai"); syn- + onym for "character". See "name" for an alternate method of + specifying your role. Normally only the first letter of the + value is examined; `r' is an exception with "Rogue", "Ranger", and "random" values. If you prefix the value with `!' or "no", - you will exclude that role from being picked randomly. Cannot + you will exclude that role from being picked randomly. Cannot be set with the `O' command. Persistent. roguesymset - This option may be used to select one of the named symbol sets - found within "symbols" to alter the symbols displayed on the + This option may be used to select one of the named symbol sets + found within "symbols" to alter the symbols displayed on the screen on the rogue level. rlecomp When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has + 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 - control+direction and so forth, or via the travel command or + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -4404,19 +4413,10 @@ 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 ac- - tual 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. Persistent. - - safe_pet - Prevent you from (knowingly) attacking your pets (default on). - Persistent. + This option only affects the game's screen display, not the - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4426,13 +4426,22 @@ + 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. Persistent. + + safe_pet + Prevent you from (knowingly) attacking your pets (default on). + Persistent. + sanity_check 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 + 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. @@ -4441,9 +4450,9 @@ off). Persistent. showrace - Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4455,34 +4464,25 @@ sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + 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, + 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. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. sparkle Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- + hit by an attack to which it is resistant (default on). Per- sistent. - standout - Boldface monsters and "--More--" (default off). Persistent. - statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. - See "Configuring Status Hilites" for further information. - - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4492,29 +4492,37 @@ + standout + Boldface monsters and "--More--" (default off). Persistent. + + statushilites + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. + See "Configuring 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 + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (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 "symset:default" to explicitly select the default + 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 "symset:default" to explicitly select the default symbols. time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface only; "X11" interface always uses a timer based delay. The de- fault is on if configured into the program.) Persistent. @@ -4524,31 +4532,23 @@ toptenwin Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map win- - dow. Does not affect traveling via the `_' ("#travel") com- + ed moves if you make inadvertent mouse clicks on the map win- + dow. Does not affect traveling via the `_' ("#travel") com- mand. Persistent. verbose - Provide more commentary during the game (default on). Persis- - tent. - - whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to - pick a location. + Provide more commentary during the game (default on). - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4558,6 +4558,14 @@ + Persistent. + + whatis_coord + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to + pick a location. + The possible settings are: c - compass ("east" or "3s" or "2n,4w"); @@ -4572,49 +4580,41 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possi- + through next and previous targets, allows filtering the possi- ble 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 + 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 + Filtering can also be changed when getting a location with the "getpos.filter" key. whatis_menu - When getting a location on the map, and using a key to cycle + 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. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement + 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 de- + select which one to use, such as "tty" or "X11" (default de- pends 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 op- - tions. 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 option in the list. - - wizweight - Augment object descriptions with their objects' weight (default - off). Debug mode only. + When used, it should be the first option set since its value + might enable or disable the availability of various other - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4624,36 +4624,45 @@ + 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 option in the list. + + wizweight + 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 + 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 + 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 adjust- - ing 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 + 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 adjust- + ing 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. Some options - are dynamic and can be specified during the game with the `O' + 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, + 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, + Where to align or place the status window (top, bottom, left, or right). ascii_map - If NetHack can, it should display an ascii character map if it + If NetHack can, it should display an ascii character map if it can. color @@ -4661,26 +4670,17 @@ monsters, objects, and dungeon features. eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to your terminal (default off). font_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 windows. - - font_message - If NetHack can, it should use a font by the chosen name for the - message window. - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4690,63 +4690,63 @@ + font_menu + If NetHack can, it should use a font by the chosen name for + menu windows. + + font_message + If NetHack can, it should use a font by the chosen name for the + message window. + font_status If NetHack can, it should use a font by the chosen name for the status window. font_text - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for text windows. font_size_map - If NetHack can, it should use this size font for the map win- + If NetHack can, it should use this size font for the map win- dow. 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 + 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 + 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. fullscreen - If NetHack can, it should try and display on the entire screen + If NetHack can, it should try and display on the entire screen rather than in a window. guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- terface only; default is on. large_font If NetHack can, it should use a large font. map_mode - If NetHack can, it should display the map in the manner speci- + If NetHack can, it should display the map in the manner speci- fied. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts + 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 exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4756,24 +4756,32 @@ + 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 exam- + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount - If NetHack can, it should scroll the display by this number of + If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- dow. selectsaved - If NetHack can, it should display a menu of existing saved + If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to + Display an onscreen keyboard. Handhelds are most likely to support this option. splash_screen @@ -4781,38 +4789,30 @@ 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). Curses and tty + Number of lines for traditional below-the-map status display. + Acceptable values are 2 and 3 (default is 2). Curses and tty interfaces only. term_cols and term_rows - Curses interface only. Number of columns and rows to use for + Curses interface only. Number of columns and rows to use for the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. + ified but will settle for smaller sizes if they are too big. Default is the current window size. tiled_map If NetHack can, it should display a tiled map if it can. 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. tile_height - Specify the preferred height of each tile in a tile capable - port. - - tile_width - Specify the preferred width of each tile in a tile capable port - - use_darkgray - Use bold black instead of blue for black glyphs (TTY only). + Specify the preferred height of each tile in a tile capable - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4822,63 +4822,63 @@ + port. + + tile_width + Specify the preferred width of each tile in a tile capable port + + 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 speci- + If NetHack can, it should display inverse when the game speci- fies it. vary_msgcount - If NetHack can, it should display this number of messages at a + 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 in- + Whether to draw boxes around the map, status area, message + area, and persistent inventory window if enabled. Curses in- terface only. Acceptable values are 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) (default) - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns + (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 for align_status set to left or right.) windowcolors - If NetHack can, it should display windows with the specified + If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- text). 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. Platform-specific Customization options - - Here are explanations of options that are used by specific - platforms or ports to customize and change the port behavior. - - altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without - the .dll extension and without any path information. Cannot be - set with the `O' command. - NetHack 3.7 July 25, 2020 + + + NetHack 3.7 August 5, 2020 @@ -4888,29 +4888,40 @@ + 9.6. Platform-specific Customization options + + Here are explanations of options that are used by specific + platforms or ports to customize and change the port behavior. + + altkeyhandler + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without + the .dll extension and without any path information. Cannot be + set with the `O' command. + altmeta On Amiga, this option controls whether typing "Alt" plus anoth- er key functions as a meta-shift for that key (default on). altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). flush @@ -4923,28 +4934,17 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of - keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally - going to be returned. You can use multiple subkeyvalue state- - ments in the configuration file if needed. Cannot be set with - the `O' command. - - video - Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause - the game to display tiles, using the full capability of the VGA + (Win32 tty NetHack only). May be used to alter the value of - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -4954,63 +4954,63 @@ - hardware. Setting "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 of those modes works. Cannot be set + keystrokes that the operating system returns to NetHack to help + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally + going to be returned. You can use multiple subkeyvalue assign- + ments in the configuration file if needed. Cannot be set with + the `O' command. + + video + Set the video mode used (PC NetHack only). Values are "autode- + tect", "default", "vga", or "vesa". Setting "vesa" will cause + the game to display tiles, using the full capability of the VGA + hardware. Setting "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 of those modes works. Cannot be set with the `O' command. video_height - Set the VGA mode resolution height (MS-DOS only, with + Set the VGA mode resolution height (MS-DOS only, with video:vesa) video_width - Set the VGA mode resolution width (MS-DOS only, with + 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 bright.cyan. Cannot be set with the `O' + 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 (de- fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the `O' command. 9.7. Regular Expressions - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. - 9.8. Configuring Autopickup Exceptions - - 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 autopickup something. - - autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of - the description of an object at your location. - NetHack 3.7 July 25, 2020 + + + + NetHack 3.7 August 5, 2020 @@ -5020,19 +5020,34 @@ - In addition, some characters are treated specially if they oc- + 9.8. Configuring Autopickup Exceptions + + 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 autopickup something. + + autopickup_exception + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as 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 oc- cur 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 + 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 save and then restore your game. autopickup_ex- + 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 save and then restore your game. autopickup_ex- ception rules and not saved with the game. Here are some examples: @@ -5041,42 +5056,27 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - 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 ex- + 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 ex- clusion of items known to be cursed from autopickup. 9.9. 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 + 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"), or a three-digit decimal ASCII code. For example: - BIND=^X:getpos.autodescribe - BIND={:menu_first_page - BIND=v:loot - - Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a 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 lines in the configuration file. You cannot bind ob- - ject symbols into menu accelerators. - - Special command keys - Below are the special commands you can rebind. Some of them - NetHack 3.7 July 25, 2020 + + + NetHack 3.7 August 5, 2020 @@ -5086,13 +5086,30 @@ - can be bound to same keys with no problems, others are in the - same "context", and if bound to same keys, only one of those - commands will be available. Special command can only be bound + BIND=^X:getpos.autodescribe + BIND={:menu_first_page + BIND=v:loot + + Extended command keys + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- + ject symbols into menu accelerators. + + 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 "context", 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 + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. doinv @@ -5102,19 +5119,19 @@ Prefix key to force fight a direction. Default is `F'. fight.numpad - Prefix key to force fight a direction. With number_pad only. + Prefix key to force fight a direction. With number_pad only. Default is `-'. getdir.help - When asked for a direction, the key to show the help. Default + When asked for a direction, the key to show the help. Default is `?'. getdir.self - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `.'. getdir.self2 - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `s'. getpos.autodescribe @@ -5122,27 +5139,10 @@ fault is `#'. getpos.all.next - When asked for a location, the key to go to next closest inter- - esting thing. Default is `a'. - - getpos.all.prev - When asked for a location, the key to go to previous closest - interesting thing. Default is `A'. - - getpos.door.next - When asked for a location, the key to go to next closest door - or 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'. - - getpos.help - When asked for a location, the key to show help. Default is - `?'. + When asked for a location, the key to go to next closest - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -5152,63 +5152,63 @@ + interesting thing. Default is `a'. + + getpos.all.prev + When asked for a location, the key to go to previous closest + interesting thing. Default is `A'. + + getpos.door.next + When asked for a location, the key to go to next closest door + or 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'. + + getpos.help + 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 mon- + When asked for a location, the key to go to next closest mon- ster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest monster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest ob- + When asked for a location, the key to go to next closest ob- ject. Default is `o'. getpos.obj.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest object. Default is `O'. getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- stead. 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 + 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 + 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 + When asked for a location, the key to choose the location, and possibly ask for more info. Default is `.'. - getpos.pick.once - When asked for a location, the key to choose the location, and - skip asking for more info. Default is `,'. - - getpos.pick.quick - When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- - fault is `;'. - - getpos.pick.verbose - 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. De- - fault is `@'. - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -5218,24 +5218,41 @@ + getpos.pick.once + When asked for a location, the key to choose the location, and + skip asking for more info. Default is `,'. + + getpos.pick.quick + When asked for a location, the key to choose the location, skip + asking for more info, and exit the location asking loop. De- + fault is `;'. + + getpos.pick.verbose + 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. De- + fault is `@'. + getpos.unexplored.next - When asked for a location, the key to go to next closest unex- + When asked for a location, the key to go to next closest unex- plored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest unexplored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target + When asked for a location, the key to go to show valid target locations. Default is `$'. getpos.valid.next - When asked for a location, the key to go to next closest valid + When asked for a location, the key to go to next closest valid location. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest valid location. Default is `Z'. nopickup @@ -5245,7 +5262,7 @@ Key to redraw the screen. Default is `^R'. redraw.numpad - Key to redraw the screen. With number_pad only. Default is + Key to redraw the screen. With number_pad only. Default is `^L'. repeat @@ -5254,15 +5271,28 @@ reqmenu Prefix key to request menu from some commands. Default is `m'. + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 81 + + + run Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad - Prefix key to run towards a direction. With number_pad only. + Prefix key to run towards a direction. With number_pad only. Default is `5'. rush @@ -5273,18 +5303,7 @@ You can change the way the messages are shown in the message area, when the message matches a user-defined pattern. - - NetHack 3.7 July 25, 2020 - - - - - - NetHack Guidebook 81 - - - - In general, the configuration file entries to describe the + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5297,50 +5316,31 @@ 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 mes- + norep - show the message once, but not again if no other mes- sage is shown in between. - Here's an example of message types using NetHack's internal + 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 + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when 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 color mappings look like this: - MENUCOLOR="pattern"=color&attribute - - pattern - the pattern to match; - color - the color to use for lines matching the pat- - tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if - left out, you must also leave out the preced- - ing 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, gray, orange, light-green, yellow, light-blue, light- - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -5350,63 +5350,63 @@ - magenta, light-cyan, and white. And no-color, the default - foreground color, which isn't necessarily the same as any of - the other colors. + In general, the configuration file entries to describe the + menu color mappings look like this: - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + MENUCOLOR="pattern"=color&attribute + + pattern - the pattern to match; + color - the color to use for lines matching the pat- + tern; + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if + left out, you must also leave out the preced- + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the + other colors. + + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- + 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 line will be shown in red color and under- lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu + uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message 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 user sounds to messages: - - SOUNDDIR - The directory that houses the sound files to be played. - - SOUND - 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 - 3.6); - pattern - the pattern to match; - sound file - the sound file to play; - volume - the volume to be set while playing the sound - file; - sound index - optional; the index corresponding to a sound - file. - NetHack 3.7 July 25, 2020 + + NetHack 3.7 August 5, 2020 @@ -5416,12 +5416,32 @@ + The following configuration file entries are relevant to + mapping user sounds to messages: + + SOUNDDIR + The directory that houses the sound files to be played. + + SOUND + 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 + 3.6); + pattern - the pattern to match; + sound file - the sound file to play; + volume - the volume to be set while playing the sound + file; + sound index - optional; the index corresponding to a sound + file. + The pattern should be a POSIX extended regular expression. 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5429,8 +5449,8 @@ 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 + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -5438,41 +5458,21 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground 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, blink, - 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 example: "magenta&inverse+dim". - - Note that the display may substitute or ignore particular - attributes 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 ver- - sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- - tially (at least with the tty interface) rather than all at once, - the only way a situation like that can be controlled is to speci- - fy just one attribute. - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -5482,7 +5482,26 @@ - You can adjust the appearance of the following status + Allowed attributes are none, bold, dim, underline, blink, + 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 example: "magenta&inverse+dim". + + Note that the display may substitute or ignore particular + attributes 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 ver- + sa. On others, issuing an attribute request while another is al- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- + tially (at least with the tty interface) rather than all at once, + the only way a situation like that can be controlled is to speci- + fy just one attribute. + + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5493,16 +5512,16 @@ 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 condition- + 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 condition- ally displayed depending upon your other option settings. - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. @@ -5511,34 +5530,15 @@ * "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 + * "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 val- - ue 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 val- - ue, 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 be- - tween 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 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 corresponding maxi- - mum 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 ex- - perience level to the start of the next level. So if + ue changes. This attribute times out after statushilites - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -5548,36 +5548,72 @@ - 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 lev- - el, but a rule for =100% is allowed and matches the spe- - cial case of being exactly 1 experience point short of the - next level. + turns. (If a field has both a "changed" rule and an "up" + or "down" rule which matches a change in the field's val- + ue, the "up" or "down" one takes precedence.) - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- + perience level to the start of the next level. So if lev- + el 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 experience point short of the next lev- + el. + + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only match when strictly above or below. * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". For title, only the role's rank title is tested; + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- + The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: + + + + + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 86 + + + OPTION=hilite_status: gold/up/yellow/down/brown OPTION=hilite_status: characteristics/up/green/down/red OPTION=hilite_status: hitpoints/100%/gray&normal @@ -5593,34 +5629,23 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - - NetHack 3.7 July 25, 2020 - - - - - - NetHack Guidebook 86 - - - - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols @@ -5642,6 +5667,19 @@ - S_blcorn (bottom left corner) b S_blob (blob) + S_book (spellbook) + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 87 + + + ) S_boomleft (boomerang open left) ( S_boomright (boomerang open right) ` S_boulder (boulder) @@ -5667,19 +5705,6 @@ - S_explode2 (explosion top center) \ S_explode3 (explosion top right) | S_explode4 (explosion middle left) - - - - NetHack 3.7 July 25, 2020 - - - - - - NetHack Guidebook 87 - - - S_explode5 (explosion middle center) | S_explode6 (explosion middle right) \ S_explode7 (explosion bottom left) @@ -5708,6 +5733,19 @@ ^ S_hole (hole) @ S_human (human or elf) h S_humanoid (humanoid) + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 88 + + + - S_hwall (horizontal wall) . S_ice (ice) i S_imp (imp or minor demon) @@ -5733,19 +5771,6 @@ N S_naga (naga) . S_ndoor (doorway without door) n S_nymph (nymph) - - - - NetHack 3.7 July 25, 2020 - - - - - - NetHack Guidebook 88 - - - O S_ogre (ogre) o S_orc (orc) p S_piercer (piercer) @@ -5774,6 +5799,19 @@ ^ S_squeaky_board (squeaky board) 0 S_ss1 (magic shield 1 of 4) # S_ss2 (magic shield 2 of 4) + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 89 + + + @ S_ss3 (magic shield 3 of 4) * S_ss4 (magic shield 4 of 4) ^ S_statue_trap (statue trap) @@ -5799,19 +5837,6 @@ # S_tree (tree) T S_troll (troll) | S_trwall (wall) - - - - NetHack 3.7 July 25, 2020 - - - - - - NetHack Guidebook 89 - - - - S_tuwall (wall) U S_umber (umber hulk) S_unexplored (unexplored terrain) @@ -5840,35 +5865,10 @@ Y S_yeti (apelike creature) Z S_zombie (zombie) z S_zruty (zruty) - S_pet_override (any pet if ACCESSIBILITY=1 is set) - S_hero_override (hero if ACCESSIBILITY=1 is set) - - Notes: - - * 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 en- - abled 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 de- - pict. So S_rock is only used for boulders and not used at all - if overridden by the more specific S_boulder. - - 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. Be certain to - NetHack 3.7 July 25, 2020 + + NetHack 3.7 August 5, 2020 @@ -5878,63 +5878,63 @@ - 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 charac- + S_pet_override (any pet if ACCESSIBILITY=1 is set) + S_hero_override (hero if ACCESSIBILITY=1 is set) + + Notes: + + * 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 en- + abled 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 de- + pict. So S_rock is only used for boulders and not used at all + if overridden by the more specific S_boulder. + + 9.15. 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 the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- ter 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 + 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 location of items on the screen. - 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 message handler", your NetHack has been compiled + 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 message 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 environment variable NETHACK_MSGHANDLER + and other POSIX systems, define MSGHANDLER to enable it. To use + the capability, set the environment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task somewhat daunting. Included within the "symbols" file of all of- ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your - configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- - abled in the sysconf file. - - The most crucial settings to make the game more accessible - are: - - symset:NHAccess - Load a symbol set appropriate for use by blind players. - - roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for - use by blind players. - - menustyle:traditional - This will assist in the interface to speech synthesizers. - - nomenu_overlay - 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 the traditional Rogue-like commands. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -5944,63 +5944,63 @@ + configuration file to better suit your preferences. See the pre- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- + abled in the sysconf file. + + The most crucial settings to make the game more accessible + are: + + symset:NHAccess + Load a symbol set appropriate for use by blind players. + + roguesymset:NHAccess + Load a symbol set for the rogue level that is appropriate for + use by blind players. + + menustyle:traditional + This will assist in the interface to speech synthesizers. + + nomenu_overlay + 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 the traditional Rogue-like commands. + autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip - When targeting with cursor and using fast-move, skip the same + When targeting with cursor and using fast-move, skip the same glyphs 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 in- + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. - 9.16. Global Configuration for System Administrators - - If NetHack is compiled with the SYSCF option, a system ad- - ministrator 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 us- - es 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 mode. - - SHELLERS = A list of users who are allowed to use the shell es- - cape 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. - - MAXPLAYERS = Limit the maximum number of games that can be run- - ning at the same time. - - SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - NetHack 3.7 July 25, 2020 + + NetHack 3.7 August 5, 2020 @@ -6010,63 +6010,63 @@ - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + 9.16. Global Configuration for System Administrators + + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 us- + es 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 mode. + + SHELLERS = A list of users who are allowed to use the shell es- + cape 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. + + MAXPLAYERS = Limit the maximum number of games that can be run- + ning at the same time. + + SAVEFORMAT = A list of up to two save file formats separated by + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- + SUPPORT = A string explaining how to get local support (no de- fault value). - RECOVER = A string explaining how to recover a game on this + 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, WIZ- + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. - 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). - - The following options affect the score file: - - 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. - - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- - spectively, to identify unique people for the score file. - - MAX_STATUENAME_RANK = Maximum number of score file entries to - use for random statue names (default is 10). - - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override - symbols in their configuration file. - - PORTABLE_DEVICE_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 rather than at the standard loca- - tions. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6076,8 +6076,37 @@ + 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). + + The following options affect the score file: + + 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. + + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + spectively, to identify unique people for the score file. + + MAX_STATUENAME_RANK = Maximum number of score file entries to + use for random statue names (default is 10). + + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override + symbols in their configuration file. + + PORTABLE_DEVICE_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 rather than at the standard loca- + tions. + DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6093,46 +6122,17 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on + 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 + 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, 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 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 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 paltry cost of not getting on the high score - list. - - There are two ways of enabling explore mode. One is to - start the game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new - game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6142,63 +6142,63 @@ - other benefits of explore mode are left for the trepid reader to + 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 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 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 paltry cost of not getting on the high score + list. + + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new + game in explore mode provides your character with a wand of wish- + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 + vide god-like powers 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 par- - ticular 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 + For some systems, the player must be logged in under a par- + ticular 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. - 12. Credits - - 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 Dungeons of Doom, by Ken Arromdee. - - 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 - Woodland, Mike Thome, and Jon Payne. - - Andries Brouwer did a major re-write while at Stichting - Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming 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 ver- - sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- - sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- - sion numbers, not contemporary NetHack ones). - NetHack 3.7 July 25, 2020 + + NetHack 3.7 August 5, 2020 @@ -6208,63 +6208,63 @@ - R. Black ported PC HACK 3.51 to Lattice C and the Atari + 12. Credits + + 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 Dungeons of Doom, by Ken Arromdee. + + 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 + Woodland, Mike Thome, and Jon Payne. + + Andries Brouwer did a major re-write while at Stichting + Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- + forming 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 ver- + sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- + nally 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, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- + sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- + sion numbers, not contemporary NetHack ones). + + 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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. 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-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 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-structured 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 Addison, Mike Passaretti, and Olaf Seibert, developed - NetHack 3.1 for the Amiga. - - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- - lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6274,63 +6274,63 @@ + 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-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 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-structured 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 Addison, Mike Passaretti, and Olaf Seibert, developed + NetHack 3.1 for the Amiga. + + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 + Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor 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 ob- - jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support 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 Alli- - son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin - Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and - porting teams. - - Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned - for better game play. - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6340,63 +6340,63 @@ + 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 ob- + jects rather than just their classes. He contributed them to the + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- + son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin + Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- + ic 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 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 cancer and passed away. That + release of the game was dedicated to him by the development and + porting teams. + + Version 3.2 proved to be more stable than previous versions. + Many bugs were fixed, abuses eliminated, and game features tuned + for better game play. + During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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 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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, 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 - separate race and profession. The Elf class was removed in pref- - erence 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, Barbar- - ians, 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 listing 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. - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6406,63 +6406,63 @@ - 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 + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 + separate race and profession. The Elf class was removed in pref- + erence 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, Barbar- + ians, 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 listing 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 NetHack 3.4.0 in March 2002. - As with version 3.3, various people contributed to the game + 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 plat- + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows 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 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 af- - ter he resurrected it for 3.3.1. - - The release of NetHack 3.4.3 in December 2003 marked the be- - ginning 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 continued 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 con- - tinue to be developed, maintained, and enjoyed by the community - to this day. - - In September 2014, an interim snapshot of the code under de- - velopment 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 - - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6472,63 +6472,63 @@ - and never used in an official NetHack release. An announcement + 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. + + Christian "Marvin" Bressler maintained 3.4 for the Atari af- + ter he resurrected it for 3.3.1. + + The release of NetHack 3.4.3 in December 2003 marked the be- + ginning 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 continued 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 con- + tinue to be developed, maintained, and enjoyed by the community + to this day. + + In September 2014, an interim snapshot of the code under de- + velopment 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 Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 - restructured. - - The NetHack Development Team, as well as Steve VanDevender - and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- - ate on various UNIX flavors and maintained the X11 interface. - - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- - tained the port of NetHack 3.6 for Mac OSX. - - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- - tained 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 up- - dated 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 contrib- - uted 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 con- - sisted 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. - - NetHack 3.7 July 25, 2020 + NetHack 3.7 August 5, 2020 @@ -6538,21 +6538,51 @@ + restructured. + + The NetHack Development Team, as well as Steve VanDevender + and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- + ate on various UNIX flavors and maintained the X11 interface. + + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + tained the port of NetHack 3.6 for Mac OSX. + + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + tained 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 up- + dated 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 contrib- + uted 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 con- + sisted 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 en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6561,22 +6591,35 @@ The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 101 + + + 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6591,19 +6634,6 @@ Bill Dyer Jon W{tte Ray Chason Boudewijn Waijers Jonathan Handler Richard Addison Bruce Cox Joshua Delahunty Richard Beigel - - - - NetHack 3.7 July 25, 2020 - - - - - - NetHack Guidebook 101 - - - Bruce Holloway Karl Garrison Richard P. Hughey Bruce Mewborne Keizo Yamamoto Rob Menke Carl Schelin Keith Simpson Robin Bandy @@ -6627,6 +6657,19 @@ Frederick Roeber Merlyn LeRoy Tim Lennan Gil Neiger Michael Allison Timo Hakulinen Greg Laskin Michael Feir Tom Almy + + + + NetHack 3.7 August 5, 2020 + + + + + + NetHack Guidebook 102 + + + Greg Olson Michael Hamel Tom West Gregg Wonderly Michael Sokolov Warren Cheung Hao-yang Wang Mike Engber Warwick Allison @@ -6634,7 +6677,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6660,7 +6703,30 @@ - NetHack 3.7 July 25, 2020 + + + + + + + + + + + + + + + + + + + + + + + + NetHack 3.7 August 5, 2020 From 46f19f89acc2bc75a9286654bf4caa686e31c41c Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 7 Aug 2020 00:29:28 -0700 Subject: [PATCH 083/708] goodbye END-CHOOSE Instead of an additional options file directive to end the last section of a CHOOSE directive, simplify by using an empty-name section, [], instead. So ... CHOOSE one,two [one] ... [two] ... [] ... As with the short-lived END-CHOOSE directive, if no [] is present then the rest of the file is part of the last choice. --- doc/Guidebook.mn | 32 ++++++++++++++++---------------- doc/Guidebook.tex | 30 ++++++++++++++++++------------ doc/fixes37.0 | 10 +++++----- src/files.c | 44 +++++++++----------------------------------- 4 files changed, 48 insertions(+), 68 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index dfa15732b..a73b5dc8e 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.394 $ $NHDT-Date: 1596754607 2020/08/06 22:56:47 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.395 $ $NHDT-Date: 1596785362 2020/08/07 07:29:22 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -3130,16 +3130,20 @@ the configuration file for you using the default template file. .pg On MS-DOS, it is \(lqdefaults.nh\(rq in the same folder as nethack.exe. .pg -Any line in the configuration file starting with \(oq#\(cq is treated -as a comment. +Any line in the configuration file starting with \(oq\f(CR#\fP\(cq is treated +as a comment and ignored. Empty lines are ignored. .pg -Any line beginning with \(oq[\(cq and ending in \(oq]\(cq is considered -a section marker. +Any line beginning with \(oq\f(CR[\fP\(cq and ending in \(oq\f(CR]\fP\(cq +is a section marker (the closing \(oq\f(CR]\fP\(cq can be followed +by whitespace and then an arbitrary comment beginning with \(oq\f(CR#\fP\(cq). The text between the square brackets is the section name. -Lines after a section marker belong to that section, and are -ignored unless a CHOOSE directive was used to select that section. -Section names are case insensitive. +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 section. .pg You can use different configuration directives in the file, some of which can be used multiple times. @@ -3232,17 +3236,13 @@ CHOOSE=char A,char B OPTIONS=role:arc,race:dwa,align:law,gender:fem [char B] OPTIONS=role:wiz,race:elf,align:cha,gender:mal -END-CHOOSE +[] #end of CHOOSE OPTIONS=!rest_on_space .ft \" revert to previous font .ed -.lp END-CHOOSE -An optional way to terminate CHOOSE. -.\" use of the \% prefix prevents END-CHOOSE from being hyphenated across -.\" line boundary despite its hyphen; needed for the plain text output to -.\" avoid splitting the directive name -You can place an \%END-CHOOSE directive after the last CHOOSE section in -order to follow that with other options which are common to all sections. +.lp "" +If \f(CR[]\fP is present, the preceding section is closed and no new +section begins; whatever follows will be common to all sections. Otherwise the last section extends to the end of the options file. .lp MENUCOLOR Highlight menu lines with different colors. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 14c3cd843..16b662884 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3355,12 +3355,20 @@ On MS-DOS it is \mbox{``defaults.nh''} in the same folder as \mbox{{\it nethack.exe\/}}.\\ %.lp "" -Any line in the configuration file starting with `{\tt \#}' is treated as a comment. -Empty lines are ignored. Any line beginning with `{\tt [}' and ending in `{\tt ]}' is considered a section -marker. The text between the square brackets is the section name. -Lines after a section marker belong to that section, and are -ignored unless a CHOOSE -directive was used to select that section. -Section names are case insensitive. +Any line in the configuration file starting with `{\tt \#}' is treated +as a comment and ignored. +Empty lines are ignored. + +Any line beginning with `{\tt [}' and ending in `{\tt ]}' +is a section marker (the closing `{\tt ]}' can be followed +by whitespace and then an arbitrary comment beginning with `{\tt #}'). +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 section. %.pg You can use different configuration directives in the file, some @@ -3474,16 +3482,14 @@ Example: OPTIONS=role:arc,race:dwa,align:law,gender:fem [char B] OPTIONS=role:wiz,race:elf,align:cha,gender:mal - END-CHOOSE + [] #end of CHOOSE OPTIONS=!rest_on_space \end{verbatim} %.ed -%.lp -\item[\bb{END-CHOOSE}] -An optional way to terminate CHOOSE. -You can place an END-CHOOSE directive after the last CHOOSE section in -order to follow that with other options which are common to all sections. +%.lp "" +If {\tt []} is present, the preceding section is closed and no new +section begins; whatever follows will be common to all sections. Otherwise the last section extends to the end of the options file. %.lp diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 35fb1fec0..857c26fce 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.275 $ $NHDT-Date: 1596754606 2020/08/06 22:56:46 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.276 $ $NHDT-Date: 1596785361 2020/08/07 07:29:21 $ General Fixes and Modified Features ----------------------------------- @@ -459,11 +459,11 @@ add 'Sokoban' conduct, tracking the number of times the special Sokoban rules reduce verbosity when a mind flayer attacks a headless monster; when a tentacle-to-head attack hits but fails to accomplish anything skip remaining attacks (mind flayer has 3, master mind flayer has 5) -add END-CHOOSE directive for run-time config file; CHOOSE section1,section2 +add section marker [] support to run-time config file; CHOOSE section1,section2 followed by [section1] ... [section2] ... forced all the rest of the - file to be part of the last section; that still works the same but - END-CHOOSE can be used to terminate the last section and revert to - common options for the remainder of the file + file to be part of the last section; that still works the same, but [] + can be used to terminate the last section and revert to common options + for the remainder of the file Platform- and/or Interface-Specific New Features diff --git a/src/files.c b/src/files.c index b79c2a913..f3c171111 100644 --- a/src/files.c +++ b/src/files.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 files.c $NHDT-Date: 1596754598 2020/08/06 22:56:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.317 $ */ +/* NetHack 3.7 files.c $NHDT-Date: 1596785343 2020/08/07 07:29:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.318 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -164,7 +164,6 @@ static boolean FDECL(config_error_nextline, (const char *)); static void NDECL(free_config_sections); static char *FDECL(choose_random_part, (char *, CHAR_P)); static char *FDECL(is_config_section, (char *)); -static boolean FDECL(is_end_of_sections, (const char *)); static boolean FDECL(handle_config_section, (char *)); static char *FDECL(find_optparam, (const char *)); static void FDECL(parseformat, (int *, char *)); @@ -2328,7 +2327,7 @@ char *str; /* trailing spaces will be stripped, ']' too iff result is good */ return (char *) 0; /* last character should be close bracket, ignoring any comment */ z = index(a, ']'); - if (!z || z == a) + if (!z) return (char *) 0; for (c = z + 1; *c && *c != '#'; ++c) continue; @@ -2342,46 +2341,27 @@ char *str; /* trailing spaces will be stripped, ']' too iff result is good */ return trimspaces(a); } -static boolean -is_end_of_sections(buf) -const char *buf; -{ - /* "END-CHOOSE"; bypass match_optname()/match_varname(); - accepts "ENDCHOOSE", "END CHOOSE", "END-CHOOSE", "END_CHOOSE" */ - if (!strncmpi(buf, "END", 3) && buf[3]) { - boolean sep = index(" -_", buf[3]) != 0; - - if (!strcmpi(&buf[sep ? 4 : 3], "CHOOSE")) { - if (!g.config_section_current) - config_error_add("END-CHOOSE when not in a CHOOSE section"); - return TRUE; - } - } - return FALSE; -} - static boolean handle_config_section(buf) char *buf; { - boolean was_in_section = (g.config_section_current != 0); char *sect = is_config_section(buf); if (sect) { if (g.config_section_current) - free(g.config_section_current); + free(g.config_section_current), g.config_section_current = 0; /* is_config_section() removed brackets from 'sect' */ if (!g.config_section_chosen) { config_error_add("Section \"[%s]\" without CHOOSE", sect); return TRUE; } - g.config_section_current = dupstr(sect); - debugpline1("set config section: '%s'", g.config_section_current); - return TRUE; - } else if (is_end_of_sections(buf)) { - if (was_in_section) + if (*sect) { /* got a section name */ + g.config_section_current = dupstr(sect); + debugpline1("set config section: '%s'", g.config_section_current); + } else { /* empty section name => end of sections */ + free_config_sections(); debugpline0("unset config section"); - free_config_sections(); + } return TRUE; } @@ -2436,12 +2416,6 @@ char *origbuf; but spaces, one of them will be kept even though it leads/trails) */ mungspaces(buf); - /* "END-CHOOSE" doesn't have a value so we need to check for it - before checking for that; if found here, is_end_of_sections() - will report a config_error */ - if (is_end_of_sections(buf)) - return FALSE; - /* find the '=' or ':' */ bufp = find_optparam(buf); if (!bufp) { From 5851888ba5458e8dee9597148d0b2639bcd3c6e3 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 7 Aug 2020 04:24:08 -0400 Subject: [PATCH 084/708] This is cron-daily v1-Jan-20-2020. guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 1620 ++++++++++++++++++++++----------------------- 1 file changed, 810 insertions(+), 810 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 4f352bf4d..2691c508c 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -3413,17 +3413,17 @@ nethack.exe. Any line in the configuration file starting with `#' is - treated as a comment. Empty lines are ignored. + treated as a comment and ignored. Empty lines are ignored. - Any line beginning with `[' and ending in `]' is considered - a section marker. The text between the square brackets is the - section name. Lines after a section marker belong to that sec- - tion, and are ignored unless a CHOOSE directive was used to se- - lect that section. Section names are case insensitive. - - You can use different configuration directives in the file, - some of which can be used multiple times. In general, the direc- - tives are written in capital letters, followed by an equals sign, + 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 directive and their names are case insensi- + tive. Lines after a section marker belong to that section up un- + til another section starts or a marker without a name is encoun- + tered or the file ends. Lines within sections are ignored unless + a CHOOSE directive has selected that section. NetHack 3.7 August 5, 2020 @@ -3436,6 +3436,9 @@ + You can use different configuration directives in the file, + some of which can be used multiple times. In general, the direc- + tives are written in capital letters, followed by an equals sign, followed by settings particular to that directive. Here is a list of allowed directives: @@ -3487,9 +3490,6 @@ pletion has no effect for the X11 windowport. You can specify multiple autocompletions. To enable autocompletion, list the extended command. Prefix the command with "!" to disable the - autocompletion for that command. - - NetHack 3.7 August 5, 2020 @@ -3502,6 +3502,8 @@ + autocompletion for that command. + Example: AUTOCOMPLETE=zap,!annotate @@ -3532,14 +3534,12 @@ OPTIONS=role:arc,race:dwa,align:law,gender:fem [char B] OPTIONS=role:wiz,race:elf,align:cha,gender:mal - END-CHOOSE + [] #end of CHOOSE OPTIONS=!rest_on_space - END-CHOOSE - An optional way to terminate CHOOSE. You can place an - END-CHOOSE directive after the last CHOOSE section in order to - follow that with other options which are common to all sec- - tions. Otherwise the last section extends to the end of the + If [] is present, the preceding section is closed and no new + section begins; whatever follows will be common to all sec- + tions. Otherwise the last section extends to the end of the options file. MENUCOLOR @@ -3547,15 +3547,15 @@ ing Menu Colors" section. MSGTYPE - Change the way messages are shown in the top status line. See + Change the way messages are shown in the top status line. See the "Configuring Message Types" section. ROGUESYMBOLS - Custom symbols for for the rogue level's symbol set. See SYM- + Custom symbols for for the rogue level's symbol set. See SYM- BOLS below. SOUND - Define a sound mapping. See the "Configuring User Sounds" + Define a sound mapping. See the "Configuring User Sounds" NetHack 3.7 August 5, 2020 @@ -3571,12 +3571,12 @@ section. SOUNDDIR - Define the directory that contains the sound files. See the + Define the directory that contains the sound files. See the "Configuring 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 + 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: @@ -3585,9 +3585,9 @@ SYMBOLS=S_boulder:0,S_golem:7 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 + 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. Example: @@ -3618,10 +3618,10 @@ 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. 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" + 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" NetHack 3.7 August 5, 2020 @@ -3635,7 +3635,7 @@ before the name. Others take a character string as a value. You - can set string options by typing the option name, a colon or + can set string options by typing the option name, a colon or equals sign, and then the value of the string. The value is ter- minated by the next comma or the end of string. @@ -3645,7 +3645,7 @@ % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" - in csh (note the need to escape the `!' since it's special to + 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" @@ -3655,38 +3655,38 @@ 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 + 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. If it does start with `/', the at-sign is op- + 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. If it does start with `/', the at-sign is op- tional. 9.4. Customization options Here are explanations of what the various options do. Char- - acter strings that are too long may be truncated. Some of the + acter 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 + Some options are persistent, and are saved and reloaded along with the game. Changing a persistent option in the config- uration file applies only to new games. acoustics - Enable messages about what your character hears (default on). + Enable messages about what your character hears (default on). Note that this has nothing to do with your computer's audio ca- pabilities. Persistent. align - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. The - default is to randomly pick an appropriate alignment. If you + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. The + default is to randomly pick an appropriate alignment. If you prefix the value with `!' or "no", you will exclude that align- - ment from being picked randomly. Cannot be set with the `O' + ment from being picked randomly. Cannot be set with the `O' command. Persistent. @@ -3701,7 +3701,7 @@ autodescribe - Automatically describe the terrain under cursor when asked to + Automatically describe the terrain under cursor when asked to get a location on the map (default true). The whatis_coord op- tion controls whether the description includes map coordinates. @@ -3710,28 +3710,28 @@ into a place that can be dug (default false). Persistent. autoopen - Walking into a closed door attempts to open it (default true). + Walking into a closed door attempts to open it (default true). Persistent. autopickup - Automatically pick up things onto which you move (default on). + Automatically pick up things onto which you move (default on). Persistent. See pickup_types to refine the behavior. 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 ready some suitable weapon. Note that it - will not take into account the blessed/cursed status, enchant- + 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, enchant- ment, damage, or quality of the weapon; you are free to manual- - ly fill your quiver or quiver sack or make ready with the `Q' + ly 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 - Walking into a locked door or looting a locked container while - carrying an unlocking tool (such as a key) will ask whether to - use that tool to unlock the door or container (default true). + Walking into a locked door or looting a locked container while + carrying an unlocking tool (such as a key) will ask whether to + use that tool to unlock the door or container (default true). Persistent. blind @@ -3739,19 +3739,19 @@ tent. bones - Allow saving and loading bones files (default true). Persis- + Allow saving and loading bones files (default true). Persis- tent. boulder - Set the character used to display boulders (default is the + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot + 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 ex- + Synonym for "role" to pick the type of your character (for ex- ample "character:Monk"). See role for more details. @@ -3767,29 +3767,29 @@ checkpoint - Save game state after each level change, for possible recovery + Save game state after each level change, for possible recovery after program crash (default on). Persistent. clicklook - Allows looking at things on the screen by navigating the mouse + Allows looking at things on the screen by navigating the mouse over them and clicking the right mouse button (default off). cmdassist - Have the game provide some additional command assistance for - new players if it detects some anticipated mistakes (default + 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 + Have user confirm attacks on pets, shopkeepers, and other peaceable creatures (default on). Persistent. dark_room Show out-of-sight areas of lit rooms (default on). Persistent. disclose - 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 re- + 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 re- sponse of `n' for each candidate). Persistent. The possibili- ties are: @@ -3800,8 +3800,8 @@ c - display your conduct; also achievements, if any; o - display dungeon overview. - Each disclosure possibility can optionally be preceded by a - prefix which lets you refine how it behaves. Here are the + 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; @@ -3809,14 +3809,14 @@ + - disclose it without prompting; - - do not disclose it and do not prompt. - The listing of vanquished monsters can be sorted, so there are + The listing of vanquished monsters can be sorted, so there are two additional choices for `v': ? - 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 + `+' disclose without prompting choice, or being prompted and answering `y' rather than `a', will default to showing monsters in the traditional order, from high level to low level. @@ -3834,16 +3834,16 @@ Omitted categories are implicitly added with `n' prefix. Spec- ified categories with omitted prefix implicitly use `+' prefix. - Order of the disclosure categories does not matter, program + 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 inven- + (for example "disclose:yi na +v -g o") The example sets inven- tory to prompt and default to yes, attributes to prompt and de- fault to no, vanquished to disclose without prompting, genocid- ed 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 + Note that the vanquished monsters list includes all monsters killed by traps and each other as well as by you. And the dun- geon overview shows all levels you had visited but does not re- veal things about them that you hadn't discovered. @@ -3853,39 +3853,39 @@ set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of + Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit + tional 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 avail- - able commands (on) or just the subset of commands which have + able commands (on) or just the subset of commands which have traditionally been considered extended ones (off). female - An obsolete synonym for "gender:female". Cannot be set with + An obsolete synonym for "gender:female". Cannot be set with the `O' command. fixinv - An object's inventory letter sticks to it when it's dropped - (default on). If this is off, dropping an object shifts all + 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 inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a + 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 - "fruit:mango") (default "slime mold"). Basically a nostalgic - whimsy that NetHack uses from time to time. You should set - this to something you find more appetizing than slime mold. - Apples, oranges, pears, bananas, and melons already exist in + 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 something 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 + Your starting gender (gender:male or gender:female). You may NetHack 3.7 August 5, 2020 @@ -3898,60 +3898,60 @@ - specify just the first letter. Although you can still denote + specify just the first letter. Although you can still denote your gender using the "male" and "female" options, the "gender" - option will take precedence. The default is to randomly pick - an appropriate gender. If you prefix the value with `!' or - "no", you will exclude that gender from being picked randomly. + option will take precedence. The default is to randomly pick + an appropriate gender. If you prefix the value with `!' or + "no", you will exclude that gender from being picked randomly. 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 de- - fault). Gold is never blessed or cursed, but it is not de- + 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 de- + fault). Gold is never blessed or cursed, but it is not de- scribed as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with + If more information is available for an object looked at with the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the "More info?" prompt, but it also + ing help off makes just looking at things faster, since you + aren't interrupted with the "More info?" prompt, but it also means that you might miss some interesting and/or important in- formation. Persistent. 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. Same as "#herecmdmenu" and "#therecmdmenu" com- + When using a windowport that supports mouse and clicking on + yourself or next to you, show a menu of possible actions for + the location. Same as "#herecmdmenu" and "#therecmdmenu" com- mands. hilite_pet - Visually distinguish pets from similar animals (default off). - The behavior of this option depends on the type of windowing + 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 + is often used; with tiles, generally displays a heart symbol near pets. - With the curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option + With the curses interface, the petattr option controls how to + 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 + 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 + 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. Only - available for TTY and Windows GUI, and only when statushilites + Show a hit point bar graph behind your name and title. Only + available for TTY and Windows GUI, and only when statushilites is on. horsename - Name your starting horse (for example "horsename:Trigger"). + Name your starting horse (for example "horsename:Trigger"). NetHack 3.7 August 5, 2020 @@ -3972,7 +3972,7 @@ implicit_uncursed Omit "uncursed" from object descriptions when it can be deduced - from other aspects of the description (default on). Persis- + from other aspects of the description (default on). Persis- tent. If you use menu coloring, you may want to turn this off. @@ -3982,42 +3982,42 @@ on). Persistent. lit_corridor - Show corridor squares seen by night vision or a light source + Show corridor squares seen by night vision or a light source held by 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 + 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 + 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 de- - scribed when covered by one or more objects (default off). + Give feedback when walking onto various dungeon features such + as stairs, fountains, or altars which are ordinarily only de- + scribed when covered by one or more objects (default off). Persistent. mention_walls - Give feedback when walking against a wall (default off). Per- + Give feedback when walking against a wall (default off). Per- sistent. menucolors - Enable coloring menu lines (default off). See "Configuring + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for early versions; it - consists of a prompt for object class characters, followed by + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for early versions; it + consists of a prompt for object class characters, followed by NetHack 3.7 August 5, 2020 @@ -4030,22 +4030,22 @@ - an object-by-object prompt for all items matching the selected - object class(es). Combination starts with a prompt for object + an object-by-object prompt for all items matching the selected + object class(es). Combination starts with a prompt for object class(es) of interest, but then displays a menu of matching ob- - jects 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. Partial skips the ob- + jects 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. Partial skips the ob- ject class filtering and immediately displays a menu of all ob- jects. Persistent. menu_deselect_all - Menu character accelerator to deselect all items in a menu. + Menu character accelerator to deselect all items in a menu. Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- fault `\'. menu_first_page @@ -4053,34 +4053,34 @@ Implemented by the Amiga, Gem and tty ports. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Values - are "none", "bold", "dim", "underline", "blink", or "inverse". + Controls how the headings in a menu are highlighted. Values + are "none", "bold", "dim", "underline", "blink", or "inverse". Not all ports can actually display all types. menu_invert_all - Menu character accelerator to invert all items in a menu. Im- + Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `@'. menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `~'. menu_last_page - Menu character accelerator to jump to the last page in a menu. + Menu character accelerator to jump to the last page in a menu. Implemented by the Amiga, Gem and tty ports. Default `|'. menu_next_page - Menu character accelerator to goto the next menu page. Imple- + Menu character accelerator to goto the next menu page. Imple- mented by the Amiga, Gem and tty ports. Default `>'. menu_objsyms - Show object symbols in menu headings in menus where the object + Show object symbols in menu headings in menus where the object symbols act as menu accelerators (default off). menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- fault on) @@ -4101,16 +4101,16 @@ plemented by the Amiga, Gem and tty ports. Default `<'. menu_search - Menu character accelerator to search for a menu item. Imple- + Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default `:'. menu_select_all - Menu character accelerator to select all items in a menu. Im- + Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `.'. menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `,'. monpolycontrol @@ -4118,24 +4118,24 @@ off). Debug mode only. mouse_support - Allow use of the mouse for input and travel. Valid settings + Allow use of the mouse for input and travel. Valid settings are: 0 - disabled 1 - enabled and make OS adjustments to support mouse use 2 - like 1 but does not make any OS adjustments - Omitting a value is the same as specifying 1 and negating + Omitting a value is the same as specifying 1 and negating mouse_support is the same as specifying 0. msghistory - The number of top line messages to keep (and be able to recall + 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. - Currently it is only supported for tty (all four choices) and - for curses (`f' and `r' choices, default `r'). The possible + Allows you to change the way recalled messages are displayed. + Currently 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); @@ -4143,13 +4143,13 @@ 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 + For backward compatibility, no value needs to be specified + (which defaults to "full"), or it can be negated (which defaults to "single"). 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 + Set your character's name (defaults to your user name). You + can also set your character's role by appending a dash and one NetHack 3.7 August 5, 2020 @@ -4163,8 +4163,8 @@ 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. Cannot + -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. Cannot be set with the `O' command. news @@ -4179,7 +4179,7 @@ Send padding nulls to the terminal (default on). Persistent. number_pad - Use digit keys instead of letters to move (default 0 or off). + Use digit keys instead of letters to move (default 0 or off). Valid settings are: 0 - move by letters; "yuhjklbn" @@ -4189,33 +4189,33 @@ 4 - combines 3 with 2; phone layout plus MS-DOS compatibility -1 - by letters but use `z' to go northwest, `y' to zap wands - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 2 and 4 are for compatibility with MS-DOS or old + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 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 accommo- - date some QWERTZ keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a + date some QWERTZ keyboards 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' + 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 containing the symbols for the various object types. Any omit- ted 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_confirma- + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma- tion:pray. - Confirm - for any prompts which are set to require "yes" - rather than `y', also require "no" to reject in- + Confirm - for any prompts which are set to require "yes" + rather than `y', also require "no" to reject in- stead of accepting any non-yes response as no quit - require "yes" rather than `y' to confirm quitting - the game or switching into non-scoring explore + the game or switching into non-scoring explore NetHack 3.7 August 5, 2020 @@ -4229,41 +4229,41 @@ mode; - die - require "yes" rather than `y' to confirm dying - (not useful in normal play; applies to explore + 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 - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attack- + attack - require "yes" rather than `y' to confirm attack- ing a peaceful monster; wand-break - require "yes" rather than `y' to confirm breaking a wand; - eating - require "yes" rather than `y' to confirm whether + 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 + form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather + pray - require `y' to confirm an attempt to pray rather than immediately praying; on by default; - Remove - require selection from inventory for `R' and `T' - commands even when wearing just one applicable + Remove - require selection from inventory for `R' and `T' + commands even when wearing just one applicable item. all - turn on all of the above. - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use "paranoid_confirmation:none". To keep it enabled while setting - any of the others, include it in the list, such as "para- + any of the others, include it in the list, such as "para- noid_confirmation:attack pray Remove". perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. petattr - Specifies one or more text highlighting attributes to use when - showing pets on the map. Effectively a superset of the + Specifies one or more text highlighting attributes to use when + showing pets on the map. Effectively a superset of the hilite_pet boolean option. Curses interface only; value is one or more of the following letters. @@ -4277,8 +4277,8 @@ l - Left line indicator r - Right line indicator - Some of those choices might not work, particularly the final - three, depending upon terminal hardware or terminal emulation + Some of those choices might not work, particularly the final + three, depending upon terminal hardware or terminal emulation software. @@ -4294,31 +4294,31 @@ - Currently multiple highlight-style letters can be combined by - simply stringing them together (for example, "bk"), but in the - future they might require being separated by plus signs (such - as "b+k", which works already). When using the `n' choice, it - should be specified on its own, not in combination with any of + Currently multiple highlight-style letters can be combined by + simply stringing them together (for example, "bk"), but in the + future they might require being separated by plus signs (such + as "b+k", which works already). When using the `n' choice, it + should be specified on its own, not in combination with any of the other letters. 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", + 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". If the choice is not allowed for the role - you are currently playing, it will be silently ignored. For - example, "horse" will only be honored when playing a knight. + you are currently playing, it will be silently ignored. For + example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. (Default `S'). Persistent. 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 + 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 @@ -4328,26 +4328,26 @@ sistent. 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 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. + 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 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. playmode - Values are "normal", "explore", or "debug". Allows selection - of explore mode (also known as discovery mode) or debug mode + 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 + 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 it when not allowed or not possible re- + entirely. Requesting it when not allowed or not possible re- sults in explore mode instead. Default is normal play. pushweapon - Using the `w' (wield) command when already wielding something + Using the `w' (wield) command when already wielding something NetHack 3.7 August 5, 2020 @@ -4360,52 +4360,52 @@ - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. quick_farsight - When set, usually prevents the "you sense your surroundings" - message where play pauses to allow you to browse the map when- + When set, usually prevents the "you sense your surroundings" + message where play pauses to allow you to browse the map when- ever clairvoyance randomly activates. Some situations, such as - being underwater or engulfed, ignore this option. It does not + being underwater or engulfed, ignore this option. It does not affect the clairvoyance spell where pausing to examine revealed - objects or monsters is less intrusive. Default is off. Per- + objects or monsters is less intrusive. Default is off. Per- sistent. race Selects your race (for example, "race:human"). Default is ran- - dom. If you prefix the value with `!' or "no", you will ex- + dom. If you prefix the value with `!' or "no", you will ex- clude that race from being picked randomly. Cannot be set with the `O' command. Persistent. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (de- + Make the space bar a synonym for the `.' (#wait) command (de- fault off). Persistent. role - Pick your type of character (for example "role:Samurai"); syn- - onym for "character". See "name" for an alternate method of - specifying your role. Normally only the first letter of the - value is examined; `r' is an exception with "Rogue", "Ranger", + Pick your type of character (for example "role:Samurai"); syn- + onym for "character". See "name" for an alternate method of + specifying your role. Normally only the first letter of the + value is examined; `r' is an exception with "Rogue", "Ranger", and "random" values. If you prefix the value with `!' or "no", - you will exclude that role from being picked randomly. Cannot + you will exclude that role from being picked randomly. Cannot be set with the `O' command. Persistent. roguesymset - This option may be used to select one of the named symbol sets - found within "symbols" to alter the symbols displayed on the + This option may be used to select one of the named symbol sets + found within "symbols" to alter the symbols displayed on the screen on the rogue level. rlecomp When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has + 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 - control+direction and so forth, or via the travel command or + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -4413,7 +4413,7 @@ 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 + This option only affects the game's screen display, not the NetHack 3.7 August 5, 2020 @@ -4427,12 +4427,12 @@ actual results of moving. The default is "run"; versions prior - to 3.4.1 used "teleport" only. Whether or not the effect is + 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. Persistent. safe_pet - Prevent you from (knowingly) attacking your pets (default on). + Prevent you from (knowingly) attacking your pets (default on). Persistent. sanity_check @@ -4440,8 +4440,8 @@ 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 + 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. @@ -4450,9 +4450,9 @@ off). Persistent. showrace - Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4464,21 +4464,21 @@ sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + 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, + 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. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. sparkle Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- + hit by an attack to which it is resistant (default on). Per- sistent. @@ -4496,33 +4496,33 @@ Boldface monsters and "--More--" (default off). Persistent. statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. See "Configuring 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 + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (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 "symset:default" to explicitly select the default + 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 "symset:default" to explicitly select the default symbols. time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface only; "X11" interface always uses a timer based delay. The de- fault is on if configured into the program.) Persistent. @@ -4532,20 +4532,20 @@ toptenwin Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map win- - dow. Does not affect traveling via the `_' ("#travel") com- + ed moves if you make inadvertent mouse clicks on the map win- + dow. Does not affect traveling via the `_' ("#travel") com- mand. Persistent. verbose - Provide more commentary during the game (default on). + Provide more commentary during the game (default on). NetHack 3.7 August 5, 2020 @@ -4561,9 +4561,9 @@ Persistent. whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -4580,38 +4580,38 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possi- + through next and previous targets, allows filtering the possi- ble 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 + 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 + Filtering can also be changed when getting a location with the "getpos.filter" key. whatis_menu - When getting a location on the map, and using a key to cycle + 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. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement + 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 de- + select which one to use, such as "tty" or "X11" (default de- pends 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 + When used, it should be the first option set since its value + might enable or disable the availability of various other NetHack 3.7 August 5, 2020 @@ -4624,9 +4624,9 @@ - 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 + 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 option in the list. wizweight @@ -4634,35 +4634,35 @@ 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 + 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 + 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 adjust- - ing 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 + 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 adjust- + ing 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. Some options - are dynamic and can be specified during the game with the `O' + 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, + 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, + Where to align or place the status window (top, bottom, left, or right). ascii_map - If NetHack can, it should display an ascii character map if it + If NetHack can, it should display an ascii character map if it can. color @@ -4670,8 +4670,8 @@ monsters, objects, and dungeon features. eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to your terminal (default off). font_map @@ -4691,7 +4691,7 @@ font_menu - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -4703,45 +4703,45 @@ status window. font_text - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for text windows. font_size_map - If NetHack can, it should use this size font for the map win- + If NetHack can, it should use this size font for the map win- dow. 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 + 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 + 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. fullscreen - If NetHack can, it should try and display on the entire screen + If NetHack can, it should try and display on the entire screen rather than in a window. guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- terface only; default is on. large_font If NetHack can, it should use a large font. map_mode - If NetHack can, it should display the map in the manner speci- + If NetHack can, it should display the map in the manner speci- fied. player_selection - If NetHack can, it should pop up dialog boxes, or use prompts + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. @@ -4761,27 +4761,27 @@ preload_tiles If NetHack can, it should preload tiles into memory. For exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount - If NetHack can, it should scroll the display by this number of + If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- dow. selectsaved - If NetHack can, it should display a menu of existing saved + If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to + Display an onscreen keyboard. Handhelds are most likely to support this option. splash_screen @@ -4789,27 +4789,27 @@ 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). Curses and tty + Number of lines for traditional below-the-map status display. + Acceptable values are 2 and 3 (default is 2). Curses and tty interfaces only. term_cols and term_rows - Curses interface only. Number of columns and rows to use for + Curses interface only. Number of columns and rows to use for the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. + ified but will settle for smaller sizes if they are too big. Default is the current window size. tiled_map If NetHack can, it should display a tiled map if it can. 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. tile_height - Specify the preferred height of each tile in a tile capable + Specify the preferred height of each tile in a tile capable NetHack 3.7 August 5, 2020 @@ -4831,42 +4831,42 @@ Use bold black instead of blue for black glyphs (TTY only). use_inverse - If NetHack can, it should display inverse when the game speci- + If NetHack can, it should display inverse when the game speci- fies it. vary_msgcount - If NetHack can, it should display this number of messages at a + 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 in- + Whether to draw boxes around the map, status area, message + area, and persistent inventory window if enabled. Curses in- terface only. Acceptable values are 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) (default) - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns + (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 for align_status set to left or right.) windowcolors - If NetHack can, it should display windows with the specified + If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- text). wraptext @@ -4890,12 +4890,12 @@ 9.6. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be set with the `O' command. @@ -4905,23 +4905,23 @@ altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). flush @@ -4934,14 +4934,14 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of + (Win32 tty NetHack only). May be used to alter the value of NetHack 3.7 August 5, 2020 @@ -4955,53 +4955,53 @@ keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assign- - ments in the configuration file if needed. Cannot be set with + ments in the configuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause + tect", "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA - hardware. Setting "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 of those modes works. Cannot be set + hardware. Setting "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 of those modes works. Cannot be set with the `O' command. video_height - Set the VGA mode resolution height (MS-DOS only, with + Set the VGA mode resolution height (MS-DOS only, with video:vesa) video_width - Set the VGA mode resolution width (MS-DOS only, with + 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 bright.cyan. Cannot be set with the `O' + 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 (de- fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the `O' command. 9.7. Regular Expressions - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -5025,29 +5025,29 @@ 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 + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as 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 oc- + In addition, some characters are treated specially if they oc- cur 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 + 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 save and then restore your game. autopickup_ex- + 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 save and then restore your game. autopickup_ex- ception rules and not saved with the game. Here are some examples: @@ -5056,17 +5056,17 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - 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 ex- + 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 ex- clusion of items known to be cursed from autopickup. 9.9. 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 + 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"), or a three-digit decimal ASCII code. @@ -5091,25 +5091,25 @@ BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a key by using "nothing" as the extended command to bind - to. You can also bind the "", "", and "" + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- + The menu control or accelerator keys can also be rebound via + OPTIONS lines in the configuration file. You cannot bind ob- ject symbols into menu accelerators. 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 "context", and if bound to same keys, only one of those - commands will be available. Special command can only be bound + 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 "context", 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 + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. doinv @@ -5119,19 +5119,19 @@ Prefix key to force fight a direction. Default is `F'. fight.numpad - Prefix key to force fight a direction. With number_pad only. + Prefix key to force fight a direction. With number_pad only. Default is `-'. getdir.help - When asked for a direction, the key to show the help. Default + When asked for a direction, the key to show the help. Default is `?'. getdir.self - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `.'. getdir.self2 - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `s'. getpos.autodescribe @@ -5139,7 +5139,7 @@ fault is `#'. getpos.all.next - When asked for a location, the key to go to next closest + When asked for a location, the key to go to next closest NetHack 3.7 August 5, 2020 @@ -5155,55 +5155,55 @@ interesting thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest interesting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door + When asked for a location, the key to go to next closest door or doorway. Default is `d'. getpos.door.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest door or doorway. Default is `D'. getpos.help - When asked for a location, the key to show help. Default is + 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 mon- + When asked for a location, the key to go to next closest mon- ster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest monster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest ob- + When asked for a location, the key to go to next closest ob- ject. Default is `o'. getpos.obj.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest object. Default is `O'. getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- stead. 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 + 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 + 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 + When asked for a location, the key to choose the location, and possibly ask for more info. Default is `.'. @@ -5219,16 +5219,16 @@ getpos.pick.once - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. getpos.pick.quick When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- + asking for more info, and exit the location asking loop. De- fault is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self @@ -5236,23 +5236,23 @@ fault is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unex- + When asked for a location, the key to go to next closest unex- plored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest unexplored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target + When asked for a location, the key to go to show valid target locations. Default is `$'. getpos.valid.next - When asked for a location, the key to go to next closest valid + When asked for a location, the key to go to next closest valid location. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest valid location. Default is `Z'. nopickup @@ -5262,7 +5262,7 @@ Key to redraw the screen. Default is `^R'. redraw.numpad - Key to redraw the screen. With number_pad only. Default is + Key to redraw the screen. With number_pad only. Default is `^L'. repeat @@ -5288,11 +5288,11 @@ Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad - Prefix key to run towards a direction. With number_pad only. + Prefix key to run towards a direction. With number_pad only. Default is `5'. rush @@ -5303,7 +5303,7 @@ 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 + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5316,27 +5316,27 @@ 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 mes- + norep - show the message once, but not again if no other mes- sage is shown in between. - Here's an example of message types using NetHack's internal + 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 + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when the line matches a user-defined pattern. At this time the tty, curses, win32tty and win32gui interfaces support this. @@ -5350,56 +5350,56 @@ - In general, the configuration file entries to describe the + 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 pat- + color - the color to use for lines matching the pat- tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- - genta, light-cyan, and white. And no-color, the default fore- - ground color, which isn't necessarily the same as any of the + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- + 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 line will be shown in red color and under- lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu + uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. @@ -5416,24 +5416,24 @@ - The following configuration file entries are relevant to + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + 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 3.6); pattern - the pattern to match; sound file - the sound file to play; - volume - the volume to be set while playing the sound + volume - the volume to be set while playing the sound file; - sound index - optional; the index corresponding to a sound + sound index - optional; the index corresponding to a sound file. The pattern should be a POSIX extended regular expression. @@ -5441,7 +5441,7 @@ 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5449,8 +5449,8 @@ 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 + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -5458,15 +5458,15 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground color on the display, which is not necessarily the same as black or white or any of the other colors. @@ -5482,26 +5482,26 @@ - Allowed attributes are none, bold, dim, underline, blink, - and inverse. "Normal" is a synonym for "none"; they should not + Allowed attributes are none, bold, dim, underline, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5512,16 +5512,16 @@ 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 condition- + 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 condition- ally displayed depending upon your other option settings. - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. @@ -5530,12 +5530,12 @@ * "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 + * "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 val- - ue changes. This attribute times out after statushilites + ue changes. This attribute times out after statushilites NetHack 3.7 August 5, 2020 @@ -5548,51 +5548,51 @@ - turns. (If a field has both a "changed" rule and an "up" - or "down" rule which matches a change in the field's val- + turns. (If a field has both a "changed" rule and an "up" + or "down" rule which matches a change in the field's val- ue, 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 be- - tween 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 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 corresponding maxi- - mum field. Percentage highlight rules are also allowed + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- perience level to the start of the next level. So if lev- - el 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 + el 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 + a rule for =100% is allowed and matches the special case of being exactly 1 experience point short of the next lev- el. - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only match when strictly above or below. * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". For title, only the role's rank title is tested; + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- + The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: @@ -5629,23 +5629,23 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols @@ -5884,53 +5884,53 @@ Notes: * 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 en- + space character, except for S_pet_override and S_hero_override + which don't have any default value and can only be used if en- abled 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 de- - pict. So S_rock is only used for boulders and not used at all + * 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 de- + pict. So S_rock is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. 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 charac- + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- ter 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 + 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 location of items on the screen. - 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 message handler", your NetHack has been compiled + 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 message 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 environment variable NETHACK_MSGHANDLER + and other POSIX systems, define MSGHANDLER to enable it. To use + the capability, set the environment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task somewhat daunting. Included within the "symbols" file of all of- ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your @@ -5945,19 +5945,19 @@ configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- abled in the sysconf file. - The most crucial settings to make the game more accessible + The most crucial settings to make the game more accessible are: symset:NHAccess Load a symbol set appropriate for use by blind players. roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional @@ -5967,34 +5967,34 @@ 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 + 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. autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip - When targeting with cursor and using fast-move, skip the same + When targeting with cursor and using fast-move, skip the same glyphs 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 in- + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. @@ -6012,16 +6012,16 @@ 9.16. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed + 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. @@ -6029,38 +6029,38 @@ SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS = A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- + SUPPORT = A string explaining how to get local support (no de- fault value). - RECOVER = A string explaining how to recover a game on this + 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, WIZ- + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. @@ -6077,8 +6077,8 @@ 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6087,26 +6087,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6122,12 +6122,12 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on + 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 + 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. @@ -6142,55 +6142,55 @@ - Your score is chiefly based upon how much experience you + 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 + 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 all your gold, but if + 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 + 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 + 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 paltry cost of not getting on the high score + "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 game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - other benefits of explore mode are left for the trepid reader to + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 + vide god-like powers 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 par- - ticular 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 + For some systems, the player must be logged in under a par- + ticular 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. @@ -6210,55 +6210,55 @@ 12. Credits - 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 + 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 Dungeons of Doom, by Ken Arromdee. NetHack is the product of literally scores of people's work. - Main events in the course of the game development are described + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting + Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming Hack into a very different game. He published the Hack - source code for use on UNIX systems by posting that to Usenet + forming 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 ver- sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 1.0.3 in July of 1985. Usenet newsgroup net.games.hack - (later renamed rec.games.hack, eventually replaced by + nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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. @@ -6274,57 +6274,57 @@ - 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 + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 + Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor and so forth, not separate images for beetles and ants or for cloaks and boots). @@ -6340,58 +6340,58 @@ - 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 ob- + 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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. @@ -6406,59 +6406,59 @@ - (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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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 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 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 plat- + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows CE port for 3.4.1. @@ -6473,12 +6473,12 @@ 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 + 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 + 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 af- @@ -6487,44 +6487,44 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 + velopment 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 Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 @@ -6540,49 +6540,49 @@ restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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 en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6607,19 +6607,19 @@ 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6677,7 +6677,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. From e1cab093bdacf1015581aa450ed4a2c78789bff8 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 7 Aug 2020 16:05:11 -0700 Subject: [PATCH 085/708] fix put request #377 - worm mismanagement An earlier change resulted in place_worm_tail_randomly() sometimes removing a long worm from the map unintentionally. It was still on the monster list so if wizard mode sanity_check option was On, there would be warnings of a monster which isn't on the map. The change which triggered this was necessary so I'm inclined to blame place_worm_tail_randomly() laziness. This is a superset of the pull request's fix. Fixes #377 --- doc/fixes37.0 | 7 ++++++- src/worm.c | 16 ++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 857c26fce..b5f63675c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.276 $ $NHDT-Date: 1596785361 2020/08/07 07:29:21 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.277 $ $NHDT-Date: 1596841504 2020/08/07 23:05:04 $ General Fixes and Modified Features ----------------------------------- @@ -313,6 +313,11 @@ some versions of tiles processing (not X11's) complained about the rename of "{acid,blinding} venom" to "splash of {acid,blinding} venom" wizard mode #timeout changed to show timed Displacement in 'can be timed in normal play' section instead of 'timed via #wizintrinsic only' section +the fix to make worm visibility checks work as intended forced the coordinates + of the extra tail segment co-located with the worm monster to match + the worm instead of leaving it off the map; place_worm_tail_randomly() + reverses the segments and can throw some away if there isn't room, + but throwing away the extra segment removed the worm from the map curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/worm.c b/src/worm.c index 7deb90cb6..c32c8c928 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worm.c $NHDT-Date: 1596498230 2020/08/03 23:43:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 3.7 worm.c $NHDT-Date: 1596841504 2020/08/07 23:05:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -727,6 +727,18 @@ xchar x, y; impossible("place_worm_tail_randomly: wormno is set without a tail!"); return; } + if (wtails[wnum] == wheads[wnum]) { + /* single segment, co-located with worm so nothing to place */ + if (curr->wx != worm->mx || curr->wy != worm->my) + impossible( + "place_worm_tail_randomly: tail segement at <%d,%d>, worm at <%d,%d>", + curr->wx, curr->wy, worm->mx, worm->my); + return; + } + /* remove head segment from map in case we end up calling toss_wsegs(); + if it doesn't get tossed, it will become the final tail segment and + get new coordinates */ + wheads[wnum]->wx = wheads[wnum]->wy = 0; wheads[wnum] = new_tail = curr; curr = curr->nseg; @@ -736,7 +748,7 @@ xchar x, y; while (curr) { xchar nx, ny; - char tryct = 0; + int tryct = 0; /* pick a random direction from x, y and search for goodpos() */ do { From a8502126d62cb732e72cabde149fbaeaa8161f9f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 8 Aug 2020 18:21:38 -0700 Subject: [PATCH 086/708] Qt menu bandaid Menu hackery: change a couple of menu entry names on OSX to control where they end up. Move nethack's 'O' command from its hijacked position (due to name "Options") of "nethack->Preferences..." to "Game->Run-time options". Move persistent Qt settings on OSX from "Game->Qt settings" to "nethack->Preferences...". The Qt settings dialog (now accessed as Preferences...) desperately needs a title and/or other explanatory text but I haven't figured out how do to that. The values set with it are persistent, with apparently quite a few choices for where to save them for future runs. I used it to increase the size of text in the status window, and found my settings stored in binary file ~/Library/Preferences/org.nethack.NetHack.plist The subdirectories ~/Library and ~/Library/Preferences are standard OSX per-user things. The file name is derived from values set up in main routine: qt_main.cpp is setting OrganizationDomain to "nethack.org" and ApplicationName to "NetHack". I've added a value for ApplicationVersion but don't know whether anything cares about it. --- doc/fixes37.0 | 7 ++++-- win/Qt/qt_main.cpp | 61 ++++++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 15 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b5f63675c..7f5bc138f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.277 $ $NHDT-Date: 1596841504 2020/08/07 23:05:04 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.278 $ $NHDT-Date: 1596936095 2020/08/09 01:21:35 $ General Fixes and Modified Features ----------------------------------- @@ -355,7 +355,6 @@ Qt: switch to fixed-width font for menus Qt: don't disable [cancel] button when viewing inventory or other pick-none menus; ESC works to dismiss those and [cancel] should be the same Qt: bring status conditions up to 3.6 levels but new ones lack pictures -Qt: fix control key on OSX Qt: clicking on the window's Close button brought up a dialog offering choices of "Save" and "Cancel"; picking Cancel sent nethack into an infinite loop with complaints about Qt's event loop already being @@ -363,6 +362,10 @@ Qt: clicking on the window's Close button brought up a dialog offering with no opportunity to try to back out of the Close operation Qt: add 3.6 status fields Stone, Slime, Strngl, Deaf, Lev, Fly, Ride Qt: add Attributes, Overview, and Annotate to the "Info" pull down menu +Qt+QSX: fix control key +Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's + 'O' command to "Game->Run-time options" and entry "Game->Qt settings" + for making persistent Qt customizations to "nethack->Preferences..." tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 0f6870b9d..163616d76 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -520,6 +520,11 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : QCoreApplication::setOrganizationName("The NetHack DevTeam"); QCoreApplication::setOrganizationDomain("nethack.org"); QCoreApplication::setApplicationName("NetHack"); + { + char cvers[BUFSZ]; + QString qvers = version_string(cvers); + QCoreApplication::setApplicationVersion(qvers); + } #ifdef MACOSX /* without this, neither control+x nor option+x do anything; with it, control+x is ^X and option+x still does nothing */ @@ -527,11 +532,24 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : #endif setWindowTitle("Qt NetHack"); - if ( qt_compact_mode ) - setWindowIcon(QIcon(QPixmap(nh_icon_small))); - else - setWindowIcon(QIcon(QPixmap(nh_icon))); + setWindowIcon(QIcon(QPixmap(qt_compact_mode ? nh_icon_small : nh_icon))); +#ifdef MACOSX + /* + * OSX Note: + * The toolbar on OSX starts with a system menu labeled with the + * Apple logo and an application menu labeled with the application's + * name (taken from Info.plist if present, otherwise the base name + * of the running program). After that, application-specific menus + * (in our case "game",...,"help") follow. Several menu entry + * names ("About", "Quit"/"Exit", "Preferences"/"Options"/ + * "Settings"/"Setup"/"Config") get hijacked and placed in the + * application menu (and renamed in the process) even if the code + * here tries to put them in another menu. + * See QtWidgets/doc/qmenubar.html for slightly more information. + * setMenuRole() is supposed to be able to override this behavior. + */ +#endif QMenu* game=new QMenu; QMenu* apparel=new QMenu; QMenu* act1=new QMenu; @@ -540,7 +558,6 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : QMenu* info=new QMenu; QMenu *help; - #ifdef KDE help = kapp->getHelpMenu( true, "" ); help->addSeparator(); @@ -560,7 +577,15 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { game, "Compilation", 3, doextversion}, { game, "History", 3, dohistory}, { game, "Redraw", 0, doredraw}, // useless - { game, "Options", 3, doset}, + { game, +#ifndef MACOSX + "Options", +#else + /* Qt on OSX would rename "Options" to "Preferences..." and + move it from intended destination to the application menu */ + "Run-time options", +#endif + 3, doset}, { game, "Explore mode", 3, enter_explore_mode}, { game, 0, 3}, { game, "Save", 3, dosave}, @@ -574,11 +599,11 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { apparel, "Two weapon combat", 3, dotwoweapon}, { apparel, "Load quiver", 3, dowieldquiver}, { apparel, 0, 3}, - { apparel, "Wear armour", 3, dowear}, - { apparel, "Take off armour", 3, dotakeoff}, + { apparel, "Wear armor", 3, dowear}, + { apparel, "Take off armor", 3, dotakeoff}, { apparel, 0, 3}, - { apparel, "Put on non-armour", 3, doputon}, - { apparel, "Remove non-armour", 3, doremring}, + { apparel, "Put on accessories", 3, doputon}, + { apparel, "Remove accessories", 3, doremring}, /* { act1, "Again\tCtrl+A", "\001", 2}, { act1, 0, 0, 3}, */ @@ -636,10 +661,10 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { info, "Conduct", 3, doconduct}, { info, "Discoveries", 3, dodiscovered}, { info, "List/reorder spells", 3, dovspell}, - { info, "Adjust inventory letters", 2, doorganize }, + { info, "Adjust inventory letters", 3, doorganize }, { info, 0, 3}, { info, "Name object or creature", 3, docallcmd}, - { info, "Annotate level", 2, donamelevel }, + { info, "Annotate level", 3, donamelevel }, { info, 0, 3}, { info, "Skills", 3, enhance_weapon_skill}, @@ -648,7 +673,17 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : int i; - game->addAction("Qt settings...",this,SLOT(doQtSettings(bool))); + game->addAction( +#ifndef MACOSX + "Qt settings...", +#else + /* on OSX, put this in the application menu by using + a name that Qt will move to that menu */ + "Preferences...", +#endif + this, SLOT(doQtSettings(bool))); + /* on OSX, 'about' will end up in the application menu + rather than the help menu; at present, just live with that */ help->addAction("About Qt NetHack...",this,SLOT(doAbout(bool))); //help->addAction("NetHack Guidebook...",this,SLOT(doGuidebook(bool))); help->addSeparator(); From 07510fc833520bcdd848fa177e887e6e517abb80 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 8 Aug 2020 18:42:26 -0700 Subject: [PATCH 087/708] Qt Confusion icon In the Qt status panel the six characteristics and the older status conditions all have icons (similar to map tiles) drawn above their values. (The 3.6 era conditions that I added all have blank icons and are in need of artwork. 3.7 conditions aren't implemented.) Int, Stun, and Conf all feature a brain oriented towards the player's right shoulder. The intelligence one is just a bare brain, the stunned one features a black cloud over it, and the confusion one has something over it that is cloud-like but shaped differently from Stun as well has being white rather than black; I'm not sure what that depicts. This transposes the Confusion icon so that it faces the player's left shoulder instead of right. Not a very emphatic suggestion of confusion but seems a useful difference without requiring any artistic competence. --- win/Qt/qt_xpms.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/win/Qt/qt_xpms.h b/win/Qt/qt_xpms.h index 2c842b84b..3f674ceb3 100644 --- a/win/Qt/qt_xpms.h +++ b/win/Qt/qt_xpms.h @@ -305,6 +305,49 @@ static const char *confused_xpm[] = { "* c #303030", "= c #6C91B6", /* pixels */ +#if 1 +/* mirror image of original; confused brain is facing the other way */ +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOO+.OO+O+OO.O+.=OO+.=.OOOOOOOOOOOOO", +"OOOOOO+O=++==+O=+=====O=====++OOOOOOOOOO", +"OOOOO+=O+==OO===++++=.=====.=+OOOOOOOOOO", +"OOOO======OoO&+===o==o=+.===+=OOOOOOOOOO", +"O.O.=+==+Oo&o==oO&&&&o=+OO====+O+OOOOOOO", +"O=+=O==Oooo&=ooo&o&oOooo=o&&+==O+=+.+OOO", +"O==++==+o&==o=oo&&o&=&oo=oo===O++OOOOOOO", +"OO=======oo&&o&oo&o&OO&o====O=.o=OOOOOOO", +"OOOO=====O&o=oOOoooo=Ooo=O=O=+===oOOOOOO", +"OOOO+===O=o=O====oo=O=======+==+OOOOOOOO", +"OOOOO======O========O====+=X=#=.OOOOOOOO", +"OOOO+==OO==========O====%#=.++oX#.OOOOOO", +"OOOO+==+=+=O====+====X==.=#.+#+#oX+OOOOO", +"OOOOO.OO+o===##Xo====.X=#.##===O+.+.OOOO", +"OOOO+=oOO=...+#O#X#==+#.o##O#O####+#OOOO", +"OOOOo=OO+==+X+#.X#+#.O#.#++++X+#+o#++OOO", +"OOOOOOO..+##+#XX+..#++#++X##.+X..+.+#OOO", +"OOOOOOO#+#+..X#+#+X+#++.+#++#+O....##OOO", +"OOOOOO$X.++#.##++.#XX#X#X+O#+#.+.+#++OOO", +"OOOOO**+##X+X+###X+##+++.++#+++.+#+#OOOO", +"OOOO@ *#+#+X#+.++..+.###o##.+#OO#..#OOOO", +"OOOO$ *#.+###++##+###.+++.O#+#+O#.#+OOOO", +"OOOO* ###+#.##..+#++##X..o#+#+#+XXOOOOO", +"OOOO %%XX%####+..+#.+#+#+#+X#.#XOOOOOO", +"OOOO* %.=++X.+#+#+#++.#+#+#.X%%.OOOOOOO", +"OOOO$ %#%%%%XX+.####O.+#+##* *.OOOOOOOO", +"OOOO$ X#+++.=XXX+++#.+.X% .OOOOOOOOOO", +"OOOO$ *X%####.=%X#..X%% *.OOOOOOOOOOO", +"OOOOO *=###%X#.=%%%XX* $.OOOOOOOOOOOOO", +"OOOOO@ *=#.+.#%%=%%%+OOOOOOOOOOOOOOOOO", +"OOOOOO *%X##X==%%%=oOOOOOOOOOOOOOOOOO", +"OOOOOO@ *%=X%%%%X+OOOOOOOOOOOOOOOOOO", +"OOOOOOO@* X%%%%XOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOO$$* *X%%%=OOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOO. =%%X+OOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO %%%XOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO$ *%%=OOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO$ %%%=OOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO$ %%%+OOOOOOOOOOOOOOOOOOOO" +#else "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", "OOOOOOOOOOOOOO.=.+OO=.+O.OO+O+OO.+OOOOOO", "OOOOOOOOOOO++=====O=====+=O+==++=O+OOOOO", @@ -345,6 +388,7 @@ static const char *confused_xpm[] = { "OOOOOOOOOOOOOOOOOOOOO=%%* $OOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOO=%%% $OOOOOOOOOOOOO", "OOOOOOOOOOOOOOOOOOOOO+%%% $OOOOOOOOOOOOO" +#endif }; /* XPM */ static const char *dex_xpm[] = { From 251fd5c0f7f8359665e9cb1e742e6b2f0dd0b0cd Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 9 Aug 2020 12:36:13 -0700 Subject: [PATCH 088/708] X11 icons Update the two X11 bitmaps which have embedded version numbers, nh32icon and nh56icon. ("3.6" -> "3.7"; the third, nh72icon, doesn't show version.) --- win/X11/nh32icon | 6 +++--- win/X11/nh56icon | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/win/X11/nh32icon b/win/X11/nh32icon index e080e3b1c..cdacc920b 100644 --- a/win/X11/nh32icon +++ b/win/X11/nh32icon @@ -1,4 +1,4 @@ -/* NetHack 3.7 nh32icon $NHDT-Date: 1596498369 2020/08/03 23:46:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* 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 may be freely redistributed. See license for details. */ @@ -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, 0x08, 0x90, 0x89, 0x81, 0x08, 0x80, 0x81, 0x61, 0x38, 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 e3b4e0281..5de4aa8bf 100644 --- a/win/X11/nh56icon +++ b/win/X11/nh56icon @@ -1,4 +1,4 @@ -/* NetHack 3.7 nh56icon $NHDT-Date: 1596498369 2020/08/03 23:46:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* 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 may be freely redistributed. See license for details. */ @@ -25,12 +25,12 @@ static unsigned char nh56icon_bits[] = { 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, 0x40, 0xc0, 0xc3, 0x10, 0x21, 0x38, - 0x88, 0x20, 0xc0, 0xc3, 0x10, 0x21, 0x38, 0x80, 0x20, 0xc0, 0x43, 0x11, - 0x21, 0x38, 0x80, 0x20, 0xc0, 0x43, 0x12, 0x3f, 0x38, 0x70, 0xe0, 0xc1, - 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, From a87a83fc83f8d634625d503e2b698093b6cf72c1 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 9 Aug 2020 14:55:05 -0700 Subject: [PATCH 089/708] Qt menu fixes: mainly Quit Changes affecting everybody (using Qt): rename game->Save to game->Save-and-exit and game->Quit to game->Quit-without-saving. OSX-specific changes: add separate nethack->Quit and change game->Quit-without-saving to game->_Quit-without-saving to prevent that from being hijacked for the nethack menu. nethack->Quit menu entry works. Command+Q is a keyboard shortcut for it. They bring up a menu with choices of "Quit without saving" and "Cancel and return to game". It's not the same as the handler for the window Close button, which used to offer "Save" or "Cancel" (with the latter triggering an infinite loop) but now offers "Save and exit" or "Quit without saving". They don't share any code. The game->_Quit-without-saving entry doesn't work; it runs nethack's '?' command like a bunch of other broken menu entries. If it did work, it would give nethack's "Really quit?" prompt and proceed from there. The "Quit without saving" response for nethack->Quit confirmation bypasses that and just quits. Also OSX, add a second 'about' entry. The first one is hijacked and added to the nethack menu, the second is help->_About_Qt_NetHack_ and avoids hijacking. Both nethack->About and help->_About_ bring up the same dialog box showing version and assorted other info. A lot of flailing about with for relatively small amount of progress. --- doc/fixes37.0 | 11 ++++- win/Qt/qt_main.cpp | 105 ++++++++++++++++++++++++++++++++++----------- win/Qt/qt_main.h | 1 + 3 files changed, 91 insertions(+), 26 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 7f5bc138f..869863efc 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.278 $ $NHDT-Date: 1596936095 2020/08/09 01:21:35 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ $NHDT-Date: 1597010101 2020/08/09 21:55:01 $ General Fixes and Modified Features ----------------------------------- @@ -362,10 +362,19 @@ Qt: clicking on the window's Close button brought up a dialog offering with no opportunity to try to back out of the Close operation Qt: add 3.6 status fields Stone, Slime, Strngl, Deaf, Lev, Fly, Ride Qt: add Attributes, Overview, and Annotate to the "Info" pull down menu +Qt: rename menu entries game->Save to game->Save-and-exit and game->Quit + to game->Quit-without-saving Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" for making persistent Qt customizations to "nethack->Preferences..." +Qt+OSX: prevent game->Quit-without-saving from being hijacked for the nethack + menu by renaming it game->_Quit-without-saving (OSX only) +Qt+OSX: add a separate nethack->Quit menu entry with different functionality; + Command+Q invokes it +Qt+OSX: since menu entry help->"About Qt NetHack" gets hijacked and becomes + "nethack->About nethack", add a separate help->_About_Qt_NetHack_ + which stays where intended and brings up the same information tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 163616d76..82bdf16ec 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -578,18 +578,22 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { game, "History", 3, dohistory}, { game, "Redraw", 0, doredraw}, // useless { game, -#ifndef MACOSX - "Options", -#else - /* Qt on OSX would rename "Options" to "Preferences..." and - move it from intended destination to the application menu */ - "Run-time options", +#ifdef MACOSX + /* Qt on OSX would rename "Options" to "Preferences..." and + move it from intended destination to the application menu */ + "Run-time &" // rely on adjacent string concatenation #endif - 3, doset}, + "Options", 3, doset}, { game, "Explore mode", 3, enter_explore_mode}, { game, 0, 3}, - { game, "Save", 3, dosave}, - { game, "Quit", 3, done2}, + { game, "Save-and-exit", 3, dosave}, + { game, +#ifdef MACOSX + /* need something to prevent matching leading "quit" + so that it isn't hijacked for the application menu */ + "_&" +#endif + "Quit-without-saving", 3, done2}, { apparel, "Apparel off", 2, doddoremarm}, { apparel, "Remove many", 1, doddoremarm}, @@ -682,10 +686,12 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : "Preferences...", #endif this, SLOT(doQtSettings(bool))); - /* on OSX, 'about' will end up in the application menu - rather than the help menu; at present, just live with that */ - help->addAction("About Qt NetHack...",this,SLOT(doAbout(bool))); - //help->addAction("NetHack Guidebook...",this,SLOT(doGuidebook(bool))); + /* on OSX, 'about' will end up in the application menu rather than + the help menu (this had trailing "..." but that conflicts with + the convention that an elipsis indicates the choice will bring + up its own sub-menu) */ + help->addAction("About Qt NetHack", this, SLOT(doAbout(bool))); + //help->addAction("NetHack Guidebook", this, SLOT(doGuidebook(bool))); help->addSeparator(); for (i=0; item[i].menu; i++) { @@ -747,6 +753,21 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : help->setTitle("Help"); menubar->addMenu(help); } +#ifdef MACOSX + /* for OSX, the attempt above to add "About Qt NetHack" went into + the application menu instead of the help menu; we'll add it to + the latter now and have two ways to access it; without the + leading underscore (or some other spelling variation such as + "'bout"), this one would get interceptd too and then evidently + be discarded as a duplicate */ + help->addSeparator(); + help->addAction("_About_Qt_NetHack_", this, SLOT(doAbout(bool))); + /* we also want a "Quit NetHack" entry in the application menu; + when "_Quit-without-saving" was called "Quit" it got intercepted + for that, but now it needs to be added separately; we'll use a + handy menu and let the interception put it in the intended place */ + game->addAction("Quit NetHack", this, SLOT(doQuit(bool))); +#endif QSignalMapper* sm = new QSignalMapper(this); connect(sm, SIGNAL(mapped(const QString&)), this, SLOT(doKeys(const QString&))); @@ -912,6 +933,41 @@ void NetHackQtMainWindow::doAbout(bool) QMessageBox::about(this, "About Qt NetHack", aboutMsg()); } +// on OSX, "quit nethack" has been selected in the application menu or +// "Command+Q" has been typed -- user is asking to quit the application; +// unlike with the window's Close button, user has a chance to back out +void NetHackQtMainWindow::doQuit(bool) +{ + // there is a separate Quit-without-saving menu entry in the game menu + // that leads to nethack's "Really quit?" prompt; OSX players can use + // either one, other implementations only have that other one but this + // routine is unconditional in case someone wants to change that +#ifdef MACOSX + QString info; + info.sprintf("This will end your NetHack session.%s", + !g.program_state.something_worth_saving ? "" + : "\n(Cancel quitting and use the Save command" + "\nto save your current game.)"); + /* this is similar to closeEvent but the details are different */ + int act = QMessageBox::information(this, "NetHack", info, + "&Quit without saving", + "&Cancel and return to game", + 0, 1); + switch (act) { + case 0: + // quit -- bypass the prompting preformed by done2() + g.program_state.stopprint++; + done(QUIT); + /*NOTREACHED*/ + break; + case 1: + // cancel + break; // return to game + } +#endif + return; +} + #if 0 // RLC this isn't used void NetHackQtMainWindow::doGuidebook(bool) { @@ -1106,16 +1162,17 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) } } -void NetHackQtMainWindow::closeEvent(QCloseEvent* e) +// game window's Close button has been activated +void NetHackQtMainWindow::closeEvent(QCloseEvent *e UNUSED) { + int ok = 0; if ( g.program_state.something_worth_saving ) { - int ok = 0; /* this used to offer "Save" and "Cancel" but cancel (ignoring the close attempt) won't work if user has clicked on the window's Close button */ int act = QMessageBox::information(this, "NetHack", - "This will end your NetHack session", - "&Save and exit", "&Quit without saving", 0, 1); + "This will end your NetHack session.", + "&Save and exit", "&Quit without saving", 0, 1); switch (act) { case 0: // See dosave() function @@ -1128,17 +1185,15 @@ void NetHackQtMainWindow::closeEvent(QCloseEvent* e) done(QUIT); /*NOTREACHED*/ break; - case 2: - // cancel -- no longer an alternative - break; // ignore the event } - /* if !ok, we should try to continue, but we don't... */ - u.uhp = -1; - NetHackQtBind::qt_exit_nhwindows(0); - nh_terminate(EXIT_SUCCESS); } else { - e->accept(); + /* nothing worth saving; just close/quit */ + ok = 1; } + /* if !ok, we should try to continue, but we don't... */ + u.uhp = -1; + NetHackQtBind::qt_exit_nhwindows(0); + nh_terminate(EXIT_SUCCESS); } void NetHackQtMainWindow::ShowIfReady() diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index 2e4a2a5d0..461a4a471 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -53,6 +53,7 @@ public slots: void doMenuItem(QAction *); void doQtSettings(bool); void doAbout(bool); + void doQuit(bool); //RLC void doGuidebook(bool); void doKeys(const QString&); From 90a418a80a10617162956f6997e51ef09ad2cccf Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 9 Aug 2020 19:02:50 -0400 Subject: [PATCH 090/708] This sys/unix/hints/linux.2020 file can support tty, curses, x11, and Qt in the same binary, or any subset of those. - For x11 support, you'll need to obtain and install x11 development libraries. For example, on Ubuntu 20.04 (as of August 2020): 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) - For Qt support, you'll need to obtain and install Qt. For example, on Ubuntu 20.04 (as of August 2020): 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: "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 only) by the following command: sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 - For curses support, you may need to obtain and install the ncurses development libraries if they aren't already installed with your distribution. They seem to be there already with Ubuntu 20.04, but for example, if you needed to install ncurses: sudo apt-get install libncurses-dev - tty support shouldn't require any prerequisite additional packages. --- Assuming you have the prerequisite packages mentioned above, you can specify, right on the make command line, which window ports (or interfaces) to include in your build. Doing it via the make command line means that you don't have to edit the Makefile. The make command line example below will build one binary that has support for tty, curses, x11, and Qt. You can select between them via your .nethackrc file (OPTIONS=windowtype:curses, OPTIONS=windowtype:tty, OPTIONS=windowtype:x11, or OPTIONS=windowtype:Qt). make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 install --- sys/unix/hints/linux.2020 | 258 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100755 sys/unix/hints/linux.2020 diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 new file mode 100755 index 000000000..0472d13af --- /dev/null +++ b/sys/unix/hints/linux.2020 @@ -0,0 +1,258 @@ +# +# NetHack 3.7 linux.2020 $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. +# +#-PRE +# Linux hints file with support for multiple window ports (interfaces) +# +# This hints file supports tty, curses, x11, and Qt in the same binary, +# but: +# +# - For x11 support, you'll need to obtain and install x11 development libraries. +# For example, on Ubuntu 20.04 (as of August 2020): +# 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) +# +# - For Qt support, you'll need to obtain and install Qt. +# For example, on Ubuntu 20.04 (as of August 2020): +# 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: +# "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 only) by the following command: +# sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 +# +# - For curses support, you may need to obtain and install the +# ncurses development libraries if they aren't already installed +# with your distribution. They seem to be there already with Ubuntu 20.04, but +# for example, if you needed to install ncurses: +# sudo apt-get install libncurses-dev +# +# - tty support shouldn't require any prerequisite additional packages. +# +# Assuming you have the prerequisite packages mentioned above, you can +# specify, right on the make command line, which window ports (or interfaces) +# to include in your build. Doing it via the make command line means that won't +# have to edit the Makefile. +# +# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 install +# +# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use +# something other than tty as the default interface. +# +# 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 +# on the 'make' command line. If none are enabled, tty will be used. +#WANT_WIN_TTY=1 +#WANT_WIN_CURSES=1 +#WANT_WIN_X11=1 +#WANT_WIN_QT=1 + +# 1a. What is the default window system? +# Exactly one of these can be manually uncommented and/or can be specified +# on the 'make' command line. If none is enabled, the first among +# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. +#WANT_DEFAULT=tty +#WANT_DEFAULT=curses +#WANT_DEFAULT=Qt +#WANT_DEFAULT=X11 + +ifdef WANT_WIN_QT +QTDIR=/usr +endif # WANT_WIN_QT +ifndef LIBXPM +LIBXPM= -L/opt/X11/lib -lXpm +endif + +# 2. Not customizable in this linux.2020 hints file, which provides +# a single-user build for Linux (such as Ubuntu focal). +GAMEUID = $(USER) +GAMEGRP = games + +# 3. miscellaneous: compiler selection; Qt5 requires C++11 +ifdef WANT_WIN_QT +CC=clang +CXX=clang++ -std=gnu++11 +#CC=gcc +#CXX=g++ -std=gnu++11 +LINK= $(CXX) +else +# compiling C code only; CC and CXX defaults can be used +#CC= +#CXX= +LINK = $(CC) +endif +#MOC = moc + +# +# You shouldn't need to change anything below here (in the hints file; if +# you're reading this in Makefile augmented by hints, that may not be true). +# + +# Make sure that at least one interface is enabled. +ifndef WANT_WIN_TTY +ifndef WANT_WIN_CURSES +ifndef WANT_WIN_X11 +ifndef WANT_WIN_QT +WANT_WIN_TTY=1 +endif +endif +endif +endif + +# Make sure that a default interface is specified; this doesn't guarantee +# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but +# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. +ifndef WANT_DEFAULT +# pick the first one enabled among { tty, curses, X11, Qt } +ifdef WANT_WIN_TTY +WANT_DEFAULT=tty +else +ifdef WANT_WIN_CURSES +WANT_DEFAULT=curses +else +ifdef WANT_WIN_X11 +WANT_DEFAULT=X11 +else +ifdef WANT_WIN_QT +WANT_DEFAULT=Qt +else +# ? shouldn't be able to get here... +endif +endif +endif +endif +endif + +CFLAGS=-g -O -I../include -DNOTPARMDECL +CFLAGS+=-DDLB +CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +CFLAGS+=-DTIMED_DELAY +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDUMPLOG +CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +#CFLAGS+=-DEXTRA_SANITY_CHECKS +#CFLAGS+=-DEDIT_GETLIN +#CFLAGS+=-DSCORE_ON_BOTL +#CFLAGS+=-DMSGHANDLER +#CFLAGS+=-DTTY_TILES_ESCCODES +#CFLAGS+=-DTTY_SOUND_ESCCODES + +WINSRC = +WINOBJ0 = +WINLIB = +VARDATND = +VARDATND0 = +CURSESLIB = + +ifdef WANT_WIN_TTY +WINSRC += $(WINTTYSRC) +WINOBJ0 += $(WINTTYOBJ) +CURSESLIB = -lncurses -ltinfo +else # !WANT_WIN_TTY +CFLAGS += -DNOTTYGRAPHICS +endif # !WANT_WIN_TTY + +ifdef WANT_WIN_CURSES +CFLAGS += -DCURSES_GRAPHICS +WINSRC += $(WINCURSESSRC) +WINOBJ0 += $(WINCURSESOBJ) +CURSESLIB = -lncurses -ltinfo +endif + +ifdef CURSESLIB +WINLIB += $(CURSESLIB) +endif + +ifdef WANT_WIN_X11 +CFLAGS += -DX11_GRAPHICS +USE_XPM=1 +WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 +VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +# -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 +X11CFLAGS = -I/opt/X11/include +# avoid repeated complaints about _X_NONNULL(args...) in +X11CFLAGS += -Wno-variadic-macros +ifdef USE_XPM +CFLAGS += -DUSE_XPM +WINX11LIB += -lXpm +VARDATND0 += rip.xpm +endif +WINSRC += $(WINX11SRC) +WINOBJ0 += $(WINX11OBJ) +WINLIB += $(WINX11LIB) +LFLAGS=-L/opt/X11/lib +endif # WANT_WIN_X11 + +ifdef WANT_WIN_QT +CFLAGS += -DQT_GRAPHICS +QTCXXFLAGS += -Wno-deprecated-declarations +QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) +QTCXXFLAGS += -fPIC +WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) +WINSRC += $(WINQTSRC) +WINOBJ0 += $(WINQTOBJ) +VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm +# XXX if /Developer/qt exists and QTDIR not set, use that +ifndef QTDIR +$(error QTDIR not defined in the environment or Makefile) +endif # QTDIR +# XXX make sure QTDIR points to something reasonable +POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; \ + chmod $(VARFILEPERM) $(INSTDIR)/sysconf; +POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(INSTDIR)/nh10.pcf; \ + ( cd $(INSTDIR); mkfontdir -x .lev ); +endif # !WANT_WIN_QT + +# prevent duplicate tile.o in WINOBJ +WINOBJ = $(sort $(WINOBJ0)) +# prevent duplicates in VARDATND if both X11 and Qt are being supported +VARDATND += $(sort $(VARDATND0)) + +#PREFIX=/usr +PREFIX=$(wildcard ~)/nh/install +HACKDIR=$(PREFIX)/games/lib/$(GAME)dir +SHELLDIR = $(PREFIX)/games +INSTDIR=$(HACKDIR) +VARDIR = $(HACKDIR) + +POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; \ + chmod $(VARFILEPERM) $(INSTDIR)/sysconf; +# gdb may not be installed if clang is chosen compiler so the game +# won't start in that case due to a sysconf error. Comment out +# relevant lines in sysconf. +POSTINSTALL+= sed -i -e 's;^GDBPATH=/usr/bin/gdb;\#GDBPATH=/usr/bin/gdb;' \ + -e 's;PANICTRACE_GDB=1;PANICTRACE_GDB=0;' $(INSTDIR)/sysconf; + +# when building liblua.a, avoid warning that use of tmpnam() should be +# replaced by mkstemp(); the lua code doesn't use nethack's config.h so +# this needs to be passed via make rather than defined in unixconf.h +SYSCFLAGS=-DLUA_USE_POSIX + +# Only needed for GLIBC stack trace: +LFLAGS=-rdynamic + +# if TTY_TILES_ESCCODES +#WINSRC += tile.c +#WINOBJ += tile.o + +CHOWN=true +CHGRP=true + +VARDIRPERM = 0755 +VARFILEPERM = 0600 +GAMEPERM = 0755 From 6087891d4be72f79bda2038b5fba23c8fb482f60 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 9 Aug 2020 23:33:55 -0400 Subject: [PATCH 091/708] add -Wno-format-overflow to build under sys/unix/hints/linux.2020 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without that: botl.c: In function ‘status_hilite2str’: botl.c:3236:24: warning: ‘/’ directive writing 1 byte into a region of size between 0 and 255 [-Wformat-overflow=] 3236 | Sprintf(buf, "%s/%s/%s", initblstats[hl->fld].fldname, behavebuf, clrbuf); | ^ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 3 or more bytes (assuming 513) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ botl.c: In function ‘status_hilite_linestr_gather_conditions’: botl.c:3134:48: warning: ‘%s’ directive writing up to 255 bytes into a region of size 245 [-Wformat-overflow=] 3134 | Sprintf(condbuf, "condition/%s/%s", | ^~ 3135 | conditionbitmask2str(cond_maps[i].bm), clrbuf); | ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 12 or more bytes (assuming 267) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ botl.c: In function ‘do_statusline2’: botl.c:229:37: warning: ‘%s’ directive writing up to 127 bytes into a region of size between 0 and 254 [-Wformat-overflow=] 229 | Sprintf(newbot2, "%s %s %s %s %s", hlth, cond, dloc, expr, tmmv); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 5 and 640 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ botl.c:227:37: warning: ‘%s’ directive writing up to 127 bytes into a region of size between 0 and 254 [-Wformat-overflow=] 227 | Sprintf(newbot2, "%s %s %s %s %s", dloc, hlth, cond, expr, tmmv); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 5 and 640 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ botl.c:225:37: warning: ‘%s’ directive writing up to 127 bytes into a region of size between 0 and 254 [-Wformat-overflow=] 225 | Sprintf(newbot2, "%s %s %s %s %s", dloc, hlth, expr, cond, tmmv); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 5 and 640 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ botl.c:219:33: warning: ‘%s’ directive writing up to 127 bytes into a region of size between 0 and 254 [-Wformat-overflow=] 219 | Sprintf(newbot2, "%s %s %s %s %s", dloc, hlth, expr, tmmv, cond); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 5 and 640 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ botl.c: In function ‘status_hilite_menu_add’: botl.c:3726:38: warning: ‘ or ’ directive writing 4 bytes into a region of size between 1 and 80 [-Wformat-overflow=] 3726 | Sprintf(obuf, "%s or %s", | ^~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from botl.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 5 and 163 bytes into a destination of size 80 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cmd.c: In function ‘extcmd_via_menu’: cmd.c:668:44: warning: ‘%s’ directive writing up to 127 bytes into a region of size 110 [-Wformat-overflow=] 668 | Sprintf(prompt, "Extended Command: %s", cbuf); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from cmd.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 19 and 146 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cmd.c: In function ‘paranoid_query’: cmd.c:4488:30: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 113 and 128 [-Wformat-overflow=] 4488 | Sprintf(qbuf, "%s%s %s", promptprefix, pbuf, responsetype); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from cmd.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 10 and 282 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ do_name.c: In function ‘getpos_menu’: do_name.c:612:37: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=] 612 | Sprintf(fullbuf, "%s%s%s", firstmatch, | ^ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from do_name.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 1 or more bytes (assuming 257) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ do_name.c: In function ‘getpos’: do_name.c:205:31: warning: ‘%s’ directive writing up to 255 bytes into a region of size 249 [-Wformat-overflow=] 205 | Sprintf(sbuf, "Type a %s when you are at the right place.", kbuf); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from do_name.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 41 and 296 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ do_name.c:205:31: warning: ‘%s’ directive writing up to 255 bytes into a region of size 249 [-Wformat-overflow=] 205 | Sprintf(sbuf, "Type a %s when you are at the right place.", kbuf); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from do_name.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 41 and 296 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ do_wear.c: In function ‘armor_or_accessory_off’: do_wear.c:1510:52: warning: ‘%s’ directive writing up to 127 bytes into a region of size 103 [-Wformat-overflow=] 1510 | Sprintf(why, " without taking off your %s first", what); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from do_wear.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 32 and 159 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dungeon.c: In function ‘print_dungeon’: dungeon.c:2156:27: warning: ‘%s’ directive writing up to 1407 bytes into a region of size 256 [-Wformat-overflow=] 2156 | Sprintf(buf, "%s: %s %d", dptr->dname, descr, dptr->depth_start); | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from dungeon.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 10 and 1427 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dungeon.c:2153:27: warning: ‘%s’ directive writing up to 1407 bytes into a region of size 256 [-Wformat-overflow=] 2153 | Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr), | ^~ dungeon.c:2153:26: note: directive argument in the range [-2147483647, 2147483646] 2153 | Sprintf(buf, "%s: %s %d to %d", dptr->dname, makeplural(descr), | ^~~~~~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from dungeon.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 10 or more bytes (assuming 1427) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dungeon.c: In function ‘print_mapseen’: dungeon.c:3191:33: warning: ‘%s’ directive writing up to 255 bytes into a region of size 249 [-Wformat-overflow=] 3191 | Sprintf(outbuf, " (play %s to open or close drawbridge)", tmp); | ^~ ~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from dungeon.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 37 and 292 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dungeon.c:3352:35: warning: ‘%s’ directive writing up to 255 bytes into a region of size 240 [-Wformat-overflow=] 3352 | Sprintf(buf, "%sThe castle%s.", PREFIX, tunesuffix(mptr, tmpbuf)); | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from dungeon.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 18 and 273 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dungeon.c:3403:40: warning: ‘%s’ directive writing up to 255 bytes into a region of size 242 [-Wformat-overflow=] 3403 | Sprintf(buf, "%s%syou, %s%c", PREFIX, TAB, tmpbuf, | ^~ ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from dungeon.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 16 and 271 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c: In function ‘edibility_prompts’: eat.c:2359:25: warning: ‘ like ’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2359 | Sprintf(buf, "%s like %s could be tainted! %s", foodsmell, it_or_they, | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 27 and 536 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2385:25: warning: ‘ like ’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2385 | Sprintf(buf, "%s like %s might be poisonous! %s", foodsmell, | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 29 and 538 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2394:25: warning: ‘ like ’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2394 | Sprintf(buf, "%s like %s might have been poisoned. %s", foodsmell, | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 35 and 544 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2400:25: warning: ‘ unhealthy. ’ directive writing 13 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2400 | Sprintf(buf, "%s unhealthy. %s", foodsmell, eat_it_anyway); | ^~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 14 and 396 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2407:25: warning: ‘ rather acidic. ’ directive writing 17 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2407 | Sprintf(buf, "%s rather acidic. %s", foodsmell, eat_it_anyway); | ^~~~~~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 18 and 400 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2415:25: warning: ‘ disgusting to you right now...’ directive writing 31 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2415 | Sprintf(buf, "%s disgusting to you right now. %s", foodsmell, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 32 and 414 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2430:25: warning: ‘ foul and unfamiliar to you...’ directive writing 30 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2430 | Sprintf(buf, "%s foul and unfamiliar to you. %s", foodsmell, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 31 and 413 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2450:25: warning: ‘ like ’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2450 | Sprintf(buf, "%s like %s could be tainted! %s", | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 27 and 536 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2441:25: warning: ‘ unfamiliar to you. ’ directive writing 21 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2441 | Sprintf(buf, "%s unfamiliar to you. %s", foodsmell, eat_it_anyway); | ^~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 22 and 404 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2376:25: warning: ‘ like ’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2376 | Sprintf(buf, "%s like %s could be rotten! %s", foodsmell, it_or_they, | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 25 and 534 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eat.c:2367:25: warning: ‘ like ’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 2367 | Sprintf(buf, "%s like %s could be something very dangerous! %s", | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from eat.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 44 and 553 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ explode.c: In function ‘explode’: explode.c:539:69: warning: ‘%s’ directive writing up to 255 bytes into a region of size 236 [-Wformat-overflow=] 539 | Sprintf(g.killer.name, "caught %sself in %s own %s", uhim(), | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from explode.c:5: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 21 or more bytes (assuming 276) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ hacklib.c: In function ‘yyyymmddhhmmss’: hacklib.c:1089:28: warning: ‘%02d’ directive writing between 2 and 11 bytes into a region of size between 4 and 11 [-Wformat-overflow=] 1089 | Sprintf(datestr, "%04ld%02d%02d%02d%02d%02d", datenum, lt->tm_mon + 1, | ^~~~ hacklib.c:1089:22: note: directive argument in the range [-2147483647, 2147483647] 1089 | Sprintf(datestr, "%04ld%02d%02d%02d%02d%02d", datenum, lt->tm_mon + 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from hacklib.c:7: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 15 and 67 bytes into a destination of size 15 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c: In function ‘status_enlightenment’: insight.c:1208:40: warning: ‘%s’ directive writing up to 255 bytes into a region of size 127 [-Wformat-overflow=] 1208 | Sprintf(sfx, " %s", buf), buf[0] = '\0'; | ^~ ~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 2 and 257 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c: In function ‘list_vanquished’: insight.c:2464:39: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=] 2464 | Sprintf(buftoo, "%*s%s", pfx, "", buf); | ^ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 1 and 261 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c: In function ‘background_enlightenment’: insight.c:326:27: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 253 and 256 [-Wformat-overflow=] 326 | Sprintf(buf, "%s%s%s%s form", !final ? "currently " : "", | ^~ 327 | altphrasing ? just_an(anbuf, tmpbuf) : "in ", 328 | tmpbuf, uasmon->mname); | ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 6 or more bytes (assuming 264) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c:326:27: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 243 and 246 [-Wformat-overflow=] 326 | Sprintf(buf, "%s%s%s%s form", !final ? "currently " : "", | ^~ 327 | altphrasing ? just_an(anbuf, tmpbuf) : "in ", 328 | tmpbuf, uasmon->mname); | ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 16 or more bytes (assuming 274) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c:444:33: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 121 and 248 [-Wformat-overflow=] 444 | Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf); | ^~ ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 9 and 391 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c:423:48: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 223 and 233 [-Wformat-overflow=] 423 | Sprintf(buf, "in the endgame, on the %s%s", | ^~ 424 | !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf); | ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 24 and 289 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ insight.c: In function ‘enlightenment’: insight.c:245:21: warning: ‘ the ’ directive writing 5 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 245 | Sprintf(buf, "%s the %s's attributes:", tmpbuf, | ^~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from insight.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 20 or more bytes (assuming 275) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mhitm.c: In function ‘hitmm’: mhitm.c:591:37: warning: ‘ squeezes’ directive writing 9 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 591 | Sprintf(buf, "%s squeezes", magr_name); | ^~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from mhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 10 and 265 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mhitm.c:578:33: warning: ‘ stings’ directive writing 7 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 578 | Sprintf(buf, "%s stings", magr_name); | ^~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from mhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 8 and 263 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mhitm.c:584:33: warning: ‘ touches’ directive writing 8 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 584 | Sprintf(buf, "%s touches", magr_name); | ^~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from mhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 9 and 264 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mhitm.c:581:33: warning: ‘ butts’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 581 | Sprintf(buf, "%s butts", magr_name); | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from mhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 7 and 262 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mhitm.c:575:33: warning: ‘ bites’ directive writing 6 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 575 | Sprintf(buf, "%s bites", magr_name); | ^~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from mhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 7 and 262 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mhitm.c:597:37: warning: ‘ hits’ directive writing 5 bytes into a region of size between 1 and 256 [-Wformat-overflow=] 597 | Sprintf(buf, "%s hits", magr_name); | ^~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from mhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 6 and 261 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ options.c: In function ‘option_help’: options.c:8035:28: warning: ‘ - ’ directive writing 3 bytes into a region of size between 1 and 236 [-Wformat-overflow=] 8035 | Sprintf(buf, "%-20s - %s%c", buf2, allopt[i].descr, | ^~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from options.c:14: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 25 or more bytes (assuming 260) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pager.c: In function ‘do_screen_description’: pager.c:1189:38: warning: ‘%s’ directive writing up to 255 bytes into a region of size 254 [-Wformat-overflow=] 1187 | *firstmatch = look_buf; | ~~~~~~~~ 1188 | if (*(*firstmatch)) { 1189 | Sprintf(temp_buf, " (%s)", *firstmatch); | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from pager.c:9: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 4 and 259 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pager.c:1195:44: warning: ‘%s’ directive writing up to 255 bytes into a region of size 248 [-Wformat-overflow=] 1195 | Sprintf(temp_buf, " [seen: %s]", monbuf); | ^~ ~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from pager.c:9: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 10 and 265 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ potion.c: In function ‘dodip’: potion.c:1949:26: warning: ‘%s’ directive writing up to 127 bytes into a region of size 124 [-Wformat-overflow=] 1949 | Sprintf(qbuf, "%s%s into the %s?", Dip_, | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from potion.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 16 or more bytes (assuming 143) into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ potion.c:1939:26: warning: ‘%s’ directive writing up to 127 bytes into a region of size 124 [-Wformat-overflow=] 1939 | Sprintf(qbuf, "%s%s into the fountain?", Dip_, | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from potion.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 24 and 151 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ potion.c:1969:24: warning: ‘%s’ directive writing up to 127 bytes into a region of size 124 [-Wformat-overflow=] 1969 | Sprintf(qbuf, "dip %s into", flags.verbose ? obuf : shortestname); | ^~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from potion.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 10 and 137 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ potion.c: In function ‘potionhit’: potion.c:1424:41: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=] 1424 | Sprintf(saddle_glows, "%s %s", buf, aobjnam(saddle, "glow")); | ^ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from potion.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 2 or more bytes (assuming 257) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ spell.c: In function ‘getspell’: spell.c:706:47: warning: ‘%s’ directive writing up to 255 bytes into a region of size 109 [-Wformat-overflow=] 706 | Sprintf(qbuf, "Cast which spell? [%s *?]", lets); | ^~ ~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from spell.c:5: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 24 and 279 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ topten.c: In function ‘outentry’: topten.c:1060:32: warning: ‘%s’ directive writing up to 255 bytes into a region of size 240 [-Wformat-overflow=] 1060 | Sprintf(linebuf, "%15s %s", "", linebuf3); | ^~ ~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from topten.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 17 and 272 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ trap.c: In function ‘untrap’: trap.c:4462:58: warning: ‘%s’ directive writing up to 255 bytes into a region of size 88 [-Wformat-overflow=] 4462 | qbuf, "There %s and %s here. %s %s?", | ^~ ...... 4465 | (ttmp->ttyp == WEB) ? "Remove" : "Disarm", the_trap); | ~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from trap.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 42 or more bytes (assuming 297) into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ uhitm.c: In function ‘hmon_hitmon’: uhitm.c:1316:47: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 244 and 251 [-Wformat-overflow=] 1316 | Sprintf(silverobjbuf, "Your %s%s %s", | ^~ 1317 | strstri(saved_oname, "silver") ? "" : "silver ", 1318 | saved_oname, vtense(saved_oname, "sear")); | ~~~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from uhitm.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 7 or more bytes (assuming 269) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ weapon.c: In function ‘enhance_weapon_skill’: weapon.c:1271:47: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 249 and 253 [-Wformat-overflow=] 1271 | Sprintf(buf, " %s%s\t[%s]", prefix, P_NAME(i), | ^~ 1272 | sklnambuf); | ~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from weapon.c:11: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 5 or more bytes (assuming 264) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ weapon.c:1268:49: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 248 and 252 [-Wformat-overflow=] 1268 | Sprintf(buf, " %s %-*s [%s]", prefix, longest, | ^~ 1269 | P_NAME(i), sklnambuf); | ~~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from weapon.c:11: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 6 or more bytes (assuming 265) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ weapon.c:1263:46: warning: ‘%s’ directive writing up to 255 bytes into a region of size between 250 and 254 [-Wformat-overflow=] 1263 | Sprintf(buf, " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i), | ^~ 1264 | sklnambuf, P_ADVANCE(i), | ~~~~~~~~~ weapon.c:1263:38: note: directive argument in the range [0, 65535] 1263 | Sprintf(buf, " %s%s\t%s\t%5d(%4d)", prefix, P_NAME(i), | ^~~~~~~~~~~~~~~~~~~~~ weapon.c:1263:38: note: directive argument in the range [-325120, 327680] In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from weapon.c:11: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 15 or more bytes (assuming 277) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ weapon.c:1259:47: warning: ‘%-12s’ directive writing between 12 and 255 bytes into a region of size between 250 and 254 [-Wformat-overflow=] 1259 | Sprintf(buf, " %s%-*s %-12s %5d(%4d)", prefix, | ^~~~~ 1260 | longest, P_NAME(i), sklnambuf, P_ADVANCE(i), | ~~~~~~~~~ weapon.c:1259:38: note: directive argument in the range [0, 65535] 1259 | Sprintf(buf, " %s%-*s %-12s %5d(%4d)", prefix, | ^~~~~~~~~~~~~~~~~~~~~~~~ weapon.c:1259:38: note: directive argument in the range [-325120, 327680] In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from weapon.c:11: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 27 or more bytes (assuming 277) into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../win/curses/cursinit.c: In function ‘curses_choose_character’: ../win/curses/cursinit.c:454:26: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=] 454 | sprintf(choice, "%s%c", tmpchoice, '\033'); | ^ In file included from /usr/include/stdio.h:867, from /usr/include/curses.h:192, from ../win/curses/cursinit.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 2 and 129 bytes into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../win/X11/winX.c: In function ‘X11_init_nhwindows’: ../win/X11/winX.c:1509:12: warning: ignoring return value of ‘seteuid’, declared with attribute warn_unused_result [-Wunused-result] 1509 | (void) seteuid(getuid()); | ^~~~~~~~~~~~~~~~~ ../win/X11/winX.c:1570:12: warning: ignoring return value of ‘seteuid’, declared with attribute warn_unused_result [-Wunused-result] 1570 | (void) seteuid(savuid); | ^~~~~~~~~~~~~~~ ../win/tty/wintty.c: In function ‘tty_player_selection’: ../win/tty/wintty.c:964:30: warning: ‘%s’ directive writing up to 127 bytes into a region of size between 95 and 126 [-Wformat-overflow=] 964 | Sprintf(pbuf, "%s, %s%s %s %s", g.plname, aligns[ALGN].adj, plbuf, | ^~ ~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from ../win/tty/wintty.c:15: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output 5 or more bytes (assuming 163) into a destination of size 128 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ version.c: In function ‘early_version_info’: version.c:263:24: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=] 263 | Sprintf(buf2, "%s\n", buf); | ^ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from version.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 2 and 257 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ version.c:263:24: warning: ‘__builtin___sprintf_chk’ may write a terminating nul past the end of the destination [-Wformat-overflow=] 263 | Sprintf(buf2, "%s\n", buf); | ^ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from version.c:6: /usr/include/x86_64-linux-gnu/bits/stdio2.h:36:10: note: ‘__builtin___sprintf_chk’ output between 2 and 257 bytes into a destination of size 256 36 | return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 37 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- sys/unix/hints/linux.2020 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 0472d13af..5371c0c83 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux.2020 $NHDT-Date: 1596498415 2020/08/03 23:46:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1597029501 2020/08/10 03:18:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -132,6 +132,7 @@ endif endif CFLAGS=-g -O -I../include -DNOTPARMDECL +CFLAGS+=-Wno-format-overflow CFLAGS+=-DDLB CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE From a6debd4755f5b941f9e3d1fc5847d6697a1678c5 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 9 Aug 2020 19:24:07 -0400 Subject: [PATCH 092/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Files b/Files index 48c7a040b..95c782899 100644 --- a/Files +++ b/Files @@ -304,10 +304,11 @@ sys/unix/hints: (files for configuring UNIX NetHack versions) linux linux-chroot linux-minimal linux-qt4 linux-qt5 linux-x11 -macOS.2020 macosx macosx.sh -macosx10.5 macosx10.7 macosx10.8 -macosx10.10 macosx10.10-qt macosx10.14 -solaris solaris-playground unix +linux.2020 macOS.2020 macosx +macosx.sh macosx10.5 macosx10.7 +macosx10.8 macosx10.10 macosx10.10-qt +macosx10.14 solaris solaris-playground +unix sys/vms: (files for VMS version) From 084d1a8773ea9049fc6a704ad706c68d5527401c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 9 Aug 2020 23:54:15 -0400 Subject: [PATCH 093/708] Use the same compiler for Lua as specified for NetHack It tried to use gcc for Lua when no gcc was available and failed. --- sys/unix/Makefile.top | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index a9c0f81cb..b604bb7ef 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: 1596498292 2020/08/03 23:44:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1597031649 2020/08/10 03:54:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -106,7 +106,7 @@ lua_support: lib/lua/liblua.a include/nhlua.h @true lib/lua-$(LUA_VERSION)/src/liblua.a: lib/lua-$(LUA_VERSION)/src/lua.h ( cd lib/lua-$(LUA_VERSION)/src \ - && make SYSCFLAGS='$(SYSCFLAGS)' a && cd ../../.. ) + && make CC='$(CC)' SYSCFLAGS='$(SYSCFLAGS)' a && cd ../../.. ) lib/lua/liblua.a: lib/lua-$(LUA_VERSION)/src/liblua.a @( if [ ! -d lib/lua ] ; then mkdir -p lib/lua ; fi ) cp lib/lua-$(LUA_VERSION)/src/liblua.a $@ From ef9caca4daa3d9d05d45aea29cb0c62c49604b21 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 10 Aug 2020 10:03:12 -0400 Subject: [PATCH 094/708] distinguish compiler version before adding new -Wno option --- sys/unix/hints/linux.2020 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 5371c0c83..7d19ddc04 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -132,7 +132,10 @@ endif endif CFLAGS=-g -O -I../include -DNOTPARMDECL +GTEQ9 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 9) +ifeq "$(GTEQ9)" "1" CFLAGS+=-Wno-format-overflow +endif #compiler version greater than or equal to 9 CFLAGS+=-DDLB CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE From 264cbed2cc5618c19973e8679e0c5d0f1faa48e0 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 10 Aug 2020 07:24:16 -0700 Subject: [PATCH 095/708] Qt menu sanity The Qt menu entries which were executing nethack's help command (the '?' menu) were doing so because their command keystroke was a meta-character and such characters are being converted to '?' to indicate an error in conversion to Latin1 character set. The old Qt3 code didn't perform any such conversion. This fix feels fragile because there are two different places deciding how to disambiguate partial extended commands (the code for Qt's '#' handling and a new routine in the core). Qt menus now send '#' and enough letters to satisfy '#' handling for any command which uses M-c or has no regular keystroke nor M-c one. (If it were to send the full extended command name, the letters after the unambiguous prefix would be left in the input queue to be processed as subsequent commands.) There is a fundamental problem that this doesn't address: if the player uses BIND directives in the run-time config file, the Qt menu bindings will break unless the BINDs are all done before selecting windowtype. Qt's menu bindings translate a click on a menu entry into the keystroke used to invoke the corresponding command, so using BIND to change that after the menus are set up will result in the wrong commands being executed. --- doc/fixes37.0 | 7 +++++- include/extern.h | 3 ++- src/cmd.c | 53 +++++++++++++++++++++++++++++++++++++++++++++- win/Qt/qt_main.cpp | 22 ++++++++++++++++--- 4 files changed, 79 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 869863efc..ec0cd9f91 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.279 $ $NHDT-Date: 1597010101 2020/08/09 21:55:01 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.280 $ $NHDT-Date: 1597069374 2020/08/10 14:22:54 $ General Fixes and Modified Features ----------------------------------- @@ -364,6 +364,11 @@ Qt: add 3.6 status fields Stone, Slime, Strngl, Deaf, Lev, Fly, Ride Qt: add Attributes, Overview, and Annotate to the "Info" pull down menu Qt: rename menu entries game->Save to game->Save-and-exit and game->Quit to game->Quit-without-saving +Qt: menu commands are now working; commands invoked via M-c were having that + keystroke changed to '?', bringing up nethack's help menu; now those + send #abc with just enough letters to disambiguate from other commands + ("Compilation" is one remaining problem; it yields "#version" which + brings up '#' menu subset with choices of "version" and "versionshort") Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/include/extern.h b/include/extern.h index 77d4c6d5e..437431035 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1596498536 2020/08/03 23:48:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.854 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1597069374 2020/08/10 14:22:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.855 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -204,6 +204,7 @@ E void FDECL(random_response, (char *, int)); E int NDECL(rnd_extcmd_idx); E int NDECL(domonability); E char FDECL(cmd_from_func, (int NDECL((*)))); +E const char *FDECL(cmdname_from_func, (int NDECL((*)), char *, BOOLEAN_P)); E boolean FDECL(redraw_cmd, (CHAR_P)); E const char *FDECL(levltyp_to_name, (int)); #ifdef USE_TRAMPOLI diff --git a/src/cmd.c b/src/cmd.c index c9ee5115b..19ae95498 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1596498153 2020/08/03 23:42:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.421 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1597069374 2020/08/10 14:22:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.422 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2278,6 +2278,57 @@ int NDECL((*fn)); return '\0'; } +/* return extended command name (without leading '#') for command (*fn)() */ +const char * +cmdname_from_func(fn, outbuf, fullname) +int NDECL((*fn)); +char outbuf[]; +boolean fullname; /* False: just enough to disambiguate */ +{ + const struct ext_func_tab *extcmd, *cmdptr = 0; + const char *res = 0; + + for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) + if (extcmd->ef_funct == fn) { + cmdptr = extcmd; + res = cmdptr->ef_txt; + break; + } + + if (!res) { + /* make sure output buffer doesn't contain junk or stale data; + return Null below */ + outbuf[0] = '\0'; + } else if (fullname) { + /* easy; the entire command name */ + res = strcpy(outbuf, res); + } else { + const struct ext_func_tab *matchcmd = extcmdlist; + int len = 0; + + /* find the shortest leading substring which is unambiguous */ + do { + if (++len >= (int) strlen(res)) + break; + for (extcmd = matchcmd; extcmd->ef_txt; ++extcmd) { + if (extcmd == cmdptr) + continue; + if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0 + || ((extcmd->flags & WIZMODECMD) != 0 && !wizard)) + continue; + if (!strncmp(res, extcmd->ef_txt, len)) { + matchcmd = extcmd; + break; + } + } + } while (extcmd->ef_txt); + copynchars(outbuf, res, len); + debugpline2("shortened %s: \"%s\"", res, outbuf); + res = outbuf; + } + return res; +} + /* * wizard mode sanity_check code */ diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 82bdf16ec..32c791a02 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -699,16 +699,24 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : if (item[i].name) { char actchar[32]; char menuitem[BUFSZ]; - actchar[0] = '\0'; + actchar[0] = actchar[1] = '\0'; if (item[i].funct) { actchar[0] = cmd_from_func(item[i].funct); - actchar[1] = '\0'; + /* M-c won't work */ + if ((actchar[0] & 0x7f) != actchar[0]) + actchar[0] = '\0'; } if (actchar[0] && !qt_compact_mode) - Sprintf(menuitem, "%s\t%s", item[i].name, + Sprintf(menuitem, "%.50s\t%.9s", item[i].name, visctrl(actchar[0])); else Sprintf(menuitem, "%s", item[i].name); + + if (item[i].funct && !actchar[0]) { + actchar[0] = '#'; + (void) cmdname_from_func(item[i].funct, + &actchar[1], FALSE); + } if (actchar[0]) { QString name = menuitem; QAction *action = item[i].menu->addAction(name); @@ -919,6 +927,12 @@ public: void NetHackQtMainWindow::doMenuItem(QAction *action) { + /* this converts meta characters to '?'; menu processing has been + changed to send multi-character "#abc" instead (already needed + for commands that didn't have either a regular keystroke or a + meta shortcut); it must send just enough to disambiguate from + other extended command names, otherwise the remainder would be + left in the queue for subsequent handling as additional commands */ doKeys(action->data().toString()); } @@ -985,6 +999,8 @@ void NetHackQtMainWindow::doGuidebook(bool) void NetHackQtMainWindow::doKeys(const QString& k) { + /* [this should probably be using toLocal8Bit(); + toAscii() is not offered as an alternative...] */ keysink.Put(k.toLatin1().constData()); qApp->exit(); } From 8dca9b4f8ad350cbeca045a0b9aaf8414072192c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 10 Aug 2020 11:13:16 -0400 Subject: [PATCH 096/708] add compiler detection so warnings adjusted appropriately --- sys/unix/hints/linux.2020 | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 7d19ddc04..99240fd51 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,5 +1,5 @@ # -# NetHack 3.7 linux.2020 $NHDT-Date: 1597029501 2020/08/10 03:18:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.0 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1597072358 2020/08/10 15:12:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -132,10 +132,13 @@ endif endif CFLAGS=-g -O -I../include -DNOTPARMDECL -GTEQ9 := $(shell expr `gcc -dumpversion | cut -f1 -d.` \>= 9) -ifeq "$(GTEQ9)" "1" +CCISCLANG := $(shell echo `$(CC) --version` | grep clang) +ifeq "$(CCISCLANG)" "" +GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) +ifeq "$(GCCGTEQ9)" "1" CFLAGS+=-Wno-format-overflow -endif #compiler version greater than or equal to 9 +endif #gcc version greater than or equal to 9 +endif #not clang CFLAGS+=-DDLB CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE From 75fa283fb6a4d8462e03990e7de42dd776ac5d56 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 10 Aug 2020 13:20:24 -0700 Subject: [PATCH 097/708] leash use vs perm_invent Noticed while working on Qt's version of persistent inventory window (paper doll-style display of equipment in use), leashing or unleashing a pet wasn't updating persistent inventory. Leash descriptions format differently when in use so immediate update is warranted. --- doc/fixes37.0 | 3 ++- src/apply.c | 38 ++++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index ec0cd9f91..92522330c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.280 $ $NHDT-Date: 1597069374 2020/08/10 14:22:54 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.281 $ $NHDT-Date: 1597090815 2020/08/10 20:20:15 $ General Fixes and Modified Features ----------------------------------- @@ -243,6 +243,7 @@ wizard mode #wizintrinsic: setting Levitation wouldn't block Flying as chatting to the quest leader in wizard mode with sufficient experience level and insufficient piety, player is asked whether alignment should be boosted; answering 'n' resulted in being prompted a second time +leashing or unleashing pets wasn't updating persistent inventory window Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/apply.c b/src/apply.c index 849d11004..faef080bf 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1596498148 2020/08/03 23:42:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1597090815 2020/08/10 20:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.327 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -548,20 +548,23 @@ number_leashed() /* otmp is about to be destroyed or stolen */ void o_unleash(otmp) -register struct obj *otmp; +struct obj *otmp; { register struct monst *mtmp; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) - if (mtmp->m_id == (unsigned) otmp->leashmon) + if (mtmp->m_id == (unsigned) otmp->leashmon) { mtmp->mleashed = 0; - otmp->leashmon = 0; + otmp->leashmon = 0; + update_inventory(); + break; + } } /* mtmp is about to die, or become untame */ void m_unleash(mtmp, feedback) -register struct monst *mtmp; +struct monst *mtmp; boolean feedback; { register struct obj *otmp; @@ -573,8 +576,11 @@ boolean feedback; Your("leash falls slack."); } for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (otmp->otyp == LEASH && otmp->leashmon == (int) mtmp->m_id) + if (otmp->otyp == LEASH && (unsigned) otmp->leashmon == mtmp->m_id) { otmp->leashmon = 0; + update_inventory(); + break; + } mtmp->mleashed = 0; } @@ -686,6 +692,7 @@ struct obj *obj; mtmp->mleashed = 1; obj->leashmon = (int) mtmp->m_id; mtmp->msleeping = 0; + update_inventory(); } } else { /* applying a leash which is currently in use */ @@ -697,6 +704,7 @@ struct obj *obj; } else { mtmp->mleashed = 0; obj->leashmon = 0; + update_inventory(); You("remove the leash from %s%s.", spotmon ? "your " : "", l_monnam(mtmp)); } @@ -711,13 +719,10 @@ struct monst *mtmp; { struct obj *otmp; - otmp = g.invent; - while (otmp) { - if (otmp->otyp == LEASH && otmp->leashmon == (int) mtmp->m_id) - return otmp; - otmp = otmp->nobj; - } - return (struct obj *) 0; + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (otmp->otyp == LEASH && (unsigned) otmp->leashmon == mtmp->m_id) + break; + return otmp; } boolean @@ -735,13 +740,14 @@ next_to_u() if (distu(mtmp->mx, mtmp->my) > 2) { for (otmp = g.invent; otmp; otmp = otmp->nobj) if (otmp->otyp == LEASH - && otmp->leashmon == (int) mtmp->m_id) { + && (unsigned) otmp->leashmon == mtmp->m_id) { if (otmp->cursed) return FALSE; - You_feel("%s leash go slack.", - (number_leashed() > 1) ? "a" : "the"); mtmp->mleashed = 0; otmp->leashmon = 0; + update_inventory(); + You_feel("%s leash go slack.", + (number_leashed() > 1) ? "a" : "the"); } } } From 7f854089621e3f3b804c036293db313071f40128 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 10 Aug 2020 15:25:56 -0700 Subject: [PATCH 098/708] Qt paper doll inventory In case you haven't seen it, the Qt screen layout is (a bigger instance of): +--------------------+------+--------------------------------+ | messages |invent| status | | |subset| | | | | | | | | | +------------------------------------------------------------+ | map | | | ... | | +------------------------------------------------------------+ where some status fields include an icon and the inventory subset is a miniature map showing a paper doll-style display of object tiles for worn and wielded items. The two separating lines in the top half can be dragged to resize the three windows there. The default message window width to too small to see full text of some messages but can be scrolled left and right. The window for the equipped subset of inventory is unconditionally present; 'perm_invent' is a no-op. Paper doll inventory layout (view with fixed-width font...): Old New two-hand dual-wield x H b x H b x H b . H b S " w S " w W " W X " w G C G G C q G C q G C q = A = = A = = A = = A = . U . l U L l U L l U L . F . . F . . F . . F . Legend: '.' = blank, b = blindfold, '"' = amulet, '=' = left and right rings, w/W = primary weapon, x/X = alternate/secondary weapon, q = quiver, H = helmet, S = shield, G = gloves, C = cloak, A = suit, U = shirt, F = boots, l = leash, L = active light source (lamp/candle/Sunsword). Slots which don't have something equipped are shown blank. 'q' was missing; 'G' used to be shown on both sides. 'l' and 'L' are new; for either, it picks the first one in inventory that's in active use. The 'S' and 'x' slots vary depending upon weapon situation since wearing a shield, wielding a two-handed weapon, and engaging in two-weapon combat are all mutually exclusive. --- doc/fixes37.0 | 9 ++++- win/Qt/qt_inv.cpp | 90 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 27 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 92522330c..38a7d212f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.281 $ $NHDT-Date: 1597090815 2020/08/10 20:20:15 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.282 $ $NHDT-Date: 1597098351 2020/08/10 22:25:51 $ General Fixes and Modified Features ----------------------------------- @@ -370,6 +370,13 @@ Qt: menu commands are now working; commands invoked via M-c were having that send #abc with just enough letters to disambiguate from other commands ("Compilation" is one remaining problem; it yields "#version" which brings up '#' menu subset with choices of "version" and "versionshort") +Qt: "paper doll" subset of persistent inventory has undergone several changes: + show previously missing quiver below weapon instead of duplicating + gloves there; show secondary weapon in shield slot and blank out + alternate weapon slot when two-weapon combat is active; show wielded + two-handed weapon in both the shield and primary weapon slots; show + first active light source in a previously unused slot on lower right; + show first leash-in-use in a previously unused slot on lower left Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index bf8cc9add..c900a5e7c 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -3,6 +3,9 @@ // NetHack may be freely redistributed. See license for details. // qt_inv.cpp -- inventory usage window +// +// Essentially a "paper doll" style display. [grep fodder] +// // This is at the top center of the main window extern "C" { @@ -30,13 +33,28 @@ extern "C" { namespace nethack_qt_ { +static struct obj * +find_tool(int tooltyp) +{ + struct obj *o; + + for (o = g.invent; o; o = o->nobj) { + if ((tooltyp == LEASH && o->otyp == LEASH && o->leashmon) + // OIL_LAMP is used for candles, lamps, lantern, candelabrum too + || (tooltyp == OIL_LAMP && o->lamplit)) + break; + } + return o; +} + NetHackQtInvUsageWindow::NetHackQtInvUsageWindow(QWidget* parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } -void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, int x, int y, bool canbe) +void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, + int x, int y, bool canbe) { short int glyph; if (nhobj) @@ -51,39 +69,59 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, int x, int void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) { - // 012 + // 0 1 2 two dual + // hander wielding + // 0 x H b x H b . H b + // 1 S " w W " W X " w + // 2 G C q G C q G C q + // 3 = A = = A = = A = + // 4 l U L l U L l U L + // 5 . F . . F . . F . // - //0 WhB - //1 s"w - //2 gCg - //3 =A= - //4 T - //5 S + // 3.7: use a different legend for the layout + // show quiver instead of repeating gloves on both sides; + // show secondary weapon in shield slot when two-weapon is active; + // show two-handed primary weapon in both shield and uwep slots; + // show lit lamp/lantern/candle/candelabrum on lower right side; + // show leash-in-use on lower left side QPainter painter; painter.begin(this); // Blanks - drawWorn(painter,0,0,4,false); - drawWorn(painter,0,0,5,false); - drawWorn(painter,0,2,4,false); - drawWorn(painter,0,2,5,false); + drawWorn(painter, 0, 0, 5, false); + drawWorn(painter, 0, 2, 5, false); + if (u.twoweap) // empty alt weapon slot, show uswapwep in shield slot + drawWorn(painter, 0, 0, 0, false); - drawWorn(painter,uarm,1,3); // Armour - drawWorn(painter,uarmc,1,2); // Cloak - drawWorn(painter,uarmh,1,0); // Helmet - drawWorn(painter,uarms,0,1); // Shield - drawWorn(painter,uarmg,0,2); // Gloves - repeated - drawWorn(painter,uarmg,2,2); // Gloves - repeated - drawWorn(painter,uarmf,1,5); // Shoes (feet) - drawWorn(painter,uarmu,1,4); // Undershirt - drawWorn(painter,uleft,0,3); // RingL - drawWorn(painter,uright,2,3); // RingR + // TODO: render differently if known to be non-removable (known cursed) + drawWorn(painter, uarm, 1, 3); // Armour + drawWorn(painter, uarmc, 1, 2); // Cloak + drawWorn(painter, uarmh, 1, 0); // Helmet + // shield slot varies depending upon weapon usage + if (u.twoweap) + drawWorn(painter, uswapwep, 0, 1); // Secondary weapon, in use + else if (uwep && bimanual(uwep)) + drawWorn(painter, uwep, 0, 1); // Two-handed weapon shown twice + else + drawWorn(painter, uarms, 0, 1); // Shield (might be blank) + drawWorn(painter, uarmg, 0, 2); // Gloves + drawWorn(painter, uarmf, 1, 5); // Shoes (feet) + drawWorn(painter, uarmu, 1, 4); // Undershirt + drawWorn(painter, uleft, 0, 3); // RingL + drawWorn(painter, uright, 2, 3); // RingR - drawWorn(painter,uwep,2,1); // Weapon - drawWorn(painter,uswapwep,0,0); // Secondary weapon - drawWorn(painter,uamul,1,1); // Amulet - drawWorn(painter,ublindf,2,0); // Blindfold + drawWorn(painter, uwep, 2, 1); // Weapon + drawWorn(painter, !u.twoweap ? uswapwep : NULL, 0, 0); // Alternate weapon + drawWorn(painter, uquiver, 2, 2); // Quiver + drawWorn(painter, uamul, 1, 1); // Amulet + drawWorn(painter, ublindf, 2, 0); // Blindfold/Towel/Lenses + + // light source and leash aren't unique and don't have pointers defined + drawWorn(painter, find_tool(LEASH), 0, 4); + // OIL_LAMP matches lit candles, lamps, lantern, and candelabrum (and will + // also duplicate Sunsword when it is wielded and shown in the uwep slot) + drawWorn(painter, find_tool(OIL_LAMP), 2, 4); painter.end(); } From 7310084692f956e7b904b4f9f1de3dcbade2529b Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 10 Aug 2020 16:39:30 -0700 Subject: [PATCH 099/708] Qt menu tweak An earlier tweak worked to prevent unnecessary line wrapping for ^X output in a menu, but #enhance and '+' both had problems with their last column. This seems to work better but is still based on thrashing about rather than knowledge of how things are supposed to operate. --- win/Qt/qt_menu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index aad4d5885..53b09d6ff 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -242,6 +242,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) AddRow(i, itemlist[i]); } +#define MENU_WIDTH_SLOP 10 /* this should not be necessary */ // Determine column widths std::vector col_widths; for (std::size_t i = 0; i < (size_t) itemlist.size(); ++i) { @@ -255,8 +256,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) QTableWidgetItem *twi = table->item(i, 4); if (twi) { QString text = twi->text(); -#define MENU_WIDTH_SLOP 20 /* this should not be necessary */ - WidenColumn(4, fm.width(text) + MENU_WIDTH_SLOP); + WidenColumn(4, fm.width(text)); } continue; } @@ -285,7 +285,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) } text = columns.join(""); twi->setText(text); - WidenColumn(4, fm.width(text)); + WidenColumn(4, fm.width(text) + MENU_WIDTH_SLOP); } // FIXME: size for compact mode From 8cc7580474cab20ad6ad8f0dfd5fb6aa1898903c Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 10 Aug 2020 18:11:12 -0700 Subject: [PATCH 100/708] Qt info->annotate The core is mapping #annotate to ^N, which has no effect when number_pad is Off. The Qt menu setup saw it as the way to run that command, which will only work when number_pad is On. This fixes the menu and didn't break the large subset of other menu commands I've tried, but I haven't gotten through half of them yet. --- win/Qt/qt_main.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 32c791a02..6fc39047e 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -702,8 +702,16 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : actchar[0] = actchar[1] = '\0'; if (item[i].funct) { actchar[0] = cmd_from_func(item[i].funct); - /* M-c won't work */ - if ((actchar[0] & 0x7f) != actchar[0]) + if (actchar[0] + /* M-c won't work; translation between character + sets by the QString class can classify such + characters as erroneous and change them to '?' */ + && ((actchar[0] & 0x7f) != actchar[0] + /* the vi movement keys won't work reliably + because toggling number_pad affects them but + doesn't redo these menus */ + || strchr("hjklyubnHJKLYUBN", actchar[0]) + || strchr("hjklyubn", (actchar[0] | 0x60)))) actchar[0] = '\0'; } if (actchar[0] && !qt_compact_mode) From ed46d5db0839d7da5829a29d768fe91d5a7bebcb Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 10 Aug 2020 21:27:05 -0400 Subject: [PATCH 101/708] detect the compiler available test if CC invokes clang. If not, then assume it is gcc. --- sys/unix/hints/linux.2020 | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 99240fd51..d13cd9b58 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -76,21 +76,6 @@ endif GAMEUID = $(USER) GAMEGRP = games -# 3. miscellaneous: compiler selection; Qt5 requires C++11 -ifdef WANT_WIN_QT -CC=clang -CXX=clang++ -std=gnu++11 -#CC=gcc -#CXX=g++ -std=gnu++11 -LINK= $(CXX) -else -# compiling C code only; CC and CXX defaults can be used -#CC= -#CXX= -LINK = $(CC) -endif -#MOC = moc - # # You shouldn't need to change anything below here (in the hints file; if # you're reading this in Makefile augmented by hints, that may not be true). @@ -131,9 +116,27 @@ endif endif endif -CFLAGS=-g -O -I../include -DNOTPARMDECL +# compiler detection CCISCLANG := $(shell echo `$(CC) --version` | grep clang) ifeq "$(CCISCLANG)" "" +CC=gcc +CXX=g++ -std=gnu++11 +else +CC=clang +CXX=clang++ -std=gnu++11 +endif + +ifdef WANT_WIN_QT +# Qt5 requires C++11 +LINK = $(CXX) +#MOC = moc +else +LINK = $(CC) +endif + +CFLAGS=-g -O -I../include -DNOTPARMDECL +ifeq "$(CCISCLANG)" "" +# get the version of gcc GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) ifeq "$(GCCGTEQ9)" "1" CFLAGS+=-Wno-format-overflow From 0500aae0c02f019f2622cc822bfb3d6d359a5b48 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 10 Aug 2020 21:39:00 -0400 Subject: [PATCH 102/708] another linux.2020 tweak Leave CC alone; we've already determined whether it invoked gcc or clang --- sys/unix/hints/linux.2020 | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index d13cd9b58..96db2412a 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -119,10 +119,8 @@ endif # compiler detection CCISCLANG := $(shell echo `$(CC) --version` | grep clang) ifeq "$(CCISCLANG)" "" -CC=gcc CXX=g++ -std=gnu++11 else -CC=clang CXX=clang++ -std=gnu++11 endif From 4590bf1f012a1598475ef1b89185862729a5df8b Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 11 Aug 2020 14:55:43 -0700 Subject: [PATCH 103/708] disclosing inventory The end of game disclosure for inventory was passing want_reply==True to the inventory display routine. I don't know why because you can't select anything. This resulted in Qt disclosure showing inventory with the [Ok] button disabled and blank boxes instead of object glyphs beside the inv letters. Changing to want_reply==False fixes both aspects of that. It has no apparent effect on tty or curses; on X11 (where [Ok] was already enabled) it disables the [Search] button, a plus. I don't know whether it might mess up final disclosure for inventory on WindowsGUI. Or whether any interface which uses perm_invent window for final inventory disclosure (if there are any) will be adversely affected. --- doc/fixes37.0 | 5 ++++- src/end.c | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 38a7d212f..a6a0b83e1 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.282 $ $NHDT-Date: 1597098351 2020/08/10 22:25:51 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.283 $ $NHDT-Date: 1597182932 2020/08/11 21:55:32 $ General Fixes and Modified Features ----------------------------------- @@ -244,6 +244,9 @@ chatting to the quest leader in wizard mode with sufficient experience level and insufficient piety, player is asked whether alignment should be boosted; answering 'n' resulted in being prompted a second time leashing or unleashing pets wasn't updating persistent inventory window +end of game inventory disclosure passed an inappropriate argument to the + inventory display routine; not noticeable for tty and curses, + noticeable but not harmful for X11, and slightly harmful for Qt Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/end.c b/src/end.c index b41136009..e25657c84 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1596498166 2020/08/03 23:42:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.211 $ */ +/* NetHack 3.7 end.c $NHDT-Date: 1597182933 2020/08/11 21:55:33 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -784,7 +784,7 @@ boolean taken; c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery; if (c == 'y') { /* caller has already ID'd everything */ - (void) display_inventory((char *) 0, TRUE); + (void) display_inventory((char *) 0, FALSE); container_contents(g.invent, TRUE, TRUE, FALSE); } if (c == 'q') From 0f65db801cf9aadd07c13783340509626ca3c200 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 12 Aug 2020 16:15:28 -0700 Subject: [PATCH 104/708] tile2x11.h comment --- include/tile2x11.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/tile2x11.h b/include/tile2x11.h index 3ca57315e..2839e8946 100644 --- a/include/tile2x11.h +++ b/include/tile2x11.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 tile2x11.h $NHDT-Date: 1596498563 2020/08/03 23:49:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 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. */ @@ -6,7 +6,10 @@ #define TILE2X11_H /* - * Header for the x11 tile map. + * Header for the X11 tile map. + * + * dat/x11tiles is used by Qt for fallback if nhtiles.bmp is inaccessible, + * so this header is used by Qt as well as by X11. */ typedef struct { unsigned long version; From 0645f5483d573f3314f8114f0b5186f64c2f1126 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 12 Aug 2020 17:01:03 -0700 Subject: [PATCH 105/708] Qt header usage Move the nine #undef's common to all qt_*.cpp sources into qt_pre.h. Make "hack.h" usage consistent; always enclose withing 'extern "C {' and '}' even though only some of the sources care. --- win/Qt/qt_bind.cpp | 9 --------- win/Qt/qt_click.cpp | 11 ++--------- win/Qt/qt_delay.cpp | 11 ++--------- win/Qt/qt_glyph.cpp | 11 +---------- win/Qt/qt_icon.cpp | 11 ++--------- win/Qt/qt_inv.cpp | 9 --------- win/Qt/qt_key.cpp | 11 ++--------- win/Qt/qt_line.cpp | 11 ++--------- win/Qt/qt_main.cpp | 9 --------- win/Qt/qt_map.cpp | 9 --------- win/Qt/qt_menu.cpp | 9 --------- win/Qt/qt_msg.cpp | 9 --------- win/Qt/qt_plsel.cpp | 9 --------- win/Qt/qt_post.h | 9 +++++++++ win/Qt/qt_pre.h | 23 +++++++++++++++++++++++ win/Qt/qt_rip.cpp | 11 ++--------- win/Qt/qt_set.cpp | 11 ++--------- win/Qt/qt_stat.cpp | 9 --------- win/Qt/qt_streq.cpp | 11 ++--------- win/Qt/qt_svsel.cpp | 11 ++--------- win/Qt/qt_win.cpp | 11 ++--------- win/Qt/qt_xcmd.cpp | 11 ++--------- win/Qt/qt_yndlg.cpp | 11 ++--------- 23 files changed, 57 insertions(+), 190 deletions(-) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index acf267eb7..56215a6dc 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_click.cpp b/win/Qt/qt_click.cpp index 6b9c7b4da..d8f5030b7 100644 --- a/win/Qt/qt_click.cpp +++ b/win/Qt/qt_click.cpp @@ -4,16 +4,9 @@ // qt_click.cpp -- a mouse click buffer +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_delay.cpp b/win/Qt/qt_delay.cpp index 803946aea..0fa3003ce 100644 --- a/win/Qt/qt_delay.cpp +++ b/win/Qt/qt_delay.cpp @@ -4,16 +4,9 @@ // qt_delay.cpp -- implement a delay +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index b804b939e..26ad9ec03 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -6,17 +6,8 @@ extern "C" { #include "hack.h" -} #include "tile2x11.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 87dfac10f..27b578420 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -4,16 +4,9 @@ // qt_icon.cpp -- a labelled icon +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index c900a5e7c..6a872bdd2 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -11,15 +11,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index 04d1b3d21..5aa807803 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -4,16 +4,9 @@ // qt_key.cpp -- a key buffer +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_line.cpp b/win/Qt/qt_line.cpp index 4c1f63eba..482122589 100644 --- a/win/Qt/qt_line.cpp +++ b/win/Qt/qt_line.cpp @@ -4,16 +4,9 @@ // qt_line.cpp -- a one line input window +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 6fc39047e..3c10f5fce 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 1508b2213..51fafda2d 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 53b09d6ff..b3d192eb1 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index e3e02d9a1..aee2ea135 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index 8fbafd527..d9a2d4337 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_post.h b/win/Qt/qt_post.h index d4eaba254..a63122f43 100644 --- a/win/Qt/qt_post.h +++ b/win/Qt/qt_post.h @@ -1,4 +1,13 @@ +/* NetHack 3.7 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. + * + * #include after . + */ + #ifdef __clang__ #pragma clang diagnostic pop #endif /* __clang__ */ +/*qt_post.h*/ diff --git a/win/Qt/qt_pre.h b/win/Qt/qt_pre.h index ea891fcf4..e3dcdde0d 100644 --- a/win/Qt/qt_pre.h +++ b/win/Qt/qt_pre.h @@ -1,5 +1,28 @@ +/* NetHack 3.7 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. + * + * #include after "hack.h", before . + */ + +#undef Invisible +#undef Warning +#undef index +#undef msleep +#undef rindex +#undef wizard +#undef yn +#undef min +#undef max + +/* disable warnings for shadowed names; some of the Qt prototypes use + placeholder argument names which conflict with nethack variables + ('g', 'u', a couple of others) */ #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wshadow" #endif +/*qt_pre.h*/ + diff --git a/win/Qt/qt_rip.cpp b/win/Qt/qt_rip.cpp index 49402c85f..aa7a8ebc4 100644 --- a/win/Qt/qt_rip.cpp +++ b/win/Qt/qt_rip.cpp @@ -4,16 +4,9 @@ // qt_rip.cpp -- tombstone window +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index d265acaf2..0c35291bc 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -4,16 +4,9 @@ // qt_set.cpp -- the Qt settings +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 22fb2f6a5..2a8c262ea 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -7,15 +7,6 @@ extern "C" { #include "hack.h" } -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max #include "qt_pre.h" #include diff --git a/win/Qt/qt_streq.cpp b/win/Qt/qt_streq.cpp index 9254ad04d..b37ab305f 100644 --- a/win/Qt/qt_streq.cpp +++ b/win/Qt/qt_streq.cpp @@ -4,16 +4,9 @@ // qt_streq.cpp -- string requestor +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 66ecd13e8..f11562c68 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -4,16 +4,9 @@ // qt_svsel.cpp -- saved game selector +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 7a636ac16..326acb17c 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -46,16 +46,9 @@ // identifiers. #define QT_DEPRECATED_WARNINGS +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 3bb3a4f92..a1a343610 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -4,17 +4,10 @@ // qt_xcmd.cpp -- extended command widget +extern "C" { #include "hack.h" #include "func_tab.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index cac810394..389ee4858 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -4,16 +4,9 @@ // qt_yndlg.cpp -- yes/no dialog +extern "C" { #include "hack.h" -#undef Invisible -#undef Warning -#undef index -#undef msleep -#undef rindex -#undef wizard -#undef yn -#undef min -#undef max +} #include "qt_pre.h" #include From 58d208ee8faf974f6d0d3987e40c2bb5960af310 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 13 Aug 2020 01:45:06 -0700 Subject: [PATCH 106/708] minor Qt reformatting --- win/Qt/qt_bind.cpp | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 56215a6dc..cd623fb86 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -182,14 +182,16 @@ void NetHackQtBind::qt_askname() free_saved_games(saved); switch (ch) { - case -1: - if ( splash ) splash->hide(); - if (NetHackQtPlayerSelector(keybuffer).Choose()) - return; - case -2: - break; - default: - return; + case -1: + if (splash) + splash->hide(); + if (NetHackQtPlayerSelector(keybuffer).Choose()) + return; + /*FALLTHRU*/ + case -2: + break; + default: + return; } // Quit @@ -245,22 +247,30 @@ winid NetHackQtBind::qt_create_nhwindow(int type) NetHackQtWindow* window=0; switch (type) { - case NHW_MAP: { + case NHW_MAP: { NetHackQtMapWindow2* w=new NetHackQtMapWindow2(clickbuffer); main->AddMapWindow(w); window=w; - } break; case NHW_MESSAGE: { + break; + } + case NHW_MESSAGE: { NetHackQtMessageWindow* w=new NetHackQtMessageWindow; main->AddMessageWindow(w); window=w; - } break; case NHW_STATUS: { + break; + } + case NHW_STATUS: { NetHackQtStatusWindow* w=new NetHackQtStatusWindow; main->AddStatusWindow(w); window=w; - } break; case NHW_MENU: + break; + } + case NHW_MENU: window=new NetHackQtMenuOrTextWindow(mainWidget()); - break; case NHW_TEXT: + break; + case NHW_TEXT: window=new NetHackQtTextWindow(mainWidget()); + break; } window->nhid = id; @@ -272,8 +282,7 @@ winid NetHackQtBind::qt_create_nhwindow(int type) #else && main->isVisible() #endif - ) - { + ) { delete splash; splash = 0; } From cee29d33381c60c954bcafbd60ac9f4325354cee Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 13 Aug 2020 02:00:11 -0700 Subject: [PATCH 107/708] more Qt formatting --- win/Qt/qt_glyph.cpp | 56 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 26ad9ec03..7ca292c87 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -6,7 +6,7 @@ extern "C" { #include "hack.h" -#include "tile2x11.h" +#include "tile2x11.h" /* x11tiles is potential fallback for nhtiles.bmp */ } #include "qt_pre.h" @@ -40,7 +40,7 @@ NetHackQtGlyphs::NetHackQtGlyphs() { const char* tile_file = PIXMAPDIR "/nhtiles.bmp"; - if ( iflags.wc_tile_file ) + if (iflags.wc_tile_file) tile_file = iflags.wc_tile_file; if (!img.load(tile_file)) { @@ -64,11 +64,11 @@ NetHackQtGlyphs::NetHackQtGlyphs() tiles_per_row = 40; } - if ( iflags.wc_tile_width ) + if (iflags.wc_tile_width) tilefile_tile_W = iflags.wc_tile_width; else tilefile_tile_W = img.width() / tiles_per_row; - if ( iflags.wc_tile_height ) + if (iflags.wc_tile_height) tilefile_tile_H = iflags.wc_tile_height; else tilefile_tile_H = tilefile_tile_W; @@ -79,59 +79,57 @@ NetHackQtGlyphs::NetHackQtGlyphs() void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y) { int tile = glyph2tile[glyph]; - int px = (tile%tiles_per_row)*width(); - int py = tile/tiles_per_row*height(); + int px = (tile % tiles_per_row) * width(); + int py = tile / tiles_per_row * height(); - painter.drawPixmap( - x, - y, - pm, - px,py, - width(),height() - ); + painter.drawPixmap(x, y, pm, px, py, width(), height()); } -void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, int cellx, int celly) + +void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, + int cellx, int celly) { - drawGlyph(painter,glyph,cellx*width(),celly*height()); + drawGlyph(painter, glyph, cellx * width(), celly * height()); } + QPixmap NetHackQtGlyphs::glyph(int glyph) { int tile = glyph2tile[glyph]; - int px = (tile%tiles_per_row)*tilefile_tile_W; - int py = tile/tiles_per_row*tilefile_tile_H; + int px = (tile % tiles_per_row) * tilefile_tile_W; + int py = tile / tiles_per_row * tilefile_tile_H; - return QPixmap::fromImage(img.copy(px, py, tilefile_tile_W, tilefile_tile_H)); + return QPixmap::fromImage(img.copy(px, py, + tilefile_tile_W, tilefile_tile_H)); } + void NetHackQtGlyphs::setSize(int w, int h) { - if ( size == QSize(w,h) ) + if (size == QSize(w, h)) return; - - bool was1 = size == pm1.size(); - size = QSize(w,h); + size = QSize(w, h); if (!w || !h) return; // Still not decided - if ( size == pm1.size() ) { + if (size == pm1.size()) { // not zoomed pm = pm1; return; } - if ( size == pm2.size() ) { + if (size == pm2.size()) { // zoomed pm = pm2; return; } - if (w==tilefile_tile_W && h==tilefile_tile_H) { + bool was1 = (size == pm1.size()); + if (w == tilefile_tile_W && h == tilefile_tile_H) { pm.convertFromImage(img); } else { - QApplication::setOverrideCursor( Qt::WaitCursor ); + QApplication::setOverrideCursor(Qt::WaitCursor); QImage scaled = img.scaled( - w*img.width()/tilefile_tile_W, - h*img.height()/tilefile_tile_H, + w * img.width() / tilefile_tile_W, + h * img.height() / tilefile_tile_H, Qt::IgnoreAspectRatio, Qt::FastTransformation ); - pm.convertFromImage(scaled,Qt::ThresholdDither|Qt::PreferDither); + pm.convertFromImage(scaled, Qt::ThresholdDither | Qt::PreferDither); QApplication::restoreOverrideCursor(); } (was1 ? pm2 : pm1) = pm; From bdbf8f19cc4d6993a2b2bc2efc2fbe4201da4e41 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 11:34:23 -0400 Subject: [PATCH 108/708] update some hints mechanics for 2020 Allow sharing of common code between different hints files through use of: #-INCLUDE new folder created: sys/unix/hints/include new hints include files: sys/unix/hints/include/multiw-1.2020 sys/unix/hints/include/multiw-2.2020 structure the early parts of sys/unix/hints/linux.2020 and sys/unix/hints/macOS.2020 consistently, and utilize #-INCLUDE multiw-1.2020 and #-INCLUDE multiw-2.2020 in them. That will allow the Makefile lines that they contain to be maintained in a single place. --- sys/unix/hints/include/multiw-1.2020 | 37 ++++ sys/unix/hints/include/multiw-2.2020 | 108 +++++++++++ sys/unix/hints/linux.2020 | 192 ++++++------------- sys/unix/hints/macOS.2020 | 268 ++++++++++----------------- sys/unix/mkmkfile.sh | 5 +- 5 files changed, 306 insertions(+), 304 deletions(-) create mode 100644 sys/unix/hints/include/multiw-1.2020 create mode 100644 sys/unix/hints/include/multiw-2.2020 diff --git a/sys/unix/hints/include/multiw-1.2020 b/sys/unix/hints/include/multiw-1.2020 new file mode 100644 index 000000000..3fb550882 --- /dev/null +++ b/sys/unix/hints/include/multiw-1.2020 @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# NetHack 3.7 multiw-1.2020 $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 +# on the 'make' command line. If none are enabled, tty will be used. +#WANT_WIN_TTY=1 +#WANT_WIN_CURSES=1 +#WANT_WIN_X11=1 +#WANT_WIN_QT=1 + +# 2. What is the default window system? +# Exactly one of these can be manually uncommented and/or can be specified +# on the 'make' command line. If none is enabled, the first among +# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. +#WANT_DEFAULT=tty +#WANT_DEFAULT=curses +#WANT_DEFAULT=Qt +#WANT_DEFAULT=X11 + +# 3. compiler detection or optional override +CCISCLANG := $(shell echo `$(CC) --version` | grep clang) +ifeq "$(CCISCLANG)" "" +CXX=g++ -std=gnu++11 +else +CXX=clang++ -std=gnu++11 +endif +# if you want to override the compiler detection just carried out +# uncomment one of the following pairs as desired. +#CC= gcc +#CXX= g++ -std-gnu++11 +# +#CC= clang +#CXX=clang++ -std=gnu++11 + +#end of multiw-1.2020 +#------------------------------------------------------------------------------ diff --git a/sys/unix/hints/include/multiw-2.2020 b/sys/unix/hints/include/multiw-2.2020 new file mode 100644 index 000000000..ad4028aed --- /dev/null +++ b/sys/unix/hints/include/multiw-2.2020 @@ -0,0 +1,108 @@ +#------------------------------------------------------------------------------ +# NetHack 3.7 multiw-2.2020 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# +# Sorts out support for multiple window ports (interfaces) to included in the build. +# +# Included from: +# hints/linux.2020 +# hints/macOS.2020 +# +# The following will be set appropriately following this: +# - WANT_WIN_XXX (at least one will be set; default is TTY) +# - WANT_DEFAULT (set to match one of the enabled WANT_WIN_XXX) +# - WINCFLAGS +# - WINSRC +# - WINOBJ0 +#--- +# User selections could be specified as combinations of any of the following: +# WIN_WANT_TTY=1, WIN_WANT_CURSES=1, WIN_WANT_QT=1, WIN_WANT_X11=1 +# The selections will all be linked into the same binary. +# +# Assuming you have the prerequisite packages mentioned above, you can +# specify, right on the make command line, which window ports (or interfaces) +# to include in your build. Doing it via the make command line means that won't +# have to edit the Makefile. +# +# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 install +# +# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use +# something other than tty as the default interface. +# + +# Make sure that at least one interface is enabled. +ifndef WANT_WIN_ALL +ifndef WANT_WIN_TTY +ifndef WANT_WIN_CURSES +ifndef WANT_WIN_X11 +ifndef WANT_WIN_QT +WANT_WIN_TTY=1 +endif +endif +endif +endif +endif + +ifdef WANT_WIN_ALL +WANT_WIN_TTY=1 +WANT_WIN_CURSES=1 +WANT_WIN_X11=1 +WANT_WIN_QT=1 +endif + + +# Make sure that a default interface is specified; this doesn't guarantee +# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but +# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. +ifndef WANT_DEFAULT +# pick the first one enabled among { tty, curses, X11, Qt } +ifdef WANT_WIN_TTY +WANT_DEFAULT=tty +else +ifdef WANT_WIN_CURSES +WANT_DEFAULT=curses +else +ifdef WANT_WIN_X11 +WANT_DEFAULT=X11 +else +ifdef WANT_WIN_QT +WANT_DEFAULT=Qt +else +# ? shouldn't be able to get here... +endif +endif +endif +endif +endif + +WINCFLAGS= +WINSRC = +WINOBJ0 = + +ifdef WANT_WIN_TTY +WINSRC += $(WINTTYSRC) +WINOBJ0 += $(WINTTYOBJ) +else +WINCFLAGS += -DNOTTYGRAPHICS +endif + +ifdef WANT_WIN_CURSES +WINCFLAGS += -DCURSES_GRAPHICS +WINSRC += $(WINCURSESSRC) +WINOBJ0 += $(WINCURSESOBJ) +endif + +ifdef WANT_WIN_X11 +WINCFLAGS += -DX11_GRAPHICS +WINSRC += $(WIINX11SRC) +WINOBJ0 += $(WINX11OBJ) +endif + +ifdef WANT_WIN_QT +WINCFLAGS += -DQT_GRAPHICS +WINSRC += $(WINQTSRC) +WINOBJ0 += $(WINQTOBJ) +endif + +#end of hints/include/multiw-2.2020 +#------------------------------------------------------------------------------ + diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 96db2412a..a633fec4f 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,137 +1,51 @@ -# -# NetHack 3.7 linux.2020 $NHDT-Date: 1597072358 2020/08/10 15:12:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.2 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1597332698 2020/08/13 15:31:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # -#-PRE +#--------------------------------------------------------------------- # Linux hints file with support for multiple window ports (interfaces) +# Tested on: +# - Ubuntu focal # -# This hints file supports tty, curses, x11, and Qt in the same binary, -# but: +# 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. # -# - For x11 support, you'll need to obtain and install x11 development libraries. -# For example, on Ubuntu 20.04 (as of August 2020): -# 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) -# -# - For Qt support, you'll need to obtain and install Qt. -# For example, on Ubuntu 20.04 (as of August 2020): -# 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: -# "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 only) by the following command: -# sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 -# -# - For curses support, you may need to obtain and install the -# ncurses development libraries if they aren't already installed -# with your distribution. They seem to be there already with Ubuntu 20.04, but -# for example, if you needed to install ncurses: -# sudo apt-get install libncurses-dev -# -# - tty support shouldn't require any prerequisite additional packages. -# -# Assuming you have the prerequisite packages mentioned above, you can -# specify, right on the make command line, which window ports (or interfaces) -# to include in your build. Doing it via the make command line means that won't -# have to edit the Makefile. -# -# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 install -# -# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use -# something other than tty as the default interface. -# -# 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 -# on the 'make' command line. If none are enabled, tty will be used. -#WANT_WIN_TTY=1 -#WANT_WIN_CURSES=1 -#WANT_WIN_X11=1 -#WANT_WIN_QT=1 -# 1a. What is the default window system? -# Exactly one of these can be manually uncommented and/or can be specified -# on the 'make' command line. If none is enabled, the first among -# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. -#WANT_DEFAULT=tty -#WANT_DEFAULT=curses -#WANT_DEFAULT=Qt -#WANT_DEFAULT=X11 +#-PRE +# linux.2020 hints file provides a single-user build for Linux (such +# as Ubuntu focal). +#-INCLUDE multiw-1.2020 + +# 4. If you set WANT_WIN_QT, you need to +# A) set QTDIR either here or in the environment to point to the Qt5 +# Library installation root. +# B) set XPMLIB to point to the Xpm library +ifndef WANT_WIN_QT +ifdef WANT_WIN_ALL +WANT_WIN_QT=1 +endif +endif ifdef WANT_WIN_QT QTDIR=/usr -endif # WANT_WIN_QT +endif # WANT_WIN_QT ifndef LIBXPM LIBXPM= -L/opt/X11/lib -lXpm endif -# 2. Not customizable in this linux.2020 hints file, which provides -# a single-user build for Linux (such as Ubuntu focal). +#5. Other GAMEUID = $(USER) GAMEGRP = games -# +#----------------------------------------------------------------------------- # You shouldn't need to change anything below here (in the hints file; if # you're reading this in Makefile augmented by hints, that may not be true). # -# Make sure that at least one interface is enabled. -ifndef WANT_WIN_TTY -ifndef WANT_WIN_CURSES -ifndef WANT_WIN_X11 -ifndef WANT_WIN_QT -WANT_WIN_TTY=1 -endif -endif -endif -endif - -# Make sure that a default interface is specified; this doesn't guarantee -# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but -# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. -ifndef WANT_DEFAULT -# pick the first one enabled among { tty, curses, X11, Qt } -ifdef WANT_WIN_TTY -WANT_DEFAULT=tty -else -ifdef WANT_WIN_CURSES -WANT_DEFAULT=curses -else -ifdef WANT_WIN_X11 -WANT_DEFAULT=X11 -else -ifdef WANT_WIN_QT -WANT_DEFAULT=Qt -else -# ? shouldn't be able to get here... -endif -endif -endif -endif -endif - -# compiler detection -CCISCLANG := $(shell echo `$(CC) --version` | grep clang) -ifeq "$(CCISCLANG)" "" -CXX=g++ -std=gnu++11 -else -CXX=clang++ -std=gnu++11 -endif - -ifdef WANT_WIN_QT -# Qt5 requires C++11 -LINK = $(CXX) -#MOC = moc -else -LINK = $(CC) -endif +#-INCLUDE multiw-2.2020 +# XXX -g vs -O should go here, -I../include goes in the makefile CFLAGS=-g -O -I../include -DNOTPARMDECL ifeq "$(CCISCLANG)" "" # get the version of gcc @@ -140,13 +54,26 @@ ifeq "$(GCCGTEQ9)" "1" CFLAGS+=-Wno-format-overflow endif #gcc version greater than or equal to 9 endif #not clang +# As of LLVM build 2336.1.00, this gives dozens of spurious messages, so +# leave it out by default. +#CFLAGS+=-Wunreachable-code +#CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ +# -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings +#CFLAGS+=-DGCC_WARN + +# NetHack sources control CFLAGS+=-DDLB -CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE CFLAGS+=-DTIMED_DELAY -CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" CFLAGS+=-DDUMPLOG CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +# older binaries use NOCLIPPING, but that disables SIGWINCH +#CFLAGS+=-DNOCLIPPING +#CFLAGS+=-DNOMAIL #CFLAGS+=-DEXTRA_SANITY_CHECKS #CFLAGS+=-DEDIT_GETLIN #CFLAGS+=-DSCORE_ON_BOTL @@ -154,25 +81,22 @@ CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE #CFLAGS+=-DTTY_TILES_ESCCODES #CFLAGS+=-DTTY_SOUND_ESCCODES -WINSRC = -WINOBJ0 = -WINLIB = +CFLAGS+= $(WINCFLAGS) #from multiwin.2020 + VARDATND = VARDATND0 = CURSESLIB = +#ifdef WANT_WIN_CHAIN +#HINTSRC=$(CHAINSRC) +#HINTOBJ=$(CHAINOBJ) +#endif # WANT_WIN_CHAIN + ifdef WANT_WIN_TTY -WINSRC += $(WINTTYSRC) -WINOBJ0 += $(WINTTYOBJ) CURSESLIB = -lncurses -ltinfo -else # !WANT_WIN_TTY -CFLAGS += -DNOTTYGRAPHICS -endif # !WANT_WIN_TTY +endif ifdef WANT_WIN_CURSES -CFLAGS += -DCURSES_GRAPHICS -WINSRC += $(WINCURSESSRC) -WINOBJ0 += $(WINCURSESOBJ) CURSESLIB = -lncurses -ltinfo endif @@ -181,7 +105,6 @@ WINLIB += $(CURSESLIB) endif ifdef WANT_WIN_X11 -CFLAGS += -DX11_GRAPHICS USE_XPM=1 WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm @@ -196,32 +119,27 @@ CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif -WINSRC += $(WINX11SRC) -WINOBJ0 += $(WINX11OBJ) WINLIB += $(WINX11LIB) LFLAGS=-L/opt/X11/lib endif # WANT_WIN_X11 ifdef WANT_WIN_QT -CFLAGS += -DQT_GRAPHICS +# Qt5 requires C++11 +LINK = $(CXX) QTCXXFLAGS += -Wno-deprecated-declarations QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) QTCXXFLAGS += -fPIC WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) -WINSRC += $(WINQTSRC) -WINOBJ0 += $(WINQTOBJ) VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm # XXX if /Developer/qt exists and QTDIR not set, use that ifndef QTDIR $(error QTDIR not defined in the environment or Makefile) endif # QTDIR # XXX make sure QTDIR points to something reasonable -POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \ - $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; \ - $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; \ - chmod $(VARFILEPERM) $(INSTDIR)/sysconf; POSTINSTALL+= bdftopcf win/X11/nh10.bdf > $(INSTDIR)/nh10.pcf; \ ( cd $(INSTDIR); mkfontdir -x .lev ); +else +LINK = $(CC) endif # !WANT_WIN_QT # prevent duplicate tile.o in WINOBJ @@ -240,11 +158,14 @@ POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \ $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf; \ $(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; \ chmod $(VARFILEPERM) $(INSTDIR)/sysconf; + +ifneq "$(CCISCLANG)" "" # gdb may not be installed if clang is chosen compiler so the game # won't start in that case due to a sysconf error. Comment out # relevant lines in sysconf. POSTINSTALL+= sed -i -e 's;^GDBPATH=/usr/bin/gdb;\#GDBPATH=/usr/bin/gdb;' \ -e 's;PANICTRACE_GDB=1;PANICTRACE_GDB=0;' $(INSTDIR)/sysconf; +endif # when building liblua.a, avoid warning that use of tmpnam() should be # replaced by mkstemp(); the lua code doesn't use nethack's config.h so @@ -257,6 +178,7 @@ LFLAGS=-rdynamic # if TTY_TILES_ESCCODES #WINSRC += tile.c #WINOBJ += tile.o +# endif CHOWN=true CHGRP=true diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index e02026563..4e4449e3c 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -1,64 +1,32 @@ -# NetHack 3.7 macOS.2020 $NHDT-Date: 1596489016 2020/08/03 21:10:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1597332721 2020/08/13 15:32:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # -#-PRE -# macOS X hints file +#--------------------------------------------------------------------- +# MacOS hints file with support for multiple window ports (interfaces) # Tested on: # - MacOS Catalina 10.15 # -# If this doesn't work for some other version of Mac OS X, make a new file for -# that OS, don't change this one. And let us know about it. +# If this doesn't work for some other version of Mac OS X, 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 -# -# This hints file supports tty, curses, x11, and Qt in the same binary, -# but: -# - You'll need to obtain and install XQuartz if you want X11 support. -# (Attempting to run X11.app will describe where to get it.) -# One possible way: brew install xquartz -# -# - You'll need to obtain and install Qt if you want Qt support -# One possible way: brew install Qt -# -# - You'll need to obtain and install the ncurses development libraries -# if you want curses window port support. -# -# Assuming you have the prerequisite packages, You can specify the -# window ports to include on the make command line without requiring -# you to edit the Makefile: -# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 all -# in the src/ directory prior to 'make install' in the top directory. -# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use -# something other than tty as the default interface. +#-PRE xxxx +# macOS X hints file # -# This hints file can build several different interfaces and several -# types of installations (private, shared, source). -# Edit the section (1.) to control which interface(s). -# Edit the section (2.) to match the type of build you need. +#-INCLUDE multiw-1.2020 -# 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 -# on the 'make' command line. If none are enabled, tty will be used. -#WANT_WIN_TTY=1 -#WANT_WIN_CURSES=1 -#WANT_WIN_X11=1 -#WANT_WIN_QT=1 - -# 1a. What is the default window system? -# Exactly one of these can be manually uncommented and/or can be specified -# on the 'make' command line. If none is enabled, the first among -# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. -#WANT_DEFAULT=tty -#WANT_DEFAULT=curses -#WANT_DEFAULT=Qt -#WANT_DEFAULT=X11 - -# 1b. If you set WANT_WIN_QT, you need to +# 4. If you set WANT_WIN_QT, you need to # A) set QTDIR either here or in the environment to point to the Qt5 # library installation root. (Qt2, Qt3, Qt4 will not work) # B) set XPMLIB to point to the Xpm library +ifndef WANT_WIN_QT +ifdef WANT_WIN_ALL +WANT_WIN_QT=1 +endif +endif ifdef WANT_WIN_QT #QTDIR=/Developer/Qt # Qt installed via homebrew @@ -70,92 +38,17 @@ ifndef LIBXPM LIBXPM= -L/opt/X11/lib -lXpm endif -# 2. Is this a build for a binary that will be shared among different users -# or will it be private to you? -# If it is shared: -# - it will be owned by the user and group listed -# - if the user does not exist, you MUST create it before installing -# NetHack -# - if the group does not exist, it will be created. -# NB: if the group already exists and is being used for something -# besides games, you probably want to specify a new group instead -# NB: the group will be created locally; if your computer is centrally -# administered this may not be what you (or your admin) want. -# Consider a non-shared install (WANT_SHARE_INSTALL=0) instead. -# - 'make install' must be run as "sudo make install" -# Note: 'make install' starts out be removing all files and subdirectories -# from the target destination. Use 'make update' instead if there is -# anything there that you want to keep such as the high scores file from -# a previous install. -#WANT_SHARE_INSTALL=1 -GAMEUID = $(USER) -GAMEGRP = games -# build to run in the source tree - primarily for development. Build -# with "make all" -#WANT_SOURCE_INSTALL=1 +# 5. Other -# 3. miscellaneous: compiler selection; Qt5 requires C++11 -ifdef WANT_WIN_QT -CC=clang -CXX=clang++ -std=gnu++11 -#CC=gcc -#CXX=g++ -std=gnu++11 -LINK= $(CXX) -else -# compiling C code only; CC and CXX defaults can be used -#CC= -#CXX= -LINK = $(CC) -endif -#MOC = moc - -# At the moment the 'chain' interface is just for debugging, but in the future -# it could be useful for other things. Requires SYSCF and an ANSI compiler. -#WANT_WIN_CHAIN=1 - -# +#----------------------------------------------------------------------------- # You shouldn't need to change anything below here (in the hints file; if # you're reading this in Makefile augmented by hints, that may not be true). # -# Make sure that at least one interface aside from 'chain' is enabled. -ifndef WANT_WIN_TTY -ifndef WANT_WIN_CURSES -ifndef WANT_WIN_X11 -ifndef WANT_WIN_QT -WANT_WIN_TTY=1 -endif -endif -endif -endif +#-INCLUDE multiw-2.2020 -# Make sure that a default interface is specified; this doesn't guarantee -# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but -# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. -ifndef WANT_DEFAULT -# pick the first one enabled among { tty, curses, X11, Qt } -ifdef WANT_WIN_TTY -WANT_DEFAULT=tty -else -ifdef WANT_WIN_CURSES -WANT_DEFAULT=curses -else -ifdef WANT_WIN_X11 -WANT_DEFAULT=X11 -else -ifdef WANT_WIN_QT -WANT_DEFAULT=Qt -else -# ? shouldn't be able to get here... -endif -endif -endif -endif -endif - -CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ - -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -CFLAGS+=-DGCC_WARN +# XXX -g vs -O should go here, -I../include goes in the makefile +CFLAGS+=-g -I../include -DNOTPARMDECL ifndef WANT_WIN_QT # these are normally used when compiling nethack's core CFLAGS+=-ansi -pedantic -Wno-long-long @@ -169,45 +62,51 @@ endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. #CFLAGS+=-Wunreachable-code +CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ + -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings +CFLAGS+=-DGCC_WARN -# XXX -g vs -O should go here, -I../include goes in the makefile -CFLAGS+=-g -I../include +# NetHack sources control +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +#CFLAGS+=-DTIMED_DELAY +#CFLAGS+=-DDUMPLOG +#CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" # older binaries use NOCLIPPING, but that disables SIGWINCH #CFLAGS+=-DNOCLIPPING -CFLAGS+= -DNOMAIL -DNOTPARMDECL -DHACKDIR=\"$(HACKDIR)\" -CFLAGS+= -DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB -CFLAGS+= -DGREPPATH=\"/usr/bin/grep\" +CFLAGS+=-DNOMAIL +#CFLAGS+=-DEXTRA_SANITY_CHECKS +#CFLAGS+=-DEDIT_GETLIN +#CFLAGS+=-DSCORE_ON_BOTL +#CFLAGS+=-DMSGHANDLER +#CFLAGS+=-DTTY_TILES_ESCCODES +#CFLAGS+=-DTTY_SOUND_ESCCODES + +CFLAGS+= $(WINCFLAGS) #from multiwin.2020 + +VARDATND = +VARDATND0 = +CURSESLIB = ifdef WANT_WIN_CHAIN -CFLAGS+= -DWINCHAIN HINTSRC=$(CHAINSRC) HINTOBJ=$(CHAINOBJ) endif # WANT_WIN_CHAIN -WINSRC = -WINOBJ0 = -WINLIB = -VARDATND = -VARDATND0 = -WINCURSESLIB = - ifdef WANT_WIN_TTY -WINSRC += $(WINTTYSRC) -WINOBJ0 += $(WINTTYOBJ) -WINCURSESLIB = -lncurses -else # !WANT_WIN_TTY -CFLAGS += -DNOTTYGRAPHICS -endif # !WANT_WIN_TTY - -ifdef WANT_WIN_CURSES -CFLAGS += -DCURSES_GRAPHICS -WINSRC += $(WINCURSESSRC) -WINOBJ0 += $(WINCURSESOBJ) -WINCURSESLIB = -lncurses +CURSESLIB = -lncurses endif -ifdef WINCURSESLIB -WINLIB += $(WINCURSESLIB) +ifdef WANT_WIN_CURSES +CURSESLIB = -lncurses +endif + +ifdef CURSESLIB +WINLIB += $(CURSESLIB) endif ifdef WANT_WIN_X11 @@ -216,7 +115,6 @@ WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm # -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 ); -CFLAGS += -DX11_GRAPHICS # separate from CFLAGS so that we don't pass it to every file X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in @@ -226,14 +124,13 @@ CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif -WINSRC += $(WINX11SRC) -WINOBJ0 += $(WINX11OBJ) WINLIB += $(WINX11LIB) LFLAGS=-L/opt/X11/lib endif # WANT_WIN_X11 ifdef WANT_WIN_QT -CFLAGS += -DQT_GRAPHICS +# Qt5 requires C++11 +LINK = $(CXX) QTCXXFLAGS += -Wno-deprecated-declarations QTCXXFLAGS += $(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) @@ -254,6 +151,7 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) +WANT_BUNDLE=1 ifdef WANT_SHARE_INSTALL # if $GAMEUID is root, we install into roughly proper Mac locations, otherwise # we install into ~/nethackdir @@ -278,10 +176,16 @@ 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 -PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); . sys/unix/hints/macosx.sh group2 $(GAMEGRP); mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) -POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf; -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ + . sys/unix/hints/macosx.sh group2 $(GAMEGRP); \ + mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; + else ifdef WANT_SOURCE_INSTALL + PREFIX=$(abspath $(NHSROOT)) # suppress nethack.sh #SHELLDIR= @@ -295,7 +199,9 @@ POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/s # We can use "make all" to build the whole thing - but it misses some things: MOREALL=$(MAKE) install CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE + else # !WANT_SOURCE_INSTALL + PREFIX:=$(wildcard ~) SHELLDIR=$(PREFIX)/bin HACKDIR=$(PREFIX)/nethackdir @@ -304,18 +210,46 @@ CHGRP=/usr/bin/true GAMEPERM = 0700 VARFILEPERM = 0600 VARDIRPERM = 0700 -ifdef WANT_WIN_X11 +ifdef ($(WANT_DEFAULT),X11) # install nethack.rc as ~/.nethackrc if no ~/.nethackrc exists PREINSTALL= cp -n win/X11/nethack.rc ~/.nethackrc || true -endif # WANT_WIN_X11 -POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; chmod $(VARFILEPERM) $(HACKDIR)/sysconf; -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -endif # !WANT_SOURCE_INSTALL +endif # WANT_DEFAULT X11 + +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +ifdef WANT_BUNDLE +# +# Bundle +# +# $(HACKDIR)/$(GAME).app/ +# Contents/ +# Frameworks/ +# Info.plist +# MacOS/ +# $(GAME) +# PkgInfo/ +# PlugIns/ +# Resources/ +# SharedFrameWorks/ +# +BUNDLE = mkdir -p $(HACKDIR)/nethack.app/Contents/MacOS; \ + sys/unix/hints/macosx.sh infoplist > $(HACKDIR)/nethack.app/Contents/Info.plist; \ + mv $(HACKDIR)/nethack $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +ifdef WANT_SHARE_INSTALL +BUNDLE+= chmod $(GAMEPERM) $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +endif + +POSTINSTALL+= $(BUNDLE) +POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ + sed -i '' 's;HACKDIR/$(GAME);HACKDIR/$(GAME).app/Contents/MacOS/$(GAME);' $(SHELLDIR)/$(GAME) ; fi; +endif # WANT_BUNDLE +endif # !WANT_SHARE_INSTALL INSTDIR=$(HACKDIR) VARDIR=$(HACKDIR) - # ~/Library/Preferences/NetHack Defaults # OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp # OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt diff --git a/sys/unix/mkmkfile.sh b/sys/unix/mkmkfile.sh index 478aa70cc..17d56d706 100755 --- a/sys/unix/mkmkfile.sh +++ b/sys/unix/mkmkfile.sh @@ -1,5 +1,5 @@ #!/bin/sh -# NetHack 3.7 mkmkfile.sh $NHDT-Date: 1596498293 2020/08/03 23:44:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ +# NetHack 3.7 mkmkfile.sh $NHDT-Date: 1597332770 2020/08/13 15:32:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.15 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. @@ -23,7 +23,8 @@ echo "### Start $5 PRE" >> $3 echo "###" >> $3 awk '/^#-PRE/,/^#-POST/{ \ if(index($0, "#-PRE") == 1) print "# (new segment at source line",NR,")"; \ - if(index($0, "#-P") != 1) print}' $4 >> $3 + if(index($0, "#-INCLUDE") == 1) system("cat hints/include/"$2); \ + else if(index($0, "#-P") != 1) print}' $4 >> $3 echo "### End $5 PRE" >> $3 echo "" >> $3 From 674021428ded98d380958f4be699e64574d992f8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 11:35:26 -0400 Subject: [PATCH 109/708] macosx.h Info.plist bit --- sys/unix/hints/macosx.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/unix/hints/macosx.sh b/sys/unix/hints/macosx.sh index fe096410b..544eefbd1 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: 1596498420 2020/08/03 23:47:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ +# NetHack 3.7 macosx.sh $NHDT-Date: 1597332920 2020/08/13 15:35:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -151,7 +151,7 @@ xdescplist) SVSDOT=`util/makedefs --svs .` IFPkgDescriptionDeleteWarning IFPkgDescriptionDescription - NetHack $SVSDOT for the MacOS X Terminal + NetHack $SVSDOT for MacOS IFPkgDescriptionTitle NetHack @@ -169,9 +169,9 @@ xinfoplist) SVSDOT=`util/makedefs --svs .` CFBundleGetInfoString - NetHack $SVSDOT for the MacOS X Terminal + NetHack $SVSDOT for MacOS CFBundleIdentifier - org.nethack.term + org.nethack.macos CFBundleName NetHack CFBundleShortVersionString From 410b46678bd3eebe057bb0e5c8066462ead40238 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 11:57:14 -0400 Subject: [PATCH 110/708] comment bit name had evolved but the comment had not been updated --- sys/unix/hints/linux.2020 | 2 +- sys/unix/hints/macOS.2020 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index a633fec4f..0bdce7bad 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -81,7 +81,7 @@ CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" #CFLAGS+=-DTTY_TILES_ESCCODES #CFLAGS+=-DTTY_SOUND_ESCCODES -CFLAGS+= $(WINCFLAGS) #from multiwin.2020 +CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 VARDATND = VARDATND0 = diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 4e4449e3c..278323418 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -86,7 +86,7 @@ CFLAGS+=-DNOMAIL #CFLAGS+=-DTTY_TILES_ESCCODES #CFLAGS+=-DTTY_SOUND_ESCCODES -CFLAGS+= $(WINCFLAGS) #from multiwin.2020 +CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 VARDATND = VARDATND0 = From c67ef6acf871f01548e15ae7ef20718741455746 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 13:34:18 -0400 Subject: [PATCH 111/708] update bottom of NewInstall.unx document with WANT_WIN_ build steps --- sys/unix/NewInstall.unx | 103 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 5d607c4cd..77cc3f68f 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -29,6 +29,9 @@ If you are using the traditional configuration system, see Install.unx. If the build fails, remove all the generated files before retrying the build with: cd $Top; make spotless + See the "User Interface Build Customizations" section below if you want to + configure your build with support for interfaces beyond traditional TTY. + The 'make fetch-Lua' step really only needs to be done one time unless your sources get refreshed, or the lib folder and its contents get removed. @@ -45,6 +48,104 @@ If you are using the traditional configuration system, see Install.unx. 5. If it all worked, you're done. If something went wrong, see Install.unx for information about the settings the hints file tried to automate. -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1596498295 2020/08/03 23:44:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ + + ======================================= + * User Interface Build Customizations * + ======================================= + +NetHack can support multiple user interfaces within the same binary on many +platforms. The various interface options can be specified by defining specific +variables, either on the make command line, or by setting environment variables +prior to the "make all" and "make install" steps. If you dont specify any +WANT_WIN_* customization, the build will only include traditional tty support. + +As an example, to build a binary with tty + curses + X11 support, you can use +the following build command: + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 all + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 install + +To build a binary with tty + curses + X11 + Qt support (that is, all the +available interaces that are supported, you can use the following shorthand +build command: + make WANT_WIN_ALL all + make WANT_WIN_ALL install + +Alternatively, you can set the variables in the environment first, prior +to issuing your make commands: + export WANT_WIN_TTY=1 + export WANT_WIN_X11=1 + make all + make install + +That example above will result in a build with support for tty + X11. + +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 |Interface| 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 | + |----------+---------+-----------------+-------------------------------------| + | 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 Qt | + |----------+---------+-----------------+-------------------------------------| + | Linux | tty | WANT_WIN_TTY | | + | (Ubuntu) | | | | + |----------+---------+-----------------+-------------------------------------| + | Linux | curses | WANT_WIN_CURSES | 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 | 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 | Qt | WANT_WIN_QT | Here is one possible way to obtain | + | (Ubuntu) | | | the required packages: | + | | | | | + | | | |sudo apt-get install qtbase5-dev | + | | | |sudo apt-get install qtmultimedia-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 | + +----------+---------+-----------------+-------------------------------------+ + +# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340052 2020/08/13 17:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. From cbf61af5b0f489c23da9289f989112aa795f2022 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 13 Aug 2020 12:24:07 -0400 Subject: [PATCH 112/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Files b/Files index 95c782899..9ba9750a1 100644 --- a/Files +++ b/Files @@ -310,6 +310,10 @@ macosx10.8 macosx10.10 macosx10.10-qt macosx10.14 solaris solaris-playground unix +sys/unix/hints/include: +(files for configuring UNIX NetHack versions) +multiw-1.2020 multiw-2.2020 + sys/vms: (files for VMS version) Install.vms Makefile.dat Makefile.doc Makefile.src Makefile.top From 3592604b9c0af3bf20bda62f7d81f0c9462e0578 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 13:39:17 -0400 Subject: [PATCH 113/708] minor typo bit in NewInstall.unx missing closing bracket ')' and wording change --- sys/unix/NewInstall.unx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 77cc3f68f..9061007ff 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -65,7 +65,7 @@ the following build command: make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 install To build a binary with tty + curses + X11 + Qt support (that is, all the -available interaces that are supported, you can use the following shorthand +available interaces that are available), you can use the following shorthand build command: make WANT_WIN_ALL all make WANT_WIN_ALL install @@ -146,6 +146,6 @@ additional interfaces. See below. | --remove-section=.note.ABI-tag/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 | +----------+---------+-----------------+-------------------------------------+ -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340052 2020/08/13 17:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.6 $ +# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340354 2020/08/13 17:39:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. From 39b30acb5690e72c02373eda7511e7eb7e69e96b Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 13:42:40 -0400 Subject: [PATCH 114/708] wording bit --- sys/unix/NewInstall.unx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 9061007ff..9a42e09a5 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -65,8 +65,8 @@ the following build command: make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 install To build a binary with tty + curses + X11 + Qt support (that is, all the -available interaces that are available), you can use the following shorthand -build command: +interaces that are available), you can use the following shorthand build +command: make WANT_WIN_ALL all make WANT_WIN_ALL install @@ -146,6 +146,6 @@ additional interfaces. See below. | --remove-section=.note.ABI-tag/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 | +----------+---------+-----------------+-------------------------------------+ -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340354 2020/08/13 17:39:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340557 2020/08/13 17:42:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. From 3e9eb0d784368799c1d458abd0bd23672c6055bd Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 13 Aug 2020 13:48:33 -0400 Subject: [PATCH 115/708] another typo --- sys/unix/NewInstall.unx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index 9a42e09a5..d6dbdd1eb 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -65,7 +65,7 @@ the following build command: make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 install To build a binary with tty + curses + X11 + Qt support (that is, all the -interaces that are available), you can use the following shorthand build +interfaces that are available), you can use the following shorthand build command: make WANT_WIN_ALL all make WANT_WIN_ALL install @@ -146,6 +146,6 @@ additional interfaces. See below. | --remove-section=.note.ABI-tag/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 | +----------+---------+-----------------+-------------------------------------+ -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340557 2020/08/13 17:42:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.8 $ +# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340908 2020/08/13 17:48:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. From aaf1d4d381651d44d6b748ce93a2de1d96d5e6d1 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 13 Aug 2020 15:24:24 -0700 Subject: [PATCH 116/708] 'O' couldn't change 'symset' The revised options processing from however long ago broke using 'O' to change 'symset'. ('roguesymset' worked ok.) Picking it in the main 'O' menu behaved as it nothing had been picked. The symset-specific submenu wasn't offered to the player because a two-line block of code was omitted. It seems amazing that no one has noticed in all this time. --- doc/fixes37.0 | 3 ++- src/options.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a6a0b83e1..e6831805a 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.283 $ $NHDT-Date: 1597182932 2020/08/11 21:55:32 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.284 $ $NHDT-Date: 1597357458 2020/08/13 22:24:18 $ General Fixes and Modified Features ----------------------------------- @@ -322,6 +322,7 @@ the fix to make worm visibility checks work as intended forced the coordinates the worm instead of leaving it off the map; place_worm_tail_randomly() reverses the segments and can throw some away if there isn't room, but throwing away the extra segment removed the worm from the map +using 'O' to try to change 'symset' was a no-op; 'roguesymset' worked curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/options.c b/src/options.c index 6ff7859a4..236e04ff5 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1596494520 2020/08/03 22:42:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.469 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1597357458 2020/08/13 22:24:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.470 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -359,14 +359,12 @@ boolean tinitial, tfrom_file; got_match = TRUE; } } - -#if 0 +#if 0 /* this prevents "boolopt:True" &c */ if (!got_match) { if (has_val && !allopt[i].valok) continue; } #endif - /* * During option initialization, the function * determine_ambiguities() @@ -692,8 +690,7 @@ char *op UNUSED; #ifdef BACKWARD_COMPAT /* if ((opts = string_for_env_opt(allopt[optidx].name, opts, FALSE)) - == - empty_optstr) + == empty_optstr) */ if ((opts = string_for_opt(opts, FALSE)) == empty_optstr) return FALSE; @@ -3493,6 +3490,9 @@ char *op; Strcat(opts, ", active"); return optn_ok; } + if (req == do_handler) { + return handler_symset(optidx); + } return optn_ok; } From 83f8da2a177fee4cb223c3b4362af5c6c6dc258d Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 14 Aug 2020 17:25:05 -0400 Subject: [PATCH 117/708] msdos cross-compile djggp build now with gcc 10 Also updates the travis build to Ubuntu focal because of an ar libfl.so.2 shared library load error on xenial that was easier to just get away from by moving to focal. --- .travis.yml | 5 ++++- sys/msdos/msdos-cross-compile.sh | 9 +++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ed41b36f..f72095eff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -135,12 +135,15 @@ matrix: - cd src - cp ../sys/winnt/Makefile.gcc ./Makefile - mingw32-make install - - name: msdos-linuxhost-crosscompile + - name: msdos-linux-focal-djgpp-crosscompile os: linux env: HINTS=linux LUA_VERSION=5.4.0 + dist: focal compiler: gcc script: # - export +# - export GCCVER=gcc550 + - export GCCVER=gcc1010 - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - make fetch-lua - test -d "lib/lua-$LUA_VERSION/src" || exit 0 diff --git a/sys/msdos/msdos-cross-compile.sh b/sys/msdos/msdos-cross-compile.sh index 3de2b701b..6580664eb 100644 --- a/sys/msdos/msdos-cross-compile.sh +++ b/sys/msdos/msdos-cross-compile.sh @@ -12,16 +12,17 @@ if [ ! -d "$(pwd)/lib" ]; then exit 1 fi -DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v2.9/" +#DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v2.9/" +DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/" if [ "$(uname)" = "Darwin" ]; then #Mac - DJGPP_FILE="djgpp-osx-gcc550.tar.bz2" + DJGPP_FILE="djgpp-osx-$GCCVER.tar.bz2" elif [ "$(expr substr $(uname -s) 1 5)" = "Linux" ]; then #Linux - DJGPP_FILE="djgpp-linux64-gcc550.tar.bz2" + DJGPP_FILE="djgpp-linux64-$GCCVER.tar.bz2" elif [ "$(expr substr $(uname -s) 1 10)" = "MINGW32_NT" ]; then #mingw - DJGPP_FILE="djgpp-mingw-gcc550-standalone.zip" + DJGPP_FILE="djgpp-mingw-$GCCVER-standalone.zip" else echo "No DJGPP release for you, sorry." exit 1 From 14d55c5bdba177a1a6b8830bd173fdb7226ddb8d Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 14 Aug 2020 18:23:31 -0400 Subject: [PATCH 118/708] make sys/msdos/msdos-cross-compile.sh build msdos NetHack entirely - should work on linux or MacOS to build an msdos zipfile distribution - no longer requires env variables be set ahead of it because it will set some defaults within - you must have zip and unzip on your system though - you have to "make fetch-lua" first if you haven't already done that - script takes care of obtaining the djgpp-cross-compiler etc, then uses it to build msdos NetHack - to clean and rebuild from scratch: make -f sys/msdos/Makefile1.cross clean --- sys/msdos/Makefile1.cross | 3 ++- sys/msdos/msdos-cross-compile.sh | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/sys/msdos/Makefile1.cross b/sys/msdos/Makefile1.cross index 9bf2a52f5..eb62bd337 100644 --- a/sys/msdos/Makefile1.cross +++ b/sys/msdos/Makefile1.cross @@ -569,7 +569,8 @@ $(HOST_O)panic.o: $(CONFIG_H) $(U)panic.c #========================================== clean: - rm ./host_o/*.o + -rm $(HOBJ)/*.o + -rm ./msdos_o/*.o if [ -f $(HOST_O)prereq.tag ]; then rm $(HOST_O)prereq.tag; fi; if [ -f hobj.tag ]; then rm hobj.tag; fi; if [ -f $(HOST_O)utility.tag ]; then rm $(HOST_O)utility.tag; fi; diff --git a/sys/msdos/msdos-cross-compile.sh b/sys/msdos/msdos-cross-compile.sh index 6580664eb..fc3fc31db 100644 --- a/sys/msdos/msdos-cross-compile.sh +++ b/sys/msdos/msdos-cross-compile.sh @@ -7,6 +7,14 @@ else export DJGPP_TOP="$TRAVIS_BUILD_DIR/lib/djgpp" fi +if [ -z "$GCCVER" ]; then + export GCCVER=gcc1010 +fi + +if [ -z "$LUA_VERSION" ]; then + export LUA_VERSION=5.4.0 +fi + if [ ! -d "$(pwd)/lib" ]; then echo "Set up for Unix build and 'make fetch-lua' first." exit 1 @@ -17,9 +25,15 @@ DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/" if [ "$(uname)" = "Darwin" ]; then #Mac DJGPP_FILE="djgpp-osx-$GCCVER.tar.bz2" + if [ -z "HINTS" ]; then + export HINTS=macOS.2020 + 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.2020 + fi elif [ "$(expr substr $(uname -s) 1 10)" = "MINGW32_NT" ]; then #mingw DJGPP_FILE="djgpp-mingw-$GCCVER-standalone.zip" From 1879f2117684bbadddc38aa05899745007f1a791 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 15 Aug 2020 16:43:59 -0400 Subject: [PATCH 119/708] adjust travis-ci builds add builds that tests tty, curses, X11, and Qt5 on all of the following: linux-xenial, linux-bionic, linux-focal Also still tests "nocommon" on earlier gcc versions. Add a focal with gcc9 build to test that compiler version. Here are the test builds: linux-xenial-gcc-win-all linux-bionic-gcc-win-all linux-focal-clang-win-all linux-xenial-gcc-nocommon linux-focal-gcc9-win-all linux-xenial-gcc-minimal windows-visualstudio windows-mingw msdos-linux-focal-djgpp-crosscompile --- .travis.yml | 130 ++++++++++++++++++++++++++-------------------------- 1 file changed, 66 insertions(+), 64 deletions(-) diff --git a/.travis.yml b/.travis.yml index f72095eff..a2e589a65 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,62 +1,10 @@ language: c +matrix: matrix: include: - - name: linux-xenial-gcc + - name: linux-xenial-gcc-win-all os: linux - env: HINTS=linux LUA_VERSION=5.4.0 - compiler: gcc - script: - - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua - - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - make install - - name: linux-xenial-gcc-nocommon - os: linux - env: HINTS=linux LUA_VERSION=5.4.0 - compiler: gcc - script: - - echo "CFLAGS+=-fno-common" >>sys/unix/hints/$HINTS - - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua - - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - make install - - name: linux-bionic-gcc - os: linux - env: HINTS=linux LUA_VERSION=5.4.0 - dist: bionic - compiler: gcc - script: - - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua - - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - make install - - name: linux-xenial-clang - os: linux - env: HINTS=linux LUA_VERSION=5.4.0 - compiler: clang - script: - - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua - - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - make install - - name: linux-xenial-gcc-x11 - os: linux - env: HINTS=linux-x11 LUA_VERSION=5.4.0 - compiler: gcc - addons: - apt: - packages: - - libx11-dev - - libxaw7-dev - - xfonts-utils - script: - - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua - - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - make install - - name: linux-xenial-gcc-qt5 - os: linux - env: HINTS=linux-qt5 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.0 compiler: gcc addons: apt: @@ -69,12 +17,12 @@ matrix: - qtbase5-dev-tools script: - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua + - make fetch-lua LUA_VERSION=$LUA_VERSION - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - make QT_SELECT=5 MOC=moc install - - name: linux-bionic-gcc-x11 + - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install + - name: linux-bionic-gcc-win-all os: linux - env: HINTS=linux-x11 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.0 dist: bionic compiler: gcc addons: @@ -83,11 +31,65 @@ matrix: - libx11-dev - libxaw7-dev - xfonts-utils + - qtbase5-dev + - qtmultimedia5-dev + - qtbase5-dev-tools script: - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua + - make fetch-lua LUA_VERSION=$LUA_VERSION + - test -d "lib/lua-$LUA_VERSION/src" || exit 0 + - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install + - name: linux-focal-clang-win-all + os: linux + env: HINTS=linux.2020 LUA_VERSION=5.4.0 + dist: focal + compiler: clang + addons: + apt: + packages: + - xfonts-utils + - libx11-dev + - libxaw7-dev + - qtbase5-dev + - qtmultimedia5-dev + - qtbase5-dev-tools + script: + - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ + - make fetch-lua LUA_VERSION=$LUA_VERSION + - test -d "lib/lua-$LUA_VERSION/src" || exit 0 + - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install + - name: linux-xenial-gcc-nocommon + os: linux + env: HINTS=linux.2020 LUA_VERSION=5.4.0 + dist: xenial + compiler: gcc + script: + - echo "CFLAGS+=-fno-common" >>sys/unix/hints/$HINTS + - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ + - make fetch-lua LUA_VERSION=$LUA_VERSION - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - make install + - name: linux-focal-gcc9-win-all + os: linux + env: HINTS=linux.2020 LUA_VERSION=5.4.0 + dist: focal + compiler: gcc + addons: + apt: + packages: + - gcc-9 + - g++-9 + - libx11-dev + - libxaw7-dev + - xfonts-utils + - qtbase5-dev + - qtmultimedia5-dev + - qtbase5-dev-tools + script: + - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ + - make fetch-lua LUA_VERSION=$LUA_VERSION + - test -d "lib/lua-$LUA_VERSION/src" || exit 0 + - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-xenial-gcc-minimal os: linux env: HINTS=linux-minimal LUA_VERSION=5.4.0 @@ -113,9 +115,9 @@ matrix: sed -i '/^#define SHELL/d' include/unixconf.h sed -i '/^#define SUSPEND/d' include/unixconf.h sed -i 's/^#define TEXTCOLOR//' include/unixconf.h - make fetch-lua + make fetch-lua LUA_VERSION=$LUA_VERSION test -d "lib/lua-$LUA_VERSION/src" || exit 0 - make install + make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 install cat dat/options - name: windows-visualstudio os: windows @@ -134,7 +136,7 @@ matrix: - test -d "lib/pdcurses" || exit 0 - cd src - cp ../sys/winnt/Makefile.gcc ./Makefile - - mingw32-make install + - mingw32-make LUA_VERSION=$LUA_VERSION install - name: msdos-linux-focal-djgpp-crosscompile os: linux env: HINTS=linux LUA_VERSION=5.4.0 @@ -147,7 +149,7 @@ matrix: - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - make fetch-lua - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - cd lib/lua-$LUA_VERSION/src && make a && cd ../../.. + - cd lib/lua-$LUA_VERSION/src && make CC='gcc' a && cd ../../.. - sh sys/msdos/msdos-cross-compile.sh exclude: # - os: osx From 89fbe2162e66c99c3f9561902f0c23a10f77892f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 15 Aug 2020 16:52:19 -0400 Subject: [PATCH 120/708] remove duplicate line in .travis.yml --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a2e589a65..21bd109d2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: c -matrix: matrix: include: - name: linux-xenial-gcc-win-all From 9a866d36010fa7a468f66665963df62e860332e7 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 15 Aug 2020 19:48:33 -0700 Subject: [PATCH 121/708] Qt "Paper Doll" inventory Enhance the "Qt Settings" dialog box to provide control over the paper doll subset of inventory displayed between the message and status windows (above the map). A ton of flailing about for a fairly small but useful change in functionality. Old dialog (no title): | [ ] Zoomed -- check box | "Width:" [ ] -- number entry spinner | "Height:" [ ] -- ditto | "Font:" [ ] -- Huge:18pt, Large:14, Medium:12, Small:10, Tiny:8 | [ Dismiss ] -- button New dialog: | "Qt NetHack Settings" | | "Map:" [ ] "Zoomed" -- check box | "Tile Width" [ ] -- number entry spinner | "Tile Height" [ ] -- ditto | "Invent:" [ ] "Shown" -- check box | "Doll Width" [ ] -- number entry spinner | "Doll Height" [ ] -- ditto | "Font:" [ ] -- Huge:18pt, Large:14, Medium:12, Small:10, Tiny:8 | [ Dismiss ] -- button The inventory subset can now be suppressed. When shown (the default), its size can be set independently of the map tiles' size. I've set the default to be 32x32 tiles instead of 16x16 used for the map. The settings are saved and restored automatically by Qt, and persist not just across save/restore cycles but into new games. (That's not a change, just a reminder.) --- doc/fixes37.0 | 4 +- win/Qt/qt_bind.cpp | 20 +++++- win/Qt/qt_bind.h | 6 +- win/Qt/qt_inv.cpp | 33 +++++++-- win/Qt/qt_main.cpp | 87 +++++++++++++++++++---- win/Qt/qt_main.h | 3 + win/Qt/qt_set.cpp | 167 +++++++++++++++++++++++++++++++++++++-------- win/Qt/qt_set.h | 36 +++++++++- 8 files changed, 299 insertions(+), 57 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index e6831805a..123402de3 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.284 $ $NHDT-Date: 1597357458 2020/08/13 22:24:18 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.285 $ $NHDT-Date: 1597546107 2020/08/16 02:48:27 $ General Fixes and Modified Features ----------------------------------- @@ -507,6 +507,8 @@ user_sounds: provide an experimental mechanism for terminal-side sounds similar requires compile-time definition of TTY_SOUND_ESCCODES (also requires terminal-side code external to NetHack to recognize the sequence and act on it) +Qt: the "paper doll" inventory subset can be controlled via the "Qt Settings" + dialog box ("Preferences..." on OSX) NetHack Community Patches (or Variation) Included diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index cd623fb86..ecff16587 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -110,9 +110,27 @@ NetHackQtBind::NetHackQtBind(int& argc, char** argv) : } else { splash = 0; } + + // these used to be in MainWindow but we want them before QtSettings + // which we want before MainWindow... + QCoreApplication::setOrganizationName("The NetHack DevTeam"); + QCoreApplication::setOrganizationDomain("nethack.org"); + QCoreApplication::setApplicationName("NetHack-Qt"); // Qt NetHack + { + char cvers[BUFSZ]; + QString qvers = version_string(cvers); + QCoreApplication::setApplicationVersion(qvers); + } +#ifdef MACOSX + /* without this, neither control+x nor option+x do anything; + with it, control+x is ^X and option+x still does nothing */ + QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); +#endif + + qt_settings = new NetHackQtSettings(); /*(main->width(),main->height());*/ + main = new NetHackQtMainWindow(keybuffer); connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit())); - qt_settings=new NetHackQtSettings(main->width(),main->height()); msgs_strings = new QStringList(); msgs_initd = false; msgs_saved = false; diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index e7dacf1c3..e020a83d4 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -63,14 +63,16 @@ public: 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,XCHAR_P x,XCHAR_P y,int glyph,int bkglyph); + static void qt_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, + int glyph, int bkglyph); static void qt_raw_print(const char *str); static void qt_raw_print_bold(const char *str); static int qt_nhgetch(); static int qt_nh_poskey(int *x, int *y, int *mod); static void qt_nhbell(); static int qt_doprev_message(); - static char qt_yn_function(const char *question, const char *choices, CHAR_P def); + static char qt_yn_function(const char *question, + const char *choices, CHAR_P def); static void qt_getlin(const char *prompt, char *line); static int qt_get_ext_cmd(); static void qt_number_pad(int); diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 6a872bdd2..758fcb7b6 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -49,13 +49,13 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, { short int glyph; if (nhobj) - glyph=obj_to_glyph(nhobj, rn2_on_display_rng); + glyph = obj_to_glyph(nhobj, rn2_on_display_rng); else if (canbe) - glyph=cmap_to_glyph(S_room); + glyph = cmap_to_glyph(S_room); else - glyph=cmap_to_glyph(S_stone); + glyph = GLYPH_UNEXPLORED; // was cmap_to_glyph(S_stone) - qt_settings->glyphs().drawCell(painter,glyph,x,y); + qt_settings->glyphs().drawCell(painter, glyph, x, y); } void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) @@ -76,6 +76,13 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // show lit lamp/lantern/candle/candelabrum on lower right side; // show leash-in-use on lower left side +#ifdef ENHANCED_PAPERDOLL + if (!qt_settings->doll_is_shown) + return; + qt_settings->glyphs().setSize(qt_settings->dollWidth, + qt_settings->dollHeight); +#endif + QPainter painter; painter.begin(this); @@ -115,13 +122,27 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) drawWorn(painter, find_tool(OIL_LAMP), 2, 4); painter.end(); + +#ifdef ENHANCED_PAPERDOLL + qt_settings->glyphs().setSize(qt_settings->tileWidth, + qt_settings->tileHeight); +#endif } QSize NetHackQtInvUsageWindow::sizeHint(void) const { if (qt_settings) { - return QSize(qt_settings->glyphs().width()*3, - qt_settings->glyphs().height()*6); + int w = 0, h = 0; +#ifdef ENHANCED_PAPERDOLL + if (qt_settings->doll_is_shown) { + w = qt_settings->dollWidth * 3; + h = qt_settings->dollHeight * 6; + } +#else + w = qt_settings->glyphs().width() * 3; + h = qt_settings->glyphs().height() * 6; +#endif + return QSize(w, h); } else { return QWidget::sizeHint(); } diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 3c10f5fce..ca32f1e4a 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -508,20 +508,6 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : addToolBar(toolbar); menubar = menuBar(); - QCoreApplication::setOrganizationName("The NetHack DevTeam"); - QCoreApplication::setOrganizationDomain("nethack.org"); - QCoreApplication::setApplicationName("NetHack"); - { - char cvers[BUFSZ]; - QString qvers = version_string(cvers); - QCoreApplication::setApplicationVersion(qvers); - } -#ifdef MACOSX - /* without this, neither control+x nor option+x do anything; - with it, control+x is ^X and option+x still does nothing */ - QCoreApplication::setAttribute(Qt::AA_MacDontSwapCtrlAndMeta); -#endif - setWindowTitle("Qt NetHack"); setWindowIcon(QIcon(QPixmap(qt_compact_mode ? nh_icon_small : nh_icon))); @@ -1051,8 +1037,9 @@ void NetHackQtMainWindow::RemoveWindow(NetHackQtWindow* window) void NetHackQtMainWindow::updateInventory() { - if ( invusage ) + if (invusage) { invusage->repaint(); + } } void NetHackQtMainWindow::fadeHighlighting() @@ -1084,6 +1071,76 @@ void NetHackQtMainWindow::layout() toph,c->width(),maph); } #endif + + if (qt_settings && !qt_compact_mode + && map && message && status && invusage) { + // For the initial PaperDoll sizing, message window + // and/or status window might still be empty; + // widen them before changing PaperDoll to use saved settings. + QList splittersizes = hsplitter->sizes(); +#define MIN_WIN_WIDTH 400 + if (splittersizes[0] < MIN_WIN_WIDTH + || splittersizes[2] < MIN_WIN_WIDTH) { + if (splittersizes[0] < MIN_WIN_WIDTH) + splittersizes[0] = MIN_WIN_WIDTH; +#ifndef ENHANCED_PAPERDOLL + if (splittersizes[1] < 6) // TILEWMIN + splittersizes[1] = 16; // 16x16 +#endif + if (splittersizes[2] < MIN_WIN_WIDTH) + splittersizes[2] = MIN_WIN_WIDTH; + hsplitter->setSizes(splittersizes); + } +#ifdef ENHANCED_PAPERDOLL + // call resizePaperDoll() indirectly... + qt_settings->resizeDoll(); +#endif + } +} + +void NetHackQtMainWindow::resizePaperDoll(bool showdoll) +{ +#ifdef ENHANCED_PAPERDOLL + // this is absurd... + NetHackQtInvUsageWindow *w = static_cast + (NetHackQtBind::mainWidget())->invusage; + QList hsplittersizes = hsplitter->sizes(), + vsplittersizes = vsplitter->sizes(); + w->resize(w->sizeHint()); + + int oldwidth = hsplittersizes[1], + newwidth = w->width(); + if (newwidth != oldwidth) { + if (oldwidth > newwidth) + hsplittersizes[0] += (oldwidth - newwidth); + else + hsplittersizes[2] += (newwidth - oldwidth); + hsplittersizes[1] = newwidth; + hsplitter->setSizes(hsplittersizes); + } + + // Height limit is 48 pixels per doll cell; + // values greater than 44 need taller window which pushes the map down. + // FIXME: this doesn't shrink the window back if size is reduced from 45+ + int oldheight = vsplittersizes[0], + newheight = w->height(); + if (newheight > oldheight && oldheight > 0 && vsplittersizes[1] > 0) { + vsplittersizes[0] = newheight; + vsplitter->setSizes(vsplittersizes); + } + + if (showdoll) { + if (w->isHidden()) + w->show(); + else + w->repaint(); + } else { + if (w->isVisible()) + w->hide(); + } +#else + nhUse(showdoll); +#endif /* ENHANCED_PAPERDOLL */ } void NetHackQtMainWindow::resizeEvent(QResizeEvent*) diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index 461a4a471..f043c619f 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -49,6 +49,9 @@ public: void fadeHighlighting(); + // this is unconditional in case qt_main.h comes before qt_set.h + void resizePaperDoll(bool); // ENHANCED_PAPERDOLL + public slots: void doMenuItem(QAction *); void doQtSettings(bool); diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index 0c35291bc..fc4df1ac1 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -2,7 +2,8 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// qt_set.cpp -- the Qt settings +// qt_set.cpp -- Qt-specific settings, saved and restored by Qt so +// persist not just across save/restore but into new games. extern "C" { #include "hack.h" @@ -17,8 +18,36 @@ extern "C" { #include "qt_set.h" #include "qt_set.moc" #include "qt_glyph.h" +#include "qt_main.h" +#include "qt_bind.h" #include "qt_str.h" +// Dialog box accessed via "Qt Settings..." in the games menu (non-OSX) +// or via "Preferences..." in the application menu (OSX): +//-- +// "Qt NetHack Settings" +// "Map:" [ ] Zoomed -- check box +// tilewidth -- number entry spinner +// tileheight -- ditto +// "Invent:" [ ] Shown -- check box +// dollwidth -- number entry spinner +// dollheight -- ditto +// "Font:" fontsize -- Huge:18pt, Large:14, Medium:12, Small:10, Tiny:8 +// [dismiss] -- button +//-- +// Map remembers 2 size pairs, one for Zoomed unchecked, another for checked. +// (Player controls whether the box is checked, using the dialog to manually +// switch back and forth if desired; nothing forces the Zoomed setting to +// specify larger tile size than not-Zoomed.) +// Paper doll inventory subset is shown or suppressed depending on check box. +// (It only remembers one tile size pair and that only matters when shown. +// The size could be different from both map settings but it is highly +// recommended that it match one of those unless Zoomed is never toggled.) +// Font size is used for message window and for text in the status window. +// (TODO: support separate font sizes for the two windows.) +// There's no way to undo or avoid saving any changes which player makes but +// all of the fields can be manually reversed. + /* Used by tile/font-size patch below and in ../../src/files.c */ char *qt_tilewidth=NULL; char *qt_tileheight=NULL; @@ -34,13 +63,20 @@ namespace nethack_qt_ { #define TILEWMIN 6 #define TILEHMIN 6 -NetHackQtSettings::NetHackQtSettings(int w UNUSED, int h UNUSED) : +NetHackQtSettings::NetHackQtSettings() : settings(), + whichsize("&Zoomed", this), tilewidth(this), tileheight(this), - widthlbl("&Width:",this), - heightlbl("&Height:",this), - whichsize("&Zoomed",this), + widthlbl("Tile &width:", this), + heightlbl("Tile &height:", this), +#ifdef ENHANCED_PAPERDOLL + dollshown("&Shown", this), + dollwidth(this), + dollheight(this), + dollwidthlbl("&Doll width:", this), // should "Doll tile width"... + dollheightlbl("Doll height:", this), // ...but that's too verbose +#endif fontsize(this), normal("times"), #ifdef WS_WIN @@ -50,7 +86,6 @@ NetHackQtSettings::NetHackQtSettings(int w UNUSED, int h UNUSED) : #endif large("times"), theglyphs(0) - { int default_fontsize; @@ -58,9 +93,19 @@ NetHackQtSettings::NetHackQtSettings(int w UNUSED, int h UNUSED) : tilewidth.setRange(TILEWMIN, 128); heightlbl.setBuddy(&tileheight); tileheight.setRange(TILEHMIN, 128); - tilewidth.setValue(settings.value("tilewidth", 16).toInt()); tileheight.setValue(settings.value("tileheight", 16).toInt()); +#ifdef ENHANCED_PAPERDOLL + dollwidthlbl.setBuddy(&dollwidth); + dollwidth.setRange(TILEWMIN, 48); + dollheightlbl.setBuddy(&dollheight); + dollheight.setRange(TILEHMIN, 48); + dollwidth.setValue(settings.value("dollwidth", 32).toInt()); + dollheight.setValue(settings.value("dollheight", 32).toInt()); + doll_is_shown = settings.value("dollShown", true).toBool(); + // needed the very first time + settings.setValue("dollShown", QVariant(doll_is_shown)); +#endif default_fontsize = settings.value("fontsize", 2).toInt(); // Tile/font sizes read from .nethackrc @@ -86,9 +131,15 @@ NetHackQtSettings::NetHackQtSettings(int w UNUSED, int h UNUSED) : theglyphs=new NetHackQtGlyphs(); resizeTiles(); - connect(&tilewidth,SIGNAL(valueChanged(int)),this,SLOT(resizeTiles())); - connect(&tileheight,SIGNAL(valueChanged(int)),this,SLOT(resizeTiles())); - connect(&whichsize,SIGNAL(toggled(bool)),this,SLOT(setGlyphSize(bool))); + connect(&whichsize, SIGNAL(toggled(bool)), this, SLOT(setGlyphSize(bool))); + connect(&tilewidth, SIGNAL(valueChanged(int)), this, SLOT(resizeTiles())); + connect(&tileheight, SIGNAL(valueChanged(int)), this, SLOT(resizeTiles())); + +#ifdef ENHANCED_PAPERDOLL + connect(&dollshown, SIGNAL(toggled(bool)), this, SLOT(setDollShown(bool))); + connect(&dollwidth, SIGNAL(valueChanged(int)), this, SLOT(resizeDoll())); + connect(&dollheight, SIGNAL(valueChanged(int)), this, SLOT(resizeDoll())); +#endif fontsize.addItem("Huge"); fontsize.addItem("Large"); @@ -96,25 +147,51 @@ NetHackQtSettings::NetHackQtSettings(int w UNUSED, int h UNUSED) : fontsize.addItem("Small"); fontsize.addItem("Tiny"); fontsize.setCurrentIndex(default_fontsize); - connect(&fontsize,SIGNAL(activated(int)),this,SLOT(changedFont())); + connect(&fontsize, SIGNAL(activated(int)), this, SLOT(changedFont())); - QGridLayout* grid = new QGridLayout(this); - grid->addWidget(&whichsize, 0, 0, 1, 2); - grid->addWidget(&tilewidth, 1, 1); grid->addWidget(&widthlbl, 1, 0); - grid->addWidget(&tileheight, 2, 1); grid->addWidget(&heightlbl, 2, 0); - QLabel* flabel=new QLabel("&Font:",this); + int row = 0; // used like X11-style XtSetArg(), ++argc + QGridLayout *grid = new QGridLayout(this); + // dialog box label, spans first two rows and all three columns + QLabel *settings_label = new QLabel("Qt NetHack Settings\n", this); + grid->addWidget(settings_label, row, 0, 2, 3), row += 2; // uses extra row + settings_label->setAlignment(Qt::AlignHCenter | Qt::AlignTop); + + QLabel *map_label = new QLabel("&Map:", this); + map_label->setBuddy(&whichsize); + grid->addWidget(map_label, row, 0), // "Map: [ ]Zoomed" + grid->addWidget(&whichsize, row, 1), ++row; + grid->addWidget(&widthlbl, row, 1), + grid->addWidget(&tilewidth, row, 2), ++row; + grid->addWidget(&heightlbl, row, 1), + grid->addWidget(&tileheight, row, 2), ++row; + +#ifdef ENHANCED_PAPERDOLL + dollshown.QAbstractButton::setChecked(doll_is_shown); + QLabel *doll_label = new QLabel("&Invent:", this); + doll_label->setBuddy(&dollshown); + grid->addWidget(doll_label, row, 0), // "Invent: [ ]Shown" + grid->addWidget(&dollshown, row, 1), ++row; + grid->addWidget(&dollwidthlbl, row, 1), + grid->addWidget(&dollwidth, row, 2), ++row; + grid->addWidget(&dollheightlbl, row, 1), + grid->addWidget(&dollheight, row, 2), ++row; +#endif + + QLabel *flabel = new QLabel("&Font:", this); flabel->setBuddy(&fontsize); - grid->addWidget(flabel, 3, 0); grid->addWidget(&fontsize, 3, 1); - QPushButton* dismiss=new QPushButton("Dismiss",this); + grid->addWidget(flabel, row, 0), + grid->addWidget(&fontsize, row, 1), ++row; + + QPushButton *dismiss = new QPushButton("Dismiss", this); dismiss->setDefault(true); - grid->addWidget(dismiss, 4, 0, 1, 2); - grid->setRowStretch(4,0); - grid->setColumnStretch(1,1); - grid->setColumnStretch(2,2); + grid->addWidget(dismiss, row, 0, 1, 3), ++row; + grid->setRowStretch(row - 1, 0); + grid->setColumnStretch(1, 1); + grid->setColumnStretch(2, 2); grid->activate(); - connect(dismiss,SIGNAL(clicked()),this,SLOT(accept())); - resize(150,140); + connect(dismiss, SIGNAL(clicked()), this, SLOT(accept())); + resize(150, 140); } NetHackQtGlyphs& NetHackQtSettings::glyphs() @@ -130,12 +207,13 @@ void NetHackQtSettings::changedFont() void NetHackQtSettings::resizeTiles() { - int w = tilewidth.value(); - int h = tileheight.value(); + tileWidth = tilewidth.value(); + tileHeight = tileheight.value(); - settings.setValue("tilewidth", tilewidth.value()); - settings.setValue("tileheight", tileheight.value()); - theglyphs->setSize(w,h); + settings.setValue("tilewidth", tileWidth); + settings.setValue("tileheight", tileHeight); + + theglyphs->setSize(tileWidth, tileHeight); emit tilesChanged(); } @@ -159,6 +237,37 @@ void NetHackQtSettings::setGlyphSize(bool which UNUSED) othersize = n; } +#ifdef ENHANCED_PAPERDOLL +void NetHackQtSettings::resizeDoll() +{ + dollWidth = dollwidth.value(); + dollHeight = dollheight.value(); + + settings.setValue("dollwidth", dollWidth); + settings.setValue("dollheight", dollHeight); + settings.setValue("dollShown", doll_is_shown); + + //NetHackQtMainWindow::resizePaperDoll(doll_is_shown); + NetHackQtMainWindow *w = static_cast + (NetHackQtBind::mainWidget()); + w->resizePaperDoll(doll_is_shown); +} + +void NetHackQtSettings::toggleDollShown() +{ + dollshown.toggle(); +} + +void NetHackQtSettings::setDollShown(bool on_off) +{ + if (on_off != doll_is_shown) { + dollshown.QAbstractButton::setChecked(on_off); + doll_is_shown = on_off; + resizeDoll(); + } +} +#endif + const QFont& NetHackQtSettings::normalFont() { static int size[]={ 18, 14, 12, 10, 8 }; diff --git a/win/Qt/qt_set.h b/win/Qt/qt_set.h index 6b2aa6a4a..36f9c0ac3 100644 --- a/win/Qt/qt_set.h +++ b/win/Qt/qt_set.h @@ -7,15 +7,25 @@ #ifndef QT4SET_H #define QT4SET_H +#define ENHANCED_PAPERDOLL /* separate size from map tiles, can be hidden */ + +#include "qt_bind.h" // needed for mainWidget() for updateInventory() + namespace nethack_qt_ { class NetHackQtGlyphs; +class NetHackQtMainWindow; class NetHackQtSettings : public QDialog { Q_OBJECT public: - // Size of window - used to decide default sizes - NetHackQtSettings(int width, int height); + int tileWidth = 16, tileHeight = 16; +#ifdef ENHANCED_PAPERDOLL + int dollWidth = 32, dollHeight = 32; + bool doll_is_shown = true; +#endif + // dialog box for Qt-specific settings + NetHackQtSettings(); NetHackQtGlyphs& glyphs(); const QFont& normalFont(); @@ -31,21 +41,41 @@ signals: public slots: void toggleGlyphSize(); void setGlyphSize(bool); +#ifdef ENHANCED_PAPERDOLL + void toggleDollShown(); + void setDollShown(bool); + void resizeDoll(); +#endif private: QSettings settings; + + QCheckBox whichsize; QSpinBox tilewidth; QSpinBox tileheight; QLabel widthlbl; QLabel heightlbl; - QCheckBox whichsize; QSize othersize; +#ifdef ENHANCED_PAPERDOLL + QCheckBox dollshown; + QSpinBox dollwidth; + QSpinBox dollheight; + QLabel dollwidthlbl; + QLabel dollheightlbl; +#endif QComboBox fontsize; QFont normal, normalfixed, large; NetHackQtGlyphs* theglyphs; +#if 0 + void updateInventory() + { + static_cast (NetHackQtBind::mainWidget()) + ->updateInventory(); + } +#endif private slots: void resizeTiles(); From 3a078806846a142fcf4711b0072822900ee46744 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 17 Aug 2020 14:48:00 -0700 Subject: [PATCH 122/708] paper doll inventory display vs hallucination During hallucination, actions which triggered update of persistent inventory made Qt's display of map tiles for equipped objects have those tiles switch randomly, but ordinary move-by-move fluctations applied to floor objects left them alone. Initially I took out hallucination of inventory items altogether, but ended up putting that back and changing the floor hallucination to affect Qt's paper doll too. The display.h change isn't needed but I've left it in. --- doc/fixes37.0 | 3 ++- include/display.h | 32 +++++++++++++++++++++----------- src/display.c | 9 ++++++++- win/Qt/qt_inv.cpp | 13 ++++++------- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 123402de3..76f29dfe1 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.285 $ $NHDT-Date: 1597546107 2020/08/16 02:48:27 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ $NHDT-Date: 1597700875 2020/08/17 21:47:55 $ General Fixes and Modified Features ----------------------------------- @@ -381,6 +381,7 @@ Qt: "paper doll" subset of persistent inventory has undergone several changes: two-handed weapon in both the shield and primary weapon slots; show first active light source in a previously unused slot on lower right; show first leash-in-use in a previously unused slot on lower left +Qt: paper doll inventory view was inconsistently updated during Hallucination Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/include/display.h b/include/display.h index 272ed163d..721b7f10b 100644 --- a/include/display.h +++ b/include/display.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.h $NHDT-Date: 1596498533 2020/08/03 23:48:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ +/* NetHack 3.7 display.h $NHDT-Date: 1597700875 2020/08/17 21:47:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -328,18 +328,18 @@ enum explosion_types { /* This has the unfortunate side effect of needing a global variable */ /* to store a result. 'otg_temp' is defined and declared in decl.{ch}. */ -#define random_obj_to_glyph(rng) \ - ((g.otg_temp = random_object(rng)) == CORPSE \ - ? random_monster(rng) + GLYPH_BODY_OFF \ +#define random_obj_to_glyph(rng) \ + ((g.otg_temp = random_object(rng)) == CORPSE \ + ? random_monster(rng) + GLYPH_BODY_OFF \ : g.otg_temp + GLYPH_OBJ_OFF) -#define obj_to_glyph(obj, rng) \ - (((obj)->otyp == STATUE) \ - ? statue_to_glyph(obj, rng) \ - : Hallucination \ - ? random_obj_to_glyph(rng) \ - : ((obj)->otyp == CORPSE) \ - ? (int) (obj)->corpsenm + GLYPH_BODY_OFF \ +#define obj_to_glyph(obj, rng) \ + (((obj)->otyp == STATUE) \ + ? statue_to_glyph(obj, rng) \ + : Hallucination \ + ? random_obj_to_glyph(rng) \ + : ((obj)->otyp == CORPSE) \ + ? (int) (obj)->corpsenm + GLYPH_BODY_OFF \ : (int) (obj)->otyp + GLYPH_OBJ_OFF) /* MRKR: Statues now have glyphs corresponding to the monster they */ @@ -349,6 +349,16 @@ enum explosion_types { (Hallucination ? random_monster(rng) + GLYPH_MON_OFF \ : (int) (obj)->corpsenm + GLYPH_STATUE_OFF) +/* briefly used for Qt's "paper doll" inventory which shows map tiles for + equipped objects; those vary like floor items during hallucination now + so this isn't used anywhere */ +#define obj_to_true_glyph(obj) \ + (((obj)->otyp == STATUE) \ + ? ((int) (obj)->corpsenm + GLYPH_STATUE_OFF) \ + : ((obj)->otyp == CORPSE) \ + ? ((int) (obj)->corpsenm + GLYPH_BODY_OFF) \ + : ((int) (obj)->otyp + GLYPH_OBJ_OFF)) + #define cmap_to_glyph(cmap_idx) ((int) (cmap_idx) + GLYPH_CMAP_OFF) #define explosion_to_glyph(expltype, idx) \ ((((expltype) * MAXEXPCHARS) + ((idx) - S_explode1)) + GLYPH_EXPLODE_OFF) diff --git a/src/display.c b/src/display.c index 7445486dd..0efe1582c 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.c $NHDT-Date: 1596498156 2020/08/03 23:42:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ +/* NetHack 3.7 display.c $NHDT-Date: 1597700875 2020/08/17 21:47:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1339,9 +1339,16 @@ void see_objects() { register struct obj *obj; + for (obj = fobj; obj; obj = obj->nobj) if (vobj_at(obj->ox, obj->oy) == obj) newsym(obj->ox, obj->oy); + + /* Qt's "paper doll" subset of persistent inventory shows map tiles + for objects which aren't on the floor so not handled by above loop; + inventory which includes glyphs should also be affected, so do this + for all interfaces in case any feature that for persistent inventory */ + update_inventory(); } /* diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 758fcb7b6..f34d0e48a 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -48,13 +48,12 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, int x, int y, bool canbe) { short int glyph; - if (nhobj) - glyph = obj_to_glyph(nhobj, rn2_on_display_rng); - else if (canbe) - glyph = cmap_to_glyph(S_room); - else - glyph = GLYPH_UNEXPLORED; // was cmap_to_glyph(S_stone) - + if (nhobj) { + /* Hallucination doesn't affect inventory */ + glyph = obj_to_glyph(nhobj, rn2_on_display_rng); + } else { + glyph = canbe ? cmap_to_glyph(S_room) : GLYPH_UNEXPLORED; + } qt_settings->glyphs().drawCell(painter, glyph, x, y); } From 26060634f60f126405b1e4789606dd4b85be35bc Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 17 Aug 2020 15:41:33 -0700 Subject: [PATCH 123/708] Qt: paper doll display of BUC status When items in the paper doll inventory subset (primary worn and wielded items) have known BUC state, indicate what that is. It now draws a one pixel wide white border around each doll tile, and if BUC is known, that border gets its color changed (red for known cursed, yellow for known uncursed, cyan for known blessed). That isn't very visual so the first pixel inside the tile is overwritten with the same color, and alternating pixels are also overwritten for the second rectangle within. The 2..3 pixel wide border is visible without cluttering the tile for 'normal' sized paper doll. The tiles are allowed to be scrunched down to as small as 6x6 so there won't be much left after 1 or 2 around the edge are replaced. Initially I was going to try to highlight welded items but the more general BUC highlighting is simpler and usually more useful to the player. The qt_map.* bits are just reformatting. I was looking at pet and pile annotations as a way to do BUC annotations but decided not to attempt that. --- doc/fixes37.0 | 4 ++- win/Qt/qt_glyph.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++++ win/Qt/qt_glyph.h | 7 ++++++ win/Qt/qt_inv.cpp | 23 ++++++++++++----- win/Qt/qt_map.cpp | 38 ++++++++++++++++++++-------- win/Qt/qt_map.h | 3 ++- 6 files changed, 117 insertions(+), 18 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 76f29dfe1..e465340d5 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.286 $ $NHDT-Date: 1597700875 2020/08/17 21:47:55 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.287 $ $NHDT-Date: 1597704087 2020/08/17 22:41:27 $ General Fixes and Modified Features ----------------------------------- @@ -510,6 +510,8 @@ user_sounds: provide an experimental mechanism for terminal-side sounds similar act on it) Qt: the "paper doll" inventory subset can be controlled via the "Qt Settings" dialog box ("Preferences..." on OSX) +Qt: draw a border around each tile in the paper door inventory; when BUC is + known for a doll item, change the border's color and thicken it NetHack Community Patches (or Variation) Included diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 7ca292c87..5554a7b3f 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -18,6 +18,8 @@ extern "C" { #include "qt_glyph.h" #include "qt_bind.h" #include "qt_set.h" +#include "qt_inv.h" +#include "qt_map.h" #include "qt_str.h" extern short glyph2tile[]; // from tile.c @@ -91,6 +93,64 @@ void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, drawGlyph(painter, glyph, cellx * width(), celly * height()); } +void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, + int cellx, int celly, int border) +{ + int wd = width(), + ht = height(), + lox = cellx * (wd + 2), + loy = celly * (ht + 2); + + drawGlyph(painter, glyph, lox + 1, loy + 1); + +#ifdef TEXTCOLOR + if (border != NO_BORDER) { + // gray would be a better mid-point between red and cyan but it + // doesn't show up well enough against the wall tile background + painter.setPen((border == BORDER_CURSED) ? Qt::red + : (border == BORDER_UNCURSED) ? Qt::yellow + : (border == BORDER_BLESSED) ? Qt::cyan + : Qt::white); // BORDER_DEFAULT + // assuming 32x32, draw 34x34 rectangle from 0..33x0..33, outside glyph +#if 0 /* Qt 5.11 drawRect(x,y,width,height) seems to have an off by 1 bug; + * drawRect(0,0,34,34) is drawing at 0..34x0..34 which is 35x35; + * should subtract 1 when adding width and/or height to base coord; + * the relevant code in QtCore/QRect.h is correct so this observable + * misbehavior is a mystery... */ + painter.drawRect(lox, loy, wd + 2, ht + 2); +#else + painter.drawLine(lox, loy, lox + wd + 1, loy); // 0,0->33,0 + painter.drawLine(lox, loy + ht + 1, lox + wd + 1, loy + ht + 1); + painter.drawLine(lox, loy, lox, loy + ht + 1); // 0,0->0,33 + painter.drawLine(lox + wd + 1, loy, lox + wd + 1, loy + ht + 1); +#endif + if (border != BORDER_DEFAULT) { + // assuming 32x32, draw rectangle from 1..32x1..32, inside glyph +#if 0 /* (see above) */ + painter.drawRect(lox + 1, loy + 1, wd, ht); +#else + painter.drawLine(lox + 1, loy + 1, lox + wd, loy + 1); // 1,1->32,1 + painter.drawLine(lox + 1, loy + ht, lox + wd, loy + ht); + painter.drawLine(lox + 1, loy + 1, lox + 1, loy + ht); // 1,1->1,32 + painter.drawLine(lox + wd, loy + 1, lox + wd, loy + ht); +#endif + for (int i = lox + 2; i < lox + wd - 1; i += 2) { + // assuming 32x32, draw points along <2..31,2> and <2..31,31> + painter.drawPoint(i, loy + 2); + painter.drawPoint(i + 1, loy + ht - 1); + } + for (int j = loy + 2; j < loy + ht - 1; j += 2) { + // assuming 32x32, draw points along <2,2..31> and <31,2..31> + painter.drawPoint(lox + 2, j); + painter.drawPoint(lox + wd - 1, j + 1); + } + } + } +#else + nhUse(border); +#endif +} + QPixmap NetHackQtGlyphs::glyph(int glyph) { int tile = glyph2tile[glyph]; diff --git a/win/Qt/qt_glyph.h b/win/Qt/qt_glyph.h index b85c4f4d3..719e5cf17 100644 --- a/win/Qt/qt_glyph.h +++ b/win/Qt/qt_glyph.h @@ -9,6 +9,11 @@ namespace nethack_qt_ { +enum border_code { + NO_BORDER, BORDER_DEFAULT, + BORDER_CURSED, BORDER_UNCURSED, BORDER_BLESSED +}; + class NetHackQtGlyphs { public: NetHackQtGlyphs(); @@ -20,6 +25,8 @@ public: void drawGlyph(QPainter&, int glyph, int pixelx, int pixely); void drawCell(QPainter&, int glyph, int cellx, int celly); + void drawBorderedCell(QPainter&, int glyph, + int cellx, int celly, int bordercode); QPixmap glyph(int glyph); private: diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index f34d0e48a..1cab0ab11 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -48,13 +48,22 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, int x, int y, bool canbe) { short int glyph; + int border; + if (nhobj) { - /* Hallucination doesn't affect inventory */ + border = BORDER_DEFAULT; + if (Role_if('P') && !Blind) + nhobj->bknown = 1; + if (nhobj->bknown) + border = nhobj->cursed ? BORDER_CURSED + : !nhobj->blessed ? BORDER_UNCURSED + : BORDER_BLESSED; glyph = obj_to_glyph(nhobj, rn2_on_display_rng); } else { + border = NO_BORDER; glyph = canbe ? cmap_to_glyph(S_room) : GLYPH_UNEXPLORED; } - qt_settings->glyphs().drawCell(painter, glyph, x, y); + qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border); } void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) @@ -132,14 +141,16 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const { if (qt_settings) { int w = 0, h = 0; + // 1+X+1: one pixel border surrounding each tile in the paper doll, + // so +1 left and +1 right, also +1 above and +1 below #ifdef ENHANCED_PAPERDOLL if (qt_settings->doll_is_shown) { - w = qt_settings->dollWidth * 3; - h = qt_settings->dollHeight * 6; + w = (1 + qt_settings->dollWidth + 1) * 3; + h = (1 + qt_settings->dollHeight + 1) * 6; } #else - w = qt_settings->glyphs().width() * 3; - h = qt_settings->glyphs().height() * 6; + w = (1 + qt_settings->glyphs().width() + 1) * 3; + h = (1 + qt_settings->glyphs().height() + 1) * 6; #endif return QSize(w, h); } else { diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 51fafda2d..eb497da86 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -63,7 +63,8 @@ NetHackQtMapViewport::NetHackQtMapViewport(NetHackQtClickBuffer& click_sink) : clicksink(click_sink), change(10) { - pet_annotation = QPixmap(qt_compact_mode ? pet_mark_small_xpm : pet_mark_xpm); + pet_annotation = QPixmap(qt_compact_mode ? pet_mark_small_xpm + : pet_mark_xpm); pile_annotation = QPixmap(pile_mark_xpm); Clear(); @@ -153,9 +154,13 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) } #ifdef TEXTCOLOR if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pet_annotation); } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pile_annotation); } #endif } @@ -173,9 +178,13 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) qt_settings->glyphs().drawCell(painter, g, i, j); #ifdef TEXTCOLOR if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pet_annotation); } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pile_annotation); } #endif } @@ -646,7 +655,8 @@ NetHackQtMapWindow::NetHackQtMapWindow(NetHackQtClickBuffer& click_sink) : palette.setColor(viewport.backgroundRole(), Qt::black); viewport.setPalette(palette); - pet_annotation = QPixmap(qt_compact_mode ? pet_mark_small_xpm : pet_mark_xpm); + pet_annotation = QPixmap(qt_compact_mode ? pet_mark_small_xpm + : pet_mark_xpm); pile_annotation = QPixmap(pile_mark_xpm); cursor.setX(0); @@ -836,9 +846,13 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) ); #ifdef TEXTCOLOR if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pet_annotation); } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pile_annotation); } #endif } @@ -856,9 +870,13 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) qt_settings->glyphs().drawCell(painter, g, i, j); #ifdef TEXTCOLOR if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pet_annotation); } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); + painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), + j*qt_settings->glyphs().height()), + pile_annotation); } #endif } diff --git a/win/Qt/qt_map.h b/win/Qt/qt_map.h index 8849a18da..bf8afceb4 100644 --- a/win/Qt/qt_map.h +++ b/win/Qt/qt_map.h @@ -22,7 +22,8 @@ public: protected: virtual void paintEvent(QPaintEvent* event); - bool DrawWalls(QPainter& painter, int x, int y, int w, int h, unsigned ch); + bool DrawWalls(QPainter& painter, int x, int y, + int w, int h, unsigned ch); virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; virtual void mousePressEvent(QMouseEvent* event); From 276477e953821cb6d741daaf11ed00502da1ebab Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 17 Aug 2020 15:44:16 -0700 Subject: [PATCH 124/708] win/Qt/* dependencies update A couple of qt_*.h headers now include other qt_*.h headers, adding a bunch of new dependencies for the qt_*.cpp sources. This is from 'make depend'. --- sys/unix/Makefile.src | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 278f4bbde..065f986f6 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.7 Makefile.src $NHDT-Date: 1596498291 2020/08/03 23:44:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.106 $ +# NetHack 3.7 Makefile.src $NHDT-Date: 1597704252 2020/08/17 22:44:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -871,14 +871,17 @@ qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_pre.h \ $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) ../include/tile2x11.h \ ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_glyph.h \ - ../win/Qt/qt_set.h ../win/Qt/qt_str.h + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_inv.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_icon.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ - ../win/Qt/qt_set.h + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_key.h @@ -898,18 +901,21 @@ qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_xpms.h ../win/Qt/qt_set.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ ../win/Qt/qt_rip.h qt_menu.moc ../win/Qt/qt_glyph.h \ - ../win/Qt/qt_set.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ qt_msg.moc ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ - ../win/Qt/qt_set.h ../win/Qt/qt_str.h + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_plsel.h qt_plsel.moc \ @@ -921,12 +927,14 @@ qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_pre.h \ - ../win/Qt/qt_post.h ../win/Qt/qt_set.h qt_set.moc \ + ../win/Qt/qt_post.h ../win/Qt/qt_set.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h qt_set.moc \ ../win/Qt/qt_glyph.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ ../win/Qt/qt_icon.h qt_stat.moc ../win/Qt/qt_set.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h From 0438dfe5a38b5b535862fb6cb9c769782ca6a78d Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 17 Aug 2020 15:53:18 -0700 Subject: [PATCH 125/708] Qt install dependencies Playground setup: Qt does not use external files pet_mark.xbm and pilemark.xbm, it has pixmaps for those compiled in via qt_xpms.h. Presumably because the pet mark heart has two sizes there. --- sys/unix/hints/linux.2020 | 4 ++-- sys/unix/hints/macOS.2020 | 4 ++-- sys/unix/hints/macosx10.10-qt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 0bdce7bad..df2bfc671 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.2020 $NHDT-Date: 1597332698 2020/08/13 15:31:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.5 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1597704792 2020/08/17 22:53:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -130,7 +130,7 @@ QTCXXFLAGS += -Wno-deprecated-declarations QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) QTCXXFLAGS += -fPIC WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) -VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm +VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm # XXX if /Developer/qt exists and QTDIR not set, use that ifndef QTDIR $(error QTDIR not defined in the environment or Makefile) diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 278323418..31b92dba2 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.2020 $NHDT-Date: 1597332721 2020/08/13 15:32:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1597704793 2020/08/17 22:53:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -136,7 +136,7 @@ QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Q WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) WINSRC += $(WINQTSRC) WINOBJ0 += $(WINQTOBJ) -VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm +VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm # XXX if /Developer/qt exists and QTDIR not set, use that ifndef QTDIR $(error QTDIR not defined in the environment or Makefile) diff --git a/sys/unix/hints/macosx10.10-qt b/sys/unix/hints/macosx10.10-qt index f23452672..35b83213b 100644 --- a/sys/unix/hints/macosx10.10-qt +++ b/sys/unix/hints/macosx10.10-qt @@ -1,5 +1,5 @@ # -# NetHack 3.7 macosx10.10-qt $NHDT-Date: 1596498421 2020/08/03 23:47:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ +# NetHack 3.7 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. # @@ -145,7 +145,7 @@ QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Q WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) WINSRC += $(WINQTSRC) WINOBJ0 += $(WINQTOBJ) -VARDATND0 = nhtiles.bmp rip.xpm nhsplash.xpm pet_mark.xbm pilemark.xbm +VARDATND0 = nhtiles.bmp rip.xpm nhsplash.xpm MOC = moc # XXX if /Developer/qt exists and QTDIR not set, use that From ae4c180cf62ce4f19bd020495d6b089584b2426b Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 17 Aug 2020 16:42:24 -0700 Subject: [PATCH 126/708] Qt without tiles Qt is capable of using an ascii map, and does so on the rogue level. So failing to load tiles doesn't need to quit; it can continue in text mode. Not extensively tested. This disables the paper doll when the ascii map is forced (either via options settings or due to tiles loading failure, but not when simply on the rogue level) rather than trying to display it with object class characters. --- doc/fixes37.0 | 3 ++- win/Qt/qt_glyph.cpp | 12 +++++++----- win/Qt/qt_inv.cpp | 10 ++++++++-- win/Qt/qt_set.cpp | 9 +++++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index e465340d5..64988cf11 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.287 $ $NHDT-Date: 1597704087 2020/08/17 22:41:27 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ $NHDT-Date: 1597707740 2020/08/17 23:42:20 $ General Fixes and Modified Features ----------------------------------- @@ -349,6 +349,7 @@ curses: for vertical status, line up conditions in columns; usually two but msdos: add -DSTATUES_LOOK_LIKE_MONSTERS to Makefile1.cross so the VESA mode can display statue glyphs Qt: quit if can't load tiles file instead of continuing and then segfaulting +Qt: [later] tiles load failure at startup now continues using an ascii map Qt: use more columns for extended command selection dialog so that the number of rows needed doesn't result in some commands being unaccessible Qt: suppress wizard mode commands from '#' handling when not in wizard mode diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 5554a7b3f..807b4dc7d 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -46,16 +46,15 @@ NetHackQtGlyphs::NetHackQtGlyphs() tile_file = iflags.wc_tile_file; if (!img.load(tile_file)) { + tiles_per_row = TILES_PER_ROW; + tile_file = PIXMAPDIR "/x11tiles"; if (!img.load(tile_file)) { QString msg; - msg.sprintf("Cannot load 'nhtiles.bmp' or 'x11tiles'."); - QMessageBox::warning(0, "IO Error", msg); - NetHackQtBind::qt_exit_nhwindows((const char *) 0); - nh_terminate(EXIT_FAILURE); + iflags.wc_ascii_map = 1; + iflags.wc_tiled_map = 0; } else { - tiles_per_row = TILES_PER_ROW; if (img.width() % tiles_per_row) { impossible( "Tile file \"%s\" has %d columns, not multiple of row count (%d)", @@ -68,8 +67,11 @@ NetHackQtGlyphs::NetHackQtGlyphs() if (iflags.wc_tile_width) tilefile_tile_W = iflags.wc_tile_width; + else if (iflags.wc_ascii_map) + tilefile_tile_W = 16; else tilefile_tile_W = img.width() / tiles_per_row; + if (iflags.wc_tile_height) tilefile_tile_H = iflags.wc_tile_height; else diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 1cab0ab11..f6cc6a92e 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -85,6 +85,8 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // show leash-in-use on lower left side #ifdef ENHANCED_PAPERDOLL + if (iflags.wc_ascii_map) + qt_settings->doll_is_shown = false; if (!qt_settings->doll_is_shown) return; qt_settings->glyphs().setSize(qt_settings->dollWidth, @@ -144,13 +146,17 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const // 1+X+1: one pixel border surrounding each tile in the paper doll, // so +1 left and +1 right, also +1 above and +1 below #ifdef ENHANCED_PAPERDOLL + if (iflags.wc_ascii_map) + qt_settings->doll_is_shown = false; if (qt_settings->doll_is_shown) { w = (1 + qt_settings->dollWidth + 1) * 3; h = (1 + qt_settings->dollHeight + 1) * 6; } #else - w = (1 + qt_settings->glyphs().width() + 1) * 3; - h = (1 + qt_settings->glyphs().height() + 1) * 6; + if (iflags.wc_tiles_map) { + w = (1 + qt_settings->glyphs().width() + 1) * 3; + h = (1 + qt_settings->glyphs().height() + 1) * 6; + } #endif return QSize(w, h); } else { diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index fc4df1ac1..939ae89a7 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -196,6 +196,9 @@ NetHackQtSettings::NetHackQtSettings() : NetHackQtGlyphs& NetHackQtSettings::glyphs() { + // Caveat: + // 'theglyphs' will be Null if the tiles file couldn't be loaded; + // the game can still procede with an ascii map in that situation. return *theglyphs; } @@ -213,8 +216,10 @@ void NetHackQtSettings::resizeTiles() settings.setValue("tilewidth", tileWidth); settings.setValue("tileheight", tileHeight); - theglyphs->setSize(tileWidth, tileHeight); - emit tilesChanged(); + if (theglyphs) { + theglyphs->setSize(tileWidth, tileHeight); + emit tilesChanged(); + } } void NetHackQtSettings::toggleGlyphSize() From 960f5d82b92a91128e78c0481094ee5ea9fefb1a Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 18 Aug 2020 10:26:24 -0400 Subject: [PATCH 127/708] mirror recent make depends update in some other Makefiles --- sys/winnt/Makefile.gcc | 128 +++++++++++++++++++++++++++--- sys/winnt/Makefile.msc | 173 +++++++++++++++++++++-------------------- 2 files changed, 207 insertions(+), 94 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 380cb0c8f..2d4aacc04 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.gcc $NHDT-Date: 1594155895 2020/07/07 21:04:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.109 $ +# NetHack 3.7 Makefile.gcc $NHDT-Date: 1597760766 2020/08/18 14:26:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.113 $ # Copyright (c) 2010 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -1481,15 +1481,123 @@ $(O)wintext.o: ../win/X11/wintext.c $(HACK_H) $(INCL)/winX.h $(INCL)/xwindow.h $(O)winval.o: ../win/X11/winval.c $(HACK_H) $(INCL)/winX.h $(cc) $(CFLAGS) -o$@ ../win/X11/winval.c $(O)tile.o: $(SRC)/tile.c $(HACK_H) -$(O)qt_win.o: $(QT)/qt_win.cpp $(HACK_H) $(INCL)/func_tab.h \ - $(INCL)/dlb.h $(INCL)/tile2x11.h \ - $(INCL)/qt_win.h $(INCL)/qt_clust.h $(INCL)/qt_kde0.h \ - $(INCL)/qt_xpms.h qt_win.moc qt_kde0.moc qttableview.moc - $(CXX) $(CXXFLAGS) -o$@ $(QT)/qt_win.cpp -$(O)qt_clust.o: $(QT)/qt_clust.cpp $(INCL)/qt_clust.h - $(CXX) $(CXXFLAGS) -o$@ $(QT)/qt_clust.cpp -$(O)qttableview.o: $(QT)/qttableview.cpp $(INCL)/qttableview.h - $(CXX) $(CXXFLAGS) -o$@ $(QT)/qttableview.cpp +#--- +$(O)qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h ../win/Qt/qt_delay.h \ + ../win/Qt/qt_xcmd.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_menu.h \ + ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h ../win/Qt/qt_plsel.h \ + ../win/Qt/qt_svsel.h ../win/Qt/qt_set.h ../win/Qt/qt_stat.h \ + ../win/Qt/qt_icon.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_yndlg.h ../win/Qt/qt_str.h ../include/dlb.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_bind.cpp +$(O)qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_click.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_click.cpp +$(O)qt_clust.o: ../win/Qt/qt_clust.cpp ../win/Qt/qt_clust.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_clust.cpp +$(O)qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_delay.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp +$(O)qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) ../include/tile2x11.h \ + ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_inv.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp +$(O)qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_icon.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp +$(O)qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp +$(O)qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_key.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_key.cpp +$(O)qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_line.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_line.cpp +$(O)qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + qt_main.moc ../win/Qt/qt_bind.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_inv.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_msg.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h \ + ../win/Qt/qt_str.h qt_kde0.moc +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_main.cpp +$(O)qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_xpms.h ../win/Qt/qt_set.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp +$(O)qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_rip.h qt_menu.moc ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp +$(O)qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ + qt_msg.moc ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp +$(O)qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_plsel.h qt_plsel.moc \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_plsel.cpp +$(O)qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_rip.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp +$(O)qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_set.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h qt_set.moc \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp +$(O)qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_icon.h qt_stat.moc ../win/Qt/qt_set.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp +$(O)qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_str.cpp +$(O)qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp +$(O)qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp +$(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h +# $(CXX) $(CXXFLAGS) -o$@ $(QT)/qttableview.cpp +$(O)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h ../win/Qt/qt_key.h \ + ../win/Qt/qt_icon.h ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ + ../win/Qt/qt_menu.h ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h \ + ../win/Qt/qt_set.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_win.cpp +$(O)qt_xcmd.o: ../win/Qt/qt_xcmd.cpp $(HACK_H) ../include/func_tab.h \ + ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_xcmd.h \ +# qt_xcmd.moc ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ +# ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_xcmd.cpp +$(O)qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_yndlg.h qt_yndlg.moc \ + ../win/Qt/qt_str.h +# $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp +#--- $(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h $(O)allmain.o: allmain.c $(HACK_H) $(O)alloc.o: alloc.c $(CONFIG_H) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 4cb968c8b..7b93148f4 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1788,116 +1788,121 @@ $(O)winval.o: $(X11)\winval.c $(HACK_H) $(INCL)\winX.h $(O)tile.o: $(SRC)\tile.c $(HACK_H) #cppregex.o: ..\sys\share\cppregex.cpp # $(CXX) $(CXXFLAGS) -Fo$@ ..\sys\share\cppregex.cpp -$(O)qt_bind.o: $(QT)\qt_bind.cpp $(HACK_H) $(QT)\qt_bind.h \ - $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_click.h \ - $(QT)\qt_delay.h $(QT)\qt_xcmd.h $(QT)\qt_key.h \ - $(QT)\qt_map.h $(QT)\qt_win.h $(QT)\qt_clust.h \ - $(QT)\qt_menu.h $(QT)\qt_rip.h $(QT)\qt_msg.h \ - $(QT)\qt_plsel.h $(QT)\qt_svsel.h $(QT)\qt_set.h \ - $(QT)\qt_stat.h $(QT)\qt_icon.h $(QT)\qt_streq.h \ - $(QT)\qt_line.h $(QT)\qt_yndlg.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h \ - $(INCL)\dlb.h +#--- +qt_bind.o: $(QT)\qt_bind.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_bind.h $(QT)\qt_main.h \ + $(QT)\qt_kde0.h $(QT)\qt_click.h $(QT)\qt_delay.h \ + $(QT)\qt_xcmd.h $(QT)\qt_key.h $(QT)\qt_map.h \ + $(QT)\qt_win.h $(QT)\qt_clust.h $(QT)\qt_menu.h \ + $(QT)\qt_rip.h $(QT)\qt_msg.h $(QT)\qt_plsel.h \ + $(QT)\qt_svsel.h $(QT)\qt_set.h $(QT)\qt_stat.h \ + $(QT)\qt_icon.h $(QT)\qt_streq.h $(QT)\qt_line.h \ + $(QT)\qt_yndlg.h $(QT)\qt_str.h $(INCL)\dlb.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_bind.cpp -$(O)qt_click.o: $(QT)\qt_click.cpp $(HACK_H) $(QT)\qt_click.h - $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_click.cpp \ - $(QT)\qt_pre.h $(QT)\qt_post.h -$(O)qt_clust.o: $(QT)\qt_clust.cpp $(QT)\qt_clust.h +qt_click.o: $(QT)\qt_click.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_click.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_click.cpp +qt_clust.o: $(QT)\qt_clust.cpp $(QT)\qt_clust.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_clust.cpp -$(O)qt_delay.o: $(QT)\qt_delay.cpp $(HACK_H) $(QT)\qt_delay.h - $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_delay.cpp \ - $(QT)\qt_pre.h $(QT)\qt_post.h -$(O)qt_glyph.o: $(QT)\qt_glyph.cpp $(HACK_H) $(INCL)\tile2x11.h \ - $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_delay.o: $(QT)\qt_delay.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_delay.h + $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_delay.cpp +qt_glyph.o: $(QT)\qt_glyph.cpp $(HACK_H) $(INCL)\tile2x11.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h $(QT)\qt_glyph.h \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + $(QT)\qt_set.h $(QT)\qt_inv.h $(QT)\qt_map.h \ + $(QT)\qt_win.h $(QT)\qt_clust.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_glyph.cpp -$(O)qt_icon.o: $(QT)\qt_icon.cpp $(HACK_H) $(QT)\qt_icon.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_icon.o: $(QT)\qt_icon.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_icon.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_icon.cpp -$(O)qt_inv.o: $(QT)\qt_inv.cpp $(HACK_H) $(QT)\qt_inv.h \ - $(QT)\qt_glyph.h $(QT)\qt_set.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_inv.o: $(QT)\qt_inv.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_inv.h $(QT)\qt_glyph.h \ + $(QT)\qt_set.h $(QT)\qt_bind.h $(QT)\qt_main.h \ + $(QT)\qt_kde0.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_inv.cpp -$(O)qt_key.o: $(QT)\qt_key.cpp $(HACK_H) $(QT)\qt_key.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_key.o: $(QT)\qt_key.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_key.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_key.cpp -$(O)qt_line.o: $(QT)\qt_line.cpp $(HACK_H) $(QT)\qt_line.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_line.o: $(QT)\qt_line.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_line.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_line.cpp -$(O)qt_main.o: $(QT)\qt_main.cpp $(HACK_H) \ - $(QT)\qt_main.h $(QT)\qt_kde0.h qt_main.moc \ - $(QT)\qt_bind.h $(QT)\qt_glyph.h $(QT)\qt_inv.h \ - $(QT)\qt_key.h $(QT)\qt_map.h $(QT)\qt_win.h \ - $(QT)\qt_clust.h $(QT)\qt_msg.h $(QT)\qt_set.h \ - $(QT)\qt_stat.h $(QT)\qt_icon.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h \ - qt_kde0.moc +qt_main.o: $(QT)\qt_main.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + qt_main.moc $(QT)\qt_bind.h $(QT)\qt_glyph.h \ + $(QT)\qt_inv.h $(QT)\qt_key.h $(QT)\qt_map.h \ + $(QT)\qt_win.h $(QT)\qt_clust.h $(QT)\qt_msg.h \ + $(QT)\qt_set.h $(QT)\qt_stat.h $(QT)\qt_icon.h \ + $(QT)\qt_str.h qt_kde0.moc $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_main.cpp -$(O)qt_map.o: $(QT)\qt_map.cpp $(HACK_H) $(QT)\qt_map.h $(QT)\qt_win.h \ +qt_map.o: $(QT)\qt_map.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_map.h $(QT)\qt_win.h \ $(QT)\qt_clust.h qt_map.moc $(QT)\qt_click.h \ $(QT)\qt_glyph.h $(QT)\qt_xpms.h $(QT)\qt_set.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_map.cpp -$(O)qt_menu.o: $(QT)\qt_menu.cpp $(HACK_H) $(QT)\qt_menu.h \ - $(QT)\qt_win.h $(QT)\qt_rip.h qt_menu.moc \ - $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_streq.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h \ - $(QT)\qt_line.h $(QT)\qt_str.h +qt_menu.o: $(QT)\qt_menu.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_menu.h $(QT)\qt_win.h \ + $(QT)\qt_rip.h qt_menu.moc $(QT)\qt_glyph.h \ + $(QT)\qt_set.h $(QT)\qt_bind.h $(QT)\qt_main.h \ + $(QT)\qt_kde0.h $(QT)\qt_streq.h $(QT)\qt_line.h \ + $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_menu.cpp -$(O)qt_msg.o: $(QT)\qt_msg.cpp $(HACK_H) $(QT)\qt_msg.h $(QT)\qt_win.h \ +qt_msg.o: $(QT)\qt_msg.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_msg.h $(QT)\qt_win.h \ qt_msg.moc $(QT)\qt_map.h $(QT)\qt_clust.h \ - $(QT)\qt_set.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h + $(QT)\qt_set.h $(QT)\qt_bind.h $(QT)\qt_main.h \ + $(QT)\qt_kde0.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_msg.cpp -$(O)qt_plsel.o: $(QT)\qt_plsel.cpp $(HACK_H) $(QT)\qt_plsel.h qt_plsel.moc \ +qt_plsel.o: $(QT)\qt_plsel.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_plsel.h qt_plsel.moc \ $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ - $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h + $(QT)\qt_glyph.h $(QT)\qt_set.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_plsel.cpp -$(O)qt_rip.o: $(QT)\qt_rip.cpp $(HACK_H) $(QT)\qt_rip.h \ - $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ - $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_rip.o: $(QT)\qt_rip.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_rip.h $(QT)\qt_bind.h \ + $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_rip.cpp -$(O)qt_set.o: $(QT)\qt_set.cpp $(HACK_H) $(QT)\qt_set.h qt_set.moc \ - $(QT)\qt_glyph.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_set.o: $(QT)\qt_set.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_set.h $(QT)\qt_bind.h \ + $(QT)\qt_main.h $(QT)\qt_kde0.h qt_set.moc \ + $(QT)\qt_glyph.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_set.cpp -$(O)qt_stat.o: $(QT)\qt_stat.cpp $(HACK_H) $(QT)\qt_stat.h \ - $(QT)\qt_win.h $(QT)\qt_icon.h qt_stat.moc \ - $(QT)\qt_set.h $(QT)\qt_str.h $(QT)\qt_xpms.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_stat.o: $(QT)\qt_stat.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_stat.h $(QT)\qt_win.h \ + $(QT)\qt_icon.h qt_stat.moc $(QT)\qt_set.h \ + $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ + $(QT)\qt_str.h $(QT)\qt_xpms.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_stat.cpp -$(O)qt_str.o: $(QT)\qt_str.cpp $(QT)\qt_str.h +qt_str.o: $(QT)\qt_str.cpp $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_str.cpp -$(O)qt_streq.o: $(QT)\qt_streq.cpp $(HACK_H) $(QT)\qt_streq.h \ - $(QT)\qt_line.h $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_streq.o: $(QT)\qt_streq.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_streq.h $(QT)\qt_line.h \ + $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_streq.cpp -$(O)qt_svsel.o: $(QT)\qt_svsel.cpp $(HACK_H) $(QT)\qt_svsel.h \ - $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ - $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_svsel.o: $(QT)\qt_svsel.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_svsel.h $(QT)\qt_bind.h \ + $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_svsel.cpp -$(O)qt_win.o: $(QT)\qt_win.cpp $(HACK_H) $(QT)\qt_win.h \ - $(QT)\qt_bind.h $(QT)\qt_main.h $(QT)\qt_kde0.h \ - $(QT)\qt_click.h $(QT)\qt_glyph.h $(QT)\qt_inv.h \ - $(QT)\qt_key.h $(QT)\qt_icon.h $(QT)\qt_map.h \ - $(QT)\qt_clust.h $(QT)\qt_menu.h $(QT)\qt_rip.h \ - $(QT)\qt_msg.h $(QT)\qt_set.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_win.o: $(QT)\qt_win.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_win.h $(QT)\qt_bind.h \ + $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_click.h \ + $(QT)\qt_glyph.h $(QT)\qt_inv.h $(QT)\qt_key.h \ + $(QT)\qt_icon.h $(QT)\qt_map.h $(QT)\qt_clust.h \ + $(QT)\qt_menu.h $(QT)\qt_rip.h $(QT)\qt_msg.h \ + $(QT)\qt_set.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_win.cpp -$(O)qt_xcmd.o: $(QT)\qt_xcmd.cpp $(HACK_H) $(INCL)\func_tab.h \ - $(QT)\qt_xcmd.h qt_xcmd.moc $(QT)\qt_bind.h \ - $(QT)\qt_main.h $(QT)\qt_kde0.h $(QT)\qt_set.h \ - $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_xcmd.o: $(QT)\qt_xcmd.cpp $(HACK_H) $(INCL)\func_tab.h \ + $(QT)\qt_pre.h $(QT)\qt_post.h $(QT)\qt_xcmd.h \ + qt_xcmd.moc $(QT)\qt_bind.h $(QT)\qt_main.h \ + $(QT)\qt_kde0.h $(QT)\qt_set.h $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_xcmd.cpp -$(O)qt_yndlg.o: $(QT)\qt_yndlg.cpp $(HACK_H) $(QT)\qt_yndlg.h qt_yndlg.moc \ - $(QT)\qt_str.h \ - $(QT)\qt_pre.h $(QT)\qt_post.h +qt_yndlg.o: $(QT)\qt_yndlg.cpp $(HACK_H) $(QT)\qt_pre.h \ + $(QT)\qt_post.h $(QT)\qt_yndlg.h qt_yndlg.moc \ + $(QT)\qt_str.h $(CXX) $(CXXFLAGS) -Fo$@ $(QT)\qt_yndlg.cpp +#---- $(O)wc_chainin.o: ..\win\chain\wc_chainin.c $(HACK_H) # @$(cc) $(cflagsBuild) -Fo$@ ..\win\chain\wc_chainin.c $(O)wc_chainout.o: ..\win\chain\wc_chainout.c $(HACK_H) From d86dd4bb1b64f91d1cf273a4ded1cc09fcb9a2f4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 18 Aug 2020 10:36:15 -0400 Subject: [PATCH 128/708] comment out what appears to be an obsolete bit in windows Makefile.gcc --- sys/winnt/Makefile.gcc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 2d4aacc04..996c73e6d 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -1,4 +1,4 @@ -# NetHack 3.7 Makefile.gcc $NHDT-Date: 1597760766 2020/08/18 14:26:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.113 $ +# NetHack 3.7 Makefile.gcc $NHDT-Date: 1597761345 2020/08/18 14:35:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.114 $ # Copyright (c) 2010 by Michael Allison # NetHack may be freely redistributed. See license for details. # @@ -1578,7 +1578,7 @@ $(O)qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h # $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp -$(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h +#$(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h # $(CXX) $(CXXFLAGS) -o$@ $(QT)/qttableview.cpp $(O)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ From 4620bfccbfcf1b2bc20fcb3ea2fdc96d8081ce3f Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 20 Aug 2020 09:50:07 -0400 Subject: [PATCH 129/708] grammar bit --- src/priest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/priest.c b/src/priest.c index f73cedbaf..67e8c3114 100644 --- a/src/priest.c +++ b/src/priest.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 priest.c $NHDT-Date: 1596498199 2020/08/03 23:43:19 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.62 $ */ +/* NetHack 3.7 priest.c $NHDT-Date: 1597931337 2020/08/20 13:48:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ */ /* Copyright (c) Izchak Miller, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -636,7 +636,7 @@ register struct monst *priest; && (!(HProtection & INTRINSIC) || (u.ublessed < 20 && (u.ublessed < 9 || !rn2(u.ublessed))))) { - verbalize("Thy devotion has been rewarded."); + verbalize("Thou hast been rewarded for thy devotion."); if (!(HProtection & INTRINSIC)) { HProtection |= FROMOUTSIDE; if (!u.ublessed) From e191e6bc8fd3290f5256bc989ddb73c6c3a54e87 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 20 Aug 2020 11:18:32 -0400 Subject: [PATCH 130/708] build warning fix on g++ >= 9 and Qt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ../win/Qt/qt_menu.cpp: In member function ‘virtual void nethack_qt_::NetHackQtTextWindow::UseRIP(int, time_t)’: ../win/Qt/qt_menu.cpp:680:54: warning: ‘%s’ directive output may be truncated writing up to 31 bytes into a region of size 17 [-Wformat-truncation=] 680 | snprintf(rip_line[NAME_LINE], STONE_LINE_LEN+1, "%s", g.plname); | ^~ ~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from ../win/Qt/qt_menu.cpp:8: /usr/include/x86_64-linux-gnu/bits/stdio2.h:67:35: note: ‘__builtin_snprintf’ output between 1 and 32 bytes into a destination of size 17 67 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~../win/Qt/qt_menu.cpp: In member function ‘virtual void nethack_qt_::NetHackQtTextWindow::UseRIP(int, time_t)’: ../win/Qt/qt_menu.cpp:680:54: warning: ‘%s’ directive output may be truncated writing up to 31 bytes into a region of size 17 [-Wformat-truncation=] 680 | snprintf(rip_line[NAME_LINE], STONE_LINE_LEN+1, "%s", g.plname); | ^~ ~~~~~~~~ In file included from /usr/include/stdio.h:867, from ../include/global.h:9, from ../include/config.h:608, from ../include/hack.h:10, from ../win/Qt/qt_menu.cpp:8: /usr/include/x86_64-linux-gnu/bits/stdio2.h:67:35: note: ‘__builtin_snprintf’ output between 1 and 32 bytes into a destination of size 17 67 | return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | __bos (__s), __fmt, __va_arg_pack ()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- sys/unix/hints/linux.2020 | 7 +++++++ sys/unix/hints/macOS.2020 | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index df2bfc671..3a785a530 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -127,6 +127,13 @@ ifdef WANT_WIN_QT # Qt5 requires C++11 LINK = $(CXX) QTCXXFLAGS += -Wno-deprecated-declarations +ifeq "$(CCISCLANG)" "" +# get the version of g++ +GPPGTEQ9 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 9) +ifeq "$(GPPGTEQ9)" "1" +QTCXXFLAGS+= -Wno-format-truncation +endif #g++ version greater than or equal to 9 +endif #not clang QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) QTCXXFLAGS += -fPIC WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 31b92dba2..1a81d97ad 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -132,6 +132,13 @@ ifdef WANT_WIN_QT # Qt5 requires C++11 LINK = $(CXX) QTCXXFLAGS += -Wno-deprecated-declarations +ifeq "$(CCISCLANG)" "" +# get the version of g++ +GPPGTEQ9 := $(shell expr `$(CXX) -dumpversion | cut -f1 -d.` \>= 9) +ifeq "$(GPPGTEQ9)" "1" +QTCXXFLAGS+= -Wno-format-truncation +endif #g++ version greater than or equal to 9 +endif #not clang QTCXXFLAGS += $(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) WINSRC += $(WINQTSRC) From c062822a7c1f09494ff9a888d40fab7dbd0300e2 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 20 Aug 2020 16:56:50 -0700 Subject: [PATCH 131/708] Qt tombstone bugs Infrastructure bits: Qt tombstone uses a short buffer; make sure that the plname value fits instead of relying on snprintf() to truncate it. A warning about gold, if any, was iffy but this should guarantee no reason for future complaint. Year was safe but a compiler sensitive to buffer overflows wouldn't know that. Actual bugs: Qt used money in inventory for gold amount on tombstone; that overlooks gold in containers and will be 0 by tombstone stage if bones get saved. Year was recalculated from current date+time instead of using the value that gets passed in--blindly flagging that variable as UNUSED was a mistake. --- doc/fixes37.0 | 8 +++++- include/wincurs.h | 2 +- src/rip.c | 36 ++++++++++++------------- win/Qt/qt_menu.cpp | 63 +++++++++++++++++++++++++++++-------------- win/X11/wintext.c | 18 ++++++++----- win/curses/cursmain.c | 7 ++--- 6 files changed, 85 insertions(+), 49 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 64988cf11..4a638b5f0 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ $NHDT-Date: 1597707740 2020/08/17 23:42:20 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.289 $ $NHDT-Date: 1597967807 2020/08/20 23:56:47 $ General Fixes and Modified Features ----------------------------------- @@ -383,6 +383,12 @@ Qt: "paper doll" subset of persistent inventory has undergone several changes: first active light source in a previously unused slot on lower right; show first leash-in-use in a previously unused slot on lower left Qt: paper doll inventory view was inconsistently updated during Hallucination +Qt: when hero died, gold on tombstone only included gold in inventory, not + any additional gold inside carried containers; also, inventory gold + will be zero if bones get created for all 3.6.x and for 3.4.x+GOLDOBJ +Qt: tombstone showed newly constructed date instead of the value set up at + time of death; it only shows year but that could be wrong if player + stared at or ignored prior --More-- for long enough on 31 December Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/include/wincurs.h b/include/wincurs.h index ad7be2083..4e5ce4e78 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -105,7 +105,7 @@ extern void curses_number_pad(int state); extern void curses_delay_output(void); extern void curses_start_screen(void); extern void curses_end_screen(void); -extern void curses_outrip(winid wid, int how); +extern void curses_outrip(winid wid, int how, time_t when); extern void genl_outrip(winid tmpwin, int how, time_t when); extern void curses_preference_update(const char *pref); extern void curs_reset_windows(boolean, boolean); diff --git a/src/rip.c b/src/rip.c index 2996d21a2..dca074720 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rip.c $NHDT-Date: 1596498204 2020/08/03 23:43:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.7 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. */ @@ -60,12 +60,10 @@ static const char *rip_txt[] = { }; #define STONE_LINE_CENT 19 /* char[] element of center of stone face */ #endif /* NH320_DEDICATION */ -#define STONE_LINE_LEN \ - 16 /* # chars that fit on one line \ - * (note 1 ' ' border) \ - */ -#define NAME_LINE 6 /* *char[] line # for player name */ -#define GOLD_LINE 7 /* *char[] line # for amount of gold */ +#define STONE_LINE_LEN 16 /* # chars that fit on one line + * (note 1 ' ' border) */ +#define NAME_LINE 6 /* *char[] line # for player name */ +#define GOLD_LINE 7 /* *char[] line # for amount of gold */ #define DEATH_LINE 8 /* *char[] line # for death description */ #define YEAR_LINE 12 /* *char[] line # for year */ @@ -90,9 +88,9 @@ time_t when; register char **dp; register char *dpx; char buf[BUFSZ]; - long year; register int x; - int line; + int line, year; + long cash; g.rip = dp = (char **) alloc(sizeof(rip_txt)); for (x = 0; rip_txt[x]; ++x) @@ -100,13 +98,15 @@ time_t when; dp[x] = (char *) 0; /* Put name on stone */ - Sprintf(buf, "%s", g.plname); - buf[STONE_LINE_LEN] = 0; + Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, g.plname); center(NAME_LINE, buf); /* Put $ on stone */ - Sprintf(buf, "%ld Au", g.done_money); - buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */ + cash = max(g.done_money, 0L); + /* arbitrary upper limit; practical upper limit is quite a bit less */ + if (cash > 999999999L) + cash = 999999999L; + Sprintf(buf, "%ld Au", cash); center(GOLD_LINE, buf); /* Put together death description */ @@ -114,11 +114,11 @@ time_t when; /* Put death type on stone */ for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) { - register int i, i0; char tmpchar; + int i, i0 = (int) strlen(dpx); - if ((i0 = strlen(dpx)) > STONE_LINE_LEN) { - for (i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--) + if (i0 > STONE_LINE_LEN) { + for (i = STONE_LINE_LEN; (i > 0) && (i0 > STONE_LINE_LEN); --i) if (dpx[i] == ' ') i0 = i; if (!i) @@ -135,8 +135,8 @@ time_t when; } /* Put year on stone */ - year = yyyymmdd(when) / 10000L; - Sprintf(buf, "%4ld", year); + year = (int) ((yyyymmdd(when) / 10000L) % 10000L); + Sprintf(buf, "%4d", year); center(YEAR_LINE, buf); #ifdef DUMPLOG diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index b3d192eb1..817449ee7 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -653,7 +653,7 @@ bool NetHackQtTextWindow::Destroy() return !isVisible(); } -void NetHackQtTextWindow::UseRIP(int how, time_t when UNUSED) +void NetHackQtTextWindow::UseRIP(int how, time_t when) { // Code from X11 windowport #define STONE_LINE_LEN 16 /* # chars that fit on one line */ @@ -677,41 +677,63 @@ static char** rip_line=0; int line; /* Put name on stone */ - snprintf(rip_line[NAME_LINE], STONE_LINE_LEN+1, "%s", g.plname); + (void) snprintf(rip_line[NAME_LINE], STONE_LINE_LEN + 1, + "%.*s", STONE_LINE_LEN, g.plname); - /* Put $ on stone */ - snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN+1, "%ld Au", money_cnt(g.invent)); + /* Put $ on stone; + to keep things safe and relatively simple, impose an arbitrary + upper limit that's the same for 64 bit and 32 bit configurations + (also 16 bit configurations provided they use 32 bit long); the + upper limit for directly carried gold is somewhat less than 300K + due to carrying capacity, but end-of-game handling has already + added in gold from containers, so the amount could be much more + (simplest case: ~300K four times in a blessed bag of holding, so + ~1.2M; in addition to the hassle of getting such a thing set up, + it would need many gold-rich bones levels or wizard mode wishing) */ + long cash = std::max(g.done_money, 0L); + /* force less that 10 digits to satisfy elaborate format checking; + it's arbitrary but still way, way more than could ever be needed */ + if (cash > 999999999L) + cash = 999999999L; + (void) snprintf(rip_line[GOLD_LINE], STONE_LINE_LEN + 1, "%ld Au", cash); /* Put together death description */ formatkiller(buf, sizeof buf, how, FALSE); //str_copy(buf, killer, SIZE(buf)); /* Put death type on stone */ - for (line=DEATH_LINE, dpx = buf; line STONE_LINE_LEN) { - for(i = STONE_LINE_LEN; - ((i0 > STONE_LINE_LEN) && i); i--) - if(dpx[i] == ' ') i0 = i; - if(!i) i0 = STONE_LINE_LEN; + if (i0 > STONE_LINE_LEN) { + for (i = STONE_LINE_LEN; (i > 0) && (i0 > STONE_LINE_LEN); --i) + if (dpx[i] == ' ') + i0 = i; + if (!i) + i0 = STONE_LINE_LEN; } tmpchar = dpx[i0]; dpx[i0] = 0; - str_copy(rip_line[line], dpx, STONE_LINE_LEN+1); + (void) str_copy(rip_line[line], dpx, STONE_LINE_LEN + 1); if (tmpchar != ' ') { dpx[i0] = tmpchar; dpx= &dpx[i0]; - } else dpx= &dpx[i0+1]; + } else { + dpx= &dpx[i0 + 1]; + } } - /* Put year on stone */ - snprintf(rip_line[YEAR_LINE], STONE_LINE_LEN+1, "%4d", getyear()); + /* Put year on stone; + 64 bit configuration with 64 bit int is capable of overflowing + STONE_LINE_LEN characters; a compiler might warn about that, + so force a value that it can recognize as fitting within buffer's + range ("%4d" imposes a minimum number of digits, not a maximum) */ + int year = (int) ((yyyymmdd(when) / 10000L) % 10000L); /* Y10K bug! */ + (void) snprintf(rip_line[YEAR_LINE], STONE_LINE_LEN + 1, "%4d", year); - rip.setLines(rip_line,YEAR_LINE+1); - - use_rip=true; + rip.setLines(rip_line, YEAR_LINE + 1); + use_rip = true; } void NetHackQtTextWindow::Clear() @@ -820,8 +842,9 @@ void NetHackQtMenuOrTextWindow::StartMenu() if (!actual) actual=new NetHackQtMenuWindow(parent); actual->StartMenu(); } -void NetHackQtMenuOrTextWindow::AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, unsigned itemflags) +void NetHackQtMenuOrTextWindow::AddMenu(int glyph, const ANY_P* identifier, + char ch, char gch, int attr, + const QString& str, unsigned itemflags) { if (!actual) impossible("AddMenu called before we know if Menu or Text"); actual->AddMenu(glyph,identifier,ch,gch,attr,str,itemflags); diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 2a8f19315..a6c2737b8 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wintext.c $NHDT-Date: 1596498376 2020/08/03 23:46:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.21 $ */ +/* NetHack 3.7 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. */ @@ -489,14 +489,20 @@ calculate_rip_text(int how, time_t when) char buf[BUFSZ]; char *dpx; - int line; - long year; + int line, year; + long cash; /* Put name on stone */ Sprintf(rip_line[NAME_LINE], "%s", g.plname); /* Put $ on stone */ - Sprintf(rip_line[GOLD_LINE], "%ld Au", g.done_money); + cash = max(g.done_money, 0L); + /* arbitrary upper limit; practical upper limit is quite a bit less */ + if (cash > 999999999L) + cash = 999999999L; + Sprintf(buf, "%ld Au", cash); + Sprintf(rip_line[GOLD_LINE], "%ld Au", cash); + /* Put together death description */ formatkiller(buf, sizeof buf, how, FALSE); @@ -523,8 +529,8 @@ calculate_rip_text(int how, time_t when) } /* Put year on stone */ - year = yyyymmdd(when) / 10000L; - Sprintf(rip_line[YEAR_LINE], "%4ld", year); + year = (int) ((yyyymmdd(when) / 10000L) % 10000L); + Sprintf(rip_line[YEAR_LINE], "%4d", year); } /* diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index e098e163a..4035b3c9f 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -898,12 +898,13 @@ curses_end_screen() /* outrip(winid, int) - -- The tombstone code. If you want the traditional code use - genl_outrip for the value and check the #if in rip.c. + -- The tombstone code. We use genl_outrip() from rip.c + instead of rolling our own. */ void curses_outrip(winid wid UNUSED, - int how UNUSED) + int how UNUSED, + time_t when UNUSED) { return; } From 2d70d86deda7f7c39fcf2eca5fab6b621d3ac235 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 25 Aug 2020 18:59:22 -0700 Subject: [PATCH 132/708] qt_key.cpp I've been trying to figure out how to make ^[ be treated as ESC but so far have failed. That key combination just acts like a dead key. But one bit of cp_key.cpp can be implemented instead of ignored. No change in behavior because the keyboard-state value isn't being used anywhere. --- win/Qt/qt_key.cpp | 13 +++++++------ win/Qt/qt_key.h | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index 5aa807803..480fe7f4f 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -23,18 +23,19 @@ NetHackQtKeyBuffer::NetHackQtKeyBuffer() : bool NetHackQtKeyBuffer::Empty() const { return in==out; } bool NetHackQtKeyBuffer::Full() const { return (in+1)%maxkey==out; } -void NetHackQtKeyBuffer::Put(int k, int a, int kbstate) +void NetHackQtKeyBuffer::Put(int k, int a, uint kbstate) { + //raw_fprintf("k:%3d a:%3d s:0x%08x\n", k, a, kbstate); if ( Full() ) return; // Safety - nhUse(kbstate); - key[in]=k; - ascii[in]=a; - in=(in+1)%maxkey; + key[in] = k; + ascii[in] = a; + state[in] = (Qt::KeyboardModifiers) kbstate; + in = (in + 1) % maxkey; } void NetHackQtKeyBuffer::Put(char a) { - Put(0,a,0); + Put(0, a, 0U); } void NetHackQtKeyBuffer::Put(const char* str) diff --git a/win/Qt/qt_key.h b/win/Qt/qt_key.h index c2ef3a89b..78a2c56c9 100644 --- a/win/Qt/qt_key.h +++ b/win/Qt/qt_key.h @@ -16,7 +16,7 @@ public: bool Empty() const; bool Full() const; - void Put(int k, int ascii, int state); + void Put(int k, int ascii, uint state); void Put(char a); void Put(const char* str); int GetKey(); From 1079c01333dc69d2985984f14a9724785bc0a444 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 25 Aug 2020 22:41:54 -0400 Subject: [PATCH 133/708] sys/winnt/Makefile.msc update for VS 2019 16.7.2 --- sys/winnt/Makefile.msc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 7b93148f4..be7fdcce2 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -542,7 +542,7 @@ rc=Rc # Visual Studio we are using. We set VSVER to 0000 to flag any version that # is too old or untested. # -#NMAKE version 1426288060 is distributed with latest VS 2019 +#NMAKE version 1427291110 is distributed with latest VS 2019 #!MESSAGE $(MAKEFLAGS) #!MESSAGE $(MAKEDIR) @@ -566,9 +566,9 @@ VSVER=2013 VSVER=2015 !ELSEIF ($(MAKEVERSION) > 1411000000) && ($(MAKEVERSION) < 1416270312) VSVER=2017 -!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1426288061) +!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1427291111) VSVER=$(VSNEWEST) -!ELSEIF ($(MAKEVERSION) > 1426288060) +!ELSEIF ($(MAKEVERSION) > 1427291110) VSVER=2999 #untested future version !ENDIF From 1a11d67d5846c5715df05c6d0c3b6eeeb3f9711a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 26 Aug 2020 14:47:02 -0700 Subject: [PATCH 134/708] fix commented-out debugging code I was actually using fprintf(stderr,...) when testing and didn't retry this bit after changing it to raw_printf(...). It's commented out but needs fixing. --- win/Qt/qt_key.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index 480fe7f4f..f882b458e 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -25,7 +25,7 @@ bool NetHackQtKeyBuffer::Full() const { return (in+1)%maxkey==out; } void NetHackQtKeyBuffer::Put(int k, int a, uint kbstate) { - //raw_fprintf("k:%3d a:%3d s:0x%08x\n", k, a, kbstate); + //raw_printf("k:%3d a:%3d s:0x%08x", k, a, kbstate); if ( Full() ) return; // Safety key[in] = k; ascii[in] = a; From 593977397190daca68132269a78b9016b478025c Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 26 Aug 2020 19:17:40 -0700 Subject: [PATCH 135/708] initial shim graphics --- include/config.h | 8 ++- src/mdlib.c | 3 + src/rip.c | 38 +++++------ src/windows.c | 6 ++ win/shim/winshim.c | 161 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 win/shim/winshim.c diff --git a/include/config.h b/include/config.h index bbcd4b112..a94b38267 100644 --- a/include/config.h +++ b/include/config.h @@ -64,7 +64,7 @@ * Define the default window system. This should be one that is compiled * into your system (see defines above). Known window systems are: * - * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome + * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome, shim */ /* MAC also means MAC windows */ @@ -144,6 +144,12 @@ #endif #endif +#ifdef SHIM_GRAPHICS +#ifndef DEFAULT_WINDOW_SYS +#define DEFAULT_WINDOW_SYS "shim" +#endif +#endif + #ifdef X11_GRAPHICS /* * There are two ways that X11 tiles may be defined. (1) using a custom diff --git a/src/mdlib.c b/src/mdlib.c index 59b94b459..52f6a6d59 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -123,6 +123,9 @@ static struct win_info window_opts[] = { #ifdef MSWIN_GRAPHICS /* win32 */ { "mswin", "Windows GUI", TRUE }, #endif +#ifdef SHIM_GRAPHICS + { "shim", "Nethack Library Windowing Shim", TRUE }, +#endif #if 0 /* remainder have been retired */ #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ diff --git a/src/rip.c b/src/rip.c index dca074720..b61a76254 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 3.7 rip.c $NHDT-Date: 1596498204 2020/08/03 23:43:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,7 +6,7 @@ #include "hack.h" #if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) \ - || defined(MSWIN_GRAPHICS) || defined(DUMPLOG) || defined(CURSES_GRAPHICS) + || defined(MSWIN_GRAPHICS) || defined(DUMPLOG) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) #define TEXT_TOMBSTONE #endif #if defined(mac) || defined(__BEOS__) || defined(WIN32_GRAPHICS) @@ -60,10 +60,12 @@ static const char *rip_txt[] = { }; #define STONE_LINE_CENT 19 /* char[] element of center of stone face */ #endif /* NH320_DEDICATION */ -#define STONE_LINE_LEN 16 /* # chars that fit on one line - * (note 1 ' ' border) */ -#define NAME_LINE 6 /* *char[] line # for player name */ -#define GOLD_LINE 7 /* *char[] line # for amount of gold */ +#define STONE_LINE_LEN \ + 16 /* # chars that fit on one line \ + * (note 1 ' ' border) \ + */ +#define NAME_LINE 6 /* *char[] line # for player name */ +#define GOLD_LINE 7 /* *char[] line # for amount of gold */ #define DEATH_LINE 8 /* *char[] line # for death description */ #define YEAR_LINE 12 /* *char[] line # for year */ @@ -88,9 +90,9 @@ time_t when; register char **dp; register char *dpx; char buf[BUFSZ]; + long year; register int x; - int line, year; - long cash; + int line; g.rip = dp = (char **) alloc(sizeof(rip_txt)); for (x = 0; rip_txt[x]; ++x) @@ -98,15 +100,13 @@ time_t when; dp[x] = (char *) 0; /* Put name on stone */ - Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, g.plname); + Sprintf(buf, "%s", g.plname); + buf[STONE_LINE_LEN] = 0; center(NAME_LINE, buf); /* Put $ on stone */ - cash = max(g.done_money, 0L); - /* arbitrary upper limit; practical upper limit is quite a bit less */ - if (cash > 999999999L) - cash = 999999999L; - Sprintf(buf, "%ld Au", cash); + Sprintf(buf, "%ld Au", g.done_money); + buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */ center(GOLD_LINE, buf); /* Put together death description */ @@ -114,11 +114,11 @@ time_t when; /* Put death type on stone */ for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) { + register int i, i0; char tmpchar; - int i, i0 = (int) strlen(dpx); - if (i0 > STONE_LINE_LEN) { - for (i = STONE_LINE_LEN; (i > 0) && (i0 > STONE_LINE_LEN); --i) + if ((i0 = strlen(dpx)) > STONE_LINE_LEN) { + for (i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--) if (dpx[i] == ' ') i0 = i; if (!i) @@ -135,8 +135,8 @@ time_t when; } /* Put year on stone */ - year = (int) ((yyyymmdd(when) / 10000L) % 10000L); - Sprintf(buf, "%4d", year); + year = yyyymmdd(when) / 10000L; + Sprintf(buf, "%4ld", year); center(YEAR_LINE, buf); #ifdef DUMPLOG diff --git a/src/windows.c b/src/windows.c index 03bc1e592..f3af21f49 100644 --- a/src/windows.c +++ b/src/windows.c @@ -44,6 +44,9 @@ extern struct window_procs Gnome_procs; #ifdef MSWIN_GRAPHICS extern struct window_procs mswin_procs; #endif +#ifdef SHIM_GRAPHICS +extern struct window_procs shim_procs; +#endif #ifdef WINCHAIN extern struct window_procs chainin_procs; extern void FDECL(chainin_procs_init, (int)); @@ -128,6 +131,9 @@ static struct win_choices { #ifdef MSWIN_GRAPHICS { &mswin_procs, 0 CHAINR(0) }, #endif +#ifdef SHIM_GRAPHICS + { &shim_procs, 0 CHAINR(0) }, +#endif #ifdef WINCHAIN { &chainin_procs, chainin_procs_init, chainin_procs_chain }, { (struct window_procs *) &chainout_procs, chainout_procs_init, diff --git a/win/shim/winshim.c b/win/shim/winshim.c new file mode 100644 index 000000000..d82d21334 --- /dev/null +++ b/win/shim/winshim.c @@ -0,0 +1,161 @@ +/* NetHack 3.7 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. */ + +/* not an actual windowing port, but a fake win port for libnethack */ + +#include "hack.h" + +#ifdef SHIM_GRAPHICS + +enum win_types { + WINSTUB_MESSAGE = 1, + WINSTUB_MAP, + WINSTUB_MENU, + WINSTUB_EXT +}; + +#define VSTUB(name, args) \ +void name args { \ + printf ("Running " #name "...\n"); \ +} + +#define STUB(name, retval, args) \ +name args { \ + printf ("Running " #name "...\n"); \ + return retval; \ +} + +#define DECL(name, args) \ +void name args; + +VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) +VSTUB(shim_player_selection,(void)) +VSTUB(shim_askname,(void)) +VSTUB(shim_get_nh_event,(void)) +VSTUB(shim_exit_nhwindows,(const char *a)) +VSTUB(shim_suspend_nhwindows,(const char *a)) +VSTUB(shim_resume_nhwindows,(void)) +winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) +VSTUB(shim_clear_nhwindow,(winid a)) +VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) +VSTUB(shim_destroy_nhwindow,(winid a)) +VSTUB(shim_curs,(winid a, int x, int y)) +DECL(shim_putstr,(winid w, int attr, const char *str)) +VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) +VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) +VSTUB(shim_add_menu,(winid a, int b, const ANY_P *c, CHAR_P d, CHAR_P e, int f, const char *h, unsigned int k)) +VSTUB(shim_end_menu,(winid a, const char *b)) +int STUB(shim_select_menu,0,(winid a, int b, MENU_ITEM_P **c)) +char STUB(shim_message_menu,'y',(CHAR_P a, int b, const char *c)) +VSTUB(shim_update_inventory,(void)) +VSTUB(shim_mark_synch,(void)) +VSTUB(shim_wait_synch,(void)) +VSTUB(shim_cliparound,(int a, int b)) +VSTUB(shim_update_positionbar,(char *a)) +DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) +DECL(shim_raw_print,(const char *str)) +VSTUB(shim_raw_print_bold,(const char *a)) +int STUB(shim_nhgetch,0,(void)) +int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) +VSTUB(shim_nhbell,(void)) +int STUB(shim_doprev_message,0,(void)) +char STUB(shim_yn_function,'y',(const char *a, const char *b, CHAR_P c)) +VSTUB(shim_getlin,(const char *a, char *b)) +int STUB(shim_get_ext_cmd,0,(void)) +VSTUB(shim_number_pad,(int a)) +VSTUB(shim_delay_output,(void)) +VSTUB(shim_change_color,(int a, long b, int c)) +VSTUB(shim_change_background,(int a)) +short STUB(set_shim_font_name,0,(winid a, char *b)) +VSTUB(shim_get_color_string,(void)) + +/* other defs that really should go away (they're tty specific) */ +VSTUB(shim_start_screen, (void)) +VSTUB(shim_end_screen, (void)) +VSTUB(shim_preference_update, (const char *a)) +char *STUB(shim_getmsghistory, (char *)"", (BOOLEAN_P a)) +VSTUB(shim_putmsghistory, (const char *a, BOOLEAN_P b)) +VSTUB(shim_status_init, (void)) +VSTUB(shim_status_enablefield, (int a, const char *b, const char *c, BOOLEAN_P d)) +VSTUB(shim_status_update, (int a, genericptr_t b, int c, int d, int e, unsigned long *f)) + + +/* old: | WC_TILED_MAP */ +/* Interface definition, for windows.c */ +struct window_procs shim_procs = { + "shim", + (0 + | WC_ASCII_MAP + | WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN), + (0 +#if defined(SELECTSAVED) + | WC2_SELECTSAVED +#endif +#if defined(STATUS_HILITES) + | WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS + | WC2_RESET_STATUS +#endif + | WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_STATUSLINES), +#ifdef TEXTCOLOR + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ +#else + {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1}, +#endif + shim_init_nhwindows, shim_player_selection, shim_askname, shim_get_nh_event, + shim_exit_nhwindows, shim_suspend_nhwindows, shim_resume_nhwindows, + shim_create_nhwindow, shim_clear_nhwindow, shim_display_nhwindow, + shim_destroy_nhwindow, shim_curs, shim_putstr, genl_putmixed, + shim_display_file, shim_start_menu, shim_add_menu, shim_end_menu, + shim_select_menu, shim_message_menu, shim_update_inventory, shim_mark_synch, + shim_wait_synch, +#ifdef CLIPPING + shim_cliparound, +#endif +#ifdef POSITIONBAR + shim_update_positionbar, +#endif + shim_print_glyph, shim_raw_print, shim_raw_print_bold, shim_nhgetch, + shim_nh_poskey, shim_nhbell, shim_doprev_message, shim_yn_function, + shim_getlin, shim_get_ext_cmd, shim_number_pad, shim_delay_output, +#ifdef CHANGE_COLOR /* the Mac uses a palette device */ + shim_change_color, +#ifdef MAC + shim_change_background, set_shim_font_name, +#endif + shim_get_color_string, +#endif + + /* other defs that really should go away (they're tty specific) */ + shim_start_screen, shim_end_screen, genl_outrip, + shim_preference_update, + shim_getmsghistory, shim_putmsghistory, + shim_status_init, + genl_status_finish, genl_status_enablefield, +#ifdef STATUS_HILITES + shim_status_update, +#else + genl_status_update, +#endif + genl_can_suspend_yes, +}; + +void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { + /* map glyph to character and color */ + // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); + + fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); + fflush(stdout); +} + +void shim_raw_print(const char *str) { + fprintf(stdout, "shim_raw_print: %s\n", str); + fflush(stdout); +} + +void shim_putstr(winid w, int attr, const char *str) { + fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); + fflush(stdout); +} + +#endif /* SHIM_GRAPHICS */ \ No newline at end of file From 1aa053d1d8efee01ddd09ab5fb92f5e20065c271 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 26 Aug 2020 19:22:00 -0700 Subject: [PATCH 136/708] initial libnethack --- .gitignore | 9 +- include/global.h | 11 +- sys/lib/Makefile.dat | 136 ++++ sys/lib/Makefile.src | 1160 +++++++++++++++++++++++++++ sys/lib/Makefile.top | 332 ++++++++ sys/lib/Makefile.utl | 382 +++++++++ sys/lib/hints/include/multiw-1.2020 | 37 + sys/lib/hints/include/multiw-2.2020 | 108 +++ sys/lib/hints/macOS.2020 | 443 ++++++++++ sys/lib/hints/wasm | 153 ++++ sys/lib/libnethackmain.c | 824 +++++++++++++++++++ sys/lib/mkmkfile.sh | 44 + sys/lib/setup.sh | 37 + sys/lib/sysconf | 150 ++++ util/makedefs.c | 8 + 15 files changed, 3831 insertions(+), 3 deletions(-) create mode 100644 sys/lib/Makefile.dat create mode 100644 sys/lib/Makefile.src create mode 100644 sys/lib/Makefile.top create mode 100644 sys/lib/Makefile.utl create mode 100644 sys/lib/hints/include/multiw-1.2020 create mode 100644 sys/lib/hints/include/multiw-2.2020 create mode 100755 sys/lib/hints/macOS.2020 create mode 100644 sys/lib/hints/wasm create mode 100644 sys/lib/libnethackmain.c create mode 100755 sys/lib/mkmkfile.sh create mode 100755 sys/lib/setup.sh create mode 100644 sys/lib/sysconf diff --git a/.gitignore b/.gitignore index 5c64716a3..b9196f2d1 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ Release/ binary/ build/ ipch/ -lib/ +./lib/ Nethack.sln Nethack.sdf Nethack.opensdf @@ -81,3 +81,10 @@ win/share/monthin.txt win/share/objthin.txt win/share/oththin.txt # end of ms-dos + +#libnethack +src/nethack.data +src/nethack.wasm +src/nethack.js +src/wasm-data +src/libnethack.a diff --git a/include/global.h b/include/global.h index 20939108d..8f7ed95a4 100644 --- a/include/global.h +++ b/include/global.h @@ -325,8 +325,15 @@ struct version_info { unsigned long incarnation; /* actual version number */ unsigned long feature_set; /* bitmask of config settings */ unsigned long entity_count; /* # of monsters and objects */ +#ifndef WASM unsigned long struct_sizes1; /* size of key structs */ unsigned long struct_sizes2; /* size of more key structs */ +#else /* WASM */ + /* 'long' in WASM is 4 bytes, which is too small to hold version numbers + * such as: VERSION_SANITY2 */ + unsigned long long struct_sizes1; /* size of key structs */ + unsigned long long struct_sizes2; /* size of more key structs */ +#endif /* !WASM */ }; struct savefile_info { @@ -390,7 +397,7 @@ struct savefile_info { /* PANICTRACE: Always defined for NH_DEVEL_STATUS != NH_STATUS_RELEASED but only for supported platforms. */ -#ifdef UNIX +#if defined(UNIX) && !defined(WASM) #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) /* see end.c */ #ifndef PANICTRACE @@ -405,7 +412,7 @@ struct savefile_info { #if defined(MACOSX) #define PANICTRACE_LIBC #endif -#ifdef UNIX +#if defined(UNIX) && !defined(WASM) /* no popen in WASM */ #define PANICTRACE_GDB #endif diff --git a/sys/lib/Makefile.dat b/sys/lib/Makefile.dat new file mode 100644 index 000000000..a264242ae --- /dev/null +++ b/sys/lib/Makefile.dat @@ -0,0 +1,136 @@ +# NetHack Datafiles Makefile.dat $NHDT-Date: 1596486993 2020/08/03 20:36:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ +# Copyright (c) 2018 by Pasi Kallinen +# NetHack may be freely redistributed. See license for details. + +# Root of source tree: +NHSROOT=.. + +# for Atari +# SHELL=E:/GEMINI2/MUPFEL.TTP +# UUDECODE=uudecode + +VARDAT = bogusmon data engrave epitaph rumors oracles options + +all: $(VARDAT) spec_levs quest_levs + +../util/makedefs: + (cd ../util ; $(MAKE) makedefs) + +../util/tile2x11: + (cd ../util ; $(MAKE) tile2x11) + +../util/tile2beos: + (cd ../util ; $(MAKE) tile2beos) + +../util/tile2bmp: + (cd ../util ; $(MAKE) tile2bmp) + +x11tiles: ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ + ../win/share/other.txt \ + ../win/share/monsters.txt + ../util/tile2x11 ../win/share/monsters.txt ../win/share/objects.txt \ + ../win/share/other.txt \ + -grayscale ../win/share/monsters.txt + +beostiles: ../util/tile2beos ../win/share/monsters.txt \ + ../win/share/objects.txt \ + ../win/share/other.txt + ../util/tile2beos ../win/share/monsters.txt \ + ../win/share/objects.txt \ + ../win/share/other.txt + +nhtiles.bmp: ../util/tile2bmp ../win/share/monsters.txt \ + ../win/share/objects.txt \ + ../win/share/other.txt + ../util/tile2bmp $@ + +NetHack.ad: ../win/X11/NetHack.ad +# handle "#define foo bar" -lines + grep ^#define ../win/X11/NetHack.ad | \ + sed -e 's/^#define/s/g' -e 's/ */ /g' \ + -e 's/$$/ g/g' > NetHack.ad.tmp + grep -v ^#define ../win/X11/NetHack.ad | \ + sed -f NetHack.ad.tmp > NetHack.ad + -rm -f NetHack.ad.tmp + +pet_mark.xbm: ../win/X11/pet_mark.xbm + cp ../win/X11/pet_mark.xbm pet_mark.xbm + +pilemark.xbm: ../win/X11/pilemark.xbm + cp ../win/X11/pilemark.xbm pilemark.xbm + +rip.xpm: ../win/X11/rip.xpm + cp ../win/X11/rip.xpm rip.xpm + +mapbg.xpm: ../win/gnome/mapbg.xpm + cp ../win/gnome/mapbg.xpm mapbg.xpm + +nhsplash.xpm: ../win/share/nhsplash.xpm + cp ../win/share/nhsplash.xpm nhsplash.xpm + +nethack.icns: ../win/share/nhicns.uu + $(UUDECODE) ../win/share/nhicns.uu + +Info.plist: ../win/Qt/Info.pli + cp ../win/Qt/Info.pli Info.plist + +../util/tile2img.ttp: + (cd ../util ; $(MAKE) tile2img.ttp) + +../util/xpm2img.ttp: + (cd ../util ; $(MAKE) xpm2img.ttp) +nh16.img: ../util/tile2img.ttp ../win/share/monsters.txt \ + ../win/share/objects.txt ../win/share/other.txt + ../util/tile2img.ttp nh16.img + +rip.img: ../util/xpm2img.ttp + ../util/xpm2img.ttp ../win/X11/rip.xpm rip.img +title.img: + # cp ../win/gem/title.img title.img + $(UUDECODE) ../win/gem/title.uu + +GEM_RSC.RSC: + # cp ../win/gem/GEM_RSC.RSC GEM_RSC.RSC + $(UUDECODE) ../win/gem/gem_rsc.uu + + +data: data.base ../util/makedefs + ../util/makedefs -d + +rumors: rumors.tru rumors.fal ../util/makedefs + ../util/makedefs -r + +oracles: oracles.txt ../util/makedefs + ../util/makedefs -h + +engrave: engrave.txt ../util/makedefs + ../util/makedefs -s + +epitaph: epitaph.txt ../util/makedefs + ../util/makedefs -s + +bogusmon: bogusmon.txt ../util/makedefs + ../util/makedefs -s + +# note: 'options' should have already been made when include/date.h was created +options: ../util/makedefs + ../util/makedefs -v + +# these don't actually do anything useful now that levcomp and dngcomp are gone +spec_levs: + touch spec_levs +quest_levs: + touch quest_levs + +# gitinfo.txt is optionally made by src/Makefile when creating date.h +# spec_levs and quest_levs are empty marker files to control 'make' actions +clean: + -rm -f spec_levs quest_levs gitinfo.txt + +spotless: clean + -rm -f nhdat $(VARDAT) \ + x11tiles pet_mark.xbm pilemark.xbm rip.xpm mapbg.xpm \ + rip.img GEM_RSC.RSC title.img nh16.img NetHack.ad \ + nhsplash.xpm nhtiles.bmp beostiles + +#eof# diff --git a/sys/lib/Makefile.src b/sys/lib/Makefile.src new file mode 100644 index 000000000..4a947a0c5 --- /dev/null +++ b/sys/lib/Makefile.src @@ -0,0 +1,1160 @@ +# NetHack Makefile. +# NetHack 3.7 Makefile.src $NHDT-Date: 1597704252 2020/08/17 22:44:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ +# Copyright (c) 2018 by Pasi Kallinen +# NetHack may be freely redistributed. See license for details. + +# Root of source tree: +NHSROOT=.. + +# newer makes predefine $(MAKE) to 'make' and do smarter processing of +# recursive make calls if $(MAKE) is used +# these makes allow $(MAKE) to be overridden by the environment if someone +# wants to (or has to) use something other than the standard make, so we do +# not want to unconditionally set $(MAKE) here +# +# unfortunately, some older makes do not predefine $(MAKE); if you have one of +# these, uncomment the following line +# (you will know that you have one if you get complaints about being unable +# to find 'makedefs') +# MAKE = make + +# This makefile replaces the previous Makefile.unix, Makefile.xenix, +# Makefile.3B2, Makefile.att, and Makefile.tos. +# Set SYSTEM to one of: +# 'Sysunix' -- generic UNIX +# 'Sys3B2' -- AT&T 3B2, 3B5, etc. +# 'Sysatt' -- AT&T UNIXPC, 7300, 3B1 +# 'SysV-AT' -- Microport 286 UNIX (put -DDUMB in CFLAGS) +# 'Systos' -- Atari +# 'SysBe' -- BeOS +SYSTEM = Sysunix + +# +# Make sure that your bourne shell is specified here, as you have to spawn +# some of the commands (eg. depend) in bourne shell for them to work. +# +# For Systos users compiling on the ST, you'll either need a bourne shell +# clone or you'll need to do make depend, etc. by hand. In either case, +# the line below probably needs changing +SHELL=/bin/sh +# for Atari +# SHELL=E:/GEMINI2/MUPFEL.TTP + +# Usually, the C compiler driver is used for linking: +#LINK=$(CC) + +# Pick the SYSSRC and SYSOBJ lines corresponding to your desired operating +# system. +# +# for libnethack +SYSSRC = ../sys/lib/libnethackmain.c \ + ../sys/share/ioctl.c ../sys/share/unixtty.c ../sys/unix/unixunix.c ../sys/unix/unixres.c +SYSOBJ = libnethackmain.o \ + ioctl.o unixtty.o unixunix.o unixres.o +#SYSSRC = ../sys/lib/libnethackmain.c +#SYSOBJ = libnethackmain.o + +# +# for Systos +# SYSSRC = ../sys/atari/tos.c ../sys/share/pcmain.c ../sys/share/pcsys.c \ +# ../sys/share/pctty.c ../sys/share/pcunix.c +# SYSOBJ = tos.o pcmain.o pcsys.o pctty.o pcunix.o +# +# for BeOS +#SYSSRC = ../sys/be/bemain.c ../sys/share/unixtty.c ../sys/share/ioctl.c +#SYSOBJ = bemain.o unixtty.o ioctl.o + + +# if you are using gcc as your compiler: +# uncomment the CC definition below if it's not in your environment +# if you get setcgtty() warnings during execution, you are feeding gcc +# a non-ANSI -- either run fixincludes on it or use +# -traditional in CFLAGS +# CC = gcc +# +# For Bull DPX/2 systems at B.O.S. 2.0 or higher use the following: +# +# CC = gcc -ansi -D_BULL_SOURCE -D_XOPEN_SOURCE -D_POSIX_SOURCE +# +# If you are using GCC 2.2.2 or higher on a DPX/2, just use: +# +# CC = gcc -ansi +# +# For HP/UX 10.20 with GCC: +# CC = gcc -D_POSIX_SOURCE +# +# For cross-compiling, eg. with gcc on Linux (see also CXX further down): +# CC = arm-linux-gcc +# +# +# if you're debugging and want gcc to check as much as possible, use: +# CC = gcc -W -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wcast-qual -Wwrite-strings -DGCC_WARN + +# flags may have to be changed as required +# flags for 286 Xenix: +# CFLAGS = -Ml2t16 -O -LARGE -I../include +# LFLAGS = -Ml -F 4000 -SEG 512 + +# flags for 286 Microport SysV-AT +# CFLAGS = -DDUMB -Ml -I../include +# LFLAGS = -Ml + +# flags for Atari gcc (3.2.1) +# CFLAGS = -O -I../include +# LFLAGS = -s +# flags for Atari gcc (3.3) +# CFLAGS = -mshort -O2 -fomit-frame-pointer -I../include +# LFLAGS = -mshort -s + +# flags for AIX 3.1 cc on IBM RS/6000 to define +# a suitable subset of standard libraries +# (note that there is more info regarding the "-qchars=signed" +# switch in file Install.unx note 8) +# CFLAGS = -D_NO_PROTO -D_XOPEN_SOURCE -O -I../include -qchars=signed +# +# Some of our subroutines are complex enough that this is required for full +# optimization under AIX 3.2 (I don't know about 3.1). +# +# CFLAGS = -D_NO_PROTO -D_XOPEN_SOURCE -D_ALL_SOURCE -O -I../include -qchars=signed -qmaxmem=5000 + +# flags for A/UX 2.01 using native cc or c89 +# gcc predefines AUX so that's not needed there +# Remember to use -lcurses for WINLIB below ! +# CFLAGS = -ZS -D_POSIX_SOURCE -O -I../include -DAUX + +# flags for IRIX 4.0.x using native cc +# The include files are __STDC__, but have bugs involving const +# CFLAGS = -O -I../include -D__STDC__ -Dconst= -woff 100,293 +# LFLAGS = -s + +# flags for BSD/OS 2.0 +# CFLAGS = -O -I../include -I/usr/X11/include +# LFLAGS = -L/usr/X11/lib + +# flags for Linux +# compile normally +# CFLAGS = -O2 -fomit-frame-pointer -I../include +# LFLAGS = -L/usr/X11R6/lib +# 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 + +# flags for BeOS +# on a Mac/BeBox: +#CC = mwcc +#CFLAGS = -r -I../include +#LINK = mwld +#LFLAGS = -map nethack.xMAP +# on Intel: +#CFLAGS = -O -I../include +#LINK = gcc +#LFLAGS = -Xlinker -soname=_APP_ + +# Compile with PDCurses installed in a separate directory that doesn't +# conflict with the system curses/ncurses library +#CFLAGS = -O -I../include -I/usr/local/include/pdcurses +# Same as above, but for XCurses +#CFLAGS = -O -DXCURSES -I../include -I/usr/local/include/pdcurses +# Compile against system curses library, such as ncurses +#CFLAGS = -O -I../include + +# files in ../win/X11 (relative to src) are passed $(CFLAGS) $(X11CFLAGS) +# and by default will find in /usr/include/X11/foo.h; +# can be overridden via hints; post-10.7 OSX with XQuartz uses +# X11CFLAGS=-I/opt/X11/include to find in /opt/X11/include/X11/foo.h +#X11CFLAGS= + +# Only used for the Gnome interface. +# When including the Gnome interface, you need to include gnome specific +# directories. The ones given below is the usual spot for linux systems. +# The paths are for glibconfig.h and gnomesupport.h respectively. +# +#GNOMEINC=-I/usr/lib/glib/include -I/usr/lib/gnome-libs/include -I../win/gnome + +# flags for debugging: +# CFLAGS = -g -I../include + +#CFLAGS = -O -I../include +#LFLAGS = + +# 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 +# the C++ libraries linked in. +CXXFLAGS = $(CFLAGS) -I. -I$(QTDIR)/include $(QTCXXFLAGS) +CXX ?= g++ +MOC ?= moc +#LINK=g++ +# For cross-compiling, eg. with gcc on Linux (see also CC further up): +#CXX=arm-linux-g++ +#LINK=arm-linux-gcc + +# we specify C preprocessor flags via CFLAGS; files built with default rules +# might include $(CPPFLAGS) which could get a value from user's environment; +# we avoid that by forcing it empty rather than by overriding default rules +CPPFLAGS = + +# if requested, setup cross-compiler for WASM +ifdef WANT_WASM +CC=$(EMCC) +AR=$(EMAR) +RANLIB=$(EMRANLIB) +CFLAGS+=$(EMCC_CFLAGS) +SYSCFLAGS=$(EMCC_CFLAGS) +endif # WANT_WASM + +# include path for nethack headers +CFLAGS+=-I../include +# compile with library options +CFLAGS+=-DLIBNH +# use "shim" windowing system +CFLAGS+=-DNOTTYGRAPHICS -DSHIM_GRAPHICS -DDEFAULT_WINDOW_SYS=\"shim\" + +# file for regular expression matching +REGEXOBJ = posixregex.o +#REGEXOBJ = pmatchregex.o +#REGEXOBJ = cppregex.o + +# Set the WINSRC, WINOBJ, and WINLIB lines to correspond to your desired +# combination of windowing systems. Also set windowing systems in config.h. +# Note that if you are including multiple tiled window systems, you don't +# want two copies of tile.o, so comment out all but the first. +# +# files for a straight tty port using no native windowing system +WINTTYSRC = ../win/tty/getline.c ../win/tty/termcap.c ../win/tty/topl.c \ + ../win/tty/wintty.c +WINTTYOBJ = getline.o termcap.o topl.o wintty.o +# +# Files for curses interface +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 = cursmain.o curswins.o cursmisc.o cursdial.o cursstat.o \ + cursinit.o cursmesg.o 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 \ + ../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 = Window.o dialogs.o winX.o winmap.o winmenu.o winmesg.o \ + winmisc.o winstat.o wintext.o winval.o tile.o +# +# Files for a Qt 3 port (renamed since nethack 3.6.x) +# +#WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ +# ../win/Qt3/qt3tableview.cpp +#WINQT3OBJ = qt3_win.o qt3_clust.o qt3tableview.o tile.o +# empty values for 'make depend' +WINQT3SRC = +WINQT3OBJ = + +# +# Files for a Qt 4 or 5 port +# +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 \ + ../win/Qt/qt_map.cpp ../win/Qt/qt_menu.cpp ../win/Qt/qt_msg.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 +WINQTOBJ = qt_bind.o qt_click.o qt_clust.o qt_delay.o qt_glyph.o qt_icon.o \ + qt_inv.o qt_key.o qt_line.o qt_main.o qt_map.o qt_menu.o qt_msg.o \ + qt_plsel.o qt_rip.o qt_set.o qt_stat.o qt_str.o qt_streq.o qt_svsel.o \ + qt_win.o qt_xcmd.o qt_yndlg.o tile.o +# +# Files for a Gnome port +# +#WINGNOMESRC = ../win/gnome/gnaskstr.c ../win/gnome/gnbind.c \ +# ../win/gnome/gnglyph.c ../win/gnome/gnmain.c ../win/gnome/gnmap.c \ +# ../win/gnome/gnmenu.c ../win/gnome/gnmesg.c ../win/gnome/gnopts.c \ +# ../win/gnome/gnplayer.c ../win/gnome/gnsignal.c \ +# ../win/gnome/gnstatus.c ../win/gnome/gntext.c ../win/gnome/gnyesno.c \ +# ../win/gnome/gnworn.c +#WINGNOMEOBJ = gnaskstr.o gnbind.o gnglyph.o gnmain.o gnmap.o gnmenu.o \ +# gnmesg.o gnopts.o gnplayer.o gnsignal.o gnstatus.o gntext.o \ +# gnyesno.o gnworn.o tile.o +# empty values for 'make depend' +WINGNOMESRC = +WINGNOMEOBJ = + +# +# Files for a Gem port +#WINGEMSRC = ../win/gem/wingem.c ../win/gem/wingem1.c ../win/gem/load_img.c \ +# ../win/gem/gr_rect.c tile.c +#WINGEMOBJ = wingem.o wingem1.o load_img.o gr_rect.o tile.o +# empty values for 'make depend' +WINGEMSRC = +WINGEMOBJ = + +# +# Files for Shim windowing interface for libnethack -- doesn't do anything, just passes along the API calls to the library +# +WINSHIMSRC = ../win/shim/winshim.c +WINSHIMOBJ = winshim.o + +# +# Files for a BeOS InterfaceKit port -- not ready for prime time +WINBESRC = +WINBEOBJ = +#WINBESRC = ../win/BeOS/winbe.cpp ../win/BeOS/NHWindow.cpp \ +# ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp tile.c +#WINBEOBJ = winbe.o NHWindow.o NHMenuWindow.o NHMapWindow.o tile.o +# +# +#WINSRC = $(WINTTYSRC) +#WINOBJ = $(WINTTYOBJ) +# +# Curses - Karl Garrison, Tangles +#WINSRC = $(WINCURSESSRC) +#WINOBJ = $(WINCURSESOBJ) +# +# on some systems the termcap library is in -ltermcap or -lcurses +# on 386 Xenix, the -ltermlib tputs() seems not to work; use -lcurses instead +# Sysatt uses shared library in lieu of this option +# Systos needs -lcurses16 if you use -mshort +# AIX 3.1 on RS/6000 likes -lcurses if TERMINFO defined in unixconf.h +# and -ltermcap otherwise +# Linux uses -lncurses (newer) or -ltermcap (older) +# Be uses -ltermcap +# +# libraries for tty ports +# WINTTYLIB = -ltermcap +# WINTTYLIB = -lcurses +# WINTTYLIB = -lcurses16 +# WINTTYLIB = -lncurses +#WINTTYLIB = -ltermlib +# +# libraries for X11 +# If USE_XPM is defined in config.h, you will also need -lXpm here. +#WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 +# WINX11LIB = -lXaw -lXmu -lXt -lX11 +# WINX11LIB = -lXaw -lXmu -lXext -lXt -lXpm -lX11 -lm +# WINX11LIB = -lXaw -lXmu -lXpm -lXext -lXt -lX11 -lSM -lICE -lm # BSD/OS 2.0 +# +# +# libraries for Qt 3 +WINQT3LIB = -L$(QTDIR)/lib -lqt +# +# libraries for Qt 4 +WINQT4LIB = `pkg-config QtGui --libs` +# +# libraries for Qt 5 (use with WINQTSRC and WINQTOBJ) +WINQT5LIB = `pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs` +# +# libraries for KDE (with Qt) +WINKDELIB = -lkdecore -lkdeui -lXext +# +# libraries for Gnome +WINGNOMELIB = -lgnomeui -lgnome -lart_lgpl -lgtk -lgdk -lpopt +# +# libraries for Gem port +WINGEMLIB = -le_gem -lgem +# +# libraries for BeOS +WINBELIB = -lbe +# +# libraries for curses port +# link with ncurses +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 +#WINCURSESLIB = -L/usr/local/lib/pdcurses -lXCurses -lXawM -lXmu -lXext -lXt -lX11 +# +#WINLIB = $(WINTTYLIB) +# +# For Curses +#WINLIB = $(WINCURSESLIB) +# +# any other strange libraries your system needs (for Sysunix only -- the more +# specialized targets should already be right) +# +# on HP-UX 8.x, the malloc(3x) routines in libmalloc.a seem to align things +# better than the malloc(3) ones in libc.a +# LIBS = -lmalloc +# +# DPX/2's also use the malloc(3x) routines. In addition, if you are building +# for X11, you must include libinet.a. +# LIBS = -lmalloc -linet +# +# Linux NetHack uses some bsd style ioctl functions, thus it is necessary to +# use the bsd libs. (Only if still compiling as BSD in unixconf.h; recent +# versions compile fine using SYSV without this.) +# LIBS = -lbsd +# +# for CYGWIN32 aka cygwin 1.1.1 +# LIBS = -lcygwin +# +# Solaris 2.x seems to work with the following +# LIBS = -lsocket -lnsl +# +# IRIX 4.0.x needs -lsun if NIS (YP) is being used for passwd file lookup +# LIBS = -lsun +# +# If ZLIB_COMP is defined in config.h this is necessary to link with zlib. +# LIBS = -lz +# +# LIBS = + +# make libnethack +LIBNH_TARGET=libnethack.a +WASM_TARGET=nethack.js + +ifdef WANT_WASM +MAIN_TARGET=$(WASM_TARGET) +else +MAIN_TARGET=$(LIBNH_TARGET) +endif + +# if you defined RANDOM in unixconf.h since your system did not come +# with a reasonable random number generator +# RANDOBJ = random.o +RANDOBJ = + + +# used by `make depend' to reconstruct this Makefile; you shouldn't need this +AWK = nawk + +# 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 +# it doesn't already exist; to skip it completely, create an empty file +# of that name and also set this to 0; there shouldn't be any need to +# skip it--if nethack's sources don't reside in a git repository than +# the script which creates that file will fail benignly and 'makedefs -v' +# will proceed without it +GITINFO=1 + +# if you change this to 1, feedback while building will omit -Dthis -Wthat +# -Isomewhere so that each file being compiled is listed on one short line; +# it requires support for '$<' in rules with more than one prerequisite +# (rather than just in suffix default rule), such as is implemented by +# gnu make and others which have picked up its extensions; +# allowed values are 0, 1, and empty (which behaves like 0) +QUIETCC=0 + +# ---------------------------------------- +# +# Nothing below this line should have to be changed. +# +# Other things that have to be reconfigured are in config.h, +# {unixconf.h, pcconf.h}, and possibly system.h + +# Verbosity definitions, begin +# Set QUIETCC=1 above to output less feedback while building. +# CC and CXX obey verbosity, LD and LINK don't. +# AT is @ when not verbose, empty otherwise +ACTUAL_CC := $(CC) +ACTUAL_CXX := $(CXX) +ACTUAL_LD := $(LD) +ACTUAL_LINK := $(LINK) + +CC_V0 = $(ACTUAL_CC) +CC_V = $(CC_V0) +CC_V1 = @echo "[CC] $<"; $(ACTUAL_CC) +CC = $(CC_V$(QUIETCC)) + +CXX_V0 = $(ACTUAL_CXX) +CXX_V = $(CXX_V0) +CXX_V1 = @echo "[CXX] $<"; $(ACTUAL_CXX) +CXX = $(CXX_V$(QUIETCC)) + +# LD and LINK might be based on invoking CC and may not be able to substitute +# for QUIETCC, so feedback from them is handled differently (via $AT) +LD = $(ACTUAL_LD) +LINK = $(ACTUAL_LINK) + +AT_V0 := +AT_V := $(AT_V0) +AT_V1 := @ +AT = $(AT_V$(QUIETCC)) +# Verbosity, end + +MAKEDEFS = ../util/makedefs + +# -lm required by lua +LUALIB = ../lib/lua/liblua.a -lm + +# timestamp files to reduce `make' overhead and shorten .o dependency lists +CONFIG_H = ../src/config.h-t +HACK_H = ../src/hack.h-t + +# all .c that are part of the main NetHack program and are not operating- or +# windowing-system specific +HACKCSRC = allmain.c alloc.c apply.c artifact.c attrib.c ball.c bones.c \ + botl.c cmd.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 eat.c end.c engrave.c exper.c explode.c extralev.c \ + files.c fountain.c hack.c hacklib.c \ + insight.c invent.c isaac64.c light.c \ + lock.c mail.c makemon.c mapglyph.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 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 restore.c \ + rip.c rnd.c role.c rumors.c save.c sfstruct.c \ + shk.c shknam.c sit.c sounds.c \ + sp_lev.c spell.c steal.c steed.c symbols.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 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 \ + ../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/libnethackmain.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 = vis_tab.c #tile.c + +# all windowing-system-dependent .c (for dependencies and such) +WINCSRC = $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINGNOMESRC) $(WINGEMSRC) $(WINSHIMSRC) +# all windowing-system-dependent .cpp (for dependencies and such) +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 \ + ../win/chain/wc_trace.c +CHAINOBJ = wc_chainin.o wc_chainout.o wc_trace.o + +# .c files for this version (for date.h) +VERSOURCES = $(HACKCSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) + +WINSRC=$(WINSHIMSRC) +WINOBJ=$(WINSHIMOBJ) +# .c files for all versions using this Makefile (for lint and tags) +CSOURCES = $(HACKCSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC) + + +# all .h files except date.h, onames.h, pm.h, and vis_tab.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 \ + color.h config.h config1.h context.h coord.h decl.h \ + display.h dlb.h dungeon.h engrave.h extern.h flag.h fnamesiz.h \ + func_tab.h global.h hack.h lint.h mextra.h mfndpos.h \ + micro.h mkroom.h \ + monattk.h mondata.h monflag.h monst.h monsym.h obj.h objclass.h \ + optlist.h patchlevel.h pcconf.h permonst.h prop.h rect.h \ + region.h rm.h sp_lev.h spell.h sys.h system.h tcap.h timeout.h \ + tradstdc.h trampoli.h trap.h unixconf.h vision.h vmsconf.h \ + wintty.h wincurs.h winX.h winprocs.h wintype.h you.h youprop.h + +HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h dgn_file.h + +# the following .o's _must_ be made before any others (for makedefs) +FIRSTOBJ = monst.o objects.o + +HOBJ = $(FIRSTOBJ) allmain.o alloc.o apply.o artifact.o attrib.o ball.o \ + bones.o botl.o cmd.o dbridge.o decl.o detect.o dig.o display.o dlb.o \ + do.o do_name.o do_wear.o dog.o dogmove.o dokick.o dothrow.o \ + drawing.o dungeon.o eat.o end.o engrave.o exper.o explode.o \ + extralev.o files.o fountain.o hack.o hacklib.o \ + insight.o invent.o isaac64.o \ + light.o lock.o mail.o makemon.o mapglyph.o mcastu.o mdlib.o mhitm.o \ + mhitu.o minion.o mklev.o mkmap.o mkmaze.o mkobj.o mkroom.o mon.o \ + mondata.o monmove.o mplayer.o mthrowu.o muse.o music.o \ + nhlua.o nhlsel.o nhlobj.o o_init.o objnam.o options.o \ + pager.o pickup.o pline.o polyself.o potion.o pray.o priest.o \ + quest.o questpgr.o read.o rect.o region.o restore.o rip.o rnd.o \ + role.o rumors.o save.o sfstruct.o \ + shk.o shknam.o sit.o sounds.o sp_lev.o spell.o symbols.o sys.o \ + steal.o steed.o teleport.o timeout.o topten.o track.o trap.o u_init.o \ + uhitm.o vault.o vision.o vis_tab.o weapon.o were.o wield.o windows.o \ + wizard.o worm.o worn.o write.o zap.o \ + $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) version.o +# the .o files from the HACKCSRC, SYSSRC, and WINSRC lists + +# first target is also the default target for 'make' without any arguments +all: $(MAIN_TARGET) + @echo "Done building main target:" $(MAIN_TARGET) + @echo "" + +libnh: $(LIBNH_TARGET) + @echo "libnethack done." + +wasm: $(WASM_TARGET) + @echo "nethack.js done." + +$(LIBNH_TARGET): $(HOBJ) Makefile + -rm $@ + $(AR) $(LIBNH_TARGET) $(HOBJ) ../lib/lua/liblua.a + +$(WASM_TARGET): $(HOBJ) Makefile $(WASM_DATA_DIR) + -rm $@ + $(EMCC) $(EMCC_LFLAGS) $(EMCC_CFLAGS) -o $(WASM_TARGET) $(HOBJ) ../lib/lua/liblua.a + +$(WASM_DATA_DIR): + -mkdir -p $(WASM_DATA_DIR) + touch $(WASM_DATA_DIR)/perm + touch $(WASM_DATA_DIR)/record + touch $(WASM_DATA_DIR)/logfile + touch $(WASM_DATA_DIR)/xlogfile + ( cd ..; $(MAKE) dofiles-dlb ) + cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf + +Sysunix: $(HOBJ) Makefile + @echo "Linking $(GAME)." + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) $(LUALIB) + @touch Sysunix + +Sys3B2: $(HOBJ) Makefile + @echo "Linking $(GAME)." + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) -lmalloc + @touch Sys3B2 + +Sysatt: $(HOBJ) Makefile + @echo "Loading $(GAME)." + $(AT)$(LD) $(LFLAGS) /lib/crt0s.o /lib/shlib.ifile -o $(GAME) $(HOBJ) \ + $(LUALIB) + @touch Sysatt + +Systos: $(HOBJ) Makefile + @echo "Linking $(GAME)." + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) + @touch Systos + +SysV-AT: DUMB.Setup $(HOBJ) Makefile + @echo "Linking $(GAME)." + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) + @touch SysV-AT + +SysBe: $(HOBJ) Makefile + @echo "Linking $(GAME)." + $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) $(LUALIB) + @xres -o $(GAME) ../win/BeOS/nethack.rsrc + @mimeset -f $(GAME) + @touch SysBe + +DUMB.Setup: ../include/extern.h + cp ../include/extern.h ../include/extern.h.BAK + cat ../include/extern.h | \ + sed -e '/^E\ int\ /!b' \ + -e '/[^;/ ]$$/N' \ + -e '/[(][*]occupation[)]/b' \ + -e '/[(][*]afternmv[)]/b' \ + -e '/float_down/b' \ + -e '/done1/b' \ + -e '/identify/b' \ + -e '/Hear_again/b' \ + -e '/hangup/b' \ + -e 's/^\(.*\)$$/\/\* \1 \/\*\*\//' | \ + sed -e '/^E\ void\ /!b' \ + -e '/[^;/ ]$$/N' \ + -e 's/^\(.*\)$$/\/\* \1 \/\*\*\//' \ + >../include/extern.DUMB + cp ../include/extern.DUMB ../include/extern.h + @touch DUMB.Setup + +../lib/lua/liblua.a ../include/nhlua.h: + @( cd .. ; $(MAKE) lua_support ) + +# dependencies for makedefs and its outputs, which the util +# Makefile is responsible for keeping up to date +# + +# special rules, to force update of makedefs, real dependencies should be +# below in the 'make depend' output. +monst.o: + $(CC) $(CFLAGS) -c monst.c + @rm -f $(MAKEDEFS) + +objects.o: + $(CC) $(CFLAGS) -c objects.c + @rm -f $(MAKEDEFS) + +# Qt 3 windowport meta-object-compiler output +qt3_kde0.moc: ../win/Qt3/qt3_kde0.h + $(QTDIR)/bin/moc -o qt3kde0.moc ../win/Qt3/qt3_kde0.h +qt3_win.moc: ../win/Qt3/qt3_win.h + $(QTDIR)/bin/moc -o qt3win.moc ../win/Qt3/qt3_win.h +qt3tableview.moc: ../win/Qt3/qt3tableview.h + $(QTDIR)/bin/moc -o qt3tableview.moc ../win/Qt/qt3tableview.h + +# Qt 4 windowport meta-object-compiler output +qt_kde0.moc : ../win/Qt/qt_kde0.h + $(QTDIR)/bin/$(MOC) -o qt_kde0.moc ../win/Qt/qt_kde0.h +qt_main.moc : ../win/Qt/qt_main.h + $(QTDIR)/bin/$(MOC) -o qt_main.moc ../win/Qt/qt_main.h +qt_map.moc : ../win/Qt/qt_map.h + $(QTDIR)/bin/$(MOC) -o qt_map.moc ../win/Qt/qt_map.h +qt_menu.moc : ../win/Qt/qt_menu.h + $(QTDIR)/bin/$(MOC) -o qt_menu.moc ../win/Qt/qt_menu.h +qt_msg.moc : ../win/Qt/qt_msg.h + $(QTDIR)/bin/$(MOC) -o qt_msg.moc ../win/Qt/qt_msg.h +qt_plsel.moc : ../win/Qt/qt_plsel.h + $(QTDIR)/bin/$(MOC) -o qt_plsel.moc ../win/Qt/qt_plsel.h +qt_set.moc : ../win/Qt/qt_set.h + $(QTDIR)/bin/$(MOC) -o qt_set.moc ../win/Qt/qt_set.h +qt_stat.moc : ../win/Qt/qt_stat.h + $(QTDIR)/bin/$(MOC) -o qt_stat.moc ../win/Qt/qt_stat.h +qt_xcmd.moc : ../win/Qt/qt_xcmd.h + $(QTDIR)/bin/$(MOC) -o qt_xcmd.moc ../win/Qt/qt_xcmd.h +qt_yndlg.moc : ../win/Qt/qt_yndlg.h + $(QTDIR)/bin/$(MOC) -o qt_yndlg.moc ../win/Qt/qt_yndlg.h + +# build monst.o and objects.o before executing '$(MAKE) makedefs' +$(MAKEDEFS): $(FIRSTOBJ) \ + ../util/makedefs.c ../src/mdlib.c $(CONFIG_H) \ + ../include/permonst.h \ + ../include/objclass.h ../include/monsym.h \ + ../include/artilist.h ../include/dungeon.h ../include/obj.h \ + ../include/monst.h ../include/you.h ../include/flag.h \ + ../include/dlb.h ../include/patchlevel.h + @( cd ../util ; $(MAKE) makedefs ) + +# Source files created by 'makedefs' at build time. +# Each is given an artificial dependency upon the one before +# so that parallel makes will have to build them sequentially. +# (More for documentation than effect; 'make' should know not +# to try to build $(MAKEDEFS) for bar.h while it is in the +# process of building it for foo.h.) +../include/onames.h: $(MAKEDEFS) + @( cd ../util ; $(MAKE) ../include/onames.h ) +../include/pm.h: $(MAKEDEFS) ../include/onames.h + @( cd ../util ; $(MAKE) ../include/pm.h ) +../include/vis_tab.h: $(MAKEDEFS) ../include/pm.h + @( cd ../util ; $(MAKE) ../include/vis_tab.h ) +# makedefs -z makes both vis_tab.h and vis_tab.c, but writes the .h first +vis_tab.c: ../include/vis_tab.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) ../src/tile.c ) + +../win/gnome/gn_rip.h: ../win/X11/rip.xpm + cp ../win/X11/rip.xpm ../win/gnome/gn_rip.h + +sfstruct.o: sfstruct.c $(HACK_H) + +# 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. +# Do NOT include ../dat/gitinfo.txt as either a prerequisite or target. +# 'makedefs -v' processes it when present and ignores it if not. +# +# hack.h depends on makedefs' output, so we know makedefs will be +# up to date before being executed +../include/date.h: $(VERSOURCES) $(HACK_H) + -$(SHELL) ../sys/unix/gitinfo.sh $(GITINFO) #before 'makedefs -v' + ../util/makedefs -v + +lint: +# lint cannot have -p here because (i) capitals are meaningful: +# [Ww]izard, (ii) identifiers may coincide in the first six places: +# doweararm() versus dowearring(). +# _flsbuf comes from , a bug in the system libraries. + @echo lint -axbh -DLINT ... + @lint -axbh -I../include -DLINT $(CSOURCES) | sed '/_flsbuf/d' + + +tags: $(CSOURCES) + @echo ctags -tw ... + @ctags -tw $(CSOURCES) + @( cd ../include ; ctags -tw $(HSOURCES) ) + @( cd ../util ; $(MAKE) tags ) + +clean: + -rm -f *.o $(HACK_H) $(CONFIG_H) $(WASM_TARGET) $(WASM_TARGET:.js=.wasm) $(LIBNH_TARGET) + -rm -rf $(WASM_DATA_DIR) + +spotless: clean + -rm -f a.out core $(GAME) Sys* + -rm -f ../lib/lua/liblua.a ../include/nhlua.h + -rm -f ../include/date.h ../include/onames.h ../include/pm.h + -rm -f ../include/vis_tab.h vis_tab.c tile.c *.moc + -rm -f ../win/gnome/gn_rip.h + + +depend: ../sys/unix/depend.awk \ + $(SYSCSRC) $(WINCSRC) $(SYSCXXSRC) $(WINCXXSRC) \ + $(CHAINSRC) $(GENCSRC) $(HACKCSRC) + $(AWK) -f ../sys/unix/depend.awk ../include/*.h ../win/*/*.h \ + $(SYSCSRC) $(WINCSRC) $(SYSCXXSRC) $(WINCXXSRC) \ + $(CHAINSRC) $(GENCSRC) $(HACKCSRC) >makedep + @echo '/^# DO NOT DELETE THIS LINE OR CHANGE ANYTHING BEYOND IT/+2,$$d' >eddep + @echo '$$r makedep' >>eddep + @echo 'w' >>eddep + @cp Makefile Makefile.bak + ed - Makefile < eddep + @rm -f eddep makedep + @echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile + @echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile + @echo '# see make depend above' >> Makefile + - diff Makefile.bak Makefile + @rm -f Makefile.bak + +# DO NOT DELETE THIS LINE OR CHANGE ANYTHING BEYOND IT + +# config.h timestamp +$(CONFIG_H): ../include/config.h ../include/config1.h ../include/patchlevel.h \ + ../include/tradstdc.h ../include/global.h ../include/coord.h \ + ../include/vmsconf.h ../include/system.h ../include/nhlua.h \ + ../include/unixconf.h ../include/pcconf.h ../include/micro.h \ + ../include/ntconf.h ../include/fnamesiz.h + touch $(CONFIG_H) +# hack.h timestamp +$(HACK_H): ../include/hack.h $(CONFIG_H) ../include/lint.h ../include/align.h \ + ../include/dungeon.h ../include/monsym.h ../include/mkroom.h \ + ../include/objclass.h ../include/youprop.h ../include/prop.h \ + ../include/permonst.h ../include/monattk.h \ + ../include/monflag.h ../include/mondata.h ../include/pm.h \ + ../include/wintype.h ../include/context.h ../include/rm.h \ + ../include/botl.h ../include/rect.h ../include/region.h \ + ../include/decl.h ../include/quest.h ../include/spell.h \ + ../include/color.h ../include/obj.h ../include/engrave.h \ + ../include/you.h ../include/attrib.h ../include/monst.h \ + ../include/mextra.h ../include/skills.h ../include/onames.h \ + ../include/timeout.h ../include/trap.h ../include/flag.h \ + ../include/vision.h ../include/display.h ../include/winprocs.h \ + ../include/sys.h ../include/wintty.h ../include/trampoli.h + touch $(HACK_H) +# +pcmain.o: ../sys/share/pcmain.c $(HACK_H) ../include/dlb.h + $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcmain.c +pcsys.o: ../sys/share/pcsys.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcsys.c +pctty.o: ../sys/share/pctty.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/pctty.c +pcunix.o: ../sys/share/pcunix.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcunix.c +pmatchregex.o: ../sys/share/pmatchregex.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/pmatchregex.c +posixregex.o: ../sys/share/posixregex.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/posixregex.c +random.o: ../sys/share/random.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/random.c +ioctl.o: ../sys/share/ioctl.c $(HACK_H) ../include/tcap.h + $(CC) $(CFLAGS) -c -o $@ ../sys/share/ioctl.c +unixtty.o: ../sys/share/unixtty.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/share/unixtty.c +libnethackmain.o: ../sys/lib/libnethackmain.c $(HACK_H) ../include/dlb.h + $(CC) $(CFLAGS) -c -o $@ ../sys/lib/libnethackmain.c +unixunix.o: ../sys/unix/unixunix.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixunix.c +unixres.o: ../sys/unix/unixres.c $(CONFIG_H) + $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixres.c +getline.o: ../win/tty/getline.c $(HACK_H) ../include/func_tab.h + $(CC) $(CFLAGS) -c -o $@ ../win/tty/getline.c +termcap.o: ../win/tty/termcap.c $(HACK_H) ../include/tcap.h + $(CC) $(CFLAGS) -c -o $@ ../win/tty/termcap.c +topl.o: ../win/tty/topl.c $(HACK_H) ../include/tcap.h + $(CC) $(CFLAGS) -c -o $@ ../win/tty/topl.c +wintty.o: ../win/tty/wintty.c $(HACK_H) ../include/dlb.h ../include/tcap.h + $(CC) $(CFLAGS) -c -o $@ ../win/tty/wintty.c +cursmain.o: ../win/curses/cursmain.c $(HACK_H) ../include/wincurs.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursmain.c +curswins.o: ../win/curses/curswins.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/curswins.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/curswins.c +cursmisc.o: ../win/curses/cursmisc.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursmisc.h ../include/func_tab.h ../include/dlb.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursmisc.c +cursdial.o: ../win/curses/cursdial.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursdial.h ../include/func_tab.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursdial.c +cursstat.o: ../win/curses/cursstat.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursstat.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursstat.c +cursinit.o: ../win/curses/cursinit.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursinit.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursinit.c +cursmesg.o: ../win/curses/cursmesg.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursmesg.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursmesg.c +cursinvt.o: ../win/curses/cursinvt.c $(HACK_H) ../include/wincurs.h \ + ../win/curses/cursinvt.h + $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursinvt.c +Window.o: ../win/X11/Window.c ../include/xwindowp.h ../include/xwindow.h \ + $(CONFIG_H) ../include/lint.h ../include/winX.h \ + ../include/color.h ../include/wintype.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/Window.c +dialogs.o: ../win/X11/dialogs.c $(CONFIG_H) ../include/lint.h \ + ../include/winX.h ../include/color.h ../include/wintype.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/dialogs.c +winX.o: ../win/X11/winX.c $(HACK_H) ../include/winX.h ../include/dlb.h \ + ../include/xwindow.h ../win/X11/nh72icon ../win/X11/nh56icon \ + ../win/X11/nh32icon + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winX.c +winmap.o: ../win/X11/winmap.c ../include/xwindow.h $(HACK_H) ../include/dlb.h \ + ../include/winX.h ../include/tile2x11.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmap.c +winmenu.o: ../win/X11/winmenu.c $(HACK_H) ../include/winX.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmenu.c +winmesg.o: ../win/X11/winmesg.c ../include/xwindow.h $(HACK_H) ../include/winX.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmesg.c +winmisc.o: ../win/X11/winmisc.c $(HACK_H) ../include/func_tab.h \ + ../include/winX.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmisc.c +winshim.o: ../win/shim/winshim.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../win/shim/winshim.c +winstat.o: ../win/X11/winstat.c $(HACK_H) ../include/winX.h ../include/xwindow.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winstat.c +wintext.o: ../win/X11/wintext.c $(HACK_H) ../include/winX.h ../include/xwindow.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/wintext.c +winval.o: ../win/X11/winval.c $(HACK_H) ../include/winX.h + $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winval.c +tile.o: tile.c $(HACK_H) +cppregex.o: ../sys/share/cppregex.cpp + $(CXX) $(CXXFLAGS) -c -o $@ ../sys/share/cppregex.cpp +qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h ../win/Qt/qt_delay.h \ + ../win/Qt/qt_xcmd.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_menu.h \ + ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h ../win/Qt/qt_plsel.h \ + ../win/Qt/qt_svsel.h ../win/Qt/qt_set.h ../win/Qt/qt_stat.h \ + ../win/Qt/qt_icon.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_yndlg.h ../win/Qt/qt_str.h ../include/dlb.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_bind.cpp +qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_click.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_click.cpp +qt_clust.o: ../win/Qt/qt_clust.cpp ../win/Qt/qt_clust.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_clust.cpp +qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_delay.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp +qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) ../include/tile2x11.h \ + ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_inv.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp +qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_icon.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp +qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp +qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_key.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_key.cpp +qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_line.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_line.cpp +qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + qt_main.moc ../win/Qt/qt_bind.h ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_inv.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ + ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_msg.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h \ + ../win/Qt/qt_str.h qt_kde0.moc + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_main.cpp +qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_xpms.h ../win/Qt/qt_set.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp +qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_rip.h qt_menu.moc ../win/Qt/qt_glyph.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp +qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ + qt_msg.moc ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ + ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp +qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_plsel.h qt_plsel.moc \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_plsel.cpp +qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_rip.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp +qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_set.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h qt_set.moc \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp +qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ + ../win/Qt/qt_icon.h qt_stat.moc ../win/Qt/qt_set.h \ + ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ + ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp +qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_str.cpp +qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ + ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp +qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp +qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h ../win/Qt/qt_key.h \ + ../win/Qt/qt_icon.h ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ + ../win/Qt/qt_menu.h ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h \ + ../win/Qt/qt_set.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_win.cpp +qt_xcmd.o: ../win/Qt/qt_xcmd.cpp $(HACK_H) ../include/func_tab.h \ + ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_xcmd.h \ + qt_xcmd.moc ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_xcmd.cpp +qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + ../win/Qt/qt_post.h ../win/Qt/qt_yndlg.h qt_yndlg.moc \ + ../win/Qt/qt_str.h + $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp +wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_chainin.c +wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) + $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_chainout.c +wc_trace.o: ../win/chain/wc_trace.c $(HACK_H) ../include/func_tab.h + $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_trace.c +vis_tab.o: vis_tab.c $(CONFIG_H) ../include/vis_tab.h +allmain.o: allmain.c $(HACK_H) +alloc.o: alloc.c $(CONFIG_H) +apply.o: apply.c $(HACK_H) +artifact.o: artifact.c $(HACK_H) ../include/artifact.h ../include/artilist.h +attrib.o: attrib.c $(HACK_H) +ball.o: ball.c $(HACK_H) +bones.o: bones.c $(HACK_H) +botl.o: botl.c $(HACK_H) +cmd.o: cmd.c $(HACK_H) ../include/func_tab.h +dbridge.o: dbridge.c $(HACK_H) +decl.o: decl.c $(HACK_H) +detect.o: detect.c $(HACK_H) ../include/artifact.h +dig.o: dig.c $(HACK_H) +display.o: display.c $(HACK_H) +dlb.o: dlb.c $(CONFIG_H) ../include/dlb.h +do.o: do.c $(HACK_H) +do_name.o: do_name.c $(HACK_H) +do_wear.o: do_wear.c $(HACK_H) +dog.o: dog.c $(HACK_H) +dogmove.o: dogmove.c $(HACK_H) ../include/mfndpos.h +dokick.o: dokick.c $(HACK_H) +dothrow.o: dothrow.c $(HACK_H) +drawing.o: drawing.c $(CONFIG_H) ../include/color.h ../include/rm.h \ + ../include/objclass.h ../include/monsym.h +dungeon.o: dungeon.c $(HACK_H) ../include/dgn_file.h ../include/dlb.h +eat.o: eat.c $(HACK_H) +end.o: end.c $(HACK_H) ../include/dlb.h +engrave.o: engrave.c $(HACK_H) +exper.o: exper.c $(HACK_H) +explode.o: explode.c $(HACK_H) +extralev.o: extralev.c $(HACK_H) +files.o: files.c $(HACK_H) ../include/dlb.h #zlib.h +fountain.o: fountain.c $(HACK_H) +hack.o: hack.c $(HACK_H) +hacklib.o: hacklib.c $(HACK_H) +insight.o: insight.c $(HACK_H) +invent.o: invent.c $(HACK_H) +isaac64.o: isaac64.c $(CONFIG_H) ../include/isaac64.h +light.o: light.c $(HACK_H) +lock.o: lock.c $(HACK_H) +mail.o: mail.c $(HACK_H) ../include/mail.h +makemon.o: makemon.c $(HACK_H) +mapglyph.o: mapglyph.c $(HACK_H) +mcastu.o: mcastu.c $(HACK_H) +mdlib.o: mdlib.c $(CONFIG_H) ../include/permonst.h ../include/align.h \ + ../include/monattk.h ../include/monflag.h \ + ../include/objclass.h ../include/monsym.h \ + ../include/artilist.h ../include/dungeon.h ../include/obj.h \ + ../include/monst.h ../include/mextra.h ../include/you.h \ + ../include/attrib.h ../include/prop.h ../include/skills.h \ + ../include/context.h ../include/flag.h ../include/dlb.h +mhitm.o: mhitm.c $(HACK_H) ../include/artifact.h +mhitu.o: mhitu.c $(HACK_H) ../include/artifact.h +minion.o: minion.c $(HACK_H) +mklev.o: mklev.c $(HACK_H) +mkmap.o: mkmap.c $(HACK_H) ../include/sp_lev.h +mkmaze.o: mkmaze.c $(HACK_H) ../include/sp_lev.h +mkobj.o: mkobj.c $(HACK_H) +mkroom.o: mkroom.c $(HACK_H) +mon.o: mon.c $(HACK_H) ../include/mfndpos.h +mondata.o: mondata.c $(HACK_H) +monmove.o: monmove.c $(HACK_H) ../include/mfndpos.h ../include/artifact.h +monst.o: monst.c $(CONFIG_H) ../include/permonst.h ../include/align.h \ + ../include/monattk.h ../include/monflag.h ../include/monsym.h \ + ../include/color.h +mplayer.o: mplayer.c $(HACK_H) +mthrowu.o: mthrowu.c $(HACK_H) +muse.o: muse.c $(HACK_H) +music.o: music.c $(HACK_H) +nhlua.o: nhlua.c $(HACK_H) ../include/dlb.h +nhlsel.o: nhlsel.c $(HACK_H) ../include/sp_lev.h +nhlobj.o: nhlobj.c $(HACK_H) ../include/sp_lev.h +o_init.o: o_init.c $(HACK_H) +objects.o: objects.c $(CONFIG_H) ../include/obj.h ../include/objclass.h \ + ../include/prop.h ../include/skills.h ../include/color.h +objnam.o: objnam.c $(HACK_H) +options.o: options.c $(CONFIG_H) ../include/objclass.h ../include/flag.h \ + $(HACK_H) ../include/tcap.h ../include/optlist.h +pager.o: pager.c $(HACK_H) ../include/dlb.h +pickup.o: pickup.c $(HACK_H) +pline.o: pline.c $(HACK_H) +polyself.o: polyself.c $(HACK_H) +potion.o: potion.c $(HACK_H) +pray.o: pray.c $(HACK_H) +priest.o: priest.c $(HACK_H) ../include/mfndpos.h +quest.o: quest.c $(HACK_H) +questpgr.o: questpgr.c $(HACK_H) ../include/dlb.h +read.o: read.c $(HACK_H) +rect.o: rect.c $(HACK_H) +region.o: region.c $(HACK_H) +restore.o: restore.c $(HACK_H) ../include/tcap.h +rip.o: rip.c $(HACK_H) +rnd.o: rnd.c $(HACK_H) ../include/isaac64.h +role.o: role.c $(HACK_H) +rumors.o: rumors.c $(HACK_H) ../include/dlb.h +save.o: save.c $(HACK_H) +sfstruct.o: sfstruct.c $(HACK_H) +shk.o: shk.c $(HACK_H) +shknam.o: shknam.c $(HACK_H) +sit.o: sit.c $(HACK_H) ../include/artifact.h +sounds.o: sounds.c $(HACK_H) +sp_lev.o: sp_lev.c $(HACK_H) ../include/sp_lev.h +spell.o: spell.c $(HACK_H) +steal.o: steal.c $(HACK_H) +steed.o: steed.c $(HACK_H) +symbols.o: symbols.c $(HACK_H) ../include/tcap.h +sys.o: sys.c $(HACK_H) +teleport.o: teleport.c $(HACK_H) +timeout.o: timeout.c $(HACK_H) +topten.o: topten.c $(HACK_H) ../include/dlb.h +track.o: track.c $(HACK_H) +trap.o: trap.c $(HACK_H) +u_init.o: u_init.c $(HACK_H) +uhitm.o: uhitm.c $(HACK_H) +vault.o: vault.c $(HACK_H) +version.o: version.c $(HACK_H) ../include/dlb.h ../include/date.h +vision.o: vision.c $(HACK_H) ../include/vis_tab.h +weapon.o: weapon.c $(HACK_H) +were.o: were.c $(HACK_H) +wield.o: wield.c $(HACK_H) +windows.o: windows.c $(HACK_H) ../include/wingem.h ../include/winGnome.h +wizard.o: wizard.c $(HACK_H) +worm.o: worm.c $(HACK_H) +worn.o: worn.c $(HACK_H) +write.o: write.c $(HACK_H) +zap.o: zap.c $(HACK_H) +# DEPENDENCIES MUST END AT END OF FILE +# IF YOU PUT STUFF HERE IT WILL GO AWAY +# see make depend above diff --git a/sys/lib/Makefile.top b/sys/lib/Makefile.top new file mode 100644 index 000000000..c3ca8fda3 --- /dev/null +++ b/sys/lib/Makefile.top @@ -0,0 +1,332 @@ +# NetHack Top-level Makefile. +# NetHack 3.7 Makefile.top $NHDT-Date: 1597031649 2020/08/10 03:54:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ +# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland +# NetHack may be freely redistributed. See license for details. + +# Root of source tree: +NHSROOT=$(abspath .) + +# newer makes predefine $(MAKE) to 'make' and do smarter processing of +# recursive make calls if $(MAKE) is used +# these makes allow $(MAKE) to be overridden by the environment if someone +# wants to (or has to) use something other than the standard make, so we do +# not want to unconditionally set $(MAKE) here +# +# unfortunately, some older makes do not predefine $(MAKE); if you have one of +# these, uncomment the following line +# (you will know that you have one if you get complaints about unable to +# execute things like 'data' and 'rumors') +# MAKE = make + +# make libnethack +LIBNH = libnethack.a + +# if requested, setup cross-compiler for WASM +ifdef WANT_WASM +CC=$(EMCC) +AR=$(EMAR) +RANLIB=$(EMRANLIB) +CFLAGS=$(EMCC_CFLAGS) +SYSCFLAGS=$(EMCC_CFLAGS) +INSTDIR=$(WASM_DATA_DIR) +endif # WANT_WASM + +# Permissions - some places use setgid instead of setuid, for instance +# See also the option "SECURE" in include/config.h +#GAMEPERM = 04755 +FILEPERM = 0644 +# VARFILEPERM = 0644 +EXEPERM = 0755 +DIRPERM = 0755 +# VARDIRPERM = 0755 + +# VARDIR may also appear in unixconf.h as "VAR_PLAYGROUND" else HACKDIR +# +# note that 'make install' believes in creating a nice tidy HACKDIR for +# installation, free of debris from previous NetHack versions -- +# therefore there should not be anything in HACKDIR that you want to keep +# (if there is, you'll have to do the installation by hand or modify the +# instructions) +#HACKDIR = $(PREFIX)/games/lib/$(GAME)dir +#VARDIR = $(HACKDIR) +# Where nethack.sh in installed. If this is not defined, the wrapper is not used. +#SHELLDIR = $(PREFIX)/games + +# per discussion in Install.X11 and Install.Qt +#VARDATND = +# VARDATND = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +# VARDATND = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm rip.xpm +# for Atari/Gem +# VARDATND = nh16.img title.img GEM_RSC.RSC rip.img +# for BeOS +# VARDATND = beostiles +# for Gnome +# VARDATND = x11tiles pet_mark.xbm pilemark.xbm rip.xpm mapbg.xpm + +VARDATD = bogusmon data engrave epitaph oracles options quest.lua rumors +VARDAT = $(VARDATD) $(VARDATND) + +# Some versions of make use the SHELL environment variable as the shell +# for running commands. We need this to be a Bourne shell. +# SHELL = /bin/sh +# for Atari +# SHELL=E:/GEMINI2/MUPFEL.TTP + +# Commands for setting the owner and group on files during installation. +# Some systems fail with one or the other when installing over NFS or for +# other permission-related reasons. If that happens, you may want to set the +# command to "true", which is a no-op. Note that disabling chown or chgrp +# will only work if setuid (or setgid) behavior is not desired or required. +#CHOWN = chown +#CHGRP = chgrp + +# Lua version +LUA_VERSION = 5.4.0 + +# +# end of configuration +# + +DATHELP = help hh cmdhelp keyhelp history opthelp wizhelp + +SPEC_LEVS = asmodeus.lua baalz.lua bigrm-*.lua castle.lua fakewiz?.lua \ + juiblex.lua knox.lua medusa-?.lua minend-?.lua minefill.lua \ + minetn-?.lua oracle.lua orcus.lua sanctum.lua soko?-?.lua \ + tower?.lua valley.lua wizard?.lua nhlib.lua themerms.lua \ + astral.lua air.lua earth.lua fire.lua water.lua +QUEST_LEVS = ???-goal.lua ???-fil?.lua ???-loca.lua ???-strt.lua + +DATNODLB = $(VARDATND) license symbols +DATDLB = $(DATHELP) dungeon.lua tribute $(SPEC_LEVS) $(QUEST_LEVS) $(VARDATD) +DAT = $(DATNODLB) $(DATDLB) + +# first target is also the default target for 'make' without any arguments +#all: $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb +all: libnh + true; $(MOREALL) + @echo "Done." + +libnh: src/$(LIBNH) + @echo "libnethack is up to date." + +src/$(LIBNH): lua_support + ( cd src ; $(MAKE)) + +lua_support: lib/lua/liblua.a include/nhlua.h + @true +lib/lua-$(LUA_VERSION)/src/liblua.a: lib/lua-$(LUA_VERSION)/src/lua.h + ( cd lib/lua-$(LUA_VERSION)/src \ + && make CC='$(CC)' AR='$(AR)' RANLIB='$(RANLIB)' SYSCFLAGS='$(SYSCFLAGS)' a && cd ../../.. ) +lib/lua/liblua.a: lib/lua-$(LUA_VERSION)/src/liblua.a + @( if [ ! -d lib/lua ] ; then mkdir -p lib/lua ; fi ) + cp lib/lua-$(LUA_VERSION)/src/liblua.a $@ +include/nhlua.h: lib/lua/liblua.a + echo '/* nhlua.h - generated by top Makefile */' > $@ + @echo '#include "../lib/lua-$(LUA_VERSION)/src/lua.h"' >> $@ + @sed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' \ + < lib/lua-$(LUA_VERSION)/src/lua.h >> $@ + @echo '#include "../lib/lua-$(LUA_VERSION)/src/lualib.h"' >> $@ + @echo '#include "../lib/lua-$(LUA_VERSION)/src/lauxlib.h"' >> $@ + @echo '/*nhlua.h*/' >> $@ + +# Note: many of the dependencies below are here to allow parallel make +# to generate valid output + +Guidebook: + ( cd doc ; $(MAKE) Guidebook ) + +manpages: + ( cd doc ; $(MAKE) manpages ) + +data: $(GAME) + ( cd dat ; $(MAKE) data ) + +engrave: $(GAME) + ( cd dat ; $(MAKE) engrave ) + +bogusmon: $(GAME) + ( cd dat ; $(MAKE) bogusmon ) + +epitaph: $(GAME) + ( cd dat ; $(MAKE) epitaph ) + +rumors: $(GAME) + ( cd dat ; $(MAKE) rumors ) + +oracles: $(GAME) + ( cd dat ; $(MAKE) oracles ) + +# Note: options should have already been made with make, but... +options: $(GAME) + ( cd dat ; $(MAKE) options ) + +quest.lua: $(GAME) + +spec_levs: + ( cd dat ; $(MAKE) spec_levs ) + ( cd dat ; $(MAKE) quest_levs ) + +nhtiles.bmp: $(GAME) + ( cd dat ; $(MAKE) nhtiles.bmp ) + +x11tiles: $(GAME) + ( cd util ; $(MAKE) tile2x11 ) + ( cd dat ; $(MAKE) x11tiles ) + +beostiles: $(GAME) + ( cd util ; $(MAKE) tile2beos ) + ( cd dat ; $(MAKE) beostiles ) + +NetHack.ad: $(GAME) + ( cd dat ; $(MAKE) NetHack.ad ) + +pet_mark.xbm: + ( cd dat ; $(MAKE) pet_mark.xbm ) + +pilemark.xbm: + ( cd dat ; $(MAKE) pilemark.xbm ) + +rip.xpm: + ( cd dat ; $(MAKE) rip.xpm ) + +mapbg.xpm: + (cd dat ; $(MAKE) mapbg.xpm ) + +nhsplash.xpm: + ( cd dat ; $(MAKE) nhsplash.xpm ) + +nh16.img: $(GAME) + ( cd util ; $(MAKE) tile2img.ttp ) + ( cd dat ; $(MAKE) nh16.img ) + +rip.img: + ( cd util ; $(MAKE) xpm2img.ttp ) + ( cd dat ; $(MAKE) rip.img ) +GEM_RSC.RSC: + ( cd dat ; $(MAKE) GEM_RSC.RSC ) + +title.img: + ( cd dat ; $(MAKE) title.img ) + +check-dlb: options + @if egrep -s librarian dat/options ; then $(MAKE) dlb ; else true ; fi + +dlb: + ( cd util ; $(MAKE) dlb ) + ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) + +# recover can be used when INSURANCE is defined in include/config.h +# and the checkpoint option is true +recover: $(GAME) + ( cd util ; $(MAKE) recover ) + +dofiles: + target=`sed -n \ + -e '/librarian/{' \ + -e 's/.*/dlb/p' \ + -e 'q' \ + -e '}' \ + -e '$$s/.*/nodlb/p' < dat/options` ; \ + $(MAKE) dofiles-$${target-nodlb} + cp src/$(GAME) $(INSTDIR) + cp util/recover $(INSTDIR) + -if test -n '$(SHELLDIR)'; then rm -f $(SHELLDIR)/$(GAME); fi + if test -n '$(SHELLDIR)'; then \ + sed -e 's;/usr/games/lib/nethackdir;$(HACKDIR);' \ + -e 's;HACKDIR/nethack;HACKDIR/$(GAME);' \ + < sys/unix/nethack.sh \ + > $(SHELLDIR)/$(GAME) ; fi +# set up their permissions + -( cd $(INSTDIR) ; $(CHOWN) $(GAMEUID) $(GAME) recover ; \ + $(CHGRP) $(GAMEGRP) $(GAME) recover ) + chmod $(GAMEPERM) $(INSTDIR)/$(GAME) + chmod $(EXEPERM) $(INSTDIR)/recover + -if test -n '$(SHELLDIR)'; then \ + $(CHOWN) $(GAMEUID) $(SHELLDIR)/$(GAME); fi + if test -n '$(SHELLDIR)'; then \ + $(CHGRP) $(GAMEGRP) $(SHELLDIR)/$(GAME); \ + chmod $(EXEPERM) $(SHELLDIR)/$(GAME); fi + +dofiles-dlb: check-dlb + ( cd dat ; cp nhdat $(DATNODLB) $(INSTDIR) ) +# set up their permissions + -( cd $(INSTDIR) ; $(CHOWN) $(GAMEUID) nhdat $(DATNODLB) ; \ + $(CHGRP) $(GAMEGRP) nhdat $(DATNODLB) ; \ + chmod $(FILEPERM) nhdat $(DATNODLB) ) + +dofiles-nodlb: +# copy over the game files + ( cd dat ; cp $(DAT) $(INSTDIR) ) +# set up their permissions + -( cd $(INSTDIR) ; $(CHOWN) $(GAMEUID) $(DAT) ; \ + $(CHGRP) $(GAMEGRP) $(DAT) ; \ + chmod $(FILEPERM) $(DAT) ) +# +# This is not part of the dependency build hierarchy. +# It requires an explicit "make fetch-Lua". +fetch-lua: fetch-Lua + @true + +fetch-Lua: + ( mkdir -p lib && cd lib && \ + curl -R -O http://www.lua.org/ftp/lua-$(LUA_VERSION).tar.gz && \ + tar zxf lua-$(LUA_VERSION).tar.gz && rm -f lua-$(LUA_VERSION).tar.gz ) + +update: $(GAME) recover $(VARDAT) spec_levs +# (don't yank the old version out from under people who're playing it) + -mv $(INSTDIR)/$(GAME) $(INSTDIR)/$(GAME).old + -mv $(INSTDIR)/nhdat $(INSTDIR)/nhdat.old +# set up new versions of the game files + ( $(MAKE) dofiles ) +# touch time-sensitive files + -touch -c $(VARDIR)/bones* $(VARDIR)/?lock* $(VARDIR)/wizard* + -touch -c $(VARDIR)/save/* + touch $(VARDIR)/perm $(VARDIR)/record +# and a reminder + @echo You may also want to install the man pages via the doc Makefile. + +rootcheck: + @true; $(ROOTCHECK) + +install: rootcheck $(GAME) recover $(VARDAT) spec_levs + true; $(PREINSTALL) +# set up the directories +# not all mkdirs have -p; those that don't will create a -p directory + -if test -n '$(SHELLDIR)'; then \ + mkdir -p $(SHELLDIR); fi + rm -rf $(INSTDIR) $(VARDIR) + -mkdir -p $(INSTDIR) $(VARDIR) $(VARDIR)/save + if test -d ./-p; then rmdir ./-p; fi + -$(CHOWN) $(GAMEUID) $(INSTDIR) $(VARDIR) $(VARDIR)/save + $(CHGRP) $(GAMEGRP) $(INSTDIR) $(VARDIR) $(VARDIR)/save +# order counts here: + chmod $(DIRPERM) $(INSTDIR) + chmod $(VARDIRPERM) $(VARDIR) $(VARDIR)/save +# set up the game files + ( $(MAKE) dofiles ) +# set up some additional files + touch $(VARDIR)/perm $(VARDIR)/record $(VARDIR)/logfile $(VARDIR)/xlogfile + -( cd $(VARDIR) ; $(CHOWN) $(GAMEUID) perm record logfile xlogfile ; \ + $(CHGRP) $(GAMEGRP) perm record logfile xlogfile ; \ + chmod $(VARFILEPERM) perm record logfile xlogfile ) + true; $(POSTINSTALL) +# and a reminder + @echo You may also want to reinstall the man pages via the doc Makefile. + + +# 'make clean' removes all the .o files, but leaves around all the executables +# and compiled data files +clean: + ( cd src ; $(MAKE) clean ) + ( cd util ; $(MAKE) clean ) + ( cd dat ; $(MAKE) clean ) + ( cd doc ; $(MAKE) clean ) + ( cd lib/lua-$(LUA_VERSION)/src && $(MAKE) clean ) + +# 'make spotless' returns the source tree to near-distribution condition. +# it removes .o files, executables, and compiled data files +spotless:: + ( cd src ; $(MAKE) spotless ) + ( cd util ; $(MAKE) spotless ) + ( cd dat ; $(MAKE) spotless ) + ( cd doc ; $(MAKE) spotless ) diff --git a/sys/lib/Makefile.utl b/sys/lib/Makefile.utl new file mode 100644 index 000000000..8aaf07c9a --- /dev/null +++ b/sys/lib/Makefile.utl @@ -0,0 +1,382 @@ +# Makefile for NetHack's utility programs. +# NetHack 3.7 Makefile.utl $NHDT-Date: 1596498292 2020/08/03 23:44:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ +# Copyright (c) 2018 by Robert Patrick Rankin +# NetHack may be freely redistributed. See license for details. + +# Root of source tree: +NHSROOT=.. + +# newer makes predefine $(MAKE) to 'make' and do smarter processing of +# recursive make calls if $(MAKE) is used +# these makes allow $(MAKE) to be overridden by the environment if someone +# wants to (or has to) use something other than the standard make, so we do +# not want to unconditionally set $(MAKE) here +# +# unfortunately, some older makes do not predefine $(MAKE); if you have one of +# these, uncomment the following line +# (you will know that you have one if you get complaints about unable to +# execute things like 'foo.o') +# MAKE = make + +# if you are using gcc as your compiler, +# uncomment the CC definition below if it's not in your environment +# CC = gcc +# +# For Bull DPX/2 systems at B.O.S. 2.0 or higher use the following: +# +# CC = gcc -ansi -D_BULL_SOURCE -D_XOPEN_SOURCE -D_POSIX_SOURCE +# +# If you are using GCC 2.2.2 or higher on a DPX/2, just use: +# +# CC = gcc -ansi +# +# For HP/UX 10.20 with GCC: +# CC = gcc -D_POSIX_SOURCE +# +# if your make doesn't define a default SHELL properly, you may need +# the line below (Atari users will need a bourne work-alike) +# SHELL = /bin/sh +# for Atari +# SHELL=E:/GEMINI2/MUPFEL.TTP + +# flags may have to be changed as required +# flags for 286 Xenix: +# CFLAGS = -Ml2t16 -O -LARGE -I../include +# LFLAGS = -Ml -F 4000 -SEG 512 + +# flags for 286 Microport SysV-AT +# CFLAGS = -DDUMB -Ml -I../include +# LFLAGS = -Ml + +# flags for Atari GCC (3.2.1) +# CFLAGS = -O -I../include +# LFLAGS = -s +# flags for Atari GCC (3.3) +# CFLAGS = -mshort -O2 -I../include +# LFLAGS = -mshort -s + +# flags for Apollos using their native cc +# (as long as it claims to be __STDC__ but isn't) +# CFLAGS = -DAPOLLO -O -I../include + +# flags for AIX 3.1 cc on IBM RS/6000 to define +# a suitable subset of standard libraries +# (note that there is more info regarding the "-qchars=signed" +# switch in file Install.unx note 8) +# CFLAGS = -D_NO_PROTO -D_XOPEN_SOURCE -O -I../include -qchars=signed +# and for AIX 3.2: +# CFLAGS = -D_NO_PROTO -D_XOPEN_SOURCE -D_ALL_SOURCE -O -I../include -qchars=signed + +# flags for A/UX 2.01 using native cc or c89 +# gcc predefines AUX so that's not needed there +# CFLAGS = -ZS -D_POSIX_SOURCE -O -I../include -DAUX + +# flags for IRIX 4.0.x using native cc +# SGI cc 3.10 will fail to compile makedefs with -O +# CFLAGS = -I../include -D__STDC__ -woff 100,293 + +# flags for Linux +# compile normally +# CFLAGS = -O2 -fomit-frame-pointer -I../include +# LFLAGS = -L/usr/X11R6/lib +# 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 + +# flags for BeOS using the command line +# BeOS on a Mac/BeBox: +#CC = mwcc +#CFLAGS = -I../include +# BeOS on Intel: +# the default values are fine + +# flags for debugging: +# CFLAGS = -g -I../include + +#CFLAGS = -O -I../include +#LFLAGS = + +# -lm required by lua +LFLAGS += -lm + +# we specify C preprocessor flags via CFLAGS; files built with default rules +# might include $(CPPFLAGS) which could get a value from user's environment; +# we avoid that by forcing it empty rather than by overriding default rules +CPPFLAGS = + +LIBS = + +# If you are cross-compiling, you must use this: +OBJDIR = . +# otherwise, you can save a little bit of disk space with this: +#OBJDIR = ../src + +# if you change this to 1, feedback while building will omit -Dthis -Wthat +# -Isomewhere so that each file being compiled is listed on one short line; +# it requires support for '$<' in rules with more than one prerequisite +# (rather than just in suffix default rule), such as is implemented by +# gnu make and others which have picked up its extensions; +# allowed values are 0, 1, and empty (which behaves like 0) +QUIETCC=0 + +# TODO? the link/load commands below are handled differently from the ones +# in Makefile.src; these use '$(CC) $(LFLAGS)' and ought to be changed to use +# $(LD) or $(LINK) as appropriate [quiet mode echoes a misleading $< value] + +# ---------------------------------------- +# +# Nothing below this line should have to be changed. + +# Verbosity definitions, begin +# Set QUIETCC=1 above to output less feedback while building. +# CC and CXX obey verbosity, LD and LINK don't. +# AT is @ when not verbose, empty otherwise +ACTUAL_CC := $(CC) +ACTUAL_CXX := $(CXX) +ACTUAL_LD := $(LD) +ACTUAL_LINK := $(LINK) + +CC_V0 = $(ACTUAL_CC) +CC_V = $(CC_V0) +CC_V1 = @echo "[CC] $<"; $(ACTUAL_CC) +CC = $(CC_V$(QUIETCC)) + +CXX_V0 = $(ACTUAL_CXX) +CXX_V = $(CXX_V0) +CXX_V1 = @echo "[CXX] $<"; $(ACTUAL_CXX) +CXX = $(CXX_V$(QUIETCC)) + +CFLAGS+=-I../include +ifdef WANT_WASM +CFLAGS+=-DWASM +endif + +# LD and LINK might be based on invoking CC and may not be able to substitute +# for QUIETCC, so feedback from them is handled differently (via $AT) +LD = $(ACTUAL_LD) +LINK = $(ACTUAL_LINK) + +AT_V0 := +AT_V := $(AT_V0) +AT_V1 := @ +AT = $(AT_V$(QUIETCC)) +# Verbosity, end + +# timestamps for primary header files, matching src/Makefile +CONFIG_H = ../src/config.h-t +HACK_H = ../src/hack.h-t + +# utility .c files +MAKESRC = makedefs.c ../src/mdlib.c +RECOVSRC = recover.c +DLBSRC = dlb_main.c +UTILSRCS = $(MAKESRC) panic.c $(DGNCOMPSRC) $(RECOVSRC) $(DLBSRC) + +# files that define all monsters and objects +CMONOBJ = ../src/monst.c ../src/objects.c +OMONOBJ = $(OBJDIR)/monst.o $(OBJDIR)/objects.o +# files that provide access to NetHack's names +CNAMING = ../src/drawing.c $(CMONOBJ) +ONAMING = $(OBJDIR)/drawing.o $(OMONOBJ) +# dynamic memory allocation +CALLOC = ../src/alloc.c panic.c +OALLOC = $(OBJDIR)/alloc.o panic.o + +# object files for makedefs +MAKEOBJS = makedefs.o $(OMONOBJ) + +# object files for recovery utility +RECOVOBJS = recover.o + +# object files for the data librarian +DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) + + +# dependencies for makedefs +# +makedefs: $(MAKEOBJS) mdgrep.h + $(CC) $(LFLAGS) -o makedefs $(MAKEOBJS) + +makedefs.o: makedefs.c ../src/mdlib.c $(CONFIG_H) ../include/permonst.h \ + ../include/objclass.h ../include/monsym.h \ + ../include/artilist.h ../include/dungeon.h ../include/obj.h \ + ../include/monst.h ../include/you.h ../include/flag.h \ + ../include/dlb.h ../include/patchlevel.h + +# Don't require perl to build; that is why mdgrep.h is spelled wrong below. +mdgreph: mdgrep.pl + perl mdgrep.pl + +../include/onames.h: makedefs + ./makedefs -o +../include/pm.h: makedefs + ./makedefs -p +../include/vis_tab.h: makedefs + ./makedefs -z +# makedefs -z makes both vis_tab.h and vis_tab.c, but writes the .h first +../src/vis_tab.c: ../include/vis_tab.h + +lintdefs: + @lint -axbh -I../include -DLINT $(MAKESRC) $(CMONOBJ) | sed '/_flsbuf/d' + + +# we defer this makedefs call to the src Makefile, since it knows all about +# the main src and include files date.h is a timestamp for +../include/date.h:: + @( cd ../src ; $(MAKE) ../include/date.h ) + +# support code used by several of the utility programs (but not makedefs) +panic.o: panic.c $(CONFIG_H) + + +# with all of extern.h's functions to complain about, we drown in +# 'defined but not used' without -u +lintdgn: + @lint -axhu -I../include -DLINT $(DGNCOMPSRC) $(CALLOC) | sed '/_flsbuf/d' + + +# dependencies for recover +# +recover: $(RECOVOBJS) + $(CC) $(LFLAGS) -o recover $(RECOVOBJS) $(LIBS) + +recover.o: recover.c $(CONFIG_H) ../include/date.h + + +# dependencies for dlb +# +dlb: $(DLBOBJS) + $(CC) $(LFLAGS) -o dlb $(DLBOBJS) $(LIBS) + +dlb_main.o: dlb_main.c $(CONFIG_H) ../include/dlb.h ../include/date.h + $(CC) $(CFLAGS) -c dlb_main.c + + + +# dependencies for tile utilities +# +TEXT_IO = tiletext.o tiletxt.o $(OALLOC) $(ONAMING) +GIFREADERS = gifread.o +PPMWRITERS = ppmwrite.o + +tileutils: tilemap gif2txt txt2ppm tile2x11 + +gif2txt: $(GIFREADERS) $(TEXT_IO) + $(CC) $(LFLAGS) -o gif2txt $(GIFREADERS) $(TEXT_IO) $(LIBS) +txt2ppm: $(PPMWRITERS) $(TEXT_IO) + $(CC) $(LFLAGS) -o txt2ppm $(PPMWRITERS) $(TEXT_IO) $(LIBS) + +tile2x11: tile2x11.o $(TEXT_IO) + $(CC) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) $(LIBS) + +tile2img.ttp: tile2img.o bitmfile.o $(TEXT_IO) + $(CC) $(LFLAGS) -o tile2img.ttp tile2img.o bitmfile.o $(TEXT_IO) $(LIBS) + +tile2bmp: tile2bmp.o $(TEXT_IO) + $(CC) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO) + +xpm2img.ttp: xpm2img.o bitmfile.o + $(CC) $(LFLAGS) -o xpm2img.ttp xpm2img.o bitmfile.o $(LIBS) + +tile2beos: tile2beos.o $(TEXT_IO) + $(CC) $(LFLAGS) -o tile2beos tile2beos.o $(TEXT_IO) -lbe + +#--compiling and linking in one step leaves extra debugging files (in their +# own subdirectories!) on OSX; compile and link separately to suppress +# that without mucking about with extra OS-specific CFLAGS and/or LFLAGS +#tilemap: ../win/share/tilemap.c $(HACK_H) +# $(CC) $(CFLAGS) $(LFLAGS) -o tilemap ../win/share/tilemap.c $(LIBS) +tilemap: tilemap.o + $(CC) $(LFLAGS) -o tilemap tilemap.o $(LIBS) +../src/tile.c: tilemap + ./tilemap + +../include/tile.h: ../win/share/tile.h + cp ../win/share/tile.h ../include/tile.h +tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../include/tile.h + $(CC) $(CFLAGS) -c ../win/share/tiletext.c +tiletxt.c: ./Makefile + @echo '/* alternate compilation for tilemap.c to create tiletxt.o' > tiletxt.c + @echo ' that does not rely on "cc -c -o tiletxt.o tilemap.c"' >> tiletxt.c + @echo ' since many pre-POSIX compilers did not support that */' >> tiletxt.c + echo '#define TILETEXT' >> tiletxt.c + echo '#include "../win/share/tilemap.c"' >> tiletxt.c + @echo '/*tiletxt.c*/' >> tiletxt.c +tiletxt.o: tiletxt.c ../win/share/tilemap.c $(HACK_H) + $(CC) $(CFLAGS) -c tiletxt.c +tilemap.o: ../win/share/tilemap.c $(HACK_H) + $(CC) $(CFLAGS) -c ../win/share/tilemap.c + +gifread.o: ../win/share/gifread.c $(CONFIG_H) ../include/tile.h + $(CC) $(CFLAGS) -c ../win/share/gifread.c +ppmwrite.o: ../win/share/ppmwrite.c $(CONFIG_H) ../include/tile.h + $(CC) $(CFLAGS) -c ../win/share/ppmwrite.c + +tile2bmp.o: ../win/share/tile2bmp.c $(HACK_H) ../include/tile.h + $(CC) $(CFLAGS) -c ../win/share/tile2bmp.c + +tile2x11.o: ../win/X11/tile2x11.c $(HACK_H) ../include/tile.h \ + ../include/tile2x11.h + $(CC) $(CFLAGS) -c ../win/X11/tile2x11.c + +tile2img.o: ../win/gem/tile2img.c $(HACK_H) ../include/tile.h \ + ../include/bitmfile.h + $(CC) $(CFLAGS) -c ../win/gem/tile2img.c +xpm2img.o: ../win/gem/xpm2img.c $(HACK_H) ../include/bitmfile.h + $(CC) $(CFLAGS) -c ../win/gem/xpm2img.c +bitmfile.o: ../win/gem/bitmfile.c ../include/bitmfile.h + $(CC) $(CFLAGS) -c ../win/gem/bitmfile.c + +tile2beos.o: ../win/BeOS/tile2beos.cpp $(HACK_H) ../include/tile.h + $(CXX) $(CFLAGS) -c ../win/BeOS/tile2beos.cpp + +tileedit: tileedit.cpp $(TEXT_IO) + $(QTDIR)/bin/moc -o tileedit.moc tileedit.h + $(CC) -o tileedit -I../include -I$(QTDIR)/include -L$(QTDIR)/lib \ + tileedit.cpp $(TEXT_IO) -lqt + +# using dependencies like +# ../src/foo:: +# @( cd ../src ; $(MAKE) foo ) +# would always force foo to be up-to-date according to the src Makefile +# when it's needed here. Unfortunately, some makes believe this syntax +# means foo always changes, instead of foo should always be checked. +# therefore, approximate via config.h dependencies, and hope that anybody +# changing anything other than basic configuration also knows when not +# to improvise things not in the instructions, like 'make makedefs' here +# in util... + +# make sure object files from src are available when needed +# +$(OBJDIR)/alloc.o: ../src/alloc.c $(CONFIG_H) + $(CC) $(CFLAGS) -c ../src/alloc.c -o $@ +$(OBJDIR)/drawing.o: ../src/drawing.c $(CONFIG_H) + $(CC) $(CFLAGS) -c ../src/drawing.c -o $@ +$(OBJDIR)/decl.o: ../src/decl.c $(CONFIG_H) + $(CC) $(CFLAGS) -c ../src/decl.c -o $@ +$(OBJDIR)/monst.o: ../src/monst.c $(CONFIG_H) + $(CC) $(CFLAGS) -c ../src/monst.c -o $@ +$(OBJDIR)/objects.o: ../src/objects.c $(CONFIG_H) + $(CC) $(CFLAGS) -c ../src/objects.c -o $@ +$(OBJDIR)/dlb.o: ../src/dlb.c $(CONFIG_H) ../include/dlb.h + $(CC) $(CFLAGS) -c ../src/dlb.c -o $@ + +# make sure hack.h dependencies get transitive information +$(HACK_H): $(CONFIG_H) + @( cd ../src ; $(MAKE) $(HACK_H) ) +$(CONFIG_H): ../include/config.h + @( cd ../src ; $(MAKE) $(CONFIG_H) ) + +SYSSHARE=../sys/share/ + +tags: $(UTILSRCS) + @ctags -tw $(UTILSRCS) + +clean: + -rm -f *.o + +spotless: clean + -rm -f ../include/tile.h tiletxt.c + -rm -f makedefs recover dlb + -rm -f gif2txt txt2ppm tile2x11 tile2img.ttp xpm2img.ttp \ + tilemap tileedit tile2bmp diff --git a/sys/lib/hints/include/multiw-1.2020 b/sys/lib/hints/include/multiw-1.2020 new file mode 100644 index 000000000..3fb550882 --- /dev/null +++ b/sys/lib/hints/include/multiw-1.2020 @@ -0,0 +1,37 @@ +#------------------------------------------------------------------------------ +# NetHack 3.7 multiw-1.2020 $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 +# on the 'make' command line. If none are enabled, tty will be used. +#WANT_WIN_TTY=1 +#WANT_WIN_CURSES=1 +#WANT_WIN_X11=1 +#WANT_WIN_QT=1 + +# 2. What is the default window system? +# Exactly one of these can be manually uncommented and/or can be specified +# on the 'make' command line. If none is enabled, the first among +# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. +#WANT_DEFAULT=tty +#WANT_DEFAULT=curses +#WANT_DEFAULT=Qt +#WANT_DEFAULT=X11 + +# 3. compiler detection or optional override +CCISCLANG := $(shell echo `$(CC) --version` | grep clang) +ifeq "$(CCISCLANG)" "" +CXX=g++ -std=gnu++11 +else +CXX=clang++ -std=gnu++11 +endif +# if you want to override the compiler detection just carried out +# uncomment one of the following pairs as desired. +#CC= gcc +#CXX= g++ -std-gnu++11 +# +#CC= clang +#CXX=clang++ -std=gnu++11 + +#end of multiw-1.2020 +#------------------------------------------------------------------------------ diff --git a/sys/lib/hints/include/multiw-2.2020 b/sys/lib/hints/include/multiw-2.2020 new file mode 100644 index 000000000..ad4028aed --- /dev/null +++ b/sys/lib/hints/include/multiw-2.2020 @@ -0,0 +1,108 @@ +#------------------------------------------------------------------------------ +# NetHack 3.7 multiw-2.2020 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# +# Sorts out support for multiple window ports (interfaces) to included in the build. +# +# Included from: +# hints/linux.2020 +# hints/macOS.2020 +# +# The following will be set appropriately following this: +# - WANT_WIN_XXX (at least one will be set; default is TTY) +# - WANT_DEFAULT (set to match one of the enabled WANT_WIN_XXX) +# - WINCFLAGS +# - WINSRC +# - WINOBJ0 +#--- +# User selections could be specified as combinations of any of the following: +# WIN_WANT_TTY=1, WIN_WANT_CURSES=1, WIN_WANT_QT=1, WIN_WANT_X11=1 +# The selections will all be linked into the same binary. +# +# Assuming you have the prerequisite packages mentioned above, you can +# specify, right on the make command line, which window ports (or interfaces) +# to include in your build. Doing it via the make command line means that won't +# have to edit the Makefile. +# +# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 install +# +# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use +# something other than tty as the default interface. +# + +# Make sure that at least one interface is enabled. +ifndef WANT_WIN_ALL +ifndef WANT_WIN_TTY +ifndef WANT_WIN_CURSES +ifndef WANT_WIN_X11 +ifndef WANT_WIN_QT +WANT_WIN_TTY=1 +endif +endif +endif +endif +endif + +ifdef WANT_WIN_ALL +WANT_WIN_TTY=1 +WANT_WIN_CURSES=1 +WANT_WIN_X11=1 +WANT_WIN_QT=1 +endif + + +# Make sure that a default interface is specified; this doesn't guarantee +# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but +# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. +ifndef WANT_DEFAULT +# pick the first one enabled among { tty, curses, X11, Qt } +ifdef WANT_WIN_TTY +WANT_DEFAULT=tty +else +ifdef WANT_WIN_CURSES +WANT_DEFAULT=curses +else +ifdef WANT_WIN_X11 +WANT_DEFAULT=X11 +else +ifdef WANT_WIN_QT +WANT_DEFAULT=Qt +else +# ? shouldn't be able to get here... +endif +endif +endif +endif +endif + +WINCFLAGS= +WINSRC = +WINOBJ0 = + +ifdef WANT_WIN_TTY +WINSRC += $(WINTTYSRC) +WINOBJ0 += $(WINTTYOBJ) +else +WINCFLAGS += -DNOTTYGRAPHICS +endif + +ifdef WANT_WIN_CURSES +WINCFLAGS += -DCURSES_GRAPHICS +WINSRC += $(WINCURSESSRC) +WINOBJ0 += $(WINCURSESOBJ) +endif + +ifdef WANT_WIN_X11 +WINCFLAGS += -DX11_GRAPHICS +WINSRC += $(WIINX11SRC) +WINOBJ0 += $(WINX11OBJ) +endif + +ifdef WANT_WIN_QT +WINCFLAGS += -DQT_GRAPHICS +WINSRC += $(WINQTSRC) +WINOBJ0 += $(WINQTOBJ) +endif + +#end of hints/include/multiw-2.2020 +#------------------------------------------------------------------------------ + diff --git a/sys/lib/hints/macOS.2020 b/sys/lib/hints/macOS.2020 new file mode 100755 index 000000000..227f83a3c --- /dev/null +++ b/sys/lib/hints/macOS.2020 @@ -0,0 +1,443 @@ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1597704793 2020/08/17 22:53:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. +# NetHack may be freely redistributed. See license for details. +# +#--------------------------------------------------------------------- +# MacOS hints file with support for multiple window ports (interfaces) +# Tested on: +# - MacOS Catalina 10.15 +# +# If this doesn't work for some other version of Mac OS X, 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 + +#-PRE xxxx +# macOS X hints file +# + +####-INCLUDE multiw-1.2020 + +# 4. If you set WANT_WIN_QT, you need to +# A) set QTDIR either here or in the environment to point to the Qt5 +# library installation root. (Qt2, Qt3, Qt4 will not work) +# B) set XPMLIB to point to the Xpm library +ifndef WANT_WIN_QT +ifdef WANT_WIN_ALL +WANT_WIN_QT=1 +endif +endif +ifdef WANT_WIN_QT +#QTDIR=/Developer/Qt +# Qt installed via homebrew +QTDIR=$(shell brew --prefix)/opt/qt +# Qt installed via macports +#QTDIR=/opt/local/libexec/qt5 +endif # WANT_WIN_QT +ifndef LIBXPM +LIBXPM= -L/opt/X11/lib -lXpm +endif + +# 5. Other + +#----------------------------------------------------------------------------- +# You shouldn't need to change anything below here (in the hints file; if +# you're reading this in Makefile augmented by hints, that may not be true). +# + +####-INCLUDE multiw-2.2020 + +# XXX -g vs -O should go here, -I../include goes in the makefile +CFLAGS+=-g -I../include -DNOTPARMDECL +ifndef WANT_WIN_QT +# these are normally used when compiling nethack's core +CFLAGS+=-ansi -pedantic -Wno-long-long +# but -ansi forces -std=c90 for C or -std=c++98 for C++; +# win/Qt/qt_*.cpp compiled with C++98 semantics trigger +#In file included from .../qt5/include/QtCore/qglobal.h:105: +#.../qt5/include/QtCore/qcompilerdetection.h:561:6: +# error Qt requires a C++11 compiler and yours does not seem to be that. +# so we suppress -ansi when the build includes Qt +endif +# As of LLVM build 2336.1.00, this gives dozens of spurious messages, so +# leave it out by default. +#CFLAGS+=-Wunreachable-code +#TODO NHLIB +#CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings +CFLAGS+=-Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wformat -Wswitch -Wshadow -Wwrite-strings +CFLAGS+=-DGCC_WARN + +# NetHack sources control +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDLB +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +#CFLAGS+=-DTIMED_DELAY +#CFLAGS+=-DDUMPLOG +#CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +# older binaries use NOCLIPPING, but that disables SIGWINCH +#CFLAGS+=-DNOCLIPPING +CFLAGS+=-DNOMAIL +#CFLAGS+=-DEXTRA_SANITY_CHECKS +#CFLAGS+=-DEDIT_GETLIN +#CFLAGS+=-DSCORE_ON_BOTL +#CFLAGS+=-DMSGHANDLER +#CFLAGS+=-DTTY_TILES_ESCCODES +#CFLAGS+=-DTTY_SOUND_ESCCODES + +#CFLAGS+=-DDEFAULT_WINDOW_SYS=\"shim\" -DNOTTYGRAPHICS -DLIBNH + +CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 + +VARDATND = +VARDATND0 = +CURSESLIB = + +ifdef WANT_WIN_CHAIN +HINTSRC=$(CHAINSRC) +HINTOBJ=$(CHAINOBJ) +endif # WANT_WIN_CHAIN + +ifdef WANT_WIN_TTY +CURSESLIB = -lncurses +endif + +ifdef WANT_WIN_CURSES +CURSESLIB = -lncurses +endif + +ifdef CURSESLIB +WINLIB += $(CURSESLIB) +endif + +ifdef WANT_WIN_X11 +USE_XPM=1 +WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 +VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm +# -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 +X11CFLAGS = -I/opt/X11/include +# avoid repeated complaints about _X_NONNULL(args...) in +X11CFLAGS += -Wno-variadic-macros +ifdef USE_XPM +CFLAGS += -DUSE_XPM +WINX11LIB += -lXpm +VARDATND0 += rip.xpm +endif +WINLIB += $(WINX11LIB) +LFLAGS=-L/opt/X11/lib +endif # WANT_WIN_X11 + +ifdef WANT_WIN_QT +# Qt5 requires C++11 +LINK = $(CXX) +QTCXXFLAGS += -Wno-deprecated-declarations +QTCXXFLAGS += $(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) +WINSRC += $(WINQTSRC) +WINOBJ0 += $(WINQTOBJ) +VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm +# XXX if /Developer/qt exists and QTDIR not set, use that +ifndef QTDIR +$(error QTDIR not defined in the environment or Makefile) +endif # QTDIR +# XXX make sure QTDIR points to something reasonable +else # !WANT_WIN_QT +LINK=$(CC) +endif # !WANT_WIN_QT + +# prevent duplicate tile.o in WINOBJ +WINOBJ = $(sort $(WINOBJ0)) +# prevent duplicates in VARDATND if both X11 and Qt are being supported +VARDATND += $(sort $(VARDATND0)) + +WANT_BUNDLE=1 +ifdef WANT_SHARE_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 +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 +PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ + . sys/unix/hints/macosx.sh group2 $(GAMEGRP); \ + mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; + +else ifdef WANT_SOURCE_INSTALL + +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: +MOREALL=$(MAKE) install +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE + +else # !WANT_SOURCE_INSTALL + +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 +endif # WANT_DEFAULT X11 + +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +ifdef WANT_BUNDLE +# +# Bundle +# +# $(HACKDIR)/$(GAME).app/ +# Contents/ +# Frameworks/ +# Info.plist +# MacOS/ +# $(GAME) +# PkgInfo/ +# PlugIns/ +# Resources/ +# SharedFrameWorks/ +# +BUNDLE = mkdir -p $(HACKDIR)/nethack.app/Contents/MacOS; \ + sys/unix/hints/macosx.sh infoplist > $(HACKDIR)/nethack.app/Contents/Info.plist; \ + mv $(HACKDIR)/nethack $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +ifdef WANT_SHARE_INSTALL +BUNDLE+= chmod $(GAMEPERM) $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +endif + +POSTINSTALL+= $(BUNDLE) +POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ + sed -i '' 's;HACKDIR/$(GAME);HACKDIR/$(GAME).app/Contents/MacOS/$(GAME);' $(SHELLDIR)/$(GAME) ; fi; +endif # WANT_BUNDLE +endif # !WANT_SHARE_INSTALL + +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) + +# ~/Library/Preferences/NetHack Defaults +# OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp +# OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt +# +# Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary +# package under the docs directory). + +#-POST +ifdef MAKEFILE_TOP +### +### Packaging +### +# Notes: +# 1) The Apple developer utilities must be installed in the default location. +# 2) Do a normal build before trying to package the game. +# 3) This matches the 3.4.3 Term package, but there are some things that +# should be changed. +# +# Packages that are being distributed must be signed by a Developer ID +# Installer certificate. Set DEVELOPER_CERT to the name of the certificate +# if you wish for your package to be signed for distribution. +# +# If building a package for signing, you must use sudo approriately. +# the binaries and package using sudo but you DO NOT use sudo to sign the +# package. If you use sudo to sign the package, it will fail. +# +# sudo make all +# sudo make build_tty_pkg +# make sign_tty_pkg +# + +ifdef WANT_WIN_TTY +DEVUTIL=/Developer/Applications/Utilities +SVS=$(shell $(NHSROOT)/util/makedefs --svs) +SVSDOT=$(shell $(NHSROOT)/util/makedefs --svs .) + +PKGROOT_UG = PKGROOT/$(PREFIX) +PKGROOT_UGLN = PKGROOT/$(HACKDIR) +PKGROOT_BIN = PKGROOT/$(SHELLDIR) + +#DEVELOPER_CERT = Developer ID Installer: Bart House +DEVELOPER_CERT = NONE + +spotless:: + rm -rf RESOURCES + rm -rf PKG + rm -rf PKGSCRIPTS + rm -rf PKGROOT + rm -f Info.plist + rm -f Distribution.xml + rm -f NetHack-*-mac-Term* + +build_tty_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_QT)) + -echo build_tty_pkg only works for a tty-only build + exit 1 +else + rm -rf NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + $(MAKE) build_package_root + rm -rf RESOURCES + mkdir RESOURCES + #enscript --language=rtf -o - < dat/license >RESOURCES/License.rtf + sys/unix/hints/macosx.sh descplist > RESOURCES/Description.plist + sys/unix/hints/macosx.sh infoplist > Info.plist + + mkdir PKGROOT/Applications + #osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + # win/macosx/NetHackRecover.applescript + #cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + osacompile -o PKGROOT/Applications/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl $(PKGROOT_UGLN) + + osacompile -o PKGROOT/Applications/NetHackTerm.app \ + win/macosx/NetHackTerm.applescript + + # XXX integrate into Makefile.doc + (cd doc; cat Guidebook.mn | ../util/makedefs --grep --input - --output - \ + | tbl tmac.n - | groff | pstopdf -i -o Guidebook.pdf) + cp doc/Guidebook.pdf $(PKGROOT_UG)/doc/NetHackGuidebook.pdf + + osacompile -o PKGROOT/Applications/NetHackGuidebook.app \ + win/macosx/NetHackGuidebook.applescript + + mkdir -p PKG + pkgbuild --root PKGROOT --identifier org.nethack.term --scripts PKGSCRIPTS PKG/NH-Term.pkg + productbuild --synthesize --product Info.plist --package PKG/NH-Term.pkg Distribution.xml + productbuild --distribution Distribution.xml --resources RESOURCES --package-path PKG NetHack-$(SVS)-mac-Term-unsigned.pkg +ifeq ($(DEVELOPER_CERT),NONE) + cp NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term-unsigned.dmg + @echo ------------------------------------------- + @echo PACKAGE IS NOT SIGNED FOR DISTRIBUTION!!!!! + @echo =========================================== +else + @echo "run 'make sign_tty_pkg' to complete package" +endif + +sign_tty_pkg: + productsign --timestamp=none --sign "$(DEVELOPER_CERT)" NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg || (echo "Package signing failed"; exit 1) + spctl -a -v --type install NetHack-$(SVS)-mac-Term.pkg || (echo "Package not signed properly"; exit 1) + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + +build_package_root: + cd src/.. # make sure we are at TOP + rm -rf PKGROOT + mkdir -p $(PKGROOT_UG)/lib $(PKGROOT_BIN) $(PKGROOT_UG)/man/man6 $(PKGROOT_UG)/doc $(PKGROOT_UGLN) + install -p src/nethack $(PKGROOT_BIN) + # XXX should this be called nethackrecover? + install -p util/recover $(PKGROOT_BIN) + install -p doc/nethack.6 $(PKGROOT_UG)/man/man6 + install -p doc/recover.6 $(PKGROOT_UG)/man/man6 + install -p doc/Guidebook $(PKGROOT_UG)/doc + install -p dat/nhdat $(PKGROOT_UGLN) + sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(PKGROOT_UGLN)/sysconf + cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN) +# XXX these files should be somewhere else for good Mac form + touch $(PKGROOT_UGLN)/perm $(PKGROOT_UGLN)/record $(PKGROOT_UGLN)/logfile $(PKGROOT_UGLN)/xlogfile + mkdir $(PKGROOT_UGLN)/save +# XXX what about a news file? + + mkdir -p PKGSCRIPTS + echo '#!/bin/sh' > PKGSCRIPTS/postinstall + echo dseditgroup -o create -r '"Games Group"' -s 3600 $(GAMEGRP) >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(HACKDIR)/* >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(HACKDIR)/* >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + echo chmod $(VARDIRPERM) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo chmod $(VARDIRPERM) $(HACKDIR)/save >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/license >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/nhdat >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/symbols >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/perm >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/record >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/logfile >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/xlogfile >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/sysconf >> PKGSCRIPTS/postinstall + echo chmod $(GAMEPERM) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo chmod $(EXEPERM) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + chmod 0775 PKGSCRIPTS/postinstall + +endif # end of build_tty_pkg +endif # WANT_WIN_TTY for packaging + +ifdef WANT_WIN_QT +# XXX untested and incomplete (see below) +build_qt_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_TTY)) + -echo build_qt_pkg only works for a qt-only build + exit 1 +else + $(MAKE) build_package_root + rm -rf NetHackQt + mkdir -p NetHackQt/NetHackQt.app/nethackdir/save + mkdir NetHackQt/Documentation + cp doc/Guidebook.txt doc/nethack.txt doc/recover.txt NetHackQt/Documentation + + osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + + mkdir -p NetHackQt/NetHackQt.app/Contents/Frameworks + cp $(QTDIR)/libqt-mt.3.dylib NetHackQt/NetHackQt.app/Contents/Frameworks + + mkdir NetHackQt/NetHackQt.app/Contents/MacOS + mv PKGROOT/nethack NetHackQt/NetHackQt.app/Contents/MacOS + + mv PKGROOT/lib/nethackdir NetHackQt/NetHackQt.app/nethackdir + +# XXX still missing: +#NetHackQt/NetHackQt.app +# /Contents +# Info.plist +# Resources/nethack.icns +#NetHackQt/Documentation +#NetHackQtRecover.txt +#NetHack Defaults.txt +#changes.patch XXX is this still needed? why isn't it part of the tree? +# doesn't go here + hdiutil create -verbose -srcfolder NetHackQt NetHack-$(SVS)-macosx-qt.dmg +endif # end of build_qt_pkg +endif # WANT_WIN_QT for packaging +endif # MAKEFILE_TOP diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm new file mode 100644 index 000000000..0591db7ba --- /dev/null +++ b/sys/lib/hints/wasm @@ -0,0 +1,153 @@ + +#-PRE xxxx +# enscripten WebAssembly config + +WANT_WASM=1 +WASM_DEBUG=1 +WASM_DATA_DIR=$(NHSROOT)/src/wasm-data/Users/ampower/nethackdir + +# toolchain +EMCC=emcc +EMAR=emar rcu +EMRANLIB=emranlib + +# link flags +EMCC_LFLAGS=-s SINGLE_FILE=1 +EMCC_LFLAGS=-s WASM=1 +EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH +EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["_nhmain"]' -O3 +EMCC_LFLAGS+=-s MODULARIZE +EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main"]' +EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString"]' +EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 +EMCC_LFLAGS+=--embed-file wasm-data@/ + +# WASM C flags +EMCC_CFLAGS= +EMCC_CFLAGS+=-Wall -Werror +EMCC_CFLAGS+=-DWASM +EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 +EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 +EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 +EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED +EMCC_PROD_CFLAGS+=-O3 + +# Nethack C flags +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +CFLAGS+=-g -I../include -DNOTPARMDECL +CFLAGS+=-Wall -Werror +CFLAGS+=-DGCC_WARN + +# NetHack sources control +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDLB +CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +CFLAGS+=-DNOMAIL + +ifdef WASM_DEBUG +EMCC_CFLAGS+=$(EMCC_DEBUG_CFLAGS) +else +EMCC_CFLAGS+=$(EMCC_PROD_CFLAGS) +endif + +ifdef WANT_SHARE_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 +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 +PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ + . sys/unix/hints/macosx.sh group2 $(GAMEGRP); \ + mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; + +else ifdef WANT_SOURCE_INSTALL + +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: +MOREALL=$(MAKE) install +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE + +else # !WANT_SOURCE_INSTALL + +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 +endif # WANT_DEFAULT X11 + +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +ifdef WANT_BUNDLE +# +# Bundle +# +# $(HACKDIR)/$(GAME).app/ +# Contents/ +# Frameworks/ +# Info.plist +# MacOS/ +# $(GAME) +# PkgInfo/ +# PlugIns/ +# Resources/ +# SharedFrameWorks/ +# +BUNDLE = mkdir -p $(HACKDIR)/nethack.app/Contents/MacOS; \ + sys/unix/hints/macosx.sh infoplist > $(HACKDIR)/nethack.app/Contents/Info.plist; \ + mv $(HACKDIR)/nethack $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +ifdef WANT_SHARE_INSTALL +BUNDLE+= chmod $(GAMEPERM) $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +endif + +POSTINSTALL+= $(BUNDLE) +POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ + sed -i '' 's;HACKDIR/$(GAME);HACKDIR/$(GAME).app/Contents/MacOS/$(GAME);' $(SHELLDIR)/$(GAME) ; fi; +endif # WANT_BUNDLE +endif # !WANT_SHARE_INSTALL + +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) + +#-POST +# no post \ No newline at end of file diff --git a/sys/lib/libnethackmain.c b/sys/lib/libnethackmain.c new file mode 100644 index 000000000..ed8142bd7 --- /dev/null +++ b/sys/lib/libnethackmain.c @@ -0,0 +1,824 @@ +/* NetHack 3.7 unixmain.c $NHDT-Date: 1596498297 2020/08/03 23:44:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/*-Copyright (c) Robert Patrick Rankin, 2011. */ +/* NetHack may be freely redistributed. See license for details. */ + +/* main.c - Unix NetHack */ + +#include "hack.h" +#include "dlb.h" + +#include +#include +#include +#include +#ifndef O_RDONLY +#include +#endif + +/* for cross-compiling to WebAssembly (WASM) */ +#ifdef __EMSCRIPTEN__ +#include +#endif + +#if !defined(_BULL_SOURCE) && !defined(__sgi) && !defined(_M_UNIX) +#if !defined(SUNOS4) && !(defined(ULTRIX) && defined(__GNUC__)) +#if defined(POSIX_TYPES) || defined(SVR4) || defined(HPUX) +extern struct passwd *FDECL(getpwuid, (uid_t)); +#else +extern struct passwd *FDECL(getpwuid, (int)); +#endif +#endif +#endif +extern struct passwd *FDECL(getpwnam, (const char *)); +#ifdef CHDIR +static void FDECL(chdirx, (const char *, BOOLEAN_P)); +#endif /* CHDIR */ +static boolean NDECL(whoami); +static void FDECL(process_options, (int, char **)); + +#ifdef _M_UNIX +extern void NDECL(check_sco_console); +extern void NDECL(init_sco_cons); +#endif +#ifdef __linux__ +extern void NDECL(check_linux_console); +extern void NDECL(init_linux_cons); +#endif + +static void NDECL(wd_message); +static boolean wiz_error_flag = FALSE; +static struct passwd *NDECL(get_unix_pw); + +#ifdef __EMSCRIPTEN__ +/* if WebAssembly, export this API and don't optimize it out */ +EMSCRIPTEN_KEEPALIVE +int +main(argc, argv) +int argc; +char *argv[]; + +#else /* !__EMSCRIPTEN__ */ + +int +nhmain(argc, argv) +int argc; +char *argv[]; + +#endif /* __EMSCRIPTEN__ */ +{ +#ifdef CHDIR + register char *dir; +#endif + NHFILE *nhfp; + boolean exact_username; + boolean resuming = FALSE; /* assume new game */ + boolean plsel_once = FALSE; + int i; + + printf ("nhmain\n"); + printf ("argc: %d\n", argc); + printf ("argv: %p\n", (void *)argv); + for (i = 0; i < argc; i++) { + printf ("argv[%d]: %s\n", i, argv[i]); + } + + early_init(); + +#if 0 /* __APPLE__ */ + { +/* special hack to change working directory to a resource fork when + running from finder --sam */ +#define MAC_PATH_VALUE ".app/Contents/MacOS/" + char mac_cwd[1024], *mac_exe = argv[0], *mac_tmp; + int arg0_len = strlen(mac_exe), mac_tmp_len, mac_lhs_len = 0; + getcwd(mac_cwd, 1024); + if (mac_exe[0] == '/' && !strcmp(mac_cwd, "/")) { + if ((mac_exe = strrchr(mac_exe, '/'))) + mac_exe++; + else + mac_exe = argv[0]; + mac_tmp_len = (strlen(mac_exe) * 2) + strlen(MAC_PATH_VALUE); + if (mac_tmp_len <= arg0_len) { + mac_tmp = malloc(mac_tmp_len + 1); + sprintf(mac_tmp, "%s%s%s", mac_exe, MAC_PATH_VALUE, mac_exe); + if (!strcmp(argv[0] + (arg0_len - mac_tmp_len), mac_tmp)) { + mac_lhs_len = + (arg0_len - mac_tmp_len) + strlen(mac_exe) + 5; + if (mac_lhs_len > mac_tmp_len - 1) + mac_tmp = realloc(mac_tmp, mac_lhs_len); + strncpy(mac_tmp, argv[0], mac_lhs_len); + mac_tmp[mac_lhs_len] = '\0'; + chdir(mac_tmp); + } + free(mac_tmp); + } + } + } +#endif /* __APPLE__ */ + + g.hname = argv[0]; + g.hackpid = getpid(); + (void) umask(0777 & ~FCMASK); + + choose_windows(DEFAULT_WINDOW_SYS); + +#ifdef CHDIR /* otherwise no chdir() */ + /* + * See if we must change directory to the playground. + * (Perhaps hack runs suid and playground is inaccessible + * for the player.) + * The environment variable HACKDIR is overridden by a + * -d command line option (must be the first option given). + */ + dir = nh_getenv("NETHACKDIR"); + if (!dir) + dir = nh_getenv("HACKDIR"); + + if (argc > 1) { + if (argcheck(argc, argv, ARG_VERSION) == 2) + exit(EXIT_SUCCESS); + + if (argcheck(argc, argv, ARG_SHOWPATHS) == 2) { +#ifdef CHDIR + chdirx((char *) 0, 0); +#endif + iflags.initoptions_noterminate = TRUE; + initoptions(); + iflags.initoptions_noterminate = FALSE; + reveal_paths(); + exit(EXIT_SUCCESS); + } + if (argcheck(argc, argv, ARG_DEBUG) == 1) { + argc--; + argv++; + } + if (argc > 1 && !strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') { + /* avoid matching "-dec" for DECgraphics; since the man page + * says -d directory, hope nobody's using -desomething_else + */ + argc--; + argv++; + dir = argv[0] + 2; + if (*dir == '=' || *dir == ':') + dir++; + if (!*dir && argc > 1) { + argc--; + argv++; + dir = argv[0]; + } + if (!*dir) + error("Flag -d must be followed by a directory name."); + } + } +#endif /* CHDIR */ + + if (argc > 1) { + /* + * Now we know the directory containing 'record' and + * may do a prscore(). Exclude `-style' - it's a Qt option. + */ + if (!strncmp(argv[1], "-s", 2) && strncmp(argv[1], "-style", 6)) { +#ifdef CHDIR + chdirx(dir, 0); +#endif +#ifdef SYSCF + initoptions(); +#endif +#ifdef PANICTRACE + ARGV0 = g.hname; /* save for possible stack trace */ +#ifndef NO_SIGNAL + panictrace_setsignals(TRUE); +#endif +#endif + prscore(argc, argv); + /* FIXME: shouldn't this be using nh_terminate() to free + up any memory allocated by initoptions() */ + exit(EXIT_SUCCESS); + } + } /* argc > 1 */ + +/* + * Change directories before we initialize the window system so + * we can find the tile file. + */ +#ifdef CHDIR + chdirx(dir, 1); +#endif + +#ifdef _M_UNIX + check_sco_console(); +#endif +#ifdef __linux__ + check_linux_console(); +#endif + initoptions(); +#ifdef PANICTRACE + ARGV0 = g.hname; /* save for possible stack trace */ +#ifndef NO_SIGNAL + panictrace_setsignals(TRUE); +#endif +#endif + exact_username = whoami(); + + /* + * It seems you really want to play. + */ + u.uhp = 1; /* prevent RIP on early quits */ + g.program_state.preserve_locks = 1; +#ifndef NO_SIGNAL + sethanguphandler((SIG_RET_TYPE) hangup); +#endif + + process_options(argc, argv); /* command line options */ +#ifdef WINCHAIN + commit_windowchain(); +#endif + init_nhwindows(&argc, argv); /* now we can set up window system */ +#ifdef _M_UNIX + init_sco_cons(); +#endif +#ifdef __linux__ + init_linux_cons(); +#endif + +#ifdef DEF_PAGER + if (!(g.catmore = nh_getenv("HACKPAGER")) + && !(g.catmore = nh_getenv("PAGER"))) + g.catmore = DEF_PAGER; +#endif +#ifdef MAIL + getmailstatus(); +#endif + + /* wizard mode access is deferred until here */ + set_playmode(); /* sets plname to "wizard" for wizard mode */ + /* hide any hyphens from plnamesuffix() */ + g.plnamelen = exact_username ? (int) strlen(g.plname) : 0; + /* strip role,race,&c suffix; calls askname() if plname[] is empty + or holds a generic user name like "player" or "games" */ + plnamesuffix(); + + if (wizard) { + /* use character name rather than lock letter for file names */ + g.locknum = 0; + } else { + /* suppress interrupts while processing lock file */ + (void) signal(SIGQUIT, SIG_IGN); + (void) signal(SIGINT, SIG_IGN); + } + + dlb_init(); /* must be before newgame() */ + + /* + * Initialize the vision system. This must be before mklev() on a + * new game or before a level restore on a saved game. + */ + vision_init(); + + display_gamewindows(); + + /* + * First, try to find and restore a save file for specified character. + * We'll return here if new game player_selection() renames the hero. + */ + attempt_restore: + + /* + * getlock() complains and quits if there is already a game + * in progress for current character name (when g.locknum == 0) + * or if there are too many active games (when g.locknum > 0). + * When proceeding, it creates an empty .0 file to + * designate the current game. + * getlock() constructs based on the character + * name (for !g.locknum) or on first available of alock, block, + * clock, &c not currently in use in the playground directory + * (for g.locknum > 0). + */ + if (*g.plname) { + getlock(); + g.program_state.preserve_locks = 0; /* after getlock() */ + } + + if (*g.plname && (nhfp = restore_saved_game()) != 0) { + const char *fq_save = fqname(g.SAVEF, SAVEPREFIX, 1); + + (void) chmod(fq_save, 0); /* disallow parallel restores */ +#ifndef NO_SIGNAL + (void) signal(SIGINT, (SIG_RET_TYPE) done1); +#endif +#ifdef NEWS + if (iflags.news) { + display_file(NEWS, FALSE); + iflags.news = FALSE; /* in case dorecover() fails */ + } +#endif + pline("Restoring save file..."); + mark_synch(); /* flush output */ + if (dorecover(nhfp)) { + resuming = TRUE; /* not starting new game */ + wd_message(); + if (discover || wizard) { + /* this seems like a candidate for paranoid_confirmation... */ + if (yn("Do you want to keep the save file?") == 'n') { + (void) delete_savefile(); + } else { + (void) chmod(fq_save, FCMASK); /* back to readable */ + nh_compress(fq_save); + } + } + } + } + + if (!resuming) { + boolean neednewlock = (!*g.plname); + /* new game: start by choosing role, race, etc; + player might change the hero's name while doing that, + in which case we try to restore under the new name + and skip selection this time if that didn't succeed */ + if (!iflags.renameinprogress || iflags.defer_plname || neednewlock) { + if (!plsel_once) + player_selection(); + plsel_once = TRUE; + if (neednewlock && *g.plname) + goto attempt_restore; + if (iflags.renameinprogress) { + /* player has renamed the hero while selecting role; + if locking alphabetically, the existing lock file + can still be used; otherwise, discard current one + and create another for the new character name */ + if (!g.locknum) { + delete_levelfile(0); /* remove empty lock file */ + getlock(); + } + goto attempt_restore; + } + } + newgame(); + wd_message(); + } + + /* moveloop() never returns but isn't flagged NORETURN */ + moveloop(resuming); + + exit(EXIT_SUCCESS); + /*NOTREACHED*/ + return 0; +} + +/* caveat: argv elements might be arbitrary long */ +static void +process_options(argc, argv) +int argc; +char *argv[]; +{ + int i, l; + + /* + * Process options. + */ + while (argc > 1 && argv[1][0] == '-') { + argv++; + argc--; + l = (int) strlen(*argv); + /* must supply at least 4 chars to match "-XXXgraphics" */ + if (l < 4) + l = 4; + + switch (argv[0][1]) { + case 'D': + case 'd': + if ((argv[0][1] == 'D' && !argv[0][2]) + || !strcmpi(*argv, "-debug")) { + wizard = TRUE, discover = FALSE; + } else if (!strncmpi(*argv, "-DECgraphics", l)) { + load_symset("DECGraphics", PRIMARY); + switch_symbols(TRUE); + } else { + raw_printf("Unknown option: %.60s", *argv); + } + break; + case 'X': + discover = TRUE, wizard = FALSE; + break; +#ifdef NEWS + case 'n': + iflags.news = FALSE; + break; +#endif + case 'u': + if (argv[0][2]) { + (void) strncpy(g.plname, argv[0] + 2, sizeof g.plname - 1); + g.plnamelen = 0; /* plname[] might have -role-race attached */ + } else if (argc > 1) { + argc--; + argv++; + (void) strncpy(g.plname, argv[0], sizeof g.plname - 1); + g.plnamelen = 0; + } else { + raw_print("Player name expected after -u"); + } + break; + case 'I': + case 'i': + if (!strncmpi(*argv, "-IBMgraphics", l)) { + load_symset("IBMGraphics", PRIMARY); + load_symset("RogueIBM", ROGUESET); + switch_symbols(TRUE); + } else { + raw_printf("Unknown option: %.60s", *argv); + } + break; + case 'p': /* profession (role) */ + if (argv[0][2]) { + if ((i = str2role(&argv[0][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 (argv[0][2]) { + if ((i = str2race(&argv[0][2])) >= 0) + flags.initrace = i; + } else if (argc > 1) { + argc--; + argv++; + if ((i = str2race(argv[0])) >= 0) + flags.initrace = i; + } + break; + case 'w': /* windowtype */ + config_error_init(FALSE, "command line", FALSE); + choose_windows(&argv[0][2]); + config_error_done(); + break; + case '@': + flags.randomall = 1; + break; + default: + if ((i = str2role(&argv[0][1])) >= 0) { + flags.initrole = i; + break; + } + /* else raw_printf("Unknown option: %.60s", *argv); */ + } + } + +#ifdef SYSCF + if (argc > 1) + raw_printf("MAXPLAYERS are set in sysconf file.\n"); +#else + /* XXX This is deprecated in favor of SYSCF with MAXPLAYERS */ + if (argc > 1) + g.locknum = atoi(argv[1]); +#endif +#ifdef MAX_NR_OF_PLAYERS + /* limit to compile-time limit */ + if (!g.locknum || g.locknum > MAX_NR_OF_PLAYERS) + g.locknum = MAX_NR_OF_PLAYERS; +#endif +#ifdef SYSCF + /* let syscf override compile-time limit */ + if (!g.locknum || (sysopt.maxplayers && g.locknum > sysopt.maxplayers)) + g.locknum = sysopt.maxplayers; +#endif +} + +#ifdef CHDIR +static void +chdirx(dir, wr) +const char *dir; +boolean wr; +{ + if (dir /* User specified directory? */ +#ifdef HACKDIR + && strcmp(dir, HACKDIR) /* and not the default? */ +#endif + ) { +#ifdef SECURE + (void) setgid(getgid()); + (void) setuid(getuid()); /* Ron Wessels */ +#endif + } else { + /* non-default data files is a sign that scores may not be + * compatible, or perhaps that a binary not fitting this + * system's layout is being used. + */ +#ifdef VAR_PLAYGROUND + int len = strlen(VAR_PLAYGROUND); + + g.fqn_prefix[SCOREPREFIX] = (char *) alloc(len + 2); + Strcpy(g.fqn_prefix[SCOREPREFIX], VAR_PLAYGROUND); + if (g.fqn_prefix[SCOREPREFIX][len - 1] != '/') { + g.fqn_prefix[SCOREPREFIX][len] = '/'; + g.fqn_prefix[SCOREPREFIX][len + 1] = '\0'; + } + +#endif + } + +#ifdef HACKDIR + if (dir == (const char *) 0) + dir = HACKDIR; +#endif + + if (dir && chdir(dir) < 0) { + perror(dir); + error("Cannot chdir to %s.", dir); + } + + /* warn the player if we can't write the record file + * perhaps we should also test whether . is writable + * unfortunately the access system-call is worthless. + */ + if (wr) { +#ifdef VAR_PLAYGROUND + g.fqn_prefix[LEVELPREFIX] = g.fqn_prefix[SCOREPREFIX]; + g.fqn_prefix[SAVEPREFIX] = g.fqn_prefix[SCOREPREFIX]; + g.fqn_prefix[BONESPREFIX] = g.fqn_prefix[SCOREPREFIX]; + g.fqn_prefix[LOCKPREFIX] = g.fqn_prefix[SCOREPREFIX]; + g.fqn_prefix[TROUBLEPREFIX] = g.fqn_prefix[SCOREPREFIX]; +#endif + check_recordfile(dir); + } +} +#endif /* CHDIR */ + +/* returns True iff we set plname[] to username which contains a hyphen */ +static boolean +whoami() +{ + /* + * Who am i? Algorithm: 1. Use name as specified in NETHACKOPTIONS + * 2. Use $USER or $LOGNAME (if 1. fails) + * 3. Use getlogin() (if 2. fails) + * The resulting name is overridden by command line options. + * If everything fails, or if the resulting name is some generic + * account like "games", "play", "player", "hack" then eventually + * we'll ask him. + * Note that we trust the user here; it is possible to play under + * somebody else's name. + */ + if (!*g.plname) { + register const char *s; + + s = nh_getenv("USER"); + if (!s || !*s) + s = nh_getenv("LOGNAME"); + if (!s || !*s) + s = getlogin(); + + if (s && *s) { + (void) strncpy(g.plname, s, sizeof g.plname - 1); + if (index(g.plname, '-')) + return TRUE; + } + } + return FALSE; +} + +void +sethanguphandler(handler) +void FDECL((*handler), (int)); +{ +#ifdef SA_RESTART + /* don't want reads to restart. If SA_RESTART is defined, we know + * sigaction exists and can be used to ensure reads won't restart. + * If it's not defined, assume reads do not restart. If reads restart + * and a signal occurs, the game won't do anything until the read + * succeeds (or the stream returns EOF, which might not happen if + * reading from, say, a window manager). */ + struct sigaction sact; + + (void) memset((genericptr_t) &sact, 0, sizeof sact); + sact.sa_handler = (SIG_RET_TYPE) handler; + (void) sigaction(SIGHUP, &sact, (struct sigaction *) 0); +#ifdef SIGXCPU + (void) sigaction(SIGXCPU, &sact, (struct sigaction *) 0); +#endif +#else /* !SA_RESTART */ + (void) signal(SIGHUP, (SIG_RET_TYPE) handler); +#ifdef SIGXCPU + (void) signal(SIGXCPU, (SIG_RET_TYPE) handler); +#endif +#endif /* ?SA_RESTART */ +} + +#ifdef PORT_HELP +void +port_help() +{ + /* + * Display unix-specific help. Just show contents of the helpfile + * named by PORT_HELP. + */ + display_file(PORT_HELP, TRUE); +} +#endif + +/* validate wizard mode if player has requested access to it */ +boolean +authorize_wizard_mode() +{ + struct passwd *pw = get_unix_pw(); + + if (pw && sysopt.wizards && sysopt.wizards[0]) { + if (check_user_string(sysopt.wizards)) + return TRUE; + } + wiz_error_flag = TRUE; /* not being allowed into wizard mode */ + return FALSE; +} + +static void +wd_message() +{ + if (wiz_error_flag) { + if (sysopt.wizards && sysopt.wizards[0]) { + char *tmp = build_english_list(sysopt.wizards); + pline("Only user%s %s may access debug (wizard) mode.", + index(sysopt.wizards, ' ') ? "s" : "", tmp); + free(tmp); + } else + pline("Entering explore/discovery mode instead."); + wizard = 0, discover = 1; /* (paranoia) */ + } else if (discover) + You("are in non-scoring explore/discovery mode."); +} + +/* + * Add a slash to any name not ending in /. There must + * be room for the / + */ +void +append_slash(name) +char *name; +{ + char *ptr; + + if (!*name) + return; + ptr = name + (strlen(name) - 1); + if (*ptr != '/') { + *++ptr = '/'; + *++ptr = '\0'; + } + return; +} + +boolean +check_user_string(optstr) +char *optstr; +{ + struct passwd *pw; + int pwlen; + char *eop, *w; + char *pwname = 0; + + if (optstr[0] == '*') + return TRUE; /* allow any user */ + if (sysopt.check_plname) + pwname = g.plname; + else if ((pw = get_unix_pw()) != 0) + pwname = pw->pw_name; + if (!pwname || !*pwname) + return FALSE; + pwlen = (int) strlen(pwname); + eop = eos(optstr); + w = optstr; + while (w + pwlen <= eop) { + if (!*w) + break; + if (isspace(*w)) { + w++; + continue; + } + if (!strncmp(w, pwname, pwlen)) { + if (!w[pwlen] || isspace(w[pwlen])) + return TRUE; + } + while (*w && !isspace(*w)) + w++; + } + return FALSE; +} + +static struct passwd * +get_unix_pw() +{ + char *user; + unsigned uid; + static struct passwd *pw = (struct passwd *) 0; + + if (pw) + return pw; /* cache answer */ + + uid = (unsigned) getuid(); + user = getlogin(); + if (user) { + pw = getpwnam(user); + if (pw && ((unsigned) pw->pw_uid != uid)) + pw = 0; + } + if (pw == 0) { + user = nh_getenv("USER"); + if (user) { + pw = getpwnam(user); + if (pw && ((unsigned) pw->pw_uid != uid)) + pw = 0; + } + if (pw == 0) { + pw = getpwuid(uid); + } + } + return pw; +} + +char * +get_login_name() +{ + static char buf[BUFSZ]; + struct passwd *pw = get_unix_pw(); + + buf[0] = '\0'; + if (pw) + (void)strcpy(buf, pw->pw_name); + + return buf; +} + +#if 0 /* __APPLE__ */ +extern int errno; + +void +port_insert_pastebuf(buf) +char *buf; +{ + /* This should be replaced when there is a Cocoa port. */ + const char *errfmt; + size_t len; + FILE *PB = popen("/usr/bin/pbcopy", "w"); + + if (!PB) { + errfmt = "Unable to start pbcopy (%d)\n"; + goto error; + } + + len = strlen(buf); + /* Remove the trailing \n, carefully. */ + if (buf[len - 1] == '\n') + len--; + + /* XXX Sorry, I'm too lazy to write a loop for output this short. */ + if (len != fwrite(buf, 1, len, PB)) { + errfmt = "Error sending data to pbcopy (%d)\n"; + goto error; + } + + if (pclose(PB) != -1) { + return; + } + errfmt = "Error finishing pbcopy (%d)\n"; + + error: + raw_printf(errfmt, strerror(errno)); +} +#endif /* __APPLE__ */ + +unsigned long +sys_random_seed() +{ + unsigned long seed = 0L; + unsigned long pid = (unsigned long) getpid(); + boolean no_seed = TRUE; +#ifdef DEV_RANDOM + FILE *fptr; + + fptr = fopen(DEV_RANDOM, "r"); + if (fptr) { + fread(&seed, sizeof (long), 1, fptr); + has_strong_rngseed = TRUE; /* decl.c */ + no_seed = FALSE; + (void) fclose(fptr); + } else { + /* leaves clue, doesn't exit */ + paniclog("sys_random_seed", "falling back to weak seed"); + } +#endif + if (no_seed) { + seed = (unsigned long) getnow(); /* time((TIME_type) 0) */ + /* Quick dirty band-aid to prevent PRNG prediction */ + if (pid) { + if (!(pid & 3L)) + pid -= 1L; + seed *= pid; + } + } + return seed; +} + +/*unixmain.c*/ diff --git a/sys/lib/mkmkfile.sh b/sys/lib/mkmkfile.sh new file mode 100755 index 000000000..e1afc0e15 --- /dev/null +++ b/sys/lib/mkmkfile.sh @@ -0,0 +1,44 @@ +#!/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 $ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. +# NetHack may be freely redistributed. See license for details. + +# build one makefile +# args are: +# $1 basefile +# $2 basefile tag +# $3 install path +# $4 hints file (path) +# $5 hints file (as given by user) + +echo "#" > $3 +echo "# This file is generated automatically. Do not edit." >> $3 +echo "# Your changes will be lost." >> $3 +echo "# Identify this file:" >> $3 +echo "MAKEFILE_$2=1" >> $3 +echo "" >> $3 + +echo "###" >> $3 +echo "### Start $5 PRE" >> $3 +echo "###" >> $3 +awk '/^#-PRE/,/^#-POST/{ \ + if(index($0, "#-PRE") == 1) print "# (new segment at source line",NR,")"; \ + if(index($0, "#-INCLUDE") == 1) system("cat hints/include/"$2); \ + else if(index($0, "#-P") != 1) print}' $4 >> $3 +echo "### End $5 PRE" >> $3 +echo "" >> $3 + +echo "###" >> $3 +echo "### Start $1" >> $3 +echo "###" >> $3 +cat $1 >> $3 +echo "### End $1" >> $3 +echo "" >> $3 + +echo "###" >> $3 +echo "### Start $5 POST" >> $3 +echo "###" >> $3 +awk '/^#-POST/,/^#-PRE/{ \ + if(index($0, "#-POST") == 1) print "# (new segment at source line",NR,")"; \ + if(index($0, "#-P") != 1) print}' $4 >> $3 +echo "### End $5 POST" >> $3 diff --git a/sys/lib/setup.sh b/sys/lib/setup.sh new file mode 100755 index 000000000..2db51ba69 --- /dev/null +++ b/sys/lib/setup.sh @@ -0,0 +1,37 @@ +#!/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 $ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. +# NetHack may be freely redistributed. See license for details. +# +# Build and install makefiles. +# +# Argument is the hints file to use (or no argument for traditional setup). +# e.g.: +# sh setup.sh +# or +# sh setup.sh hints/macosx10.5 (from sys/unix) +# or +# sh setup.sh sys/unix/hints/macosx10.5 (from top) + +# Were we started from the top level? Cope. +prefix=. +if [ -f sys/unix/Makefile.top ]; then cd sys/unix; prefix=../..; fi + +case "x$1" in +x) hints=/dev/null + hfile=/dev/null + ;; +*) hints=$prefix/$1 + hfile=$1 + # sanity check + if [ ! -f "$hints" ]; then + echo "Cannot find hints file $hfile" + exit 1 + fi + ;; +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.src SRC ../../src/Makefile $hints $hfile +/bin/sh ./mkmkfile.sh Makefile.utl UTL ../../util/Makefile $hints $hfile diff --git a/sys/lib/sysconf b/sys/lib/sysconf new file mode 100644 index 000000000..77b4c383f --- /dev/null +++ b/sys/lib/sysconf @@ -0,0 +1,150 @@ +# NetHack 3.7 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland +# NetHack may be freely redistributed. See license for details. +# +# Sample sysconf file. +# The sysconf file is only used if NetHack is compiled with SYSCF defined. +# It can be used to augment or override certain settings compiled into the +# program. +# +# This file can also be used to set local system defaults for run-time +# options, using the same syntax as an individual user's ./nethackrc file. + +# Which users can use debug mode (aka wizard mode; accessed via '-D' command +# line flag or OPTIONS=playmode:debug in the runtime options config file). +# A value of * allows anyone to enter debugging mode. +WIZARDS=root games + +# Which users can use explore mode (aka discover mode; accessed via '-X' +# command line flag or OPTIONS=playmode:explore in runtime options file or +# via '#exploremode' command during normal play). Same syntax as WIZARDS. +EXPLORERS=* + +# Users allowed to use the '!' (shell escape) and '^Z' (suspend process) +# commands to temporarily leave the game and enter a shell process. +# (To resume play, use the shell command 'exit' (for most shells) to +# return from '!' or the shell command 'fg' to return from '^Z'. +# For the typical multi-user system where players have access to a shell +# prompt when logged in and run the game from their own username, a value +# of 'SHELLERS=*' is appropriate. However, some inexperienced players +# occasionally get stuck outside the game by accidentally typing '!' or +# '^Z' during play and not knowing how to go back.) +# Uses the same syntax as the WIZARDS and EXPLORERS options above. +#SHELLERS= + +# If the user name is found in this list, prompt for username instead. +# Uses the same syntax as the WIZARDS option above. +# A public server should probably disable this. +# ["ec2-user" is the default user name on Amazon Linux] +GENERICUSERS=play player game games nethack nethacker ec2-user + +# Use the player name for matching WIZARDS, EXPLORERS and SHELLERS, +# instead of the user's login name. +#CHECK_PLNAME=1 + +# Limit the number of simultaneous games (see also nethack.sh). +# Valid values are 0-25. +# Commenting this out or setting the value to 0 constructs lock files +# with UID and playername, so each user may have one game at a time, +# but number of different players is not limited. +# Setting this to any other value constructs the lock files with +# letter and "lock" (eg. alock, block, ...) +MAXPLAYERS=10 + +# If not null, added to string "To get local support, " in the support +# information help. +#SUPPORT=call Izchak at extension 42. + +# If not null, displayed at the end of a panic-save sequence. +#RECOVER=Run the recover program. + +# Uncomment the next line to disable the SEDUCE option, causing succubi and +# incubi to use nymphs' charm behavior rather than their own seduce behavior. +#SEDUCE=0 + +# Uncomment the next line to enable some accessibility features such +# as S_hero_override and S_pet_override symbols for screen readers +# in the user config file. +#ACCESSIBILITY=1 + +# Uncomment to disable savefile UID checking. +#CHECK_SAVE_UID=0 + +# Record (high score) file options. +# CAUTION: changing these after people have started playing games can +# lead to lost high scores! +# Maximum entries for one person. +#PERSMAX=10 +# Maximum entries in the record file. +#ENTRYMAX=100 +# Minimum points to get an entry. +#POINTSMIN=1 +# Determine identity of "person" in the score file with name (0) or +# numeric (1) user id. +#PERS_IS_UID=1 + +# Maximum number of score file entries to use for random statue names +#MAX_STATUENAME_RANK=10 + +# Show debugging information originating from these source files. +# Use '*' for all, or list source files separated by spaces. +# Only available if game has been compiled with DEBUG, and can be +# overridden via DEBUGFILES environment variable. +#DEBUGFILES=* + +# Save end of game dump log to this file. +# Only available if NetHack was compiled with DUMPLOG +# Allows following placeholders: +# %% literal '%' +# %v version (eg. "3.7.0-0") +# %u game UID +# %t game start time, UNIX timestamp format +# %T current time, UNIX timestamp format +# %d game start time, YYYYMMDDhhmmss format +# %D current time, YYYYMMDDhhmmss format +# %n player name +# %N first character of player name +#DUMPLOGFILE=/tmp/nethack.%n.%d.log + +# Number of bones file pools. +# The pool you belong to is determined at game start. You will +# load and save bones only from that pool. Generally useful +# for public servers only. +# Changing this might make existing bones inaccessible. +# Disabled by setting to 0, or commenting out. +#BONES_POOLS=10 + +# Try to get more info in case of a program bug or crash. Only used +# if the program is built with the PANICTRACE compile-time option enabled. +# By default PANICTRACE is enabled if (NH_DEVEL_STATUS != NH_STATUS_RELEASED), +# otherwise disabled. +# Using GDB can get more information and works on more systems but requires +# 'gdb' be available; using LIBC only works if NetHack is linked with a +# libc that supports the backtrace(3) API. Both require certain compilation +# options. See src/end.c and sys/unix/hints/* for more information. +#GDBPATH=/usr/bin/gdb +#GREPPATH=/bin/grep +# Values are priorities: 0 - do not use this method, 1 - low priority, +# 2 - high priority. Non-zero priority methods are tried in order. +PANICTRACE_GDB=0 +PANICTRACE_LIBC=0 + +# 'portable_device_paths' is only supported for Windows. Starting with +# 3.6.3, nethack on Windows treats the folder containing nethack.exe and +# nethackW.exe as read-only and puts data files which are generated or +# modified during play or by the user in assorted folders derived from +# user name. 3.6.4 added PORTABLE_DEVICE_PATHS to allow reverting to +# the old behavior of having the run-time configuration file and other +# data in the same directory as the executable so that the whole thing +# can be moved from one machine to another (flash drive or perhaps cloud) +# without updating folder paths. +#PORTABLE_DEVICE_PATHS=0 + +# Ordinary run-time options can be set here to override the builtin-in +# default values. Unlike all the SYSCF values above, individual users +# can override the overridden options set here by choosing their own +# option settings via NETHACKOPTIONS in their environment or via +# ~/.nethackrc run-time configuration file. +#OPTIONS=!autopickup,fruit:tomato,symset:DECgraphics + +#eof diff --git a/util/makedefs.c b/util/makedefs.c index 8b5179c1b..7ff0ec2c9 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1218,10 +1218,18 @@ do_date() #endif Fprintf(ofp, "#define VERSION_SANITY1 0x%08lx%s\n", version.entity_count, ul_sfx); +#ifndef WASM Fprintf(ofp, "#define VERSION_SANITY2 0x%08lx%s\n", version.struct_sizes1, ul_sfx); Fprintf(ofp, "#define VERSION_SANITY3 0x%08lx%s\n", version.struct_sizes2, ul_sfx); +#else /* WASM */ + Fprintf(ofp, "#define VERSION_SANITY2 0x%08llx%s\n", version.struct_sizes1, + ul_sfx); + Fprintf(ofp, "#define VERSION_SANITY3 0x%08llx%s\n", version.struct_sizes2, + ul_sfx); +#endif /* !WASM */ + Fprintf(ofp, "\n"); Fprintf(ofp, "#define VERSION_STRING \"%s\"\n", version_string(buf, ".")); Fprintf(ofp, "#define VERSION_ID \\\n \"%s\"\n", From 3f81bd5af64863165be2e43f373ca6cb4774a903 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 27 Aug 2020 16:14:17 -0700 Subject: [PATCH 137/708] fix pull request #380 - turning into slime The turn-to-slime countdown is one of the ones that uses turns/2 to stretch the sequence out longer and it was displaying the hero as green slime when there was another turn before it happened. (In theory anyway. I could not get my hero to be shown as slime and still have one move left, even when hasted.) Make the hero mimic green slime starting on the last turn before being polymorphed instead of next to last. Fixes #380 --- doc/fixes37.0 | 3 ++- src/timeout.c | 14 +++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4a638b5f0..d4c1b2628 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.289 $ $NHDT-Date: 1597967807 2020/08/20 23:56:47 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.290 $ $NHDT-Date: 1598570054 2020/08/27 23:14:14 $ General Fixes and Modified Features ----------------------------------- @@ -247,6 +247,7 @@ leashing or unleashing pets wasn't updating persistent inventory window end of game inventory disclosure passed an inappropriate argument to the inventory display routine; not noticeable for tty and curses, noticeable but not harmful for X11, and slightly harmful for Qt +turning into slime rendered hero as slime one turn too soon Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/timeout.c b/src/timeout.c index fb24b87f0..ca24e94b9 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.c $NHDT-Date: 1596498217 2020/08/03 23:43:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.118 $ */ +/* NetHack 3.7 timeout.c $NHDT-Date: 1598570054 2020/08/27 23:14:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -316,16 +316,20 @@ static NEARDATA const char *const slime_texts[] = { static void slime_dialogue() { - register long i = (Slimed & TIMEOUT) / 2L; + long t = (Slimed & TIMEOUT), i = t / 2L; - if (i == 1L) { + if (t == 1L) { /* 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 */ g.youmonst.m_ap_type = M_AP_MONSTER; g.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); } - if (((Slimed & TIMEOUT) % 2L) && i >= 0L && i < SIZE(slime_texts)) { + + if ((t % 2L) != 0L && i >= 0L && i < SIZE(slime_texts)) { char buf[BUFSZ]; Strcpy(buf, slime_texts[SIZE(slime_texts) - i - 1L]); @@ -2403,7 +2407,7 @@ long adjust; /* how much to adjust timeout */ /* restore elements */ if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t) &count, sizeof count); - + while (count-- > 0) { curr = (timer_element *) alloc(sizeof(timer_element)); if (nhfp->structlevel) From 1df2fdca4422db5b567f5a7613ef2295799cabf9 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 27 Aug 2020 17:38:11 -0700 Subject: [PATCH 138/708] fix pull request #379 - is_displacer() A couple of places which could/should have been using existing is_displacer() macro weren't. No change in behavior. Fixes #379 --- src/do.c | 4 ++-- src/mon.c | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/do.c b/src/do.c index f4415b251..580c701c0 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do.c $NHDT-Date: 1596498158 2020/08/03 23:42:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ */ +/* NetHack 3.7 do.c $NHDT-Date: 1598575088 2020/08/28 00:38:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1944,7 +1944,7 @@ long timeout UNUSED; /* corpse will revive somewhere else if there is a monster in the way; Riders get a chance to try to bump the obstacle out of their way */ - if ((mptr->mflags3 & M3_DISPLACES) != 0 && body->where == OBJ_FLOOR + if (is_displacer(mptr) && body->where == OBJ_FLOOR && get_obj_location(body, &x, &y, 0) && (mtmp = m_at(x, y)) != 0) { boolean notice_it = canseemon(mtmp); /* before rloc() */ char *monname = Monnam(mtmp); diff --git a/src/mon.c b/src/mon.c index 2a81379e7..a4c0f6f90 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1596498185 2020/08/03 23:43:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.343 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1598575089 2020/08/28 00:38:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1742,8 +1742,7 @@ struct monst *magr, /* monster that is currently deciding where to move */ as high as the attacker, don't let attacker do so, otherwise they might just end up swapping places again when defender gets its chance to move */ - if ((pa->mflags3 & M3_DISPLACES) != 0 - && ((pd->mflags3 & M3_DISPLACES) == 0 || magr->m_lev > mdef->m_lev) + if (is_displacer(pa) && (!is_displacer(pd) || magr->m_lev > mdef->m_lev) /* no displacing grid bugs diagonally */ && !(magr->mx != mdef->mx && magr->my != mdef->my && NODIAG(monsndx(pd))) From d3bbf02d2e62ee019a76c9ea7c715182eb0cab93 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Thu, 27 Aug 2020 21:12:51 -0700 Subject: [PATCH 139/708] fix 'spotless' bug noticed during cross-compile --- 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 b604bb7ef..60455a384 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -315,7 +315,7 @@ clean: # 'make spotless' returns the source tree to near-distribution condition. # it removes .o files, executables, and compiled data files -spotless:: +spotless:: clean ( cd src ; $(MAKE) spotless ) ( cd util ; $(MAKE) spotless ) ( cd dat ; $(MAKE) spotless ) From e5604d575f62501726de79d6a0c620206f376eb7 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Thu, 27 Aug 2020 21:37:16 -0700 Subject: [PATCH 140/708] fix undefined symbol in nhlib --- src/version.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/version.c b/src/version.c index 049b92137..7645969d4 100644 --- a/src/version.c +++ b/src/version.c @@ -265,7 +265,7 @@ boolean pastebuf; raw_printf("%s", buf2); if (pastebuf) { -#ifdef RUNTIME_PASTEBUF_SUPPORT +#if defined(RUNTIME_PASTEBUF_SUPPORT) && !defined(LIBNH) /* * Call a platform/port-specific routine to insert the * version information into a paste buffer. Useful for From 18254eb2912368e25c1ed5485f91576c3d27a94d Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Thu, 27 Aug 2020 21:38:21 -0700 Subject: [PATCH 141/708] make system cleanup --- sys/lib/Makefile.src | 3 +- sys/lib/Makefile.top | 6 +- sys/lib/Makefile.utl | 1 + sys/lib/hints/include/multiw-1.2020 | 37 ---------- sys/lib/hints/include/multiw-2.2020 | 108 ---------------------------- sys/lib/hints/macOS.2020 | 89 +---------------------- sys/lib/hints/wasm | 94 ++---------------------- 7 files changed, 12 insertions(+), 326 deletions(-) delete mode 100644 sys/lib/hints/include/multiw-1.2020 delete mode 100644 sys/lib/hints/include/multiw-2.2020 diff --git a/sys/lib/Makefile.src b/sys/lib/Makefile.src index 4a947a0c5..0d75f1b37 100644 --- a/sys/lib/Makefile.src +++ b/sys/lib/Makefile.src @@ -600,6 +600,7 @@ $(WASM_DATA_DIR): touch $(WASM_DATA_DIR)/record touch $(WASM_DATA_DIR)/logfile touch $(WASM_DATA_DIR)/xlogfile + ( cd ..; $(MAKE) dlb ) ( cd ..; $(MAKE) dofiles-dlb ) cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf @@ -767,7 +768,7 @@ tags: $(CSOURCES) @( cd ../util ; $(MAKE) tags ) clean: - -rm -f *.o $(HACK_H) $(CONFIG_H) $(WASM_TARGET) $(WASM_TARGET:.js=.wasm) $(LIBNH_TARGET) + -rm -f *.o $(HACK_H) $(CONFIG_H) $(WASM_TARGET) $(WASM_TARGET:.js=.wasm) $(WASM_TARGET:.js=.data) $(LIBNH_TARGET) -rm -rf $(WASM_DATA_DIR) spotless: clean diff --git a/sys/lib/Makefile.top b/sys/lib/Makefile.top index c3ca8fda3..34d35fb26 100644 --- a/sys/lib/Makefile.top +++ b/sys/lib/Makefile.top @@ -211,7 +211,7 @@ title.img: check-dlb: options @if egrep -s librarian dat/options ; then $(MAKE) dlb ; else true ; fi -dlb: +dlb: $(VARDATD) ( cd util ; $(MAKE) dlb ) ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) @@ -320,13 +320,11 @@ clean: ( cd src ; $(MAKE) clean ) ( cd util ; $(MAKE) clean ) ( cd dat ; $(MAKE) clean ) - ( cd doc ; $(MAKE) clean ) ( cd lib/lua-$(LUA_VERSION)/src && $(MAKE) clean ) # 'make spotless' returns the source tree to near-distribution condition. # it removes .o files, executables, and compiled data files -spotless:: +spotless: clean ( cd src ; $(MAKE) spotless ) ( cd util ; $(MAKE) spotless ) ( cd dat ; $(MAKE) spotless ) - ( cd doc ; $(MAKE) spotless ) diff --git a/sys/lib/Makefile.utl b/sys/lib/Makefile.utl index 8aaf07c9a..ce39a3edf 100644 --- a/sys/lib/Makefile.utl +++ b/sys/lib/Makefile.utl @@ -95,6 +95,7 @@ NHSROOT=.. #CFLAGS = -O -I../include #LFLAGS = +CFLAGS+=-DNOTTYGRAPHICS -DSHIM_GRAPHICS -DDEFAULT_WINDOW_SYS=\"shim\" # -lm required by lua LFLAGS += -lm diff --git a/sys/lib/hints/include/multiw-1.2020 b/sys/lib/hints/include/multiw-1.2020 deleted file mode 100644 index 3fb550882..000000000 --- a/sys/lib/hints/include/multiw-1.2020 +++ /dev/null @@ -1,37 +0,0 @@ -#------------------------------------------------------------------------------ -# NetHack 3.7 multiw-1.2020 $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 -# on the 'make' command line. If none are enabled, tty will be used. -#WANT_WIN_TTY=1 -#WANT_WIN_CURSES=1 -#WANT_WIN_X11=1 -#WANT_WIN_QT=1 - -# 2. What is the default window system? -# Exactly one of these can be manually uncommented and/or can be specified -# on the 'make' command line. If none is enabled, the first among -# WANT_WIN_{tty,curses,X11,Qt} that is enabled will become default. -#WANT_DEFAULT=tty -#WANT_DEFAULT=curses -#WANT_DEFAULT=Qt -#WANT_DEFAULT=X11 - -# 3. compiler detection or optional override -CCISCLANG := $(shell echo `$(CC) --version` | grep clang) -ifeq "$(CCISCLANG)" "" -CXX=g++ -std=gnu++11 -else -CXX=clang++ -std=gnu++11 -endif -# if you want to override the compiler detection just carried out -# uncomment one of the following pairs as desired. -#CC= gcc -#CXX= g++ -std-gnu++11 -# -#CC= clang -#CXX=clang++ -std=gnu++11 - -#end of multiw-1.2020 -#------------------------------------------------------------------------------ diff --git a/sys/lib/hints/include/multiw-2.2020 b/sys/lib/hints/include/multiw-2.2020 deleted file mode 100644 index ad4028aed..000000000 --- a/sys/lib/hints/include/multiw-2.2020 +++ /dev/null @@ -1,108 +0,0 @@ -#------------------------------------------------------------------------------ -# NetHack 3.7 multiw-2.2020 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ -# -# Sorts out support for multiple window ports (interfaces) to included in the build. -# -# Included from: -# hints/linux.2020 -# hints/macOS.2020 -# -# The following will be set appropriately following this: -# - WANT_WIN_XXX (at least one will be set; default is TTY) -# - WANT_DEFAULT (set to match one of the enabled WANT_WIN_XXX) -# - WINCFLAGS -# - WINSRC -# - WINOBJ0 -#--- -# User selections could be specified as combinations of any of the following: -# WIN_WANT_TTY=1, WIN_WANT_CURSES=1, WIN_WANT_QT=1, WIN_WANT_X11=1 -# The selections will all be linked into the same binary. -# -# Assuming you have the prerequisite packages mentioned above, you can -# specify, right on the make command line, which window ports (or interfaces) -# to include in your build. Doing it via the make command line means that won't -# have to edit the Makefile. -# -# make WANT_WIN_QT=1 WANT_WIN_X11=1 WANT_WIN_CURSES=1 WANT_WIN_TTY=1 install -# -# Add WANT_DEFAULT=Qt (or other interface) if you want nethack to use -# something other than tty as the default interface. -# - -# Make sure that at least one interface is enabled. -ifndef WANT_WIN_ALL -ifndef WANT_WIN_TTY -ifndef WANT_WIN_CURSES -ifndef WANT_WIN_X11 -ifndef WANT_WIN_QT -WANT_WIN_TTY=1 -endif -endif -endif -endif -endif - -ifdef WANT_WIN_ALL -WANT_WIN_TTY=1 -WANT_WIN_CURSES=1 -WANT_WIN_X11=1 -WANT_WIN_QT=1 -endif - - -# Make sure that a default interface is specified; this doesn't guarantee -# sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but -# 'makedefs -v' would notice, complain, and quit causing 'make' to quit. -ifndef WANT_DEFAULT -# pick the first one enabled among { tty, curses, X11, Qt } -ifdef WANT_WIN_TTY -WANT_DEFAULT=tty -else -ifdef WANT_WIN_CURSES -WANT_DEFAULT=curses -else -ifdef WANT_WIN_X11 -WANT_DEFAULT=X11 -else -ifdef WANT_WIN_QT -WANT_DEFAULT=Qt -else -# ? shouldn't be able to get here... -endif -endif -endif -endif -endif - -WINCFLAGS= -WINSRC = -WINOBJ0 = - -ifdef WANT_WIN_TTY -WINSRC += $(WINTTYSRC) -WINOBJ0 += $(WINTTYOBJ) -else -WINCFLAGS += -DNOTTYGRAPHICS -endif - -ifdef WANT_WIN_CURSES -WINCFLAGS += -DCURSES_GRAPHICS -WINSRC += $(WINCURSESSRC) -WINOBJ0 += $(WINCURSESOBJ) -endif - -ifdef WANT_WIN_X11 -WINCFLAGS += -DX11_GRAPHICS -WINSRC += $(WIINX11SRC) -WINOBJ0 += $(WINX11OBJ) -endif - -ifdef WANT_WIN_QT -WINCFLAGS += -DQT_GRAPHICS -WINSRC += $(WINQTSRC) -WINOBJ0 += $(WINQTOBJ) -endif - -#end of hints/include/multiw-2.2020 -#------------------------------------------------------------------------------ - diff --git a/sys/lib/hints/macOS.2020 b/sys/lib/hints/macOS.2020 index 227f83a3c..3edd3b768 100755 --- a/sys/lib/hints/macOS.2020 +++ b/sys/lib/hints/macOS.2020 @@ -16,28 +16,6 @@ # macOS X hints file # -####-INCLUDE multiw-1.2020 - -# 4. If you set WANT_WIN_QT, you need to -# A) set QTDIR either here or in the environment to point to the Qt5 -# library installation root. (Qt2, Qt3, Qt4 will not work) -# B) set XPMLIB to point to the Xpm library -ifndef WANT_WIN_QT -ifdef WANT_WIN_ALL -WANT_WIN_QT=1 -endif -endif -ifdef WANT_WIN_QT -#QTDIR=/Developer/Qt -# Qt installed via homebrew -QTDIR=$(shell brew --prefix)/opt/qt -# Qt installed via macports -#QTDIR=/opt/local/libexec/qt5 -endif # WANT_WIN_QT -ifndef LIBXPM -LIBXPM= -L/opt/X11/lib -lXpm -endif - # 5. Other #----------------------------------------------------------------------------- @@ -45,25 +23,11 @@ endif # you're reading this in Makefile augmented by hints, that may not be true). # -####-INCLUDE multiw-2.2020 +AR=ar rcu +RANLIB=ranlib # XXX -g vs -O should go here, -I../include goes in the makefile CFLAGS+=-g -I../include -DNOTPARMDECL -ifndef WANT_WIN_QT -# these are normally used when compiling nethack's core -CFLAGS+=-ansi -pedantic -Wno-long-long -# but -ansi forces -std=c90 for C or -std=c++98 for C++; -# win/Qt/qt_*.cpp compiled with C++98 semantics trigger -#In file included from .../qt5/include/QtCore/qglobal.h:105: -#.../qt5/include/QtCore/qcompilerdetection.h:561:6: -# error Qt requires a C++11 compiler and yours does not seem to be that. -# so we suppress -ansi when the build includes Qt -endif -# As of LLVM build 2336.1.00, this gives dozens of spurious messages, so -# leave it out by default. -#CFLAGS+=-Wunreachable-code -#TODO NHLIB -#CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings CFLAGS+=-Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wformat -Wswitch -Wshadow -Wwrite-strings CFLAGS+=-DGCC_WARN @@ -87,7 +51,7 @@ CFLAGS+=-DNOMAIL #CFLAGS+=-DTTY_TILES_ESCCODES #CFLAGS+=-DTTY_SOUND_ESCCODES -#CFLAGS+=-DDEFAULT_WINDOW_SYS=\"shim\" -DNOTTYGRAPHICS -DLIBNH +CFLAGS+=-DDEFAULT_WINDOW_SYS=\"shim\" -DNOTTYGRAPHICS -DLIBNH CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 @@ -100,54 +64,7 @@ HINTSRC=$(CHAINSRC) HINTOBJ=$(CHAINOBJ) endif # WANT_WIN_CHAIN -ifdef WANT_WIN_TTY -CURSESLIB = -lncurses -endif - -ifdef WANT_WIN_CURSES -CURSESLIB = -lncurses -endif - -ifdef CURSESLIB -WINLIB += $(CURSESLIB) -endif - -ifdef WANT_WIN_X11 -USE_XPM=1 -WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11 -VARDATND0 += x11tiles NetHack.ad pet_mark.xbm pilemark.xbm -# -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 -X11CFLAGS = -I/opt/X11/include -# avoid repeated complaints about _X_NONNULL(args...) in -X11CFLAGS += -Wno-variadic-macros -ifdef USE_XPM -CFLAGS += -DUSE_XPM -WINX11LIB += -lXpm -VARDATND0 += rip.xpm -endif -WINLIB += $(WINX11LIB) -LFLAGS=-L/opt/X11/lib -endif # WANT_WIN_X11 - -ifdef WANT_WIN_QT -# Qt5 requires C++11 -LINK = $(CXX) -QTCXXFLAGS += -Wno-deprecated-declarations -QTCXXFLAGS += $(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) -WINSRC += $(WINQTSRC) -WINOBJ0 += $(WINQTOBJ) -VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm -# XXX if /Developer/qt exists and QTDIR not set, use that -ifndef QTDIR -$(error QTDIR not defined in the environment or Makefile) -endif # QTDIR -# XXX make sure QTDIR points to something reasonable -else # !WANT_WIN_QT LINK=$(CC) -endif # !WANT_WIN_QT # prevent duplicate tile.o in WINOBJ WINOBJ = $(sort $(WINOBJ0)) diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index 0591db7ba..e5cf4bc7b 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -4,7 +4,7 @@ WANT_WASM=1 WASM_DEBUG=1 -WASM_DATA_DIR=$(NHSROOT)/src/wasm-data/Users/ampower/nethackdir +WASM_DATA_DIR=$(NHSROOT)/src/wasm-data # toolchain EMCC=emcc @@ -51,100 +51,14 @@ else EMCC_CFLAGS+=$(EMCC_PROD_CFLAGS) endif -ifdef WANT_SHARE_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 -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 -PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ - . sys/unix/hints/macosx.sh group2 $(GAMEGRP); \ - mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) -POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ - $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ - $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ - chmod $(VARFILEPERM) $(HACKDIR)/sysconf; - -else ifdef WANT_SOURCE_INSTALL - -PREFIX=$(abspath $(NHSROOT)) -# suppress nethack.sh -#SHELLDIR= -HACKDIR=$(PREFIX)/playground +# installation config +# hackdir is the wasm / emscripten embed data root directory +HACKDIR=/ 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: -MOREALL=$(MAKE) install -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE - -else # !WANT_SOURCE_INSTALL - -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 -endif # WANT_DEFAULT X11 - -POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ - $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ - $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ - chmod $(VARFILEPERM) $(HACKDIR)/sysconf; -ifdef WANT_BUNDLE -# -# Bundle -# -# $(HACKDIR)/$(GAME).app/ -# Contents/ -# Frameworks/ -# Info.plist -# MacOS/ -# $(GAME) -# PkgInfo/ -# PlugIns/ -# Resources/ -# SharedFrameWorks/ -# -BUNDLE = mkdir -p $(HACKDIR)/nethack.app/Contents/MacOS; \ - sys/unix/hints/macosx.sh infoplist > $(HACKDIR)/nethack.app/Contents/Info.plist; \ - mv $(HACKDIR)/nethack $(HACKDIR)/nethack.app/Contents/MacOS/nethack; -ifdef WANT_SHARE_INSTALL -BUNDLE+= chmod $(GAMEPERM) $(HACKDIR)/nethack.app/Contents/MacOS/nethack; -endif - -POSTINSTALL+= $(BUNDLE) -POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ - sed -i '' 's;HACKDIR/$(GAME);HACKDIR/$(GAME).app/Contents/MacOS/$(GAME);' $(SHELLDIR)/$(GAME) ; fi; -endif # WANT_BUNDLE -endif # !WANT_SHARE_INSTALL INSTDIR=$(HACKDIR) VARDIR=$(HACKDIR) From c9f5bb9ac40600d91c03709b41ea18f9c0750930 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Thu, 27 Aug 2020 22:15:12 -0700 Subject: [PATCH 142/708] replace -DWASM with compiler internal __EMSCRIPTEN__ --- include/global.h | 10 +++++----- sys/lib/Makefile.utl | 3 --- sys/lib/hints/wasm | 3 +-- util/makedefs.c | 6 +++--- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/include/global.h b/include/global.h index 8f7ed95a4..b3f17e996 100644 --- a/include/global.h +++ b/include/global.h @@ -325,15 +325,15 @@ struct version_info { unsigned long incarnation; /* actual version number */ unsigned long feature_set; /* bitmask of config settings */ unsigned long entity_count; /* # of monsters and objects */ -#ifndef WASM +#ifndef __EMSCRIPTEN__ unsigned long struct_sizes1; /* size of key structs */ unsigned long struct_sizes2; /* size of more key structs */ -#else /* WASM */ +#else /* __EMSCRIPTEN__ */ /* 'long' in WASM is 4 bytes, which is too small to hold version numbers * such as: VERSION_SANITY2 */ unsigned long long struct_sizes1; /* size of key structs */ unsigned long long struct_sizes2; /* size of more key structs */ -#endif /* !WASM */ +#endif /* !__EMSCRIPTEN__ */ }; struct savefile_info { @@ -397,7 +397,7 @@ struct savefile_info { /* PANICTRACE: Always defined for NH_DEVEL_STATUS != NH_STATUS_RELEASED but only for supported platforms. */ -#if defined(UNIX) && !defined(WASM) +#if defined(UNIX) && !defined(__EMSCRIPTEN__) #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) /* see end.c */ #ifndef PANICTRACE @@ -412,7 +412,7 @@ struct savefile_info { #if defined(MACOSX) #define PANICTRACE_LIBC #endif -#if defined(UNIX) && !defined(WASM) /* no popen in WASM */ +#if defined(UNIX) && !defined(__EMSCRIPTEN__) /* no popen in WASM */ #define PANICTRACE_GDB #endif diff --git a/sys/lib/Makefile.utl b/sys/lib/Makefile.utl index ce39a3edf..cd1cca159 100644 --- a/sys/lib/Makefile.utl +++ b/sys/lib/Makefile.utl @@ -148,9 +148,6 @@ CXX_V1 = @echo "[CXX] $<"; $(ACTUAL_CXX) CXX = $(CXX_V$(QUIETCC)) CFLAGS+=-I../include -ifdef WANT_WASM -CFLAGS+=-DWASM -endif # LD and LINK might be based on invoking CC and may not be able to substitute # for QUIETCC, so feedback from them is handled differently (via $AT) diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index e5cf4bc7b..8715104c8 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -17,7 +17,7 @@ EMCC_LFLAGS=-s WASM=1 EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["_nhmain"]' -O3 EMCC_LFLAGS+=-s MODULARIZE -EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main"]' +EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_stub_graphics_set_callback"]' EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString"]' EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 EMCC_LFLAGS+=--embed-file wasm-data@/ @@ -25,7 +25,6 @@ EMCC_LFLAGS+=--embed-file wasm-data@/ # WASM C flags EMCC_CFLAGS= EMCC_CFLAGS+=-Wall -Werror -EMCC_CFLAGS+=-DWASM EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 diff --git a/util/makedefs.c b/util/makedefs.c index 7ff0ec2c9..68421776f 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1218,17 +1218,17 @@ do_date() #endif Fprintf(ofp, "#define VERSION_SANITY1 0x%08lx%s\n", version.entity_count, ul_sfx); -#ifndef WASM +#ifndef __EMSCRIPTEN__ Fprintf(ofp, "#define VERSION_SANITY2 0x%08lx%s\n", version.struct_sizes1, ul_sfx); Fprintf(ofp, "#define VERSION_SANITY3 0x%08lx%s\n", version.struct_sizes2, ul_sfx); -#else /* WASM */ +#else /* __EMSCRIPTEN__ */ Fprintf(ofp, "#define VERSION_SANITY2 0x%08llx%s\n", version.struct_sizes1, ul_sfx); Fprintf(ofp, "#define VERSION_SANITY3 0x%08llx%s\n", version.struct_sizes2, ul_sfx); -#endif /* !WASM */ +#endif /* !__EMSCRIPTEN__ */ Fprintf(ofp, "\n"); Fprintf(ofp, "#define VERSION_STRING \"%s\"\n", version_string(buf, ".")); From fae20ad3e20fdbb82338dddc490154e9a53ea1fb Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 28 Aug 2020 17:31:33 -0700 Subject: [PATCH 143/708] Qt menu fix Menus have [ok], [cancel], [all], [none], [invert], and [search] buttons across their top but the [all], [none], and [invert] choices didn't redraw the menu after making changes to the pending selections so it seemed as if they weren't doing anything. Subsequently picking [ok] revealed otherwise. [search] is broken (instead of accepting a search string, the letters I type are being used to toggle individual entries as I type). This doesn't attempt to address that. --- doc/fixes37.0 | 4 +++- win/Qt/qt_menu.cpp | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d4c1b2628..6336374f4 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.290 $ $NHDT-Date: 1598570054 2020/08/27 23:14:14 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.291 $ $NHDT-Date: 1598661087 2020/08/29 00:31:27 $ General Fixes and Modified Features ----------------------------------- @@ -390,6 +390,8 @@ Qt: when hero died, gold on tombstone only included gold in inventory, not Qt: tombstone showed newly constructed date instead of the value set up at time of death; it only shows year but that could be wrong if player stared at or ignored prior --More-- for long enough on 31 December +Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu + entry checkboxes internally but didn't redraw the menu to show that Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 817449ee7..a90cb7d9b 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -215,7 +215,7 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) how=h; - ok->setEnabled(how!=PICK_ONE);ok->setDefault(how!=PICK_ONE); + ok->setEnabled(how!=PICK_ONE); ok->setDefault(how!=PICK_ONE); cancel->setEnabled(true); all->setEnabled(how==PICK_ANY); none->setEnabled(how==PICK_ANY); @@ -499,7 +499,8 @@ void NetHackQtMenuWindow::keyPressEvent(QKeyEvent* event) InputCount(key); else { for (int i=0; iitem(i, 0); if (count != NULL) count->setText(""); QCheckBox *cb = dynamic_cast(table->cellWidget(i, 1)); - if (cb != NULL) cb->setChecked(true); + if (cb != NULL) { + cb->setChecked(true); + didcheck = true; + } } + if (didcheck) + table->repaint(); } void NetHackQtMenuWindow::ChooseNone() { if (how != PICK_ANY) return; + bool diduncheck = false; for (int i=0; iitem(i, 0); if (count != NULL) count->setText(""); QCheckBox *cb = dynamic_cast(table->cellWidget(i, 1)); - if (cb != NULL) cb->setChecked(false); + if (cb != NULL) { + cb->setChecked(false); + diduncheck = true; + } } + if (diduncheck) + table->repaint(); } void NetHackQtMenuWindow::Invert() { if (how != PICK_ANY) return; + boolean didtoggle = false; for (int i=0; isetText(""); QCheckBox *cb = dynamic_cast(table->cellWidget(i, 1)); - if (cb != NULL) cb->setChecked(cb->checkState() == Qt::Unchecked); + if (cb != NULL) { + cb->setChecked(cb->checkState() == Qt::Unchecked); + didtoggle = true; + } } + if (didtoggle) + table->repaint(); } void NetHackQtMenuWindow::Search() { @@ -556,6 +575,7 @@ void NetHackQtMenuWindow::Search() NetHackQtStringRequestor requestor(this, "Search for:"); char line[256]; + line[0] = '\0'; /* for EDIT_GETLIN */ if (requestor.Get(line)) { for (int i=0; i(table->cellWidget(i, 1)); if (cb == NULL) return; - cb->setChecked((counting && !countstr.isEmpty()) - || cb->checkState() == Qt::Unchecked); + cb->setChecked((counting && !countstr.isEmpty()) + || cb->checkState() == Qt::Unchecked); QTableWidgetItem *count = table->item(i, 0); if (count != NULL) count->setText(countstr); @@ -579,7 +599,9 @@ void NetHackQtMenuWindow::ToggleSelect(int i) if (how==PICK_ONE) { accept(); - } + } else { + table->repaint(); + } } } From 97a14eebbe760f7205b8a0bbbd4e9a068ffdda4d Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 10:26:58 -0700 Subject: [PATCH 144/708] functional shim graphics --- sys/lib/hints/wasm | 12 +++-- win/shim/winshim.c | 115 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 104 insertions(+), 23 deletions(-) diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index 8715104c8..799efe03c 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -18,13 +18,14 @@ EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["_nhmain"]' -O3 EMCC_LFLAGS+=-s MODULARIZE EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_stub_graphics_set_callback"]' -EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString"]' +EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue"]' EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 EMCC_LFLAGS+=--embed-file wasm-data@/ # WASM C flags EMCC_CFLAGS= -EMCC_CFLAGS+=-Wall -Werror +EMCC_CFLAGS+=-Wall +EMCC_CFLAGS+=-Werror EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 @@ -32,16 +33,17 @@ EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED EMCC_PROD_CFLAGS+=-O3 # Nethack C flags -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE CFLAGS+=-g -I../include -DNOTPARMDECL -CFLAGS+=-Wall -Werror +CFLAGS+=-Wall +CFLAGS+=-Werror CFLAGS+=-DGCC_WARN # NetHack sources control CFLAGS+=-DDLB CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" CFLAGS+=-DDLB -CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" CFLAGS+=-DNOMAIL ifdef WASM_DEBUG diff --git a/win/shim/winshim.c b/win/shim/winshim.c index d82d21334..085a27684 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -7,6 +7,80 @@ #include "hack.h" #ifdef SHIM_GRAPHICS +#include +/* for cross-compiling to WebAssembly (WASM) */ +#ifdef __EMSCRIPTEN__ +#include +#endif + +#define SHIM_DEBUG + +#ifndef __EMSCRIPTEN__ +typedef void(*stub_callback_t)(const char *name, const char *fmt, void *ret_ptr, ...); +#else /* __EMSCRIPTEN__ */ +/* WASM can't handle a variadic callback, so we pass back an array of pointers instead... */ +typedef void(*stub_callback_t)(const char *name, const char *fmt, void *ret_ptr, void *args[]); +#endif /* !__EMSCRIPTEN__ */ + +/* this is the primary interface to shim graphics, + * call this function with your declared callback function + * and you will receive all the windowing calls + */ +static stub_callback_t shim_graphics_callback = NULL; +#ifdef __EMSCRIPTEN__ + EMSCRIPTEN_KEEPALIVE +#endif +void stub_graphics_set_callback(stub_callback_t cb) { + shim_graphics_callback = cb; +} + +#ifdef __EMSCRIPTEN__ +// A2P = Argument to Pointer +#define A2P & +// P2V = Pointer to Void +#define P2V (void *) +#define DECLCB(ret_type, name, fn_args, fmt, ...) \ +ret_type name fn_args { \ + void *args[] = { __VA_ARGS__ }; \ + ret_type ret; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, (void *)&ret, args); \ + return ret; \ +} + +#define VDECLCB(name, fn_args, fmt, ...) \ +void name fn_args { \ + void *args[] = { __VA_ARGS__ }; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, NULL, args); \ +} +#else /* !__EMSCRIPTEN__ */ +#define A2P +#define P2V +#define DECLCB(ret_type, name, args, fmt, ...) \ +ret_type name args { \ + ret_type ret; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, (void *)&ret, __VA_ARGS__); \ + return ret; \ +} + +void name args { \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, fmt, NULL, __VA_ARGS__); \ +} +#endif /* __EMSCRIPTEN__ */ + +#ifdef SHIM_DEBUG +#define debugf printf +#else /* !SHIM_DEBUG */ +#define debugf(...) +#endif /* SHIM_DEBUG */ + enum win_types { WINSTUB_MESSAGE = 1, @@ -29,6 +103,7 @@ name args { \ #define DECL(name, args) \ void name args; +// void DECLCB(shim_init_nhwindows,(int *argcp, char **argv), "pp", argcp, argv) VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) VSTUB(shim_player_selection,(void)) VSTUB(shim_askname,(void)) @@ -40,8 +115,10 @@ winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) VSTUB(shim_clear_nhwindow,(winid a)) VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) VSTUB(shim_destroy_nhwindow,(winid a)) -VSTUB(shim_curs,(winid a, int x, int y)) -DECL(shim_putstr,(winid w, int attr, const char *str)) +VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) +// VSTUB(shim_curs,(winid a, int x, int y)) +// DECL(shim_putstr,(winid w, int attr, const char *str)) +VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) VSTUB(shim_add_menu,(winid a, int b, const ANY_P *c, CHAR_P d, CHAR_P e, int f, const char *h, unsigned int k)) @@ -53,8 +130,10 @@ VSTUB(shim_mark_synch,(void)) VSTUB(shim_wait_synch,(void)) VSTUB(shim_cliparound,(int a, int b)) VSTUB(shim_update_positionbar,(char *a)) -DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) -DECL(shim_raw_print,(const char *str)) +// DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) +VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) +// DECL(shim_raw_print,(const char *str)) +VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VSTUB(shim_raw_print_bold,(const char *a)) int STUB(shim_nhgetch,0,(void)) int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) @@ -140,22 +219,22 @@ struct window_procs shim_procs = { genl_can_suspend_yes, }; -void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { - /* map glyph to character and color */ - // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); +// void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { +// /* map glyph to character and color */ +// // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); - fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); - fflush(stdout); -} +// fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); +// fflush(stdout); +// } -void shim_raw_print(const char *str) { - fprintf(stdout, "shim_raw_print: %s\n", str); - fflush(stdout); -} +// void shim_raw_print(const char *str) { +// fprintf(stdout, "shim_raw_print: %s\n", str); +// fflush(stdout); +// } -void shim_putstr(winid w, int attr, const char *str) { - fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); - fflush(stdout); -} +// void shim_putstr(winid w, int attr, const char *str) { +// fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); +// fflush(stdout); +// } #endif /* SHIM_GRAPHICS */ \ No newline at end of file From e04b17911abd49dda5a36b531955c001dcebf663 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 10:27:51 -0700 Subject: [PATCH 145/708] delinting --- win/shim/winshim.c | 27 ++------------------------- 1 file changed, 2 insertions(+), 25 deletions(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 085a27684..2334e9dec 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -35,9 +35,9 @@ void stub_graphics_set_callback(stub_callback_t cb) { } #ifdef __EMSCRIPTEN__ -// A2P = Argument to Pointer +/* A2P = Argument to Pointer */ #define A2P & -// P2V = Pointer to Void +/* P2V = Pointer to Void */ #define P2V (void *) #define DECLCB(ret_type, name, fn_args, fmt, ...) \ ret_type name fn_args { \ @@ -103,7 +103,6 @@ name args { \ #define DECL(name, args) \ void name args; -// void DECLCB(shim_init_nhwindows,(int *argcp, char **argv), "pp", argcp, argv) VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) VSTUB(shim_player_selection,(void)) VSTUB(shim_askname,(void)) @@ -116,8 +115,6 @@ VSTUB(shim_clear_nhwindow,(winid a)) VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) VSTUB(shim_destroy_nhwindow,(winid a)) VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) -// VSTUB(shim_curs,(winid a, int x, int y)) -// DECL(shim_putstr,(winid w, int attr, const char *str)) VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) @@ -130,9 +127,7 @@ VSTUB(shim_mark_synch,(void)) VSTUB(shim_wait_synch,(void)) VSTUB(shim_cliparound,(int a, int b)) VSTUB(shim_update_positionbar,(char *a)) -// DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) -// DECL(shim_raw_print,(const char *str)) VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VSTUB(shim_raw_print_bold,(const char *a)) int STUB(shim_nhgetch,0,(void)) @@ -219,22 +214,4 @@ struct window_procs shim_procs = { genl_can_suspend_yes, }; -// void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { -// /* map glyph to character and color */ -// // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); - -// fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); -// fflush(stdout); -// } - -// void shim_raw_print(const char *str) { -// fprintf(stdout, "shim_raw_print: %s\n", str); -// fflush(stdout); -// } - -// void shim_putstr(winid w, int attr, const char *str) { -// fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); -// fflush(stdout); -// } - #endif /* SHIM_GRAPHICS */ \ No newline at end of file From 1a70f77b2a56c085278fafe6396f6fd58554a4fb Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 11:10:09 -0700 Subject: [PATCH 146/708] more sensible arg order for callback --- win/shim/winshim.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 2334e9dec..9fed47d9c 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -16,10 +16,10 @@ #define SHIM_DEBUG #ifndef __EMSCRIPTEN__ -typedef void(*stub_callback_t)(const char *name, const char *fmt, void *ret_ptr, ...); +typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); #else /* __EMSCRIPTEN__ */ /* WASM can't handle a variadic callback, so we pass back an array of pointers instead... */ -typedef void(*stub_callback_t)(const char *name, const char *fmt, void *ret_ptr, void *args[]); +typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, void *args[]); #endif /* !__EMSCRIPTEN__ */ /* this is the primary interface to shim graphics, @@ -45,7 +45,7 @@ ret_type name fn_args { \ ret_type ret; \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ - shim_graphics_callback(#name, fmt, (void *)&ret, args); \ + shim_graphics_callback(#name, (void *)&ret, fmt, args); \ return ret; \ } @@ -54,7 +54,7 @@ void name fn_args { \ void *args[] = { __VA_ARGS__ }; \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ - shim_graphics_callback(#name, fmt, NULL, args); \ + shim_graphics_callback(#name, NULL, fmt, args); \ } #else /* !__EMSCRIPTEN__ */ #define A2P @@ -64,14 +64,14 @@ ret_type name args { \ ret_type ret; \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ - shim_graphics_callback(#name, fmt, (void *)&ret, __VA_ARGS__); \ + shim_graphics_callback(#name, (void *)&ret, fmt, __VA_ARGS__); \ return ret; \ } void name args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ - shim_graphics_callback(#name, fmt, NULL, __VA_ARGS__); \ + shim_graphics_callback(#name, NULL, fmt, __VA_ARGS__); \ } #endif /* __EMSCRIPTEN__ */ From 22bc4ecfc0cab01848610f6730dd9529bc2fd44c Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 11:10:52 -0700 Subject: [PATCH 147/708] initial docs --- sys/lib/README.md | 166 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 sys/lib/README.md diff --git a/sys/lib/README.md b/sys/lib/README.md new file mode 100644 index 000000000..f0347b184 --- /dev/null +++ b/sys/lib/README.md @@ -0,0 +1,166 @@ +# About +This creates a library for NetHack that can be incorporated into other programs. There are two different libraries that are currently available: +* libnethack.a - a binary Unix library +* nethack.js / nethack.wasm - a [WebAssembly / WASM](https://webassembly.org/) library for use in JavaScript programs (both nodejs and browser) + +## API: libnethack.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. +* `stub_graphics_set_callback(stub_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 scrren. The callback is `void stub_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.doc) 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.doc](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc). + +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 sumbit a PR to fix it. :) + +## API: nethack.js +Building the WASM module requires that you have the [emscripten toolchain / sdk installed](https://emscripten.org/docs/getting_started/downloads.html). + +The WebAssembly API has a similar signature to `libnethack.a` with minor syntactic differences: +* `main(int argc, char argv[])` - The main function for NetHack +* `stub_graphics_set_callback(stub_callback_t cb)` - The same as above, but the signature of the callback is slightly different because WASM can't handle variadic callbacks. The callback is: `void stub_callback_t(const char *name, void *ret_ptr, const char *fmt, void *args[])` + * `name` - same as above + * `ret_ptr` - same as above + * `fmt` - same as above + * `args` - an array of pointers to the arguments, where each pointer can be de-referenced to a value as specified in the `fmt` string. + + + +## API Stability +The "stub graphics" API should generally be stable. I aspire to replace the command line arguments (argc / argv) with a structure of options, so the `nhmain()` and `main()` functions may change at some point. + +## libnethack.a example +``` c +#include + +int nhmain(int argc, char *argv[]); +typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +void stub_graphics_set_callback(stub_callback_t cb); + +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { + /* TODO -- see windowCallback below for hints */ +} + +int main(int argc, char *argv[]) { + stub_graphics_set_callback(window_cb); + nhmain(argc, argv); +} +``` + +## nethack.js example +``` js +// Module is defined by emscripten +// https://emscripten.org/docs/api_reference/module.html +let Module = { + // if this is true, main() won't be called automatically + // noInitialRun: true, + + // after loading the library, set the callback function + onRuntimeInitialized: function (... args) { + setGraphicsCallback(); + } +}; + +var factory = require("./src/nethack.js"); + +// run NetHack! +factory(Module); + +// register the callback with the WASM library +function setGraphicsCallback() { + console.log("creating WASM callback function"); + let cb = Module.addFunction(windowCallback, "viiii"); + + console.log("setting callback function with library"); + Module.ccall( + "stub_graphics_set_callback", // C function name + null, // return type + ["number"], // arg types + [cb], // arg values + {async: true} // options + ); + + /* TODO: removeFunction */ +} + +// this is the "shim graphics" callback function +// it gets called every time something needs to be displayed +// or input needs to be gathered from the user +function windowCallback(name, fmt, retPtr, args) { + name = Module.UTF8ToString(name); + fmt = Module.UTF8ToString(fmt); + let argTypes = fmt.split(""); + let retType = argTypes.shift(); + + // convert arguments to JavaScript types + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } + console.log(`graphics callback: ${name} [${jsArgs}]`); + /********** + * YOU HAVE TO IMPLEMENT THIS FUNCTION to render things + **********/ + let ret = yourFunctionToRenderGraphics(name, jsArgs); + setReturn(retPtr, retType, ret); +} + +// takes a character `type` and a WASM pointer and returns a JavaScript value +function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + return Module.getValue(Module.getValue(ptr, "*"), "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } +} + +// takes a a WASM pointer, a charater `type` and a value and sets the value at pointer +function setReturn(ptr, type, value = 0) { + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + Module.setValue(ptr, value, "i32"); + break; + case "c": + Module.setValue(ptr, value, "i8"); + break; + case "f": + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } +} +``` \ No newline at end of file From 4ef48ca49adc684459644ab9f4d7b1002c0c7bb8 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 14:48:02 -0700 Subject: [PATCH 148/708] fix syntax errors for libnethack.a --- win/shim/winshim.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 9fed47d9c..34bdccbaf 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -59,8 +59,8 @@ void name fn_args { \ #else /* !__EMSCRIPTEN__ */ #define A2P #define P2V -#define DECLCB(ret_type, name, args, fmt, ...) \ -ret_type name args { \ +#define DECLCB(ret_type, name, fn_args, fmt, ...) \ +ret_type name fn_args { \ ret_type ret; \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ @@ -68,7 +68,8 @@ ret_type name args { \ return ret; \ } -void name args { \ +#define VDECLCB(name, fn_args, fmt, ...) \ +void name fn_args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ shim_graphics_callback(#name, NULL, fmt, __VA_ARGS__); \ From 14084dc50c4751f39c11462f14ef2e244b4abbca Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 14:48:22 -0700 Subject: [PATCH 149/708] fix arg order --- sys/lib/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/lib/README.md b/sys/lib/README.md index f0347b184..3d314eb31 100644 --- a/sys/lib/README.md +++ b/sys/lib/README.md @@ -87,7 +87,7 @@ function setGraphicsCallback() { // this is the "shim graphics" callback function // it gets called every time something needs to be displayed // or input needs to be gathered from the user -function windowCallback(name, fmt, retPtr, args) { +function windowCallback(name, retPtr, fmt, args) { name = Module.UTF8ToString(name); fmt = Module.UTF8ToString(fmt); let argTypes = fmt.split(""); From 863f91433717bb9d4f7dede05b850db69c92f44f Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 29 Aug 2020 15:50:42 -0700 Subject: [PATCH 150/708] added void functions --- win/shim/winshim.c | 92 +++++++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 42 deletions(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 34bdccbaf..310a4c315 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -13,7 +13,7 @@ #include #endif -#define SHIM_DEBUG +#undef SHIM_DEBUG #ifndef __EMSCRIPTEN__ typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); @@ -42,9 +42,9 @@ void stub_graphics_set_callback(stub_callback_t cb) { #define DECLCB(ret_type, name, fn_args, fmt, ...) \ ret_type name fn_args { \ void *args[] = { __VA_ARGS__ }; \ - ret_type ret; \ + ret_type ret = (ret_type) 0; \ debugf("SHIM GRAPHICS: " #name "\n"); \ - if (!shim_graphics_callback) return; \ + if (!shim_graphics_callback) return ret; \ shim_graphics_callback(#name, (void *)&ret, fmt, args); \ return ret; \ } @@ -61,9 +61,9 @@ void name fn_args { \ #define P2V #define DECLCB(ret_type, name, fn_args, fmt, ...) \ ret_type name fn_args { \ - ret_type ret; \ + ret_type ret = (ret_type) 0; \ debugf("SHIM GRAPHICS: " #name "\n"); \ - if (!shim_graphics_callback) return; \ + if (!shim_graphics_callback) return ret; \ shim_graphics_callback(#name, (void *)&ret, fmt, __VA_ARGS__); \ return ret; \ } @@ -104,60 +104,68 @@ name args { \ #define DECL(name, args) \ void name args; -VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) -VSTUB(shim_player_selection,(void)) -VSTUB(shim_askname,(void)) -VSTUB(shim_get_nh_event,(void)) -VSTUB(shim_exit_nhwindows,(const char *a)) -VSTUB(shim_suspend_nhwindows,(const char *a)) -VSTUB(shim_resume_nhwindows,(void)) +VDECLCB(shim_init_nhwindows,(int *argcp, char **argv), "vpp", P2V argcp, P2V argv) +VDECLCB(shim_player_selection,(void), "v") +VDECLCB(shim_askname,(void), "v") +VDECLCB(shim_get_nh_event,(void), "v") +VDECLCB(shim_exit_nhwindows,(const char *str), "vs", P2V str) +VDECLCB(shim_suspend_nhwindows,(const char *str), "vs", P2V str) +VDECLCB(shim_resume_nhwindows,(void), "v") +// DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) -VSTUB(shim_clear_nhwindow,(winid a)) -VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) -VSTUB(shim_destroy_nhwindow,(winid a)) +VDECLCB(shim_clear_nhwindow,(winid window), "vi", A2P window) +VDECLCB(shim_display_nhwindow,(winid window, BOOLEAN_P blocking), "vii", A2P window, A2P blocking) +VDECLCB(shim_destroy_nhwindow,(winid window), "vi", A2P window) VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) -VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) -VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) -VSTUB(shim_add_menu,(winid a, int b, const ANY_P *c, CHAR_P d, CHAR_P e, int f, const char *h, unsigned int k)) -VSTUB(shim_end_menu,(winid a, const char *b)) +VDECLCB(shim_display_file,(const char *name, BOOLEAN_P complain), "vsi", P2V name, A2P complain) +VDECLCB(shim_start_menu,(winid window, unsigned long mbehavior), "vii", A2P window, A2P mbehavior) +VDECLCB(shim_add_menu, + (winid window, int glyph, const ANY_P *identifier, CHAR_P ch, CHAR_P gch, int attr, const char *str, unsigned int itemflags), + "viipiiisi", + A2P window, A2P glyph, P2V identifier, A2P ch, A2P gch, A2P attr, P2V str, A2P itemflags) +VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt) int STUB(shim_select_menu,0,(winid a, int b, MENU_ITEM_P **c)) char STUB(shim_message_menu,'y',(CHAR_P a, int b, const char *c)) -VSTUB(shim_update_inventory,(void)) -VSTUB(shim_mark_synch,(void)) -VSTUB(shim_wait_synch,(void)) -VSTUB(shim_cliparound,(int a, int b)) -VSTUB(shim_update_positionbar,(char *a)) +VDECLCB(shim_update_inventory,(void), "v") +VDECLCB(shim_mark_synch,(void), "v") +VDECLCB(shim_wait_synch,(void), "v") +VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) +VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) -VSTUB(shim_raw_print_bold,(const char *a)) +VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) int STUB(shim_nhgetch,0,(void)) int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) -VSTUB(shim_nhbell,(void)) +VDECLCB(shim_nhbell,(void), "v") int STUB(shim_doprev_message,0,(void)) char STUB(shim_yn_function,'y',(const char *a, const char *b, CHAR_P c)) -VSTUB(shim_getlin,(const char *a, char *b)) +VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp) int STUB(shim_get_ext_cmd,0,(void)) -VSTUB(shim_number_pad,(int a)) -VSTUB(shim_delay_output,(void)) -VSTUB(shim_change_color,(int a, long b, int c)) -VSTUB(shim_change_background,(int a)) +VDECLCB(shim_number_pad,(int state), "vi", A2P state) +VDECLCB(shim_delay_output,(void), "v") +VDECLCB(shim_change_color,(int color, long rgb, int reverse), "viii", A2P color, A2P rgb, A2P reverse) +VDECLCB(shim_change_background,(int white_or_black), "vi", A2P white_or_black) short STUB(set_shim_font_name,0,(winid a, char *b)) -VSTUB(shim_get_color_string,(void)) +char *STUB(shim_get_color_string,"",(void)) /* other defs that really should go away (they're tty specific) */ -VSTUB(shim_start_screen, (void)) -VSTUB(shim_end_screen, (void)) -VSTUB(shim_preference_update, (const char *a)) +VDECLCB(shim_start_screen, (void), "v") +VDECLCB(shim_end_screen, (void), "v") +VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref) char *STUB(shim_getmsghistory, (char *)"", (BOOLEAN_P a)) -VSTUB(shim_putmsghistory, (const char *a, BOOLEAN_P b)) -VSTUB(shim_status_init, (void)) -VSTUB(shim_status_enablefield, (int a, const char *b, const char *c, BOOLEAN_P d)) -VSTUB(shim_status_update, (int a, genericptr_t b, int c, int d, int e, unsigned long *f)) +VDECLCB(shim_putmsghistory, (const char *msg, BOOLEAN_P restoring_msghist), "vsi", P2V msg, A2P restoring_msghist) +VDECLCB(shim_status_init, (void), "v") +VDECLCB(shim_status_enablefield, + (int fieldidx, const char *nm, const char *fmt, BOOLEAN_P enable), + "vippi", + A2P fieldidx, P2V nm, P2V fmt, A2P enable) +VDECLCB(shim_status_update, + (int fldidx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks), + "vipiiip", + A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks) - -/* old: | WC_TILED_MAP */ -/* Interface definition, for windows.c */ +/* Interface definition used in windows.c */ struct window_procs shim_procs = { "shim", (0 From ca9d1c5b974fb570e794e6435180e5e2bc8cea42 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 10:30:03 -0700 Subject: [PATCH 151/708] update build notes --- sys/lib/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/lib/README.md b/sys/lib/README.md index 3d314eb31..d27a3e875 100644 --- a/sys/lib/README.md +++ b/sys/lib/README.md @@ -4,6 +4,8 @@ This creates a library for NetHack that can be incorporated into other programs. * nethack.js / nethack.wasm - a [WebAssembly / WASM](https://webassembly.org/) library for use in JavaScript programs (both nodejs and browser) ## API: libnethack.a +This libarary has only been built on MacOS, but should work on Linux and other unix-ish platforms. If you have problems, start by stealing hints files from the `sys/unix/hints` for your platform. Contributions for other platforms are happily accepted. + 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. * `stub_graphics_set_callback(stub_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 scrren. The callback is `void stub_callback_t(const char *name, void *ret_ptr, const char *fmt, ...)` From 42f948018d9fd75c6d2948a0716fc72e44258d44 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 10:31:17 -0700 Subject: [PATCH 152/708] initial helpers --- sys/lib/test/README.md | 8 ++ sys/lib/test/libtest.c | 106 +++++++++++++++++++++++ sys/lib/test/run.sh | 40 +++++++++ sys/lib/test/test.js | 186 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 340 insertions(+) create mode 100644 sys/lib/test/README.md create mode 100644 sys/lib/test/libtest.c create mode 100755 sys/lib/test/run.sh create mode 100644 sys/lib/test/test.js diff --git a/sys/lib/test/README.md b/sys/lib/test/README.md new file mode 100644 index 000000000..c9cfed377 --- /dev/null +++ b/sys/lib/test/README.md @@ -0,0 +1,8 @@ +Development helpers and tests for libnethack.a and nethack.js. + +Copy these files to the NetHack root directory. Commands include: +* run.sh wasm - rebuild makefiles and build nethack.js +* run.sh runwasm - simple testing of nethack.js +* run.sh lib - rebuild makefiles and build libnethack.a +* run.sh runlib - simple testing of libnethack.a +* run.sh bin - build the MacOS binary \ No newline at end of file diff --git a/sys/lib/test/libtest.c b/sys/lib/test/libtest.c new file mode 100644 index 000000000..9b554b986 --- /dev/null +++ b/sys/lib/test/libtest.c @@ -0,0 +1,106 @@ +#include + +/* external functions */ +int nhmain(int argc, char *argv[]); +typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +void stub_graphics_set_callback(stub_callback_t cb); + +/* forward declarations */ +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...); + + +int main(int argc, char *argv[]) { + stub_graphics_set_callback(window_cb); + nhmain(argc, argv); +} + +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { + /* TODO -- see windowCallback below for hints */ + + /* DO SOMETHING HERE */ + *ret_ptr = yourFunctionToRenderGraphics(name, va_list args); +} + + + + +#if 0 +function variadicCallback(name, retPtr, fmt, args) { + // console.log ("variadicCallback called..."); + // console.log("typeof name", typeof name); + // console.log("typeof fmt", typeof fmt); + // console.log("typeof args", typeof args); + name = Module.UTF8ToString(name); + fmt = Module.UTF8ToString(fmt); + // console.log ("name:", name); + // console.log ("fmt:", fmt); + let argTypes = fmt.split(""); + let retType = argTypes.shift(); + // console.log ("arg count:", argTypes.length); + // console.log ("arg types:", argTypes); + // console.log ("ret type:", retType); + + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } + console.log(`graphics callback: ${name} [${jsArgs}]`); + setReturn(retPtr, retType); +} + +function setReturn(ptr, type, value = 0) { + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + Module.setValue(ptr, value, "i32"); + break; + case "c": + Module.setValue(ptr, value, "i8"); // 'Z' + break; + case "f": + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } +} + +function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + return Module.getValue(Module.getValue(ptr, "*"), "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } +} +#endif /* 0 */ \ No newline at end of file diff --git a/sys/lib/test/run.sh b/sys/lib/test/run.sh new file mode 100755 index 000000000..5e2b36dfe --- /dev/null +++ b/sys/lib/test/run.sh @@ -0,0 +1,40 @@ +#!/bin/bash -x + +if [ x$1 == "xlib" ]; then + echo Doing lib... + make spotless + cd sys/lib + ./setup.sh hints/macOS.2020 + cd ../.. + make +fi + +if [ x$1 == "xrunlib" ]; then + LIBS="-Lsrc -lnethack -Llib/lua -llua -lm" + BADLIBS="-lncurses" + gcc -o nhlibtest libtest.c $LIBS $BADLIBS + ./nhlibtest +fi + +if [ x$1 == "xwasm" ]; then + echo Doing wasm... + make spotless + cd sys/lib + ./setup.sh hints/wasm + cd ../.. + make +fi + +if [ x$1 == "xrunwasm" ]; then + node test.js +fi + +if [ x$1 == "xbin" ]; then + echo Doing bin... + make spotless + cd sys/unix + ./setup.sh hints/macOS.2020 + cd ../.. + make +fi + diff --git a/sys/lib/test/test.js b/sys/lib/test/test.js new file mode 100644 index 000000000..146b56d8a --- /dev/null +++ b/sys/lib/test/test.js @@ -0,0 +1,186 @@ +const util = require("util"); + +// Emscripten Module config +let Module = { + // noInitialRun: true, + onRuntimeInitialized: function () { + setGraphicsCallback(); + }, +}; + +var factory = require("./src/nethack.js"); + +// load and run the module +factory(Module); + +function setGraphicsCallback() { + console.log("setting callback function"); + let cb = Module.addFunction(windowCallback, "viiii"); + + console.log("doing call"); + Module.ccall( + "stub_graphics_set_callback", // C function name + null, // return type + ["number"], // arg types + [cb], // arg values + {async: true} // options + ); + + /* TODO: removeFunction */ +} + +function windowCallback(name, retPtr, fmt, args) { + // console.log ("variadicCallback called..."); + // console.log("typeof name", typeof name); + // console.log("typeof fmt", typeof fmt); + // console.log("typeof args", typeof args); + name = Module.UTF8ToString(name); + fmt = Module.UTF8ToString(fmt); + // console.log ("name:", name); + // console.log ("fmt:", fmt); + let argTypes = fmt.split(""); + let retType = argTypes.shift(); + // console.log ("arg count:", argTypes.length); + // console.log ("arg types:", argTypes); + // console.log ("ret type:", retType); + + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } + console.log(`graphics callback: ${name} [${jsArgs}]`); + let retVal = doGraphics(name, ... jsArgs); + setReturn(name, retPtr, retType, retVal); +} + +function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + ptr = Module.getValue(ptr, "*"); + if(!ptr) return 0; // null pointer + return Module.getValue(ptr, "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } +} + +function setReturn(name, ptr, type, value = 0) { + + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + if(typeof value !== "string") + throw new TypeError(`expected ${name} return type to be string`); + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + Module.setValue(ptr, value, "i32"); + break; + case "c": + if(typeof value !== "number" || value < 0 || value > 128) + throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); + Module.setValue(ptr, value, "i8"); + break; + case "f": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } + + function isFloat(n){ + return n === +n && n !== (n|0) && !Number.isInteger(n); + } +} + +let winCount = 0; +function doGraphics(name, ... args) { + switch(name) { + case "shim_create_nhwindow": + winCount++; + console.log("creating window", args, "returning", winCount); + return winCount; + case "shim_yn_function": + case "shim_message_menu": + return 121; // 'y' + case "shim_nhgetch": + case "shim_nh_poskey": + return 46; + default: + return 0; + } +} + +// var Module = null; +// factory(Module).then((ret) => { +// if(ret !== Module) { +// console.log("ret and Module are not the same"); +// } else { +// console.log("ret and Module are the same"); +// } +// // console.log("Module", util.inspect(Module, {depth: null, showHidden: true})); +// // TODO: +// // stub_graphics_set_callback(); + +// // options: +// // https://emscripten.org/docs/api_reference/module.html +// // logReadFiles +// // printWithColors +// // noInitialRun +// // onRuntimeInitialized +// console.log("doing run"); +// // Module.run(); + +// // // main loop +// // console.log("creating function"); +// // let fn = Module.addFunction(wasmCallback, "vii"); + +// // console.log("doing call"); +// // Module.ccall( +// // "mainloop", // C function name +// // null, // return type +// // ["number"], // arg types +// // [fn], // arg values +// // {async: true} // options +// // ); +// // // TODO: removeFunction(fn) + +// // var i = 0; +// // setInterval(function() { +// // console.log("interval", i++); +// // },1000); +// }); + From 85108bf7ef5f5f8346d2b16e60d5185a67cac429 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 10:45:54 -0700 Subject: [PATCH 153/708] add build section, fix naming --- sys/lib/README.md | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/sys/lib/README.md b/sys/lib/README.md index d27a3e875..cbbd87b51 100644 --- a/sys/lib/README.md +++ b/sys/lib/README.md @@ -3,12 +3,27 @@ This creates a library for NetHack that can be incorporated into other programs. * libnethack.a - a binary Unix library * nethack.js / nethack.wasm - a [WebAssembly / WASM](https://webassembly.org/) library for use in JavaScript programs (both nodejs and browser) -## API: libnethack.a -This libarary has only been built on MacOS, but should work on Linux and other unix-ish platforms. If you have problems, start by stealing hints files from the `sys/unix/hints` for your platform. Contributions for other platforms are happily accepted. +## Build +This library has only been built on MacOS, but should work on Linux and other unix-ish platforms. If you have problems, start by stealing hints files from the `sys/unix/hints` for your platform. Contributions for other platforms are happily accepted. +Building the WASM module requires that you have the [emscripten toolchain / sdk installed](https://emscripten.org/docs/getting_started/downloads.html). + +Generally the build is the same as the unix build: +1. `cd sys/lib` +2. For `libnethack.a`: `./setup.sh hints/macOS.2020`; for `nethack.js`: `./setup.sh hints/wasm` +3. `cd ../..` +4. `make` + +Resulting libaries will be in the `src` directory. + +WASM also has a npm module that can be published out of `sys/lib/npm-library`. After building the `nethack.js` it can be published by: +1. `cd sys/lib/npm-library` +2. `npm publish` + +## API: libnethack.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. -* `stub_graphics_set_callback(stub_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 scrren. The callback is `void stub_callback_t(const char *name, void *ret_ptr, const char *fmt, ...)` +* `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 scrren. 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.doc) 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. @@ -17,11 +32,9 @@ The API is two functions: 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 sumbit a PR to fix it. :) ## API: nethack.js -Building the WASM module requires that you have the [emscripten toolchain / sdk installed](https://emscripten.org/docs/getting_started/downloads.html). - The WebAssembly API has a similar signature to `libnethack.a` with minor syntactic differences: * `main(int argc, char argv[])` - The main function for NetHack -* `stub_graphics_set_callback(stub_callback_t cb)` - The same as above, but the signature of the callback is slightly different because WASM can't handle variadic callbacks. The callback is: `void stub_callback_t(const char *name, void *ret_ptr, const char *fmt, void *args[])` +* `shim_graphics_set_callback(shim_callback_t cb)` - The same as above, but the signature of the callback is slightly different because WASM can't handle variadic callbacks. The callback is: `void shim_callback_t(const char *name, void *ret_ptr, const char *fmt, void *args[])` * `name` - same as above * `ret_ptr` - same as above * `fmt` - same as above @@ -30,22 +43,22 @@ The WebAssembly API has a similar signature to `libnethack.a` with minor syntact ## API Stability -The "stub graphics" API should generally be stable. I aspire to replace the command line arguments (argc / argv) with a structure of options, so the `nhmain()` and `main()` functions may change at some point. +The "shim graphics" API should generally be stable. I aspire to replace the command line arguments (argc / argv) with a structure of options, so the `nhmain()` and `main()` functions may change at some point. ## libnethack.a example ``` c #include int nhmain(int argc, char *argv[]); -typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); -void stub_graphics_set_callback(stub_callback_t cb); +typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +void shim_graphics_set_callback(shim_callback_t cb); void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { /* TODO -- see windowCallback below for hints */ } int main(int argc, char *argv[]) { - stub_graphics_set_callback(window_cb); + shim_graphics_set_callback(window_cb); nhmain(argc, argv); } ``` @@ -76,7 +89,7 @@ function setGraphicsCallback() { console.log("setting callback function with library"); Module.ccall( - "stub_graphics_set_callback", // C function name + "shim_graphics_set_callback", // C function name null, // return type ["number"], // arg types [cb], // arg values From 4ffb8c9ce364e2bed4439ec8ec5c133188a4179e Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 10:46:55 -0700 Subject: [PATCH 154/708] fix naming --- sys/lib/test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/lib/test/test.js b/sys/lib/test/test.js index 146b56d8a..d7d8f0144 100644 --- a/sys/lib/test/test.js +++ b/sys/lib/test/test.js @@ -19,7 +19,7 @@ function setGraphicsCallback() { console.log("doing call"); Module.ccall( - "stub_graphics_set_callback", // C function name + "shim_graphics_set_callback", // C function name null, // return type ["number"], // arg types [cb], // arg values @@ -153,7 +153,7 @@ function doGraphics(name, ... args) { // } // // console.log("Module", util.inspect(Module, {depth: null, showHidden: true})); // // TODO: -// // stub_graphics_set_callback(); +// // shim_graphics_set_callback(); // // options: // // https://emscripten.org/docs/api_reference/module.html From efae5590e59141ed853bb836f76c2995cf4dc627 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 11:01:34 -0700 Subject: [PATCH 155/708] completed shim graphics callbacks --- sys/lib/hints/wasm | 4 ++-- win/shim/winshim.c | 39 +++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index 799efe03c..711017bae 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -17,8 +17,8 @@ EMCC_LFLAGS=-s WASM=1 EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["_nhmain"]' -O3 EMCC_LFLAGS+=-s MODULARIZE -EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_stub_graphics_set_callback"]' -EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue"]' +EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' +EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue", "setValue"]' EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 EMCC_LFLAGS+=--embed-file wasm-data@/ diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 310a4c315..05ed09c07 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -16,21 +16,21 @@ #undef SHIM_DEBUG #ifndef __EMSCRIPTEN__ -typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); #else /* __EMSCRIPTEN__ */ /* WASM can't handle a variadic callback, so we pass back an array of pointers instead... */ -typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, void *args[]); +typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, void *args[]); #endif /* !__EMSCRIPTEN__ */ /* this is the primary interface to shim graphics, * call this function with your declared callback function * and you will receive all the windowing calls */ -static stub_callback_t shim_graphics_callback = NULL; +static shim_callback_t shim_graphics_callback = NULL; #ifdef __EMSCRIPTEN__ EMSCRIPTEN_KEEPALIVE #endif -void stub_graphics_set_callback(stub_callback_t cb) { +void shim_graphics_set_callback(shim_callback_t cb) { shim_graphics_callback = cb; } @@ -84,10 +84,10 @@ void name fn_args { \ enum win_types { - WINSTUB_MESSAGE = 1, - WINSTUB_MAP, - WINSTUB_MENU, - WINSTUB_EXT + WINSHIM_MESSAGE = 1, + WINSHIM_MAP, + WINSHIM_MENU, + WINSHIM_EXT }; #define VSTUB(name, args) \ @@ -111,8 +111,7 @@ VDECLCB(shim_get_nh_event,(void), "v") VDECLCB(shim_exit_nhwindows,(const char *str), "vs", P2V str) VDECLCB(shim_suspend_nhwindows,(const char *str), "vs", P2V str) VDECLCB(shim_resume_nhwindows,(void), "v") -// DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) -winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) +DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) VDECLCB(shim_clear_nhwindow,(winid window), "vi", A2P window) VDECLCB(shim_display_nhwindow,(winid window, BOOLEAN_P blocking), "vii", A2P window, A2P blocking) VDECLCB(shim_destroy_nhwindow,(winid window), "vi", A2P window) @@ -125,8 +124,8 @@ VDECLCB(shim_add_menu, "viipiiisi", A2P window, A2P glyph, P2V identifier, A2P ch, A2P gch, A2P attr, P2V str, A2P itemflags) VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt) -int STUB(shim_select_menu,0,(winid a, int b, MENU_ITEM_P **c)) -char STUB(shim_message_menu,'y',(CHAR_P a, int b, const char *c)) +DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiip", A2P window, A2P how, P2V menu_list) +DECLCB(char, shim_message_menu,(CHAR_P let, int how, const char *mesg), "ciis", A2P let, A2P how, P2V mesg) VDECLCB(shim_update_inventory,(void), "v") VDECLCB(shim_mark_synch,(void), "v") VDECLCB(shim_wait_synch,(void), "v") @@ -135,25 +134,25 @@ VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) -int STUB(shim_nhgetch,0,(void)) -int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) +DECLCB(int, shim_nhgetch,(void), "i") +DECLCB(int, shim_nh_poskey,(int *x, int *y, int *mod), "ippp", P2V x, P2V y, P2V mod) VDECLCB(shim_nhbell,(void), "v") -int STUB(shim_doprev_message,0,(void)) -char STUB(shim_yn_function,'y',(const char *a, const char *b, CHAR_P c)) +DECLCB(int, shim_doprev_message,(void),"iv") +DECLCB(char, shim_yn_function,(const char *query, const char *resp, CHAR_P def), "cssi", P2V query, P2V resp, A2P def) VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp) -int STUB(shim_get_ext_cmd,0,(void)) +DECLCB(int,shim_get_ext_cmd,(void),"iv") VDECLCB(shim_number_pad,(int state), "vi", A2P state) VDECLCB(shim_delay_output,(void), "v") VDECLCB(shim_change_color,(int color, long rgb, int reverse), "viii", A2P color, A2P rgb, A2P reverse) VDECLCB(shim_change_background,(int white_or_black), "vi", A2P white_or_black) -short STUB(set_shim_font_name,0,(winid a, char *b)) -char *STUB(shim_get_color_string,"",(void)) +DECLCB(short, set_shim_font_name,(winid window_type, char *font_name),"2is", A2P window_type, P2V font_name) +DECLCB(char *,shim_get_color_string,(void),"sv") /* other defs that really should go away (they're tty specific) */ VDECLCB(shim_start_screen, (void), "v") VDECLCB(shim_end_screen, (void), "v") VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref) -char *STUB(shim_getmsghistory, (char *)"", (BOOLEAN_P a)) +DECLCB(char *,shim_getmsghistory, (BOOLEAN_P init), "si", A2P init) VDECLCB(shim_putmsghistory, (const char *msg, BOOLEAN_P restoring_msghist), "vsi", P2V msg, A2P restoring_msghist) VDECLCB(shim_status_init, (void), "v") VDECLCB(shim_status_enablefield, From ffa5e319afe94ea4851b197f00c34c195f96c7bd Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 11:59:23 -0700 Subject: [PATCH 156/708] ignore libnethack dev files --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b9196f2d1..193f1cfbd 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ Release/ binary/ build/ ipch/ -./lib/ +lib/* Nethack.sln Nethack.sdf Nethack.opensdf @@ -88,3 +88,7 @@ src/nethack.wasm src/nethack.js src/wasm-data src/libnethack.a +libtest.c +nhlibtest +run.sh +test.js From 356e7432e71ae52e112060c5a0af91882b593b72 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 12:00:12 -0700 Subject: [PATCH 157/708] ignore libnethack build files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 193f1cfbd..030d3d92e 100644 --- a/.gitignore +++ b/.gitignore @@ -92,3 +92,5 @@ libtest.c nhlibtest run.sh test.js +sys/lib/npm-package/build/nethack.js +sys/lib/npm-package/build/nethack.wasm From b0e77f77290594ea92939c3771ed4c8fdc88bf1d Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 12:00:39 -0700 Subject: [PATCH 158/708] initial npm package --- sys/lib/npm-package/LICENSE.md | 95 ++++++++++++++++++ sys/lib/npm-package/README.md | 44 +++++++++ sys/lib/npm-package/package.json | 20 ++++ sys/lib/npm-package/src/nethackShim.js | 127 +++++++++++++++++++++++++ 4 files changed, 286 insertions(+) create mode 100644 sys/lib/npm-package/LICENSE.md create mode 100644 sys/lib/npm-package/README.md create mode 100644 sys/lib/npm-package/package.json create mode 100644 sys/lib/npm-package/src/nethackShim.js diff --git a/sys/lib/npm-package/LICENSE.md b/sys/lib/npm-package/LICENSE.md new file mode 100644 index 000000000..5ad7e3417 --- /dev/null +++ b/sys/lib/npm-package/LICENSE.md @@ -0,0 +1,95 @@ + NETHACK GENERAL PUBLIC LICENSE + (Copyright 1989 M. Stephenson) + + (Based on the BISON general public license, + copyright 1988 Richard M. Stallman) + + Everyone is permitted to copy and distribute verbatim copies of this + license, but changing it is not allowed. You can also use this wording to + make the terms for other programs. + + The license agreements of most software companies keep you at the mercy of +those companies. By contrast, our general public license is intended to give +everyone the right to share NetHack. To make sure that you get the rights we +want you to have, we need to make restrictions that forbid anyone to deny you +these rights or to ask you to surrender the rights. Hence this license +agreement. + + Specifically, we want to make sure that you have the right to give away +copies of NetHack, that you receive source code or else can get it if you +want it, that you can change NetHack or use pieces of it in new free +programs, and that you know you can do these things. + + To make sure that everyone has such rights, we have to forbid you to +deprive anyone else of these rights. For example, if you distribute copies +of NetHack, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must tell them their rights. + + Also, for our own protection, we must make certain that everyone finds out +that there is no warranty for NetHack. If NetHack is modified by someone +else and passed on, we want its recipients to know that what they have is +not what we distributed. + + Therefore we (Mike Stephenson and other holders of NetHack copyrights) make +the following terms which say what you must do to be allowed to distribute or +change NetHack. + + + COPYING POLICIES + + 1. You may copy and distribute verbatim copies of NetHack source code as +you receive it, in any medium, provided that you keep intact the notices on +all files that refer to copyrights, to this License Agreement, and to the +absence of any warranty; and give any other recipients of the NetHack +program a copy of this License Agreement along with the program. + + 2. You may modify your copy or copies of NetHack or any portion of it, and +copy and distribute such modifications under the terms of Paragraph 1 above +(including distributing this License Agreement), provided that you also do the +following: + + a) cause the modified files to carry prominent notices stating that you + changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that in + whole or in part contains or is a derivative of NetHack or any part + thereof, to be licensed at no charge to all third parties on terms + identical to those contained in this License Agreement (except that you + may choose to grant more extensive warranty protection to some or all + third parties, at your option) + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty protection + in exchange for a fee. + + 3. You may copy and distribute NetHack (or a portion or derivative of it, +under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete machine-readable source code, which + must be distributed under the terms of Paragraphs 1 and 2 above; or, + + b) accompany it with full information as to how to obtain the complete + machine-readable source code from an appropriate archive site. (This + alternative is allowed only for noncommercial distribution.) + +For these purposes, complete source code means either the full source +distribution as originally released over Usenet or updated copies of the +files in this distribution used to create the object code or executable. + + 4. You may not copy, sublicense, distribute or transfer NetHack except as +expressly provided under this License Agreement. Any attempt otherwise to +copy, sublicense, distribute or transfer NetHack is void and your rights to +use the program under this License agreement shall be automatically +terminated. However, parties who have received computer software programs +from you with this License Agreement will not have their licenses terminated +so long as such parties remain in full compliance. + + +Stated plainly: You are permitted to modify NetHack, or otherwise use parts +of NetHack, provided that you comply with the conditions specified above; +in particular, your modified NetHack or program containing parts of NetHack +must remain freely available as provided in this License Agreement. In +other words, go ahead and share NetHack, but don't try to stop anyone else +from sharing it farther. diff --git a/sys/lib/npm-package/README.md b/sys/lib/npm-package/README.md new file mode 100644 index 000000000..891237492 --- /dev/null +++ b/sys/lib/npm-package/README.md @@ -0,0 +1,44 @@ +# NetHack +This is the ACTUAL NetHack game, originally written in 1982 and one of the longest-standing open source collaborations. This isn't a wrapper around the binary NetHack, but the game itself compiled into [WebAssembly](https://webassembly.org/) (WASM) using [emscripten](https://emscripten.org/). This module should run [anywhere WebAssembly is supported](https://developer.mozilla.org/en-US/docs/WebAssembly#Browser_compatibility) including node.js and modern browsers. + +Since NetHack typically uses the [TTY](https://en.wikipedia.org/wiki/Computer_terminal#Text_terminals) to show depictions of the game and that won't work for WebAssembly, you are required to implement the graphics portion of NetHack to make this work. This allows a wide variety of UIs to be created, both text and graphics based as well as using keyboard and mouse to control the game. The API for implementing graphics is described below. + +## Install + +``` sh +npm install nethack +``` + +## API +The main module returns a setup function: `startNethack(myCallback, moduleOptions)`. + +## Example +``` js +let nethackStart = require("nethack"); + +nethackStart(doGraphics); + +let winCount = 0; +function doGraphics(name, ... args) { + console.log(`shim graphics: ${name} [${args}]`); + + switch(name) { + case "shim_create_nhwindow": + winCount++; + console.log("creating window", args, "returning", winCount); + return winCount; + case "shim_yn_function": + case "shim_message_menu": + return 121; // return 'y' to all questions + case "shim_nhgetch": + case "shim_nh_poskey": + return 0; // simulates a mouse click on "exit up the stairs" + default: + return 0; + } +} +``` + +## Other Notes +* This module isn't small -- the WASM code is about 10MB. It may be slow to load over non-broadband connections. There are some emscripten build optimizations that may help with browser builds (such as dynamic loading), but those aren't currently part of this package. Pull requests are always welcome. :) +* This hasn't been tested on browsers. If you get this to work on a browser, please let me know and I will add notes. Or if anyone wants to help setup automated browser testing, that would be supremely appreciated. \ No newline at end of file diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json new file mode 100644 index 000000000..ae04ac7fe --- /dev/null +++ b/sys/lib/npm-package/package.json @@ -0,0 +1,20 @@ +{ + "name": "nethack", + "version": "1.0.0", + "description": "The original NetHack rogue-like game built as a WebAssembly module", + "main": "src/nethackShim.js", + "scripts": { + "test": "node test/test.js", + "clean": "rm ./build/nethack.js; rm ./build/nethack.wasm; true", + "build": "cp ../../../src/nethack.js ../../../src/nethack.wasm ./build", + "prepack": "npm run build" + }, + "keywords": [ + "nethack", + "rogue", + "rogue-like", + "game" + ], + "author": "Adam Powers ", + "license": "SEE LICENSE IN LICENSE.md" +} diff --git a/sys/lib/npm-package/src/nethackShim.js b/sys/lib/npm-package/src/nethackShim.js new file mode 100644 index 000000000..98d0cf808 --- /dev/null +++ b/sys/lib/npm-package/src/nethackShim.js @@ -0,0 +1,127 @@ +const path = require("path"); + +let Module; +let userCallback; +let savedOnRuntimeInitialized; +function nethackStart(cb, inputModule = {}) { + console.log("cb is", cb); + if(typeof cb !== "function") throw new TypeError("expected first argument to be callback function"); + if(typeof inputModule !== "object") throw new TypeError("expected second argument to be object"); + + // Emscripten Module config + Module = inputModule; + userCallback = cb; + savedOnRuntimeInitialized = Module.onRuntimeInitialized; + Module.onRuntimeInitialized = function (... args) { + // after the WASM is loaded, add the shim graphics callback function + let cb = Module.addFunction(windowCallback, "viiii"); + Module.ccall( + "shim_graphics_set_callback", // C function name + null, // return type + ["number"], // arg types + [cb], // arg values + {async: true} // options + ); + + /* TODO: Module.removeFunction() */ + + // if the user had their own onRuntimeInitialized(), call it now + if (savedOnRuntimeInitialized) savedOnRuntimeInitialized(... args); + }; + + // load and run the module + var factory = require(path.join(__dirname, "../build/nethack.js")); + factory(Module); +} + +function windowCallback(name, retPtr, fmt, args) { + name = Module.UTF8ToString(name); + fmt = Module.UTF8ToString(fmt); + let argTypes = fmt.split(""); + let retType = argTypes.shift(); + + // build array of JavaScript args from WASM parameters + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } + let retVal = userCallback(name, ... jsArgs); + setReturn(name, retPtr, retType, retVal); +} + +function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + ptr = Module.getValue(ptr, "*"); + if(!ptr) return 0; // null pointer + return Module.getValue(ptr, "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } +} + +function setReturn(name, ptr, type, value = 0) { + + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + if(typeof value !== "string") + throw new TypeError(`expected ${name} return type to be string`); + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + Module.setValue(ptr, value, "i32"); + break; + case "c": + if(typeof value !== "number" || value < 0 || value > 128) + throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); + Module.setValue(ptr, value, "i8"); + break; + case "f": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } + + function isFloat(n){ + return n === +n && n !== (n|0) && !Number.isInteger(n); + } +} + +// TODO: ES6 'import' style module +module.exports = nethackStart; + From 0c8e4e555efbdade85abc2c5bd401dab2e3e359e Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 30 Aug 2020 12:09:42 -0700 Subject: [PATCH 159/708] complete API documentation --- sys/lib/npm-package/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/lib/npm-package/README.md b/sys/lib/npm-package/README.md index 891237492..e71f3e5a1 100644 --- a/sys/lib/npm-package/README.md +++ b/sys/lib/npm-package/README.md @@ -10,7 +10,10 @@ npm install nethack ``` ## API -The main module returns a setup function: `startNethack(myCallback, moduleOptions)`. +The main module returns a setup function: `startNethack(uiCallback, moduleOptions)`. +* `uiCallback(name, ... args)` - Your callback function that will handle rendering NetHack on the screen of your choice. The `name` argument is one of the UI functions of the [NetHack Window Interface](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) and the `args` are corresponding to the window interface function that is being called. You are required to return the correct type of data for the function that is implemented. +* `moduleOptions` - An optional [emscripten Module object](https://emscripten.org/docs/api_reference/module.html) for configuring the WASM that will be run. + * `Module.arguments` - Of note is the [arguments property](https://emscripten.org/docs/api_reference/module.html#Module.arguments) which gets passed to NetHack as its [command line parameters](https://nethackwiki.com/wiki/Options). ## Example ``` js From 0902d83d521f459ce3188653527e142fdbb35895 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 30 Aug 2020 16:00:18 -0700 Subject: [PATCH 160/708] qt_win.cpp cleanup Started out fixing a comment typo and ended up removing a bunch of unnecessary stuff, plus a little bit of lackluster reformatting. --- win/Qt/qt_win.cpp | 40 ++++++++++++---------------------------- 1 file changed, 12 insertions(+), 28 deletions(-) diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 326acb17c..12d101496 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 Binding for NetHack 3.4 +// Qt Windowing interface for NetHack 3.7 // // Copyright (C) 1996-2001 by Warwick W. Allison (warwick@troll.no) // @@ -22,7 +22,7 @@ // and also because this is my first major application of Qt. // // The problem of NetHack's getkey requirement is solved by intercepting -// key events by overiding QApplicion::notify(...), and putting them in +// key events by overiding QApplication::notify(...), and putting them in // a buffer. Mouse clicks on the map window are treated with a similar // buffer. When the NetHack engine calls for a key, one is taken from // the buffer, or if that is empty, QApplication::exec() is called. @@ -43,7 +43,7 @@ // This includes all the definitions we need from the NetHack main // engine. We pretend MSC is a STDC compiler, because C++ is close // enough, and we undefine NetHack macros which conflict with Qt -// identifiers. +// identifiers (now done in qt_pre.h). #define QT_DEPRECATED_WARNINGS extern "C" { @@ -56,6 +56,9 @@ extern "C" { #include #endif #include "qt_post.h" + +// Many of these headers are not needed here. It's a holdover +// from when most of the Qt code was in one big file. #include "qt_win.h" #include "qt_bind.h" #include "qt_click.h" @@ -68,30 +71,8 @@ extern "C" { #include "qt_msg.h" #include "qt_set.h" -#include - #include "qt_clust.h" -#include - -#ifdef _WS_X11_ -// For userid control -#include -#endif - -#ifdef USER_SOUNDS -#if QT_VERSION >= 0x050000 -# include -# else -# include -# endif -#endif - - -#ifdef USER_SOUNDS -extern void play_sound_for_message(const std::string& str); -#endif - namespace nethack_qt_ { void @@ -119,10 +100,13 @@ bool NetHackQtWindow::Destroy() { return true; } void NetHackQtWindow::CursorTo(int x UNUSED,int y UNUSED) { puts("unexpected CursorTo"); } void NetHackQtWindow::PutStr(int attr UNUSED, const QString& text UNUSED) { puts("unexpected PutStr"); } void NetHackQtWindow::StartMenu() { puts("unexpected StartMenu"); } -void NetHackQtWindow::AddMenu(int glyph UNUSED, const ANY_P* identifier UNUSED, char ch UNUSED, char gch UNUSED, int attr UNUSED, - const QString& str UNUSED, unsigned itemflags UNUSED) { puts("unexpected AddMenu"); } +void NetHackQtWindow::AddMenu(int glyph UNUSED, const ANY_P* identifier UNUSED, + char ch UNUSED, char gch UNUSED, int attr UNUSED, + const QString& str UNUSED, unsigned itemflags UNUSED) + { puts("unexpected AddMenu"); } void NetHackQtWindow::EndMenu(const QString& prompt UNUSED) { puts("unexpected EndMenu"); } -int NetHackQtWindow::SelectMenu(int how UNUSED, MENU_ITEM_P **menu_list UNUSED) { puts("unexpected SelectMenu"); return 0; } +int NetHackQtWindow::SelectMenu(int how UNUSED, MENU_ITEM_P **menu_list UNUSED) + { puts("unexpected SelectMenu"); return 0; } void NetHackQtWindow::ClipAround(int x UNUSED,int y UNUSED) { puts("unexpected ClipAround"); } void NetHackQtWindow::PrintGlyph(int x UNUSED,int y UNUSED,int glyph UNUSED) { puts("unexpected PrintGlyph"); } //void NetHackQtWindow::PrintGlyphCompose(int x,int y,int,int) { puts("unexpected PrintGlyphCompose"); } From 3cd21e1d4ff09000c1702d4fa0a3c7bb3f0c9b75 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 30 Aug 2020 16:44:39 -0700 Subject: [PATCH 161/708] Qt keyboard fixups Make ASCII control characters ^[, ^\, ^], ^^, and ^_ work on Qt, at least partly. Mainly for ^[ to be treated as ESC, which works if you're aborting a count on the map but doesn't cancel out of menus [yet?]. I didn't attempt to make ^@ send NUL. Also, fix the hardcoded macros (activated by F1: rest 100 turns, F2: search 20 times, and Tab: ^A to do-again). The first two sent 'n' before the count so wouldn't work as intended with number_pad off, and the third was executing twice as if Tab sent two ^A's instead of just one. Resting and searching might have been getting duplicated too; I don't know how to simulate the relevant keys. (I temporarily swapped definitions for F2 and Tab to test the number_pad fix but hadn't done that earlier when I discovered the Tab bug.) --- doc/fixes37.0 | 3 +- win/Qt/qt_bind.cpp | 115 ++++++++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 6336374f4..a5579a86c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.291 $ $NHDT-Date: 1598661087 2020/08/29 00:31:27 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.292 $ $NHDT-Date: 1598831076 2020/08/30 23:44:36 $ General Fixes and Modified Features ----------------------------------- @@ -392,6 +392,7 @@ Qt: tombstone showed newly constructed date instead of the value set up at stared at or ignored prior --More-- for long enough on 31 December Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu entry checkboxes internally but didn't redraw the menu to show that +Qt: fix the F1/F2/Tab macro keys to not require that number_pad be On Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index ecff16587..7e849b77b 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -46,7 +46,7 @@ extern int qt_compact_mode; namespace nethack_qt_ { -// XXX Should be from Options +// XXX Should be from Options [or from Qt Settings (aka Preferences)]. // // XXX Hmm. Tricky part is that perhaps some macros should only be active // XXX when a key is about to be gotten. For example, the user could @@ -55,13 +55,13 @@ namespace nethack_qt_ { // static struct key_macro_rec { int key; - int state; - const char* macro; + uint state; + const char *macro, *numpad_macro; } key_macro[]={ - { Qt::Key_F1, 0, "n100." }, // Rest (x100) - { Qt::Key_F2, 0, "n20s" }, // Search (x20) - { Qt::Key_Tab, 0, "\001" }, - { 0, 0, 0 } + { Qt::Key_F1, 0U, "100.", "n100." }, // Rest (x100) + { Qt::Key_F2, 0U, "20s", "n20s" }, // Search (x20) + { Qt::Key_Tab, 0U, "\001", "\001" }, // ^A (Do-again) + { 0, 0U, (const char *) 0, (const char *) 0 } }; NetHackQtBind::NetHackQtBind(int& argc, char** argv) : @@ -75,8 +75,9 @@ NetHackQtBind::NetHackQtBind(int& argc, char** argv) : { QPixmap pm("nhsplash.xpm"); if ( iflags.wc_splash_screen && !pm.isNull() ) { - splash = new QFrame(NULL, - Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::WindowStaysOnTopHint ); + splash = new QFrame(NULL, (Qt::FramelessWindowHint + | Qt::X11BypassWindowManagerHint + | Qt::WindowStaysOnTopHint)); QVBoxLayout *vb = new QVBoxLayout(splash); QLabel *lsplash = new QLabel(splash); vb->addWidget(lsplash); @@ -534,19 +535,25 @@ char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, C message = question; } - if (qt_settings->ynInMessages() && WIN_MESSAGE!=WIN_ERR) { + if (qt_settings->ynInMessages() && WIN_MESSAGE != WIN_ERR) { // Similar to X11 windowport `slow' feature. int result = -1; #ifdef USE_POPUPS if (choices) { - if (!strcmp(choices,"ynq")) - result = QMessageBox::information (NetHackQtBind::mainWidget(),"NetHack",question,"&Yes","&No","&Quit",0,2); - else if (!strcmp(choices,"yn")) - result = QMessageBox::information(NetHackQtBind::mainWidget(),"NetHack",question,"&Yes", "&No",0,1); + if (!strcmp(choices, "ynq")) + result = QMessageBox::information (NetHackQtBind::mainWidget(), + "NetHack", question, + "&Yes", "&No", "&Quit", 0, 2); + else if (!strcmp(choices, "yn")) + result = QMessageBox::information(NetHackQtBind::mainWidget(), + "NetHack", question, + "&Yes", "&No", 0, 1); else if (!strcmp(choices, "rl")) - result = QMessageBox::information(NetHackQtBind::mainWidget(),"NetHack",question,"&Right", "&Left",0,1); + result = QMessageBox::information(NetHackQtBind::mainWidget(), + "NetHack", question, + "&Right", "&Left", 0, 1); if (result >= 0 && result < strlen(choices)) { char yn_resp = choices[result]; @@ -686,46 +693,48 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) { // Ignore Alt-key navigation to menubar, it's annoying when you // use Alt-Direction to move around. - if ( main && event->type()==QEvent::KeyRelease && main==receiver - && ((QKeyEvent*)event)->key() == Qt::Key_Alt ) - return true; + if (main && receiver == main && event->type() == QEvent::KeyRelease + && ((QKeyEvent *) event)->key() == Qt::Key_Alt) + return true; - bool result=QApplication::notify(receiver,event); - if (event->type()==QEvent::KeyPress) { - QKeyEvent* key_event=(QKeyEvent*)event; + bool result = QApplication::notify(receiver, event); + if (event->type() == QEvent::KeyPress) { + QKeyEvent *key_event = (QKeyEvent *) event; - if (!key_event->isAccepted()) { - const int k=key_event->key(); - bool macro=false; - for (int i=0; !macro && key_macro[i].key; i++) { - if (key_macro[i].key==k - && ((key_macro[i].state&key_event->modifiers()) == (unsigned int) key_macro[i].state)) - { - keybuffer.Put(key_macro[i].macro); - macro=true; - } - } - QString key=key_event->text(); - QChar ch = !key.isEmpty() ? key.at(0) : 0; - if (ch > 128) ch = 0; - if ( ch == 0 && (key_event->modifiers() & Qt::ControlModifier) ) { - // On Mac, ascii control codes are not sent, force them. - if ( k>=Qt::Key_A && k<=Qt::Key_Z ) - ch = k - Qt::Key_A + 1; - } - if (!macro && ch != 0) { - bool alt = (key_event->modifiers()&Qt::AltModifier) || - (k >= Qt::Key_0 && k <= Qt::Key_9 && (key_event->modifiers()&Qt::ControlModifier)); - keybuffer.Put(key_event->key(),ch.cell() + (alt ? 128 : 0), - key_event->modifiers()); - key_event->accept(); - result=true; - } - - if (ch != 0 || macro) { - qApp->exit(); - } - } + if (!key_event->isAccepted()) { + Qt::KeyboardModifiers mod = key_event->modifiers(); + const int k = key_event->key(); + for (int i = 0; key_macro[i].key; i++) { + if (key_macro[i].key == k + && ((key_macro[i].state & mod) == key_macro[i].state)) { + // matched macro; put its expansion into the input buffer + keybuffer.Put(!::iflags.num_pad ? key_macro[i].macro + : key_macro[i].numpad_macro); + key_event->accept(); + qApp->exit(); + return true; + } + } + QString key = key_event->text(); + QChar ch = !key.isEmpty() ? key.at(0) : 0; + if (ch > 128) + ch = 0; + // on OSX, ascii control codes are not sent, force them + if ((mod & Qt::ControlModifier) != 0) { + if (ch == 0 && k >= Qt::Key_A && k <= Qt::Key_Underscore) + ch = (QChar) (k - (Qt::Key_A - 1)); + } + // if we have a valid character, queue it up + if (ch != 0) { + bool alt = ((mod & Qt::AltModifier) != 0 + || (k >= Qt::Key_0 && k <= Qt::Key_9 + && (mod & Qt::ControlModifier) != 0)); + keybuffer.Put(k, ch.cell() + (alt ? 128 : 0), (uint) mod); + key_event->accept(); + qApp->exit(); + result = true; + } + } } return result; } From 1f953fa959f14d154a0131c0c55ac04679fa8338 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 30 Aug 2020 22:50:02 -0700 Subject: [PATCH 162/708] Qt message [un]highlighting The Qt interface highlights the last message issued (using a mechanism for selection, as if for copy+paste or similar operation) but it was staying highlighted until another message was eventually given. Having an old message seem to stick around is annoying and is particularly bad when the message is a prompt. If the player's answer doesn't cause a message to be shown then it seems as if the prompt is still pending. This removes the highlighting (by bulk unselecting) once the player gives another input keystroke or mouse click. It would be much better if the selecting/highlighting was for all messages issued since last time highlighting was cleared. Figuring out how to do that correctly is more effort than I want to expend. --- doc/fixes37.0 | 3 ++- win/Qt/qt_bind.cpp | 13 ++++++++-- win/Qt/qt_main.cpp | 14 +++++++---- win/Qt/qt_main.h | 2 +- win/Qt/qt_map.cpp | 10 +++++--- win/Qt/qt_msg.cpp | 59 +++++++++++++++++++++++++++++++++------------- win/Qt/qt_msg.h | 3 +++ 7 files changed, 76 insertions(+), 28 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a5579a86c..d0d6e975f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.292 $ $NHDT-Date: 1598831076 2020/08/30 23:44:36 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.293 $ $NHDT-Date: 1598852985 2020/08/31 05:49:45 $ General Fixes and Modified Features ----------------------------------- @@ -393,6 +393,7 @@ Qt: tombstone showed newly constructed date instead of the value set up at Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu entry checkboxes internally but didn't redraw the menu to show that Qt: fix the F1/F2/Tab macro keys to not require that number_pad be On +Qt: unhighlight highlighted message (last one issued) after player has seen it Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 7e849b77b..e6492aaea 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -471,7 +471,7 @@ void NetHackQtBind::qt_raw_print_bold(const char *str) int NetHackQtBind::qt_nhgetch() { if (main) - main->fadeHighlighting(); + main->fadeHighlighting(true); // Process events until a key arrives. // @@ -479,19 +479,28 @@ int NetHackQtBind::qt_nhgetch() qApp->exec(); } + // after getting a key rather than before + if (main) + main->fadeHighlighting(false); + return keybuffer.GetAscii(); } int NetHackQtBind::qt_nh_poskey(int *x, int *y, int *mod) { if (main) - main->fadeHighlighting(); + main->fadeHighlighting(true); // Process events until a key or map-click arrives. // while (keybuffer.Empty() && clickbuffer.Empty()) { qApp->exec(); } + + // after getting a key or click rather than before + if (main) + main->fadeHighlighting(false); + if (!keybuffer.Empty()) { return keybuffer.GetAscii(); } else { diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index ca32f1e4a..e57a1a8e1 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -751,7 +751,7 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : the application menu instead of the help menu; we'll add it to the latter now and have two ways to access it; without the leading underscore (or some other spelling variation such as - "'bout"), this one would get interceptd too and then evidently + "'bout"), this one would get intercepted too and then evidently be discarded as a duplicate */ help->addSeparator(); help->addAction("_About_Qt_NetHack_", this, SLOT(doAbout(bool))); @@ -1042,10 +1042,16 @@ void NetHackQtMainWindow::updateInventory() } } -void NetHackQtMainWindow::fadeHighlighting() +void NetHackQtMainWindow::fadeHighlighting(bool before_key) { - if (status) { - status->fadeHighlighting(); + if (before_key) { + // status highlighting fades at start of turn + if (status) + status->fadeHighlighting(); + } else { + // message highlighting fades after user has given input + if (message && message->hilit_mesgs()) + message->unhighlight_mesgs(); } } diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index f043c619f..fbec9fb63 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -47,7 +47,7 @@ public: void RemoveWindow(NetHackQtWindow* window); void updateInventory(); - void fadeHighlighting(); + void fadeHighlighting(bool before_key); // this is unconditional in case qt_main.h comes before qt_set.h void resizePaperDoll(bool); // ENHANCED_PAPERDOLL diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index eb497da86..2e507e691 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -582,12 +582,16 @@ void NetHackQtMapWindow2::clearMessages() void NetHackQtMapWindow2::putMessage(int attr UNUSED, const QString& text) { - if ( !messages.isEmpty() ) + if (!messages.isEmpty()) messages += "\n"; messages += QString(text).replace(QChar(0x200B), ""); - QFontMetrics fm = fontMetrics(); #if 0 - messages_rect = fm.boundingRect(viewport.contentsX(),viewport.contentsY(),viewport.width(),0, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft|Qt::TextDontClip, messages); + QFontMetrics fm = fontMetrics(); + messages_rect = fm.boundingRect(viewport.contentsX(), viewport.contentsY(), + viewport.width(), 0, + (Qt::TextWordWrap | Qt::AlignTop + | Qt::AlignLeft | Qt::TextDontClip), + messages); update(messages_rect); #endif } diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index aee2ea135..dcb643efb 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -74,6 +74,9 @@ void NetHackQtMessageWindow::ClearMessages() void NetHackQtMessageWindow::Display(bool block UNUSED) { + // + // FIXME: support for 'block' is necessary for MSGTYPE=stop + // if (changed) { list->repaint(); changed=false; @@ -88,8 +91,9 @@ const char * NetHackQtMessageWindow::GetStr(bool init) QListWidgetItem *item = list->item(currgetmsg++); if (item) { QString str = item->text(); - //raw_printf("getstr[%i]='%s'", currgetmsg, str.toLatin1().constData()); - return str.toLatin1().constData(); + const char *result = str.toLatin1().constData(); + //raw_printf("getstr[%d]='%s'", currgetmsg, result); + return result; } return NULL; } @@ -114,31 +118,52 @@ void NetHackQtMessageWindow::PutStr(int attr, const QString& text) font.setWeight((attr == ATR_BOLD) ? QFont::Bold : QFont::Normal); item->setFont(font); - QColor fg = item->foreground().color(); - QColor bg = item->background().color(); - if (attr == ATR_DIM) - { - fg.setAlpha(fg.alpha() / 2); + if (attr == ATR_DIM || attr == ATR_INVERSE) { + QColor fg = item->foreground().color(); + QColor bg = item->background().color(); + if (attr == ATR_DIM) { + fg.setAlpha(fg.alpha() / 2); + new_fgbg = true; + } + if (attr == ATR_INVERSE) { + QColor swap; + swap = fg; fg = bg; bg = swap; + } + item->setForeground(fg); + item->setBackground(bg); } - if (attr == ATR_INVERSE) - { - QColor swap; - swap = fg; fg = bg; bg = swap; - } - item->setForeground(fg); - item->setBackground(bg); + // ATR_BLINK not supported #endif - // ATR_BLINK not supported if (list->count() >= (int) ::iflags.msg_history) delete list->item(0); list->addItem(text2); // Force scrollbar to bottom - list->setCurrentRow(list->count()-1); + list->setCurrentRow(list->count() - 1); - if ( map ) + if (map) map->putMessage(attr, text2); } +// are there any highlighted messages? +bool NetHackQtMessageWindow::hilit_mesgs() +{ + // PutStr() uses setCurrentRow() to select the last message line; + // being selected causes that line to be highlighted. + // + // We could/should keep track of whether anything is currently + // highlighted instead of just assuming that last message still is. + if (list && list->count()) + return true; + return false; +} + +// unhighlight any highlighted messages +void NetHackQtMessageWindow::unhighlight_mesgs() +{ + if (list) + list->clearSelection(); +} + } // namespace nethack_qt_ diff --git a/win/Qt/qt_msg.h b/win/Qt/qt_msg.h index 08c029b9b..1aa2b94c8 100644 --- a/win/Qt/qt_msg.h +++ b/win/Qt/qt_msg.h @@ -30,6 +30,9 @@ public: void setMap(NetHackQtMapWindow2*); + bool hilit_mesgs(); + void unhighlight_mesgs(); + private: QListWidget* list; bool changed; From 2a762ab641913466d0902f038f8019a4a2295f39 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 31 Aug 2020 00:30:36 -0700 Subject: [PATCH 163/708] Qt prompt responses in message window When Qt issues a prompt string in the message window, update it with the player's response once that has been obtained. --- doc/fixes37.0 | 4 +++- win/Qt/qt_bind.cpp | 18 +++++++++++++++++- win/Qt/qt_msg.cpp | 15 ++++++++++++++- win/Qt/qt_msg.h | 2 ++ 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d0d6e975f..b28eb8afc 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.293 $ $NHDT-Date: 1598852985 2020/08/31 05:49:45 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.294 $ $NHDT-Date: 1598859031 2020/08/31 07:30:31 $ General Fixes and Modified Features ----------------------------------- @@ -394,6 +394,8 @@ Qt: menu choices All, None, Invert were setting, unsetting, or toggling menu entry checkboxes internally but didn't redraw the menu to show that Qt: fix the F1/F2/Tab macro keys to not require that number_pad be On Qt: unhighlight highlighted message (last one issued) after player has seen it +Qt: update message window's last message with player's response if it's a + prompt string for a single-character of input (ynaq or invent letter) Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index e6492aaea..76028c65a 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -524,7 +524,8 @@ int NetHackQtBind::qt_doprev_message() return 0; } -char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, CHAR_P def) +char NetHackQtBind::qt_yn_function(const char *question_, + const char *choices, CHAR_P def) { QString question(QString::fromLatin1(question_)); QString message; @@ -548,6 +549,8 @@ char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, C // Similar to X11 windowport `slow' feature. int result = -1; + char cbuf[40]; + cbuf[0] = '\0'; #ifdef USE_POPUPS if (choices) { @@ -575,21 +578,34 @@ char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, C NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); while (result < 0) { + cbuf[0] = '\0'; 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; + Strcpy(cbuf, visctrl(def)); } else { NetHackQtBind::qt_nhbell(); // and try again... } } else { result=ch; + Strcpy(cbuf, (ch == ' ') ? "SPC" : visctrl(ch)); } } + // if answer was supplied via popup, it will already be appended + // to the prompt, so included above, and cbuf[] will be empty + if (cbuf[0]) { + NetHackQtWindow *window = id_to_window[WIN_MESSAGE]; + NetHackQtMessageWindow *mesgwin + = static_cast (window); + mesgwin->AddToStr(cbuf); + } + NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); return result; diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index dcb643efb..abde5c179 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -62,7 +62,10 @@ void NetHackQtMessageWindow::Scroll(int dx UNUSED, int dy UNUSED) void NetHackQtMessageWindow::Clear() { - if ( map ) + if (list) + NetHackQtMessageWindow::unhighlight_mesgs(); + + if (map) map->clearMessages(); } @@ -146,6 +149,16 @@ void NetHackQtMessageWindow::PutStr(int attr, const QString& text) map->putMessage(attr, text2); } +// append the user's answer to a prompt message +void NetHackQtMessageWindow::AddToStr(const char *answer) +{ + if (list) { + QListWidgetItem *item = list->currentItem(); + if (item) + item->setText(item->text() + QString(" %1").arg(answer)); + } +} + // are there any highlighted messages? bool NetHackQtMessageWindow::hilit_mesgs() { diff --git a/win/Qt/qt_msg.h b/win/Qt/qt_msg.h index 1aa2b94c8..c3cd4275c 100644 --- a/win/Qt/qt_msg.h +++ b/win/Qt/qt_msg.h @@ -32,6 +32,8 @@ public: bool hilit_mesgs(); void unhighlight_mesgs(); + // for adding the answer for yn() to its prompt string + void AddToStr(const char *answerbuf); private: QListWidget* list; From a2782d47f5b99825c17079b252cce416c1da24d7 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 31 Aug 2020 15:47:49 -0700 Subject: [PATCH 164/708] Qt without tiles again "Qt without tiles" (commit ae4c180cf62ce4f19bd020495d6b089584b2426b) two weeks ago accidentally took out a line that should have stayed. --- win/Qt/qt_glyph.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 807b4dc7d..1585d9ca9 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -52,6 +52,7 @@ NetHackQtGlyphs::NetHackQtGlyphs() if (!img.load(tile_file)) { QString msg; msg.sprintf("Cannot load 'nhtiles.bmp' or 'x11tiles'."); + QMessageBox::warning(0, "IO Error", msg); iflags.wc_ascii_map = 1; iflags.wc_tiled_map = 0; } else { From aaa4c1d37c4de69aa6a887473164dd214b72fdd6 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 1 Sep 2020 04:11:01 -0700 Subject: [PATCH 165/708] potential infinite loop on hangup (ring prompt) Core issue noticed while working on some Qt stuff. If hangup occurred while prompting for "right or left?" ring finger, the hangup yn_function() would return ESC and the accessory-on routine would not see '\0', 'r', or 'l' so reprompt. Endlessly. --- doc/fixes37.0 | 3 ++- src/do_wear.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b28eb8afc..00442d951 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.294 $ $NHDT-Date: 1598859031 2020/08/31 07:30:31 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.295 $ $NHDT-Date: 1598958650 2020/09/01 11:10:50 $ General Fixes and Modified Features ----------------------------------- @@ -248,6 +248,7 @@ end of game inventory disclosure passed an inappropriate argument to the inventory display routine; not noticeable for tty and curses, noticeable but not harmful for X11, and slightly harmful for Qt turning into slime rendered hero as slime one turn too soon +avoid potential infinite loop if hangup occurs at ring "right or left?" prompt Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/do_wear.c b/src/do_wear.c index f3a157c81..3d20fe61f 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_wear.c $NHDT-Date: 1596498163 2020/08/03 23:42:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 3.7 do_wear.c $NHDT-Date: 1598958650 2020/09/01 11:10:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1982,6 +1982,7 @@ struct obj *obj; answer = yn_function(qbuf, "rl", '\0'); switch (answer) { case '\0': + case '\033': return 0; case 'l': case 'L': From 490b2604544de227eb7538c47a257ca5fa3727e4 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Tue, 1 Sep 2020 13:11:09 -0700 Subject: [PATCH 166/708] remove stray console.log --- sys/lib/npm-package/src/nethackShim.js | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/lib/npm-package/src/nethackShim.js b/sys/lib/npm-package/src/nethackShim.js index 98d0cf808..638460278 100644 --- a/sys/lib/npm-package/src/nethackShim.js +++ b/sys/lib/npm-package/src/nethackShim.js @@ -4,7 +4,6 @@ let Module; let userCallback; let savedOnRuntimeInitialized; function nethackStart(cb, inputModule = {}) { - console.log("cb is", cb); if(typeof cb !== "function") throw new TypeError("expected first argument to be callback function"); if(typeof inputModule !== "object") throw new TypeError("expected second argument to be object"); From caaa9b058858bfd5c2ca1ca865e654d8605aa9cb Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 2 Sep 2020 07:27:29 -0700 Subject: [PATCH 167/708] remove stray printfs --- sys/lib/libnethackmain.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/lib/libnethackmain.c b/sys/lib/libnethackmain.c index ed8142bd7..5f000847f 100644 --- a/sys/lib/libnethackmain.c +++ b/sys/lib/libnethackmain.c @@ -76,9 +76,6 @@ char *argv[]; boolean plsel_once = FALSE; int i; - printf ("nhmain\n"); - printf ("argc: %d\n", argc); - printf ("argv: %p\n", (void *)argv); for (i = 0; i < argc; i++) { printf ("argv[%d]: %s\n", i, argv[i]); } From a8373f22244f11a0c240b8cdcce7b6026952481e Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 2 Sep 2020 07:28:01 -0700 Subject: [PATCH 168/708] move package to npm organization --- sys/lib/npm-package/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json index ae04ac7fe..f4e095261 100644 --- a/sys/lib/npm-package/package.json +++ b/sys/lib/npm-package/package.json @@ -1,5 +1,5 @@ { - "name": "nethack", + "name": "@neth_ck/nethack", "version": "1.0.0", "description": "The original NetHack rogue-like game built as a WebAssembly module", "main": "src/nethackShim.js", From 045a5879f141b5cf3504cac39673663d7f4cc93d Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 2 Sep 2020 07:42:29 -0700 Subject: [PATCH 169/708] npm doesn't allow 'hack' in package names --- sys/lib/npm-package/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json index f4e095261..45cea1739 100644 --- a/sys/lib/npm-package/package.json +++ b/sys/lib/npm-package/package.json @@ -1,5 +1,5 @@ { - "name": "@neth_ck/nethack", + "name": "@neth_ck/neth_ck", "version": "1.0.0", "description": "The original NetHack rogue-like game built as a WebAssembly module", "main": "src/nethackShim.js", From 152187870c4effdab2fcbcf3b847d82246df2276 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 3 Sep 2020 19:01:36 -0700 Subject: [PATCH 170/708] Qt input overhaul Enable existing wc_popup_dialog option. Use it in yn_function() instead using a mystery value which apparently used to live in Qt Settings but isn't there anymore so couldn't be turned on or off. Also replaces conditional USE_POPUPS which isn't defined anywhere either so presumably came from CFLAGS and only supported "yn?", "ynq?", and "rl?" with hardcoded Qt popups rather than using NetHackQtYnDialog. Doing that revealed that the popup dialog for ynaq was in pretty bad shape. It's functional but still needs a lot of work, beyond the limited Qt/C++ capability I possess. The KeyPress issue which accepts as input, thereby preventing + from being typed during ynaq prompting, is particularly nasty. Append the ynaq dialog's response to the message line containing the corresponding prompt similar to what's now done for regular yn_function(). Add getlin() prompt+response to the message window. --- doc/fixes37.0 | 4 +- win/Qt/qt_bind.cpp | 148 ++++++++++++++++----------- win/Qt/qt_key.cpp | 5 + win/Qt/qt_key.h | 2 + win/Qt/qt_yndlg.cpp | 239 ++++++++++++++++++++++++++++++++------------ 5 files changed, 275 insertions(+), 123 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 00442d951..b1236e979 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.295 $ $NHDT-Date: 1598958650 2020/09/01 11:10:50 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ $NHDT-Date: 1599184888 2020/09/04 02:01:28 $ General Fixes and Modified Features ----------------------------------- @@ -397,6 +397,8 @@ Qt: fix the F1/F2/Tab macro keys to not require that number_pad be On Qt: unhighlight highlighted message (last one issued) after player has seen it Qt: update message window's last message with player's response if it's a prompt string for a single-character of input (ynaq or invent letter) +Qt: for line input, display the prompt+response in the message window +Qt: enable the popup_dialog WC option (result is a bit flakey but usable) Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 76028c65a..defc0e0ad 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -530,6 +530,7 @@ char NetHackQtBind::qt_yn_function(const char *question_, QString question(QString::fromLatin1(question_)); QString message; char yn_esc_map='\033'; + int result = -1; if (choices) { // anything beyond is hidden> @@ -537,44 +538,34 @@ char NetHackQtBind::qt_yn_function(const char *question_, size_t cb = choicebuf.indexOf('\033'); choicebuf = choicebuf.mid(0U, cb); message = QString("%1 [%2] ").arg(question, choicebuf); - if (def) message += QString("(%1) ").arg(QChar(def)); + if (def) + message += QString("(%1) ").arg(QChar(def)); // escape maps to 'q' or 'n' or default, in that order - yn_esc_map = (strchr(choices, 'q') ? 'q' : - (strchr(choices, 'n') ? 'n' : def)); + yn_esc_map = strchr(choices, 'q') ? 'q' + : strchr(choices, 'n') ? 'n' + : def; } else { message = question; } - if (qt_settings->ynInMessages() && WIN_MESSAGE != WIN_ERR) { + if ( + /* + * The 'Settings' dialog doesn't present prompting-in-message-window + * as a candidate for customization but core supports 'popup_dialog' + * option so let player use that instead. + */ +#if 0 + qt_settings->ynInMessages() +#else + !::iflags.wc_popup_dialog +#endif + && WIN_MESSAGE != WIN_ERR) { // Similar to X11 windowport `slow' feature. - int result = -1; - char cbuf[40]; + char cbuf[20]; cbuf[0] = '\0'; -#ifdef USE_POPUPS - if (choices) { - if (!strcmp(choices, "ynq")) - result = QMessageBox::information (NetHackQtBind::mainWidget(), - "NetHack", question, - "&Yes", "&No", "&Quit", 0, 2); - else if (!strcmp(choices, "yn")) - result = QMessageBox::information(NetHackQtBind::mainWidget(), - "NetHack", question, - "&Yes", "&No", 0, 1); - else if (!strcmp(choices, "rl")) - result = QMessageBox::information(NetHackQtBind::mainWidget(), - "NetHack", question, - "&Right", "&Left", 0, 1); - - if (result >= 0 && result < strlen(choices)) { - char yn_resp = choices[result]; - message += QString(" %1").arg(yn_resp); - result = yn_resp; - } - } -#endif - + // add the prompt to the messsage window NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); while (result < 0) { @@ -593,41 +584,83 @@ char NetHackQtBind::qt_yn_function(const char *question_, } } else { result=ch; - Strcpy(cbuf, (ch == ' ') ? "SPC" : visctrl(ch)); + Strcpy(cbuf, visctrl(ch)); } } - // if answer was supplied via popup, it will already be appended - // to the prompt, so included above, and cbuf[] will be empty + // update the prompt message line to include the response if (cbuf[0]) { - NetHackQtWindow *window = id_to_window[WIN_MESSAGE]; - NetHackQtMessageWindow *mesgwin - = static_cast (window); - mesgwin->AddToStr(cbuf); + if (!strcmp(cbuf, " ")) + Strcpy(cbuf, "SPC"); + + NetHackQtMessageWindow *mesgwin = main->GetMessageWindow(); + if (mesgwin) + mesgwin->AddToStr(cbuf); } - NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); - - return result; } else { - NetHackQtYnDialog dialog(mainWidget(),question,choices,def); - char ret = dialog.Exec(); - if (!(ret == '\0' || ret == '\033') && choices) - message += QString(" %1").arg(ret); - else if (def) - message += QString(" %1").arg(def); + // use a popup dialog box + NetHackQtYnDialog dialog(main, question, choices, def); + char ret = dialog.Exec(); + if (ret == 0) { + ret = '\033'; + } + // discard any input that YnDialog() might have left pending + keybuffer.Drain(); + + // combine the prompt and result + char cbuf[40]; + Strcpy(cbuf, (ret == '\033') ? "ESC" + : (ret == ' ') ? "SPC" + : visctrl(ret)); + if (ret == '#' && choices && !strncmp(choices, "yn#", (size_t) 3)) + Sprintf(eos(cbuf), " %ld", ::yn_number); + message += QString(" %1").arg(cbuf); + + // add the prompt with appended response to the messsage window NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); - return ret; + result = ret; } + + // unhighlight the prompt; does not erase the multi-line message window + NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); + + return (char) result; } void NetHackQtBind::qt_getlin(const char *prompt, char *line) { NetHackQtStringRequestor requestor(mainWidget(),prompt); if (!requestor.Get(line)) { - line[0]=0; + Strcpy(line, "\033"); + // discard any input that Get() might have left pending + keybuffer.Drain(); } + + // add the prompt with appended response to the messsage window + char buf[BUFSZ + 20], *q; /* +20: plenty of extra room for visctrl() */ + copynchars(buf, prompt, BUFSZ - 1); + q = eos(buf); + *q++ = ' '; /* guaranteed to fit; temporary lack of terminator is ok */ + + if (line[0] == '\033') { + Strcpy(q, "ESC"); + } else if (line[0] == ' ' && !line[1]) { + Strcpy(q, "SPC"); + } else { + /* buf[] has more than enough room to hold one extra visctrl() + in case q is at the last viable slot and *p yields "M-^c" */ + for (char *p = line; *p && q < &buf[BUFSZ - 1]; ++p, q = eos(q)) + Strcpy(q, visctrl(*p)); + } + if (q > &buf[BUFSZ - 1]) + q = &buf[BUFSZ - 1]; + *q = '\0'; + + NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, buf); + // unhighlight the prompt; does not erase the multi-line message window + NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); } int NetHackQtBind::qt_get_ext_cmd() @@ -665,17 +698,17 @@ void NetHackQtBind::qt_outrip(winid wid, int how, time_t when) window->UseRIP(how, when); } -char * NetHackQtBind::qt_getmsghistory(BOOLEAN_P init) +char *NetHackQtBind::qt_getmsghistory(BOOLEAN_P init) { - NetHackQtMessageWindow* window = main->GetMessageWindow(); + NetHackQtMessageWindow *window = main->GetMessageWindow(); if (window) - return (char *)window->GetStr(init); + return (char *) window->GetStr((bool) init); return NULL; } void NetHackQtBind::qt_putmsghistory(const char *msg, BOOLEAN_P is_restoring) { - NetHackQtMessageWindow* window = main->GetMessageWindow(); + NetHackQtMessageWindow *window = main->GetMessageWindow(); if (!window) return; @@ -685,7 +718,7 @@ void NetHackQtBind::qt_putmsghistory(const char *msg, BOOLEAN_P is_restoring) int i = 0; const char *str; - while ((str = window->GetStr((i == 0)))) { + while ((str = window->GetStr((bool) (i == 0))) != 0) { msgs_strings->append(str); i++; } @@ -702,11 +735,11 @@ void NetHackQtBind::qt_putmsghistory(const char *msg, BOOLEAN_P is_restoring) #endif } else if (msgs_saved) { /* restore strings */ - int i; - for (i = 0; i < msgs_strings->size(); i++) { - window->PutStr(ATR_NONE, msgs_strings->at((i))); + for (int i = 0; i < msgs_strings->size(); ++i) { + const QString &nxtmsg = msgs_strings->at(i); + window->PutStr(ATR_NONE, nxtmsg); #ifdef DUMPLOG - dumplogmsg(msgs_strings->at(i).toLatin1().constData()); + dumplogmsg(nxtmsg.toLatin1().constData()); #endif } delete msgs_strings; @@ -782,9 +815,10 @@ struct window_procs Qt_procs = { WC_COLOR | WC_HILITE_PET | WC_ASCII_MAP | WC_TILED_MAP | WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT + | WC_POPUP_DIALOG | WC_PLAYER_SELECTION | WC_SPLASH_SCREEN, 0L, - {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ nethack_qt_::NetHackQtBind::qt_init_nhwindows, nethack_qt_::NetHackQtBind::qt_player_selection, nethack_qt_::NetHackQtBind::qt_askname, diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index f882b458e..81acb1786 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -85,4 +85,9 @@ Qt::KeyboardModifiers NetHackQtKeyBuffer::TopState() const return state[out]; } +void NetHackQtKeyBuffer::Drain() +{ + in = out = 0; +} + } // namespace nethack_qt_ diff --git a/win/Qt/qt_key.h b/win/Qt/qt_key.h index 78a2c56c9..a96c0a07f 100644 --- a/win/Qt/qt_key.h +++ b/win/Qt/qt_key.h @@ -27,6 +27,8 @@ public: int TopAscii() const; Qt::KeyboardModifiers TopState() const; + void Drain(); + private: enum { maxkey=64 }; int key[maxkey]; diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 389ee4858..3924050da 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -24,16 +24,47 @@ extern int qt_compact_mode; namespace nethack_qt_ { +static const char lrq[] = "lr\033LRq"; +char altchoices[BUFSZ + 12]; + // temporary void centerOnMain(QWidget *); // end temporary -NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent,const QString& q,const char* ch,char df) : +NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent, const QString &q, + const char *ch, char df) : QDialog(parent), question(q), choices(ch), def(df), keypress('\033') { setWindowTitle("NetHack: Question"); + + // plain prompt doesn't show any room for an answer (answer won't be + // echoed but the fact that a prompt is pending and accepts typed + // input as an alternative to mouse click seems clearer when there + // is some space available to accept it) + if (!question.endsWith(" ") && !question.endsWith("_")) + question += " _"; // an underlined space would be better + + if (choices) { + // special handling for wearing rings; prompt asks "right or left?" + // but side-by-side buttons look better with [left][right] instead + if (!strcmp(choices, "rl")) { + choices = lrq; + if (!def) + def = 'r'; + + // if count is allowed, explicitly add the digits as valid + } else if (!strncmp(choices, "yn#", (size_t) 3)) { + ::yn_number = 0L; + + if (!strchr(choices, '9')) { + copynchars(altchoices, choices, BUFSZ - 1); + // duplicate # is intentional; explicitly separates \... and 0 + choices = strcat(altchoices, "\033#0123456789"); + } + } + } } char NetHackQtYnDialog::Exec() @@ -53,9 +84,10 @@ char NetHackQtYnDialog::Exec() if ( question[c] == '-' ) ch.append(question[c++]); unsigned from=0; - while ( c < question.size() && question[c] != ']' && question[c] != ' ' ) { + while (c < question.size() + && question[c] != ']' && question[c] != ' ') { if ( question[c] == '-' ) { - from = question[c-1].unicode(); + from = question[c - 1].cell(); } else if ( from != 0 ) { for (unsigned f=from+1; f<=question[c]; f++) ch.append(QChar(f)); @@ -101,9 +133,9 @@ char NetHackQtYnDialog::Exec() } if (!ch.isNull()) { QVBoxLayout *vb = new QVBoxLayout; - bool bigq = qlabel.length()>40; - if ( bigq ) { - QLabel* q = new QLabel(qlabel,this); + bool bigq = (qlabel.length() > (qt_compact_mode ? 40 : 60)); + if (bigq) { + QLabel *q = new QLabel(qlabel, this); q->setAlignment(Qt::AlignLeft); q->setWordWrap(true); q->setMargin(4); @@ -116,60 +148,84 @@ char NetHackQtYnDialog::Exec() QButtonGroup *bgroup = new QButtonGroup(group); int nchoices=ch.length(); - - bool allow_count=ch.contains('#'); - QString yn = "yn", ynq = "ynq"; - bool is_ynq = ch == yn || ch == ynq; + bool allow_count = (ch.left(3) == QString("yn#")), + is_ynq = (ch == QString("ynq")), // [ Yes ][ No ][Cancel] + is_yn = (ch == QString("yn")), // [Yes ][ No ] + is_lr = (ch == QString(lrq)); // [ Left ][Right ] const int margin=8; const int gutter=8; const int extra=fontMetrics().height(); // Extra for group int x=margin, y=extra+margin; - int butsize=fontMetrics().height()*2+5; + int butheight = fontMetrics().height() * 2 + 5, + butwidth = (butheight - 5) + * ((is_ynq || is_lr) ? 3 : is_yn ? 2 : 1) + 5; - QPushButton* button; - for (int i=0; isetEnabled(false); - } - button->setFixedSize(butsize,butsize); // Square - if (ch[i]==def) button->setDefault(true); - if (i%10==9) { - // last in row - x=margin; - y+=butsize+gutter; - } else { - x+=butsize+gutter; - } + QPushButton *button; + for (int i = 0; i < nchoices; ++i) { + if (ch[i] == '\033') + break; // ESC and anything after are hidden + if (ch[i] == '#' && allow_count) + continue; // don't show a button for '#'; has Count box instead + QString button_name = QString(visctrl((char) ch[i].cell())); + if (is_yn || is_ynq || is_lr) { + switch (ch[i].cell()) { + case 'y': + button_name = "Yes"; + break; + case 'n': + button_name = "No"; + break; + case 'q': + // FIXME: sometimes the 'q' choice is ''cancel current + // action'' but other times it is actually 'quit'. + if (question.left(10) == QString("Dump core?")) + button_name = "Quit"; + else + button_name = "Cancel"; + break; + case 'l': + button_name = "Left"; + break; + case 'r': + button_name = "Right"; + break; + } + } + button=new QPushButton(button_name); + if (!enable.isNull()) { + if (!enable.contains(ch[i])) + button->setEnabled(false); + } + button->setFixedSize(butwidth, butheight); + if (ch[i] == def) + button->setDefault(true); + // 'x' and 'y' don't seem to actually used anywhere + // and limit of 10 buttons per row isn't enforced + if (i % 10 == 9) { + // last in row + x = margin; + y += butheight + gutter; + } else { + x += butwidth + gutter; + } groupbox->addWidget(button); bgroup->addButton(button, i); } - connect(bgroup,SIGNAL(buttonClicked(int)),this,SLOT(doneItem(int))); + connect(bgroup, SIGNAL(buttonClicked(int)), this, SLOT(doneItem(int))); - QLabel* lb=0; - QLineEdit* le=0; - - if (allow_count) { - QHBoxLayout *hb = new QHBoxLayout(this); - lb=new QLabel("Count: "); - hb->addWidget(lb); - le=new QLineEdit(); - hb->addWidget(le); - vb->addLayout(hb); + QLabel *lb = 0; + QLineEdit *le = 0; + if (allow_count) { + // put the Count widget in between [y] and [n][a][q] + lb = new QLabel("Count:"); + groupbox->insertWidget(1, lb); // [n] button is item #1 + le = new QLineEdit(); + groupbox->insertWidget(2, le); // [n] became #2, Count label #1 } + // add an invisible right-most field to left justify the buttons + groupbox->addStretch(80); setLayout(vb); adjustSize(); @@ -177,23 +233,70 @@ char NetHackQtYnDialog::Exec() show(); char choice=0; char ch_esc=0; - for (uint i=0; i< (uint) ch.length(); i++) { - if (ch[i].unicode()=='q') ch_esc='q'; - else if (!ch_esc && ch[i].unicode()=='n') ch_esc='n'; + for (int i = 0; i < ch.length(); ++i) { + if (ch[i].cell() == 'q') + ch_esc = 'q'; + else if (!ch_esc && ch[i].cell() == 'n') + ch_esc = 'n'; } - exec(); - if ( result() == 0) { - choice = ch_esc ? ch_esc : def ? def : ' '; - } else if ( result() == 1 ) { - choice = def ? def : ch_esc ? ch_esc : ' '; - } else if ( result() >= 1000 ) { - choice = ch[result() - 1000].unicode(); - } - if (allow_count && !le->text().isEmpty()) { - yn_number=le->text().toInt(); - choice='#'; - } - return choice; + + // + // When a count is allowed, clicking on the count widget then + // typing in digits followed by is 'normal' operation. + // However, typing a digit without clicking first will set focus + // to the count widget with that typed digit preloaded. + // FIXME: Unfortunately, it will also be selected, so typing + // another digit replaces it instead of being the next digit in + // a multiple-digit number. + // + // Theoretically typing '#' does this to, with a 0 preloaded + // and intentionally selected, but the KeyPress bug (below) of + // treating as a complete response prevents use of + // shift+3 from being used to generate '#'. + // + bool retry; // for digit + re-activate widget + rest of number + do { + retry = false; // might have a second pass (but not a third) + exec(); + int res = result(); + if (res == 0) { + choice = is_lr ? '\033' : ch_esc ? ch_esc : def ? def : ' '; + } else if (res == 1) { + choice = def ? def : ch_esc ? ch_esc : ' '; + } else if (res >= 1000) { + choice = (char) ch[res - 1000].cell(); + + if (allow_count && strchr("#0123456789", choice)) { + if (choice == '#') { + // 0 will be preselected; typing anything replaces it + le->insert(QString("0")); + } else { + le->insert(QString(choice)); + // + // FIXME: despite the documentation claiming that + // 'false' cancels any selection, the digit always + // starts out selected (from running exec() again?) + // so typing the next digit replaces it instead of + // being appended to it unless the player uses + // right-arrow to move the cursor. + // + le->end(false); + } + // (don't know whether this actually does anything useful) + le->setAttribute(Qt::WA_KeyboardFocusChange, true); + le->setFocus(Qt::ActiveWindowFocusReason); + retry = true; + } + } + } while (retry); + + // non-Null 'le' implies 'allow_count' + if (le && !le->text().isEmpty()) { + ::yn_number = le->text().toInt(); + choice = '#'; + } + keypress = choice; + } else { QLabel label(qlabel,this); QPushButton cancel("Dismiss",this); @@ -207,12 +310,18 @@ char NetHackQtYnDialog::Exec() show(); keypress = '\033'; exec(); - return keypress; } + return keypress; } void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) { + // + // FIXME: on OSX (possibly elsewhere), this accepts + // (and even ) as the entire response before the user + // has a chance to type any character to be shifted. + // + // Don't want QDialog's Return/Esc behaviour //RLC ...or do we? QString text(event->text()); From bf3697c1221dec1a3a4c3f0604bfed1c9a8cc3b9 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 4 Sep 2020 14:31:44 -0700 Subject: [PATCH 171/708] hunger checks Eliminate the feasibility of micro-managing ring hunger by swapping back and forth between a pair of rings of slow digestion. Wearing one at a time causes normal ring hunger (wearing both at once just increases such hunger), but being able to put on the second ring and take off the first just before the 1 out of 20 turns where it affects hunger, then vice versa a few turns later, is an insanely tedious way to avoid any hunger at all, made possible by the 'time' option. Make the turns where extra hunger get imposed be randomized so that that can't be done reliably. Also closes githib issue #336: hunger caused by melee attacking adds ring and amulet hunger a second time for that turn. That has always been intentional behavior; now the amount varies for any given attack due to the randomization, but on average is the same as before. Closes #336 --- doc/fixes37.0 | 3 ++- src/eat.c | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b1236e979..dc210bd01 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.296 $ $NHDT-Date: 1599184888 2020/09/04 02:01:28 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.297 $ $NHDT-Date: 1599255099 2020/09/04 21:31:39 $ General Fixes and Modified Features ----------------------------------- @@ -249,6 +249,7 @@ end of game inventory disclosure passed an inappropriate argument to the noticeable but not harmful for X11, and slightly harmful for Qt turning into slime rendered hero as slime one turn too soon avoid potential infinite loop if hangup occurs at ring "right or left?" prompt +randomize the turns where accessories and extrinsics affect nutrition Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/eat.c b/src/eat.c index a4a670df1..620f9e277 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 eat.c $NHDT-Date: 1596498165 2020/08/03 23:42:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.231 $ */ +/* NetHack 3.7 eat.c $NHDT-Date: 1599255099 2020/09/04 21:31:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2811,6 +2811,8 @@ bite() void gethungry() { + long accessorytime; + if (u.uinvulnerable) return; /* you don't feel hungrier */ @@ -2825,14 +2827,25 @@ gethungry() && !Slow_digestion) u.uhunger--; /* ordinary food consumption */ - if (g.moves % 2) { /* odd turns */ + /* + * 3.7: 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 + * off the first, then vice versa, over and over and over and ... + * to avoid any hunger from wearing a ring) become ineffective. + * Also causes melee-induced hunger to vary from turn-based hunger + * instead of just replicating that. + */ + accessorytime = g.moves + (long) rn2(20); + if (accessorytime % 2L) { /* odd */ /* Regeneration uses up food, unless due to an artifact */ if ((HRegeneration & ~FROMFORM) || (ERegeneration & ~(W_ARTI | W_WEP))) u.uhunger--; if (near_capacity() > SLT_ENCUMBER) u.uhunger--; - } else { /* even turns */ + } else { /* even */ if (Hunger) u.uhunger--; /* Conflict uses up food too */ @@ -2851,7 +2864,7 @@ gethungry() * cancellation") if hero doesn't have protection from some * other source (cloak or second ring). */ - switch ((int) (g.moves % 20)) { /* note: use even cases only */ + switch ((int) (accessorytime % 20L)) { /* note: use even cases only */ case 4: if (uleft && uleft->otyp != MEAT_RING /* more hungry if +/- is nonzero or +/- doesn't apply or From 13cf558e6bdd2c0a8e091fc7243d14c0ebbc53cb Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 4 Sep 2020 15:29:22 -0700 Subject: [PATCH 172/708] more hunger checks I don't know what I was thinking before. 'moves + rn2(20)' can be simplified to just rn2(20) and ignore moves altogether. --- src/eat.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/eat.c b/src/eat.c index 620f9e277..17040fc9e 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 eat.c $NHDT-Date: 1599255099 2020/09/04 21:31:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.232 $ */ +/* NetHack 3.7 eat.c $NHDT-Date: 1599258557 2020/09/04 22:29:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2811,7 +2811,7 @@ bite() void gethungry() { - long accessorytime; + int accessorytime; if (u.uinvulnerable) return; /* you don't feel hungrier */ @@ -2837,8 +2837,8 @@ gethungry() * Also causes melee-induced hunger to vary from turn-based hunger * instead of just replicating that. */ - accessorytime = g.moves + (long) rn2(20); - if (accessorytime % 2L) { /* odd */ + accessorytime = rn2(20); /* rn2(20) replaces (int) (g.moves % 20L) */ + if (accessorytime % 2) { /* odd */ /* Regeneration uses up food, unless due to an artifact */ if ((HRegeneration & ~FROMFORM) || (ERegeneration & ~(W_ARTI | W_WEP))) @@ -2864,7 +2864,7 @@ gethungry() * cancellation") if hero doesn't have protection from some * other source (cloak or second ring). */ - switch ((int) (accessorytime % 20L)) { /* note: use even cases only */ + switch (accessorytime) { /* note: use even cases among 0..19 only */ case 4: if (uleft && uleft->otyp != MEAT_RING /* more hungry if +/- is nonzero or +/- doesn't apply or From bce7834f71ea1c1c2e683d021ca2694f5006e024 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 5 Sep 2020 11:35:28 -0700 Subject: [PATCH 173/708] polearm context Move clearing of polearm context from migrate_to_lev() to lower level relmon(). Add missing transfer of polearm context from old mon to new mon in replmon(). These days it seems to only be used for creating a monster from saved traits, so polearm context in it should be moot. --- src/dog.c | 4 +--- src/mon.c | 8 +++++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dog.c b/src/dog.c index 44ef538ff..14a6b1992 100644 --- a/src/dog.c +++ b/src/dog.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dog.c $NHDT-Date: 1596498159 2020/08/03 23:42:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.103 $ */ +/* NetHack 3.7 dog.c $NHDT-Date: 1599330917 2020/09/05 18:35:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.104 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -726,8 +726,6 @@ coord *cc; /* optional destination coordinates */ mtmp->mux = new_lev.dnum; mtmp->muy = new_lev.dlevel; mtmp->mx = mtmp->my = 0; /* this implies migration */ - if (mtmp == g.context.polearm.hitmon) - g.context.polearm.hitmon = (struct monst *) 0; } /* return quality of food; the lower the better */ diff --git a/src/mon.c b/src/mon.c index a4c0f6f90..83e28ebbc 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1598575089 2020/08/28 00:38:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1599330921 2020/09/05 18:35:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.345 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1809,6 +1809,9 @@ struct monst *mtmp, *mtmp2; otmp->ocarry = mtmp2; } mtmp->minvent = 0; + /* before relmon(mtmp), because it could clear polearm.hitmon */ + if (g.context.polearm.hitmon == mtmp) + g.context.polearm.hitmon = mtmp2; /* remove the old monster from the map and from `fmon' list */ relmon(mtmp, (struct monst **) 0); @@ -1853,6 +1856,9 @@ struct monst **monst_list; /* &g.migrating_mons or &g.mydogs or null */ if (!fmon) panic("relmon: no fmon available."); + if (mon == g.context.polearm.hitmon) + g.context.polearm.hitmon = (struct monst *) 0; + if (unhide) { /* can't remain hidden across level changes (exception: wizard clone can continue imitating some other monster form); also, From b48ebbfe15a2694b67062bb82484345c5071ae71 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 5 Sep 2020 13:28:46 -0700 Subject: [PATCH 174/708] update unix Makefile hints --- sys/unix/NewInstall.unx | 10 +++++----- sys/unix/hints/include/multiw-2.2020 | 27 ++++++++++++--------------- sys/unix/hints/linux.2020 | 15 +++++++++++---- sys/unix/hints/macOS.2020 | 15 +++++++++++---- 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/sys/unix/NewInstall.unx b/sys/unix/NewInstall.unx index d6dbdd1eb..f0064c78a 100644 --- a/sys/unix/NewInstall.unx +++ b/sys/unix/NewInstall.unx @@ -65,10 +65,10 @@ the following build command: make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 install To build a binary with tty + curses + X11 + Qt support (that is, all the -interfaces that are available), you can use the following shorthand build -command: - make WANT_WIN_ALL all - make WANT_WIN_ALL install +interfaces that are available for unix), you can use the following shorthand +build command: + make WANT_WIN_ALL=1 all + make WANT_WIN_ALL=1 install Alternatively, you can set the variables in the environment first, prior to issuing your make commands: @@ -146,6 +146,6 @@ additional interfaces. See below. | --remove-section=.note.ABI-tag/usr/lib/x86_64-linux-gnu/libQt5Core.so.5 | +----------+---------+-----------------+-------------------------------------+ -# NetHack 3.7 NewInstall.unx $NHDT-Date: 1597340908 2020/08/13 17:48:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ +# NetHack 3.7 NewInstall.unx $NHDT-Date: 1599337707 2020/09/05 20:28:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ # Copyright (c) 2009 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. diff --git a/sys/unix/hints/include/multiw-2.2020 b/sys/unix/hints/include/multiw-2.2020 index ad4028aed..b96266ed8 100644 --- a/sys/unix/hints/include/multiw-2.2020 +++ b/sys/unix/hints/include/multiw-2.2020 @@ -1,5 +1,5 @@ #------------------------------------------------------------------------------ -# NetHack 3.7 multiw-2.2020 $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# NetHack 3.7 multiw-2.2020 $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. # @@ -29,26 +29,23 @@ # something other than tty as the default interface. # -# Make sure that at least one interface is enabled. -ifndef WANT_WIN_ALL -ifndef WANT_WIN_TTY -ifndef WANT_WIN_CURSES -ifndef WANT_WIN_X11 -ifndef WANT_WIN_QT -WANT_WIN_TTY=1 -endif -endif -endif -endif -endif - ifdef WANT_WIN_ALL WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 WANT_WIN_QT=1 +else +# Make sure that at least one interface is enabled. +ifndef WANT_WIN_TTY +ifndef WANT_WIN_CURSES +ifndef WANT_WIN_X11 +ifndef WANT_WIN_QT +WANT_WIN_TTY=1 +endif +endif +endif +endif endif - # Make sure that a default interface is specified; this doesn't guarantee # sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 3a785a530..4de9a0957 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.2020 $NHDT-Date: 1597704792 2020/08/17 22:53:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.7 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1599337708 2020/09/05 20:28:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -16,6 +16,14 @@ # linux.2020 hints file provides a single-user build for Linux (such # as Ubuntu focal). +# compiler flags: various -I, -D, and -W get appended below; +# these are the settings of most interest for an end-user build +# (clang doesn't support '-Og', gcc needs 4.x or later) +CFLAGS = -g +#CFLAGS = -g -Og +#CFLAGS = -O2 + +# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 3 #-INCLUDE multiw-1.2020 # 4. If you set WANT_WIN_QT, you need to @@ -45,8 +53,7 @@ GAMEGRP = games #-INCLUDE multiw-2.2020 -# XXX -g vs -O should go here, -I../include goes in the makefile -CFLAGS=-g -O -I../include -DNOTPARMDECL +CFLAGS+=-I../include -DNOTPARMDECL ifeq "$(CCISCLANG)" "" # get the version of gcc GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) @@ -134,7 +141,7 @@ ifeq "$(GPPGTEQ9)" "1" QTCXXFLAGS+= -Wno-format-truncation endif #g++ version greater than or equal to 9 endif #not clang -QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) +QTCXXFLAGS += $(sort $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags)) QTCXXFLAGS += -fPIC WINLIB += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --libs) VARDATND0 += nhtiles.bmp rip.xpm nhsplash.xpm diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 1a81d97ad..a5777a0f8 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.2020 $NHDT-Date: 1597704793 2020/08/17 22:53:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1599337708 2020/09/05 20:28:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -16,6 +16,14 @@ # macOS X hints file # +# compiler flags: various -I, -D, and -W get appended below; +# these are the settings of most interest for an end-user build +# (clang doesn't support '-Og', gcc needs 4.x or later) +CFLAGS = -g +#CFLAGS = -g -Og +#CFLAGS = -O2 + +# note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 3 #-INCLUDE multiw-1.2020 # 4. If you set WANT_WIN_QT, you need to @@ -47,8 +55,7 @@ endif #-INCLUDE multiw-2.2020 -# XXX -g vs -O should go here, -I../include goes in the makefile -CFLAGS+=-g -I../include -DNOTPARMDECL +CFLAGS+=-I../include -DNOTPARMDECL ifndef WANT_WIN_QT # these are normally used when compiling nethack's core CFLAGS+=-ansi -pedantic -Wno-long-long @@ -139,7 +146,7 @@ ifeq "$(GPPGTEQ9)" "1" QTCXXFLAGS+= -Wno-format-truncation endif #g++ version greater than or equal to 9 endif #not clang -QTCXXFLAGS += $(shell PKG_CONFIG_PATH=$(QTDIR)/lib/pkgconfig pkg-config Qt5Gui Qt5Widgets Qt5Multimedia --cflags) +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) WINSRC += $(WINQTSRC) WINOBJ0 += $(WINQTOBJ) From f20a6bb491c3fb2819eab968a5e071ff1eb70f0e Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 6 Sep 2020 16:17:33 -0700 Subject: [PATCH 175/708] special level's lit state when changing terrain Part of pull request #308: when using des.terrain to set terrain, default for lit state becomes 'unchanged' rather than 'unlit'. des.replace_terrain already operates that way. Replace lit state magic numbers -1 and -2 with SET_LIT_RANDOM and SET_LIT_NOCHANGE. Also change SET_TYPLIT() to not operate on map column 0 and move it from rm.h to sp_lev.h. It never belonged there, is only used in sp_lev.c, and now because of the SET_LIT_ macros it couldn't be used anywhere else unless sp_lev.h gets included too. --- doc/fixes37.0 | 4 +++- include/rm.h | 32 ++++++++------------------------ include/sp_lev.h | 23 ++++++++++++++++++++++- src/sp_lev.c | 39 ++++++++++++++++++++++++--------------- 4 files changed, 57 insertions(+), 41 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index dc210bd01..3364e09c4 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.297 $ $NHDT-Date: 1599255099 2020/09/04 21:31:39 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.298 $ $NHDT-Date: 1599434249 2020/09/06 23:17:29 $ General Fixes and Modified Features ----------------------------------- @@ -326,6 +326,8 @@ the fix to make worm visibility checks work as intended forced the coordinates reverses the segments and can throw some away if there isn't room, but throwing away the extra segment removed the worm from the map using 'O' to try to change 'symset' was a no-op; 'roguesymset' worked +change default for lit attribute in special level des.terrain directives to + 'unchanged' instead of 'unlit' curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/include/rm.h b/include/rm.h index 3f06e9d83..761e8b30c 100644 --- a/include/rm.h +++ b/include/rm.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 rm.h $NHDT-Date: 1596498558 2020/08/03 23:49:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 3.7 rm.h $NHDT-Date: 1599434249 2020/09/06 23:17:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.84 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -436,22 +436,6 @@ struct rm { Bitfield(candig, 1); /* Exception to Can_dig_down; was a trapdoor */ }; -#define SET_TYPLIT(x, y, ttyp, llit) \ - { \ - if ((x) >= 0 && (y) >= 0 && (x) < COLNO && (y) < ROWNO) { \ - if ((ttyp) < MAX_TYPE) \ - levl[(x)][(y)].typ = (ttyp); \ - if ((ttyp) == LAVAPOOL) \ - levl[(x)][(y)].lit = 1; \ - else if ((schar)(llit) != -2) { \ - if ((schar)(llit) == -1) \ - levl[(x)][(y)].lit = rn2(2); \ - else \ - levl[(x)][(y)].lit = (llit); \ - } \ - } \ - } - /* * Add wall angle viewing by defining "modes" for each wall type. Each * mode describes which parts of a wall are finished (seen as as wall) @@ -631,10 +615,10 @@ typedef struct { * Macros for encapsulation of level.monsters references. */ #if 0 -#define MON_AT(x, y) \ +#define MON_AT(x, y) \ (g.level.monsters[x][y] != (struct monst *) 0 \ && !(g.level.monsters[x][y])->mburied) -#define MON_BURIED_AT(x, y) \ +#define MON_BURIED_AT(x, y) \ (g.level.monsters[x][y] != (struct monst *) 0 \ && (g.level.monsters[x][y])->mburied) #else /* without 'mburied' */ @@ -642,15 +626,15 @@ typedef struct { #endif #ifdef EXTRA_SANITY_CHECKS #define place_worm_seg(m, x, y) \ - do { \ + do { \ if (g.level.monsters[x][y] && g.level.monsters[x][y] != m) \ - impossible("place_worm_seg over mon"); \ - g.level.monsters[x][y] = m; \ + impossible("place_worm_seg over mon"); \ + g.level.monsters[x][y] = m; \ } while(0) #define remove_monster(x, y) \ - do { \ + do { \ if (!g.level.monsters[x][y]) \ - impossible("no monster to remove"); \ + impossible("no monster to remove"); \ g.level.monsters[x][y] = (struct monst *) 0; \ } while(0) #else diff --git a/include/sp_lev.h b/include/sp_lev.h index d68250b02..821359907 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.h $NHDT-Date: 1596498560 2020/08/03 23:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.38 $ */ +/* NetHack 3.7 sp_lev.h $NHDT-Date: 1599434249 2020/09/06 23:17:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -62,6 +62,11 @@ enum lvlinit_types { #define SEL_GRADIENT_RADIAL 0 #define SEL_GRADIENT_SQUARE 1 +/* light states for terrain replacements, specifically for SET_TYPLIT + * (not used for init_level) */ +#define SET_LIT_RANDOM -1 +#define SET_LIT_NOCHANGE -2 + #define SP_COORD_IS_RANDOM 0x01000000L /* Humidity flags for get_location() and friends, used with * SP_COORD_PACK_RANDOM() */ @@ -188,4 +193,20 @@ struct mapfragment { char *data; }; +#define SET_TYPLIT(x, y, ttyp, llit) \ + { \ + if ((x) >= 1 && (y) >= 0 && (x) < COLNO && (y) < ROWNO) { \ + if ((ttyp) < MAX_TYPE) \ + levl[(x)][(y)].typ = (ttyp); \ + if ((ttyp) == LAVAPOOL) \ + levl[(x)][(y)].lit = 1; \ + else if ((schar)(llit) != SET_LIT_NOCHANGE) { \ + if ((schar)(llit) == SET_LIT_RANDOM) \ + levl[(x)][(y)].lit = rn2(2); \ + else \ + levl[(x)][(y)].lit = (llit); \ + } \ + } \ + } + #endif /* SP_LEV_H */ diff --git a/src/sp_lev.c b/src/sp_lev.c index d49d68579..d08888028 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.c $NHDT-Date: 1596498212 2020/08/03 23:43:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 3.7 sp_lev.c $NHDT-Date: 1599434249 2020/09/06 23:17:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -10,7 +10,7 @@ */ #define IN_SP_LEV_C - + #include "hack.h" #include "sp_lev.h" @@ -5089,12 +5089,15 @@ lua_State *L; return 0; } -/* terrain({ x=NN, y=NN, typ=MAPCHAR, lit=BOOL }); */ -/* terrain({ coord={X, Y}, typ=MAPCHAR, lit=BOOL }); */ -/* terrain({ selection=SELECTION, typ=MAPCHAR, lit=BOOL }); */ -/* terrain( SELECTION, MAPCHAR [, BOOL ] ); */ -/* terrain({x,y}, MAPCHAR); */ -/* terrain(x,y, MAPCHAR); */ +/* + * [lit_state: 1 On, 0 Off, -1 random, -2 leave as-is] + * terrain({ x=NN, y=NN, typ=MAPCHAR, lit=lit_state }); + * terrain({ coord={X, Y}, typ=MAPCHAR, lit=lit_state }); + * terrain({ selection=SELECTION, typ=MAPCHAR, lit=lit_state }); + * terrain( SELECTION, MAPCHAR [, lit_state ] ); + * terrain({x,y}, MAPCHAR); + * terrain(x,y, MAPCHAR); + */ int lspo_terrain(L) lua_State *L; @@ -5105,7 +5108,7 @@ lua_State *L; int argc = lua_gettop(L); create_des_coder(); - tmpterrain.tlit = 0; + tmpterrain.tlit = SET_LIT_NOCHANGE; tmpterrain.ter = INVALID_TYPE; if (argc == 1) { @@ -5120,7 +5123,7 @@ lua_State *L; lua_pop(L, 1); } tmpterrain.ter = get_table_mapchr(L, "typ"); - tmpterrain.tlit = get_table_int_opt(L, "lit", 0); + tmpterrain.tlit = get_table_int_opt(L, "lit", SET_LIT_NOCHANGE); } else if (argc == 2 && lua_type(L, 1) == LUA_TTABLE && lua_type(L, 2) == LUA_TSTRING) { int tx, ty; @@ -5154,10 +5157,16 @@ lua_State *L; return 0; } -/* replace_terrain({ x1=NN,y1=NN, x2=NN,y2=NN, fromterrain=MAPCHAR, toterrain=MAPCHAR, lit=N, chance=NN }); */ -/* replace_terrain({ region={x1,y1, x2,y2}, fromterrain=MAPCHAR, toterrain=MAPCHAR, lit=N, chance=NN }); */ -/* replace_terrain({ selection=selection.area(2,5, 40,10), fromterrain=MAPCHAR, toterrain=MAPCHAR }); */ -/* replace_terrain({ selection=SEL, mapfragment=[[...]], toterrain=MAPCHAR }); */ +/* + * replace_terrain({ x1=NN,y1=NN, x2=NN,y2=NN, fromterrain=MAPCHAR, + * toterrain=MAPCHAR, lit=N, chance=NN }); + * replace_terrain({ region={x1,y1, x2,y2}, fromterrain=MAPCHAR, + * toterrain=MAPCHAR, lit=N, chance=NN }); + * replace_terrain({ selection=selection.area(2,5, 40,10), + * fromterrain=MAPCHAR, toterrain=MAPCHAR }); + * replace_terrain({ selection=SEL, mapfragment=[[...]], + * toterrain=MAPCHAR }); + */ int lspo_replace_terrain(L) lua_State *L; @@ -5195,7 +5204,7 @@ lua_State *L; } chance = get_table_int_opt(L, "chance", 100); - tolit = get_table_int_opt(L, "lit", -2); + tolit = get_table_int_opt(L, "lit", SET_LIT_NOCHANGE); x1 = get_table_int_opt(L, "x1", -1); y1 = get_table_int_opt(L, "y1", -1); x2 = get_table_int_opt(L, "x2", -1); From 96cf11ad718eeb61950ab4e6274daed7dd08f391 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 6 Sep 2020 17:32:08 -0700 Subject: [PATCH 176/708] fix JS event loop blocking --- sys/lib/README.md | 144 ++++---------------- sys/lib/hints/wasm | 13 +- sys/lib/npm-package/README.md | 4 +- sys/lib/npm-package/src/nethackShim.js | 113 +++------------- sys/lib/test/libtest.c | 23 +++- win/shim/winshim.c | 179 +++++++++++++++++++++---- 6 files changed, 229 insertions(+), 247 deletions(-) diff --git a/sys/lib/README.md b/sys/lib/README.md index cbbd87b51..3bc7c283a 100644 --- a/sys/lib/README.md +++ b/sys/lib/README.md @@ -34,12 +34,10 @@ Where is the header file for the API you ask? There isn't one. It's three functi ## API: nethack.js 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(shim_callback_t cb)` - The same as above, but the signature of the callback is slightly different because WASM can't handle variadic callbacks. The callback is: `void shim_callback_t(const char *name, void *ret_ptr, const char *fmt, void *args[])` - * `name` - same as above - * `ret_ptr` - same as above - * `fmt` - same as above - * `args` - an array of pointers to the arguments, where each pointer can be de-referenced to a value as specified in the `fmt` string. - +* `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.doc) 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.doc](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) + * The function must return the value expected for the specified `name` ## API Stability @@ -54,7 +52,7 @@ typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, void shim_graphics_set_callback(shim_callback_t cb); void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { - /* TODO -- see windowCallback below for hints */ + /* TODO */ } int main(int argc, char *argv[]) { @@ -65,117 +63,33 @@ int main(int argc, char *argv[]) { ## nethack.js example ``` js -// Module is defined by emscripten -// https://emscripten.org/docs/api_reference/module.html -let Module = { - // if this is true, main() won't be called automatically - // noInitialRun: true, +const path = require("path"); - // after loading the library, set the callback function - onRuntimeInitialized: function (... args) { - setGraphicsCallback(); - } -}; +// starts nethack +function nethackStart(cb, inputModule = {}) { + // set callback + let cbName = cb.name; + if (cbName === "") cbName = "__anonymousNetHackCallback"; + let userCallback = globalThis[cbName] = cb; -var factory = require("./src/nethack.js"); + // Emscripten Module config + let Module = inputModule; + savedOnRuntimeInitialized = Module.onRuntimeInitialized; + Module.onRuntimeInitialized = function (... args) { + // after the WASM is loaded, add the shim graphics callback function + Module.ccall( + "shim_graphics_set_callback", // C function name + null, // return type + ["string"], // arg types + [cbName], // arg values + {async: true} // options + ); + }; -// run NetHack! -factory(Module); - -// register the callback with the WASM library -function setGraphicsCallback() { - console.log("creating WASM callback function"); - let cb = Module.addFunction(windowCallback, "viiii"); - - console.log("setting callback function with library"); - Module.ccall( - "shim_graphics_set_callback", // C function name - null, // return type - ["number"], // arg types - [cb], // arg values - {async: true} // options - ); - - /* TODO: removeFunction */ + // load and run the module + var factory = require(path.join(__dirname, "../build/nethack.js")); + factory(Module); } -// this is the "shim graphics" callback function -// it gets called every time something needs to be displayed -// or input needs to be gathered from the user -function windowCallback(name, retPtr, fmt, args) { - name = Module.UTF8ToString(name); - fmt = Module.UTF8ToString(fmt); - let argTypes = fmt.split(""); - let retType = argTypes.shift(); - - // convert arguments to JavaScript types - let jsArgs = []; - for (let i = 0; i < argTypes.length; i++) { - let ptr = args + (4*i); - let val = typeLookup(argTypes[i], ptr); - jsArgs.push(val); - } - console.log(`graphics callback: ${name} [${jsArgs}]`); - /********** - * YOU HAVE TO IMPLEMENT THIS FUNCTION to render things - **********/ - let ret = yourFunctionToRenderGraphics(name, jsArgs); - setReturn(retPtr, retType, ret); -} - -// takes a character `type` and a WASM pointer and returns a JavaScript value -function typeLookup(type, ptr) { - switch(type) { - case "s": // string - return Module.UTF8ToString(Module.getValue(ptr, "*")); - case "p": // pointer - return Module.getValue(Module.getValue(ptr, "*"), "*"); - case "c": // char - return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); - case "0": /* 2^0 = 1 byte */ - return Module.getValue(Module.getValue(ptr, "*"), "i8"); - case "1": /* 2^1 = 2 bytes */ - return Module.getValue(Module.getValue(ptr, "*"), "i16"); - case "2": /* 2^2 = 4 bytes */ - case "i": // integer - case "n": // number - return Module.getValue(Module.getValue(ptr, "*"), "i32"); - case "f": // float - return Module.getValue(Module.getValue(ptr, "*"), "float"); - case "d": // double - return Module.getValue(Module.getValue(ptr, "*"), "double"); - default: - throw new TypeError ("unknown type:" + type); - } -} - -// takes a a WASM pointer, a charater `type` and a value and sets the value at pointer -function setReturn(ptr, type, value = 0) { - switch (type) { - case "p": - throw new Error("not implemented"); - case "s": - value=value?value:"(no value)"; - var strPtr = Module.getValue(ptr, "i32"); - Module.stringToUTF8(value, strPtr, 1024); - break; - case "i": - Module.setValue(ptr, value, "i32"); - break; - case "c": - Module.setValue(ptr, value, "i8"); - break; - case "f": - // XXX: I'm not sure why 'double' works and 'float' doesn't - Module.setValue(ptr, value, "double"); - break; - case "d": - Module.setValue(ptr, value, "double"); - break; - case "v": - break; - default: - throw new Error("unknown type"); - } -} +nethackStart(yourCallbackFunction); ``` \ No newline at end of file diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index 711017bae..7f85090af 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -15,21 +15,30 @@ EMRANLIB=emranlib EMCC_LFLAGS=-s SINGLE_FILE=1 EMCC_LFLAGS=-s WASM=1 EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH -EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["_nhmain"]' -O3 +EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' +EMCC_LFLAGS+=-O3 EMCC_LFLAGS+=-s MODULARIZE EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue", "setValue"]' EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 EMCC_LFLAGS+=--embed-file wasm-data@/ +# For a list of EMCC settings: +# https://github.com/emscripten-core/emscripten/blob/master/src/settings.js + # WASM C flags EMCC_CFLAGS= EMCC_CFLAGS+=-Wall EMCC_CFLAGS+=-Werror +#EMCC_CFLAGS+=-s DISABLE_EXCEPTION_CATCHING=0 EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 +#EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=2 EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 -EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED +EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED=1 +#EMCC_DEBUG_CFLAGS+=-s EXCEPTION_DEBUG=1 +#EMCC_DEBUG_CFLAGS+=-fsanitize=undefined -fsanitize=address -fsanitize=leak +#EMCC_DEBUG_CFLAGS+=-s EXIT_RUNTIME EMCC_PROD_CFLAGS+=-O3 # Nethack C flags diff --git a/sys/lib/npm-package/README.md b/sys/lib/npm-package/README.md index e71f3e5a1..e39db8292 100644 --- a/sys/lib/npm-package/README.md +++ b/sys/lib/npm-package/README.md @@ -11,7 +11,7 @@ npm install nethack ## API The main module returns a setup function: `startNethack(uiCallback, moduleOptions)`. -* `uiCallback(name, ... args)` - Your callback function that will handle rendering NetHack on the screen of your choice. The `name` argument is one of the UI functions of the [NetHack Window Interface](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) and the `args` are corresponding to the window interface function that is being called. You are required to return the correct type of data for the function that is implemented. +* `uiCallback(name, ... args)` - Your callback function that will handle rendering NetHack on the screen of your choice. The `name` argument is one of the UI functions of the [NetHack Window Interface](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) and the `args` are corresponding to the window interface function that is being called. You are required to return the correct type of data for the function that is implemented. The `uiCallback` may be an `async` function. * `moduleOptions` - An optional [emscripten Module object](https://emscripten.org/docs/api_reference/module.html) for configuring the WASM that will be run. * `Module.arguments` - Of note is the [arguments property](https://emscripten.org/docs/api_reference/module.html#Module.arguments) which gets passed to NetHack as its [command line parameters](https://nethackwiki.com/wiki/Options). @@ -22,7 +22,7 @@ let nethackStart = require("nethack"); nethackStart(doGraphics); let winCount = 0; -function doGraphics(name, ... args) { +async function doGraphics(name, ... args) { console.log(`shim graphics: ${name} [${args}]`); switch(name) { diff --git a/sys/lib/npm-package/src/nethackShim.js b/sys/lib/npm-package/src/nethackShim.js index 638460278..e7a802c30 100644 --- a/sys/lib/npm-package/src/nethackShim.js +++ b/sys/lib/npm-package/src/nethackShim.js @@ -3,27 +3,38 @@ const path = require("path"); let Module; let userCallback; let savedOnRuntimeInitialized; + +// starts nethack function nethackStart(cb, inputModule = {}) { - if(typeof cb !== "function") throw new TypeError("expected first argument to be callback function"); + if(typeof cb !== "string" && typeof cb !== "function") throw new TypeError("expected first argument to be 'Function' or 'String' representing global callback function name"); if(typeof inputModule !== "object") throw new TypeError("expected second argument to be object"); + let cbName; + if(typeof cb === "function") { + cbName = cb.name; + if (cbName === "") cbName = "__anonymousNetHackCallback"; + if (globalThis[cbName] === undefined) globalThis[cbName] = cb; + else if (globalThis[cbName] !== cb) throw new Error (`'globalThis["${cbName}"]' is not the same as specified callback`); + } + + /* global globalThis */ + userCallback = globalThis[cbName]; + if(typeof userCallback !== "function") throw new TypeError(`expected 'globalThis["${cbName}"]' to be a function`); + // if(userCallback.constructor.name !== "AsyncFunction") throw new TypeError(`expected 'globalThis["${cbName}"]' to be an async function`); + // Emscripten Module config Module = inputModule; - userCallback = cb; savedOnRuntimeInitialized = Module.onRuntimeInitialized; Module.onRuntimeInitialized = function (... args) { // after the WASM is loaded, add the shim graphics callback function - let cb = Module.addFunction(windowCallback, "viiii"); Module.ccall( "shim_graphics_set_callback", // C function name null, // return type - ["number"], // arg types - [cb], // arg values + ["string"], // arg types + [cbName], // arg values {async: true} // options ); - /* TODO: Module.removeFunction() */ - // if the user had their own onRuntimeInitialized(), call it now if (savedOnRuntimeInitialized) savedOnRuntimeInitialized(... args); }; @@ -33,94 +44,6 @@ function nethackStart(cb, inputModule = {}) { factory(Module); } -function windowCallback(name, retPtr, fmt, args) { - name = Module.UTF8ToString(name); - fmt = Module.UTF8ToString(fmt); - let argTypes = fmt.split(""); - let retType = argTypes.shift(); - - // build array of JavaScript args from WASM parameters - let jsArgs = []; - for (let i = 0; i < argTypes.length; i++) { - let ptr = args + (4*i); - let val = typeLookup(argTypes[i], ptr); - jsArgs.push(val); - } - let retVal = userCallback(name, ... jsArgs); - setReturn(name, retPtr, retType, retVal); -} - -function typeLookup(type, ptr) { - switch(type) { - case "s": // string - return Module.UTF8ToString(Module.getValue(ptr, "*")); - case "p": // pointer - ptr = Module.getValue(ptr, "*"); - if(!ptr) return 0; // null pointer - return Module.getValue(ptr, "*"); - case "c": // char - return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); - case "0": /* 2^0 = 1 byte */ - return Module.getValue(Module.getValue(ptr, "*"), "i8"); - case "1": /* 2^1 = 2 bytes */ - return Module.getValue(Module.getValue(ptr, "*"), "i16"); - case "2": /* 2^2 = 4 bytes */ - case "i": // integer - case "n": // number - return Module.getValue(Module.getValue(ptr, "*"), "i32"); - case "f": // float - return Module.getValue(Module.getValue(ptr, "*"), "float"); - case "d": // double - return Module.getValue(Module.getValue(ptr, "*"), "double"); - default: - throw new TypeError ("unknown type:" + type); - } -} - -function setReturn(name, ptr, type, value = 0) { - - switch (type) { - case "p": - throw new Error("not implemented"); - case "s": - if(typeof value !== "string") - throw new TypeError(`expected ${name} return type to be string`); - value=value?value:"(no value)"; - var strPtr = Module.getValue(ptr, "i32"); - Module.stringToUTF8(value, strPtr, 1024); - break; - case "i": - if(typeof value !== "number" || !Number.isInteger(value)) - throw new TypeError(`expected ${name} return type to be integer`); - Module.setValue(ptr, value, "i32"); - break; - case "c": - if(typeof value !== "number" || value < 0 || value > 128) - throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); - Module.setValue(ptr, value, "i8"); - break; - case "f": - if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be float`); - // XXX: I'm not sure why 'double' works and 'float' doesn't - Module.setValue(ptr, value, "double"); - break; - case "d": - if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be float`); - Module.setValue(ptr, value, "double"); - break; - case "v": - break; - default: - throw new Error("unknown type"); - } - - function isFloat(n){ - return n === +n && n !== (n|0) && !Number.isInteger(n); - } -} - // TODO: ES6 'import' style module module.exports = nethackStart; diff --git a/sys/lib/test/libtest.c b/sys/lib/test/libtest.c index 9b554b986..31ca10e71 100644 --- a/sys/lib/test/libtest.c +++ b/sys/lib/test/libtest.c @@ -1,28 +1,37 @@ #include +#include /* external functions */ int nhmain(int argc, char *argv[]); typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); -void stub_graphics_set_callback(stub_callback_t cb); +void shim_graphics_set_callback(stub_callback_t cb); /* forward declarations */ void window_cb(const char *name, void *ret_ptr, const char *fmt, ...); - +void *yourFunctionToRenderGraphics(const char *name, va_list args); int main(int argc, char *argv[]) { - stub_graphics_set_callback(window_cb); + shim_graphics_set_callback(window_cb); nhmain(argc, argv); } -void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { - /* TODO -- see windowCallback below for hints */ - +void *yourFunctionToRenderGraphics(const char *name, va_list args) { + printf("yourFunctionToRenderGraphics name %s\n", name); /* DO SOMETHING HERE */ - *ret_ptr = yourFunctionToRenderGraphics(name, va_list args); + return NULL; } +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { + void *ret; + va_list args; + /* TODO -- see windowCallback below for hints */ + va_start(args, fmt); + ret = yourFunctionToRenderGraphics(name, args); + // *((int *)ret_ptr = *((int *)ret); // e.g. yourFunctionToRenderGraphics returns an int + va_end(args); +} #if 0 function variadicCallback(name, retPtr, fmt, args) { diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 05ed09c07..eec616f4f 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -5,6 +5,7 @@ /* not an actual windowing port, but a fake win port for libnethack */ #include "hack.h" +#include #ifdef SHIM_GRAPHICS #include @@ -15,26 +16,30 @@ #undef SHIM_DEBUG -#ifndef __EMSCRIPTEN__ -typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); -#else /* __EMSCRIPTEN__ */ -/* WASM can't handle a variadic callback, so we pass back an array of pointers instead... */ -typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, void *args[]); -#endif /* !__EMSCRIPTEN__ */ +#ifdef SHIM_DEBUG +#define debugf printf +#else /* !SHIM_DEBUG */ +#define debugf(...) +#endif /* SHIM_DEBUG */ -/* this is the primary interface to shim graphics, + +/* shim_graphics_callback is the primary interface to shim graphics, * call this function with your declared callback function * and you will receive all the windowing calls */ -static shim_callback_t shim_graphics_callback = NULL; #ifdef __EMSCRIPTEN__ - EMSCRIPTEN_KEEPALIVE -#endif -void shim_graphics_set_callback(shim_callback_t cb) { - shim_graphics_callback = cb; +/************ + * WASM interface + ************/ +EMSCRIPTEN_KEEPALIVE +static char *shim_callback_name = NULL; +void shim_graphics_set_callback(char *cbName) { + if (shim_callback_name != NULL) free(shim_callback_name); + shim_callback_name = strdup(cbName); + /* TODO: free(shim_callback_name) during shutdown? */ } +void local_callback (const char *cb_name, const char *shim_name, void *ret_ptr, const char *fmt_str, void *args); -#ifdef __EMSCRIPTEN__ /* A2P = Argument to Pointer */ #define A2P & /* P2V = Pointer to Void */ @@ -44,8 +49,8 @@ ret_type name fn_args { \ void *args[] = { __VA_ARGS__ }; \ ret_type ret = (ret_type) 0; \ debugf("SHIM GRAPHICS: " #name "\n"); \ - if (!shim_graphics_callback) return ret; \ - shim_graphics_callback(#name, (void *)&ret, fmt, args); \ + if (!shim_callback_name) return ret; \ + local_callback(shim_callback_name, #name, (void *)&ret, fmt, args); \ return ret; \ } @@ -53,10 +58,21 @@ ret_type name fn_args { \ void name fn_args { \ void *args[] = { __VA_ARGS__ }; \ debugf("SHIM GRAPHICS: " #name "\n"); \ - if (!shim_graphics_callback) return; \ - shim_graphics_callback(#name, NULL, fmt, args); \ + if (!shim_callback_name) return; \ + local_callback(shim_callback_name, #name, NULL, fmt, args); \ } + #else /* !__EMSCRIPTEN__ */ + +/************ + * libnethack.a interface + ************/ +typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +static shim_callback_t shim_graphics_callback = NULL; +void shim_graphics_set_callback(shim_callback_t cb) { + shim_graphics_callback = cb; +} + #define A2P #define P2V #define DECLCB(ret_type, name, fn_args, fmt, ...) \ @@ -64,7 +80,7 @@ ret_type name fn_args { \ ret_type ret = (ret_type) 0; \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return ret; \ - shim_graphics_callback(#name, (void *)&ret, fmt, __VA_ARGS__); \ + shim_graphics_callback(#name, (void *)&ret, fmt, ## __VA_ARGS__); \ return ret; \ } @@ -72,17 +88,10 @@ ret_type name fn_args { \ void name fn_args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ - shim_graphics_callback(#name, NULL, fmt, __VA_ARGS__); \ + shim_graphics_callback(#name, NULL, fmt, ## __VA_ARGS__); \ } #endif /* __EMSCRIPTEN__ */ -#ifdef SHIM_DEBUG -#define debugf printf -#else /* !SHIM_DEBUG */ -#define debugf(...) -#endif /* SHIM_DEBUG */ - - enum win_types { WINSHIM_MESSAGE = 1, WINSHIM_MAP, @@ -222,4 +231,122 @@ struct window_procs shim_procs = { genl_can_suspend_yes, }; +#ifdef __EMSCRIPTEN__ +/* convert the C callback to a JavaScript callback */ +EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *ret_ptr, const char *fmt_str, void *args), { + Asyncify.handleAsync(async () => { + // convert callback arguments to proper JavaScript varaidic arguments + let name = Module.UTF8ToString(shim_name); + let fmt = Module.UTF8ToString(fmt_str); + let cbName = Module.UTF8ToString(cb_name); + // console.log("local_callback:", cbName, fmt, name); + + let argTypes = fmt.split(""); + let retType = argTypes.shift(); + + // build array of JavaScript args from WASM parameters + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } + + // do the callback + let userCallback = globalThis[cbName]; + let retVal = await runJsLoop(() => userCallback(name, ... jsArgs)); + + // save the return value + setReturn(name, ret_ptr, retType, retVal); + + // convert 'ptr' to the type indicated by 'type' + function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + ptr = Module.getValue(ptr, "*"); + if(!ptr) return 0; // null pointer + return Module.getValue(ptr, "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } + } + + // setTimeout() with value of '0' is similar to setImmediate() (which isn't standard) + // this lets the JS loop run for a tick so that other events can occur + // XXX: I also tried replacing the for(;;) in allmain.c:moveloop() with emscripten_set_main_loop() + // unfortunately that won't work -- if the simulate_infinite_loop arg is false, it falls through; + // if is true, it throws an exception to break out of main(), but doesn't get caught because + // the stack isn't running under main() anymore... + // I think this is suboptimal, but we will have to live with it + async function runJsLoop(cb) { + return new Promise((resolve) => { + setTimeout(() => { + resolve(cb()); + }, 0); + }); + } + + // sets the return value of the function to the type expected + function setReturn(name, ptr, type, value = 0) { + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + if(typeof value !== "string") + throw new TypeError(`expected ${name} return type to be string`); + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + Module.setValue(ptr, value, "i32"); + break; + case "c": + if(typeof value !== "number" || value < 0 || value > 128) + throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); + Module.setValue(ptr, value, "i8"); + break; + case "f": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } + + function isFloat(n){ + return n === +n && n !== (n|0) && !Number.isInteger(n); + } + } + }); +}) +#endif /* __EMSCRIPTEN__ */ + #endif /* SHIM_GRAPHICS */ \ No newline at end of file From 7b46e3d12caa3717526157a98cb57c82e7078531 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 6 Sep 2020 17:35:03 -0700 Subject: [PATCH 177/708] update lib tests --- sys/lib/test/run.sh | 3 +- sys/lib/test/test.js | 186 ------------------------------------------- 2 files changed, 2 insertions(+), 187 deletions(-) delete mode 100644 sys/lib/test/test.js diff --git a/sys/lib/test/run.sh b/sys/lib/test/run.sh index 5e2b36dfe..b89ab55d9 100755 --- a/sys/lib/test/run.sh +++ b/sys/lib/test/run.sh @@ -12,6 +12,7 @@ fi if [ x$1 == "xrunlib" ]; then LIBS="-Lsrc -lnethack -Llib/lua -llua -lm" BADLIBS="-lncurses" + rm nhlibtest gcc -o nhlibtest libtest.c $LIBS $BADLIBS ./nhlibtest fi @@ -26,7 +27,7 @@ if [ x$1 == "xwasm" ]; then fi if [ x$1 == "xrunwasm" ]; then - node test.js + cd sys/lib/npm-package && node test/test.js fi if [ x$1 == "xbin" ]; then diff --git a/sys/lib/test/test.js b/sys/lib/test/test.js deleted file mode 100644 index d7d8f0144..000000000 --- a/sys/lib/test/test.js +++ /dev/null @@ -1,186 +0,0 @@ -const util = require("util"); - -// Emscripten Module config -let Module = { - // noInitialRun: true, - onRuntimeInitialized: function () { - setGraphicsCallback(); - }, -}; - -var factory = require("./src/nethack.js"); - -// load and run the module -factory(Module); - -function setGraphicsCallback() { - console.log("setting callback function"); - let cb = Module.addFunction(windowCallback, "viiii"); - - console.log("doing call"); - Module.ccall( - "shim_graphics_set_callback", // C function name - null, // return type - ["number"], // arg types - [cb], // arg values - {async: true} // options - ); - - /* TODO: removeFunction */ -} - -function windowCallback(name, retPtr, fmt, args) { - // console.log ("variadicCallback called..."); - // console.log("typeof name", typeof name); - // console.log("typeof fmt", typeof fmt); - // console.log("typeof args", typeof args); - name = Module.UTF8ToString(name); - fmt = Module.UTF8ToString(fmt); - // console.log ("name:", name); - // console.log ("fmt:", fmt); - let argTypes = fmt.split(""); - let retType = argTypes.shift(); - // console.log ("arg count:", argTypes.length); - // console.log ("arg types:", argTypes); - // console.log ("ret type:", retType); - - let jsArgs = []; - for (let i = 0; i < argTypes.length; i++) { - let ptr = args + (4*i); - let val = typeLookup(argTypes[i], ptr); - jsArgs.push(val); - } - console.log(`graphics callback: ${name} [${jsArgs}]`); - let retVal = doGraphics(name, ... jsArgs); - setReturn(name, retPtr, retType, retVal); -} - -function typeLookup(type, ptr) { - switch(type) { - case "s": // string - return Module.UTF8ToString(Module.getValue(ptr, "*")); - case "p": // pointer - ptr = Module.getValue(ptr, "*"); - if(!ptr) return 0; // null pointer - return Module.getValue(ptr, "*"); - case "c": // char - return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); - case "0": /* 2^0 = 1 byte */ - return Module.getValue(Module.getValue(ptr, "*"), "i8"); - case "1": /* 2^1 = 2 bytes */ - return Module.getValue(Module.getValue(ptr, "*"), "i16"); - case "2": /* 2^2 = 4 bytes */ - case "i": // integer - case "n": // number - return Module.getValue(Module.getValue(ptr, "*"), "i32"); - case "f": // float - return Module.getValue(Module.getValue(ptr, "*"), "float"); - case "d": // double - return Module.getValue(Module.getValue(ptr, "*"), "double"); - default: - throw new TypeError ("unknown type:" + type); - } -} - -function setReturn(name, ptr, type, value = 0) { - - switch (type) { - case "p": - throw new Error("not implemented"); - case "s": - if(typeof value !== "string") - throw new TypeError(`expected ${name} return type to be string`); - value=value?value:"(no value)"; - var strPtr = Module.getValue(ptr, "i32"); - Module.stringToUTF8(value, strPtr, 1024); - break; - case "i": - if(typeof value !== "number" || !Number.isInteger(value)) - throw new TypeError(`expected ${name} return type to be integer`); - Module.setValue(ptr, value, "i32"); - break; - case "c": - if(typeof value !== "number" || value < 0 || value > 128) - throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); - Module.setValue(ptr, value, "i8"); - break; - case "f": - if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be float`); - // XXX: I'm not sure why 'double' works and 'float' doesn't - Module.setValue(ptr, value, "double"); - break; - case "d": - if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be float`); - Module.setValue(ptr, value, "double"); - break; - case "v": - break; - default: - throw new Error("unknown type"); - } - - function isFloat(n){ - return n === +n && n !== (n|0) && !Number.isInteger(n); - } -} - -let winCount = 0; -function doGraphics(name, ... args) { - switch(name) { - case "shim_create_nhwindow": - winCount++; - console.log("creating window", args, "returning", winCount); - return winCount; - case "shim_yn_function": - case "shim_message_menu": - return 121; // 'y' - case "shim_nhgetch": - case "shim_nh_poskey": - return 46; - default: - return 0; - } -} - -// var Module = null; -// factory(Module).then((ret) => { -// if(ret !== Module) { -// console.log("ret and Module are not the same"); -// } else { -// console.log("ret and Module are the same"); -// } -// // console.log("Module", util.inspect(Module, {depth: null, showHidden: true})); -// // TODO: -// // shim_graphics_set_callback(); - -// // options: -// // https://emscripten.org/docs/api_reference/module.html -// // logReadFiles -// // printWithColors -// // noInitialRun -// // onRuntimeInitialized -// console.log("doing run"); -// // Module.run(); - -// // // main loop -// // console.log("creating function"); -// // let fn = Module.addFunction(wasmCallback, "vii"); - -// // console.log("doing call"); -// // Module.ccall( -// // "mainloop", // C function name -// // null, // return type -// // ["number"], // arg types -// // [fn], // arg values -// // {async: true} // options -// // ); -// // // TODO: removeFunction(fn) - -// // var i = 0; -// // setInterval(function() { -// // console.log("interval", i++); -// // },1000); -// }); - From 2e7e0c23251f11eb2b29bf3cdb6697f5781ece8c Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 6 Sep 2020 23:19:22 -0700 Subject: [PATCH 178/708] change package name --- sys/lib/npm-package/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json index 45cea1739..b4e931559 100644 --- a/sys/lib/npm-package/package.json +++ b/sys/lib/npm-package/package.json @@ -1,5 +1,5 @@ { - "name": "@neth_ck/neth_ck", + "name": "@neth4ck/neth4ck", "version": "1.0.0", "description": "The original NetHack rogue-like game built as a WebAssembly module", "main": "src/nethackShim.js", From a48b4aa8ba5e6b06a8d1d25153f8d07f3549ee10 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Sep 2020 03:03:03 -0700 Subject: [PATCH 179/708] fix #K1963 - warning after placing worm tail Report described this as a panic triggered by the sanity_check option, but that's because it was running under the fuzzer, which escalates any impossible() to panic(), rather than because nethack panicked. I couldn't find anything wrong--which doesn't mean that there isn't something wrong--with place_worm_tail_randomly() and random_dir(). They use xchar for map coordinates which should be fine as long as no negative values are generated and I couldn't discover any such. The suggested fix of changing xchar to int might indicate a compiler bug (although the odds of that are low). The bogus coordinate of -15000 in the report suggests that typedef short int schar; (which changes xchar too) is being used in the configuration but I don't recall having any problems attributable to that. This switches from xchar to int as a side-effect of replacing the offending code entirely. The new code might produce an 'ny' of -1 before goodpos() rejects it, so xchar would be inappropriate now. The old code is commented out via #if 0 _after_ changing it from xchar to int. This also adds an extra sanity_check for worm tails, unrelated to the current bug. I'm not aware of any instance where it fails. EXTRA_SANITY_CHECKS needs to be defined for it to do anything. --- doc/fixes37.0 | 4 ++- include/extern.h | 3 +- src/mon.c | 6 ++-- src/worm.c | 88 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 82 insertions(+), 19 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3364e09c4..94944bd90 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.298 $ $NHDT-Date: 1599434249 2020/09/06 23:17:29 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ General Fixes and Modified Features ----------------------------------- @@ -328,6 +328,8 @@ the fix to make worm visibility checks work as intended forced the coordinates using 'O' to try to change 'symset' was a no-op; 'roguesymset' worked change default for lit attribute in special level des.terrain directives to 'unchanged' instead of 'unlit' +replace worm tail placement code that reportedly led to a sanity_check warning + [no actual code problem found; might be compiler bug for 'xchar'] curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/include/extern.h b/include/extern.h index 437431035..c1f2ae298 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1597069374 2020/08/10 14:22:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.855 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.856 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3078,6 +3078,7 @@ E void FDECL(save_worm, (NHFILE *)); E void FDECL(rest_worm, (NHFILE *)); E void FDECL(place_wsegs, (struct monst *, struct monst *)); E void FDECL(sanity_check_worm, (struct monst *)); +E void NDECL(wormno_sanity_check); E void FDECL(remove_worm, (struct monst *)); E void FDECL(place_worm_tail_randomly, (struct monst *, XCHAR_P, XCHAR_P)); E int FDECL(size_wseg, (struct monst *)); diff --git a/src/mon.c b/src/mon.c index 83e28ebbc..2df04ef29 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1599330921 2020/09/05 18:35:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.345 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.346 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -150,6 +150,8 @@ mon_sanity_check() for (mtmp = g.migrating_mons; mtmp; mtmp = mtmp->nmon) { sanity_check_single_mon(mtmp, FALSE, "migr"); } + + wormno_sanity_check(); /* test for bogus worm tail */ } /* Would monster be OK with poison gas? */ @@ -1820,7 +1822,7 @@ struct monst *mtmp, *mtmp2; if (mtmp != u.usteed) /* don't place steed onto the map */ place_monster(mtmp2, mtmp2->mx, mtmp2->my); if (mtmp2->wormno) /* update level.monsters[wseg->wx][wseg->wy] */ - place_wsegs(mtmp2, NULL); /* locations to mtmp2 not mtmp. */ + place_wsegs(mtmp2, mtmp); /* locations to mtmp2 not mtmp. */ if (emits_light(mtmp2->data)) { /* since this is so rare, we don't have any `mon_move_light_source' */ new_light_source(mtmp2->mx, mtmp2->my, emits_light(mtmp2->data), diff --git a/src/worm.c b/src/worm.c index c32c8c928..9027f925b 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worm.c $NHDT-Date: 1596841504 2020/08/07 23:05:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 3.7 worm.c $NHDT-Date: 1599559380 2020/09/08 10:03:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -16,7 +16,9 @@ struct wseg { static void FDECL(toss_wsegs, (struct wseg *, BOOLEAN_P)); static void FDECL(shrink_worm, (int)); -static void FDECL(random_dir, (XCHAR_P, XCHAR_P, xchar *, xchar *)); +#if 0 +static void FDECL(random_dir, (int, int, int *, int *)); +#endif static struct wseg *FDECL(create_worm_tail, (int)); /* Description of long worm implementation. @@ -680,6 +682,31 @@ struct monst *worm; } } +/* called from mon_sanity_check(mon.c) */ +void +wormno_sanity_check() +{ +#ifdef EXTRA_SANITY_CHECKS + struct wseg *seg; + int wh = 0, wt = 0; + + /* checking tail management, not a particular monster; since wormno==0 + means 'not a worm', wheads[0] and wtails[0] should always be empty; + note: if erroneously non-Null, tail segment count will include the + extra segment for the worm's head that isn't shown on the map */ + for (seg = wheads[0]; seg; seg = seg->nseg) + ++wh; + for (seg = wtails[0]; seg; seg = seg->nseg) + ++wt; + if (wh || wt) { + impossible( + "phantom worm tail #0 [head=%s, %d segment%s; tail=%s, %d segment%s]", + fmt_ptr(wheads[0]), wh, plur(wh), + fmt_ptr(wtails[0]), wt, plur(wt)); + } +#endif /* EXTRA_SANITY_CHECKS */ +} + /* * remove_worm() * @@ -721,7 +748,7 @@ xchar x, y; int wnum = worm->wormno; struct wseg *curr = wtails[wnum]; struct wseg *new_tail; - xchar ox = x, oy = y; + int ox = x, oy = y; if (wnum && (!wtails[wnum] || !wheads[wnum])) { impossible("place_worm_tail_randomly: wormno is set without a tail!"); @@ -729,10 +756,14 @@ xchar x, y; } if (wtails[wnum] == wheads[wnum]) { /* single segment, co-located with worm so nothing to place */ - if (curr->wx != worm->mx || curr->wy != worm->my) + if (curr->wx != worm->mx || curr->wy != worm->my) { impossible( "place_worm_tail_randomly: tail segement at <%d,%d>, worm at <%d,%d>", curr->wx, curr->wy, worm->mx, worm->my); + if (m_at(curr->wx, curr->wy) == worm) + remove_monster(curr->wx, curr->wy); + curr->wx = worm->mx, curr->wy = worm->my; + } return; } /* remove head segment from map in case we end up calling toss_wsegs(); @@ -747,30 +778,56 @@ xchar x, y; new_tail->wy = y; while (curr) { - xchar nx, ny; - int tryct = 0; + int nx = 0, ny = 0; +#if 0 /* old code */ + int trycnt = 0; - /* pick a random direction from x, y and search for goodpos() */ + /* pick a random direction from x, y and test for goodpos() */ do { random_dir(ox, oy, &nx, &ny); - } while (!goodpos(nx, ny, worm, 0) && (tryct++ < 50)); + } while (!goodpos(nx, ny, worm, 0) && ++tryct <= 50); - if (tryct < 50) { + if (tryct <= 50) +#else /* new code */ + int i, j, k, dirs[8]; + + /* instead of picking a random direction up to 50 times, try each + of the eight directions at most once after shuffling their order */ + for (i = 0; i < 8; ++i) + dirs[i] = i; + for (i = 8; i > 0; --i) { + j = rn2(i); + k = dirs[j]; + dirs[j] = dirs[i - 1]; + dirs[i - 1] = k; + } + for (i = 0; i < 8; ++i) { + nx = ox + xdir[dirs[i]]; + ny = oy + ydir[dirs[i]]; + if (goodpos(nx, ny, worm, 0)) /* includes an isok() check */ + break; + } + + if (i < 8) +#endif + { place_worm_seg(worm, nx, ny); - curr->wx = ox = nx; - curr->wy = oy = ny; + curr->wx = (xchar) (ox = nx); + curr->wy = (xchar) (oy = ny); wtails[wnum] = curr; curr = curr->nseg; wtails[wnum]->nseg = new_tail; new_tail = wtails[wnum]; newsym(nx, ny); - } else { /* Oops. Truncate because there was */ - toss_wsegs(curr, FALSE); /* no place for the rest of it */ + } else { + /* Oops. Truncate because there is no place for rest of it. */ + toss_wsegs(curr, FALSE); curr = (struct wseg *) 0; } } } +#if 0 /* * Given a coordinate x, y. * return in *nx, *ny, the coordinates of one of the <= 8 squares adjoining. @@ -781,8 +838,8 @@ xchar x, y; static void random_dir(x, y, nx, ny) -xchar x, y; -xchar *nx, *ny; +int x, y; +int *nx, *ny; { *nx = x + (x > 1 /* extreme left ? */ ? (x < COLNO - 1 /* extreme right ? */ @@ -802,6 +859,7 @@ xchar *nx, *ny; : -1) /* bottom, use -1 */ : 1); /* top, use +1 */ } +#endif /* for size_monst(cmd.c) to support #stats */ int From 0b67fd60dff2acf0f20d86a6cf4e43f3f6b2a79c Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Sep 2020 12:36:13 -0700 Subject: [PATCH 180/708] hints/{linux,macOS}.2020 A recent change was intended to allow specifying make CFLAGS=-O on the command line to override our default of -g, but it didn't work as intended. foo=bar and foo+=bar don't work if foo has been given a value on the command line. The first was expected behavior but the second wasn't, at least for me. GNU make allows 'override foo+=bar' to cope with that. (We're already implicitly requiring GNU make for the linux and OSX hints.) --- sys/unix/hints/linux.2020 | 60 ++++++++++++++++++++++----------------- sys/unix/hints/macOS.2020 | 60 ++++++++++++++++++++++----------------- 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 4de9a0957..e5cefb777 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.2020 $NHDT-Date: 1599337708 2020/09/05 20:28:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.9 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1599593762 2020/09/08 19:36:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -53,42 +53,42 @@ GAMEGRP = games #-INCLUDE multiw-2.2020 -CFLAGS+=-I../include -DNOTPARMDECL +# MORECFLAGS is eventually appended to CFLAGS +MORECFLAGS=-I../include -DNOTPARMDECL + ifeq "$(CCISCLANG)" "" # get the version of gcc GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) ifeq "$(GCCGTEQ9)" "1" -CFLAGS+=-Wno-format-overflow +MORECFLAGS+=-Wno-format-overflow endif #gcc version greater than or equal to 9 endif #not clang # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. -#CFLAGS+=-Wunreachable-code -#CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ +#MORECFLAGS+=-Wunreachable-code +#MORECFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ # -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -#CFLAGS+=-DGCC_WARN +#MORECFLAGS+=-DGCC_WARN # NetHack sources control -CFLAGS+=-DDLB -CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" -CFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -CFLAGS+=-DTIMED_DELAY -CFLAGS+=-DDUMPLOG -CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE -#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" -CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" -# older binaries use NOCLIPPING, but that disables SIGWINCH -#CFLAGS+=-DNOCLIPPING -#CFLAGS+=-DNOMAIL -#CFLAGS+=-DEXTRA_SANITY_CHECKS -#CFLAGS+=-DEDIT_GETLIN -#CFLAGS+=-DSCORE_ON_BOTL -#CFLAGS+=-DMSGHANDLER -#CFLAGS+=-DTTY_TILES_ESCCODES -#CFLAGS+=-DTTY_SOUND_ESCCODES +MORECFLAGS+=-DDLB +MORECFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +MORECFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" +MORECFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +MORECFLAGS+=-DTIMED_DELAY +MORECFLAGS+=-DDUMPLOG +MORECFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +#MORECFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +MORECFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +#MORECFLAGS+=-DNOMAIL +#MORECFLAGS+=-DEXTRA_SANITY_CHECKS +#MORECFLAGS+=-DEDIT_GETLIN +#MORECFLAGS+=-DSCORE_ON_BOTL +#MORECFLAGS+=-DMSGHANDLER +#MORECFLAGS+=-DTTY_TILES_ESCCODES +#MORECFLAGS+=-DTTY_SOUND_ESCCODES -CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 +MORECFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 VARDATND = VARDATND0 = @@ -122,7 +122,7 @@ X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XPM -CFLAGS += -DUSE_XPM +MORECFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif @@ -161,6 +161,14 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) +# if CFLAGS=foo was specified on the command line, CFLAGS+=$(MORECFLAGS) +# would be ignored without 'override'; we want to allow CFLAGS=-g vs -O +# on the command line without having to specify all the other stuff +# +override CFLAGS+=$(MORECFLAGS) +# + + #PREFIX=/usr PREFIX=$(wildcard ~)/nh/install HACKDIR=$(PREFIX)/games/lib/$(GAME)dir diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index a5777a0f8..212c8581b 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.2020 $NHDT-Date: 1599337708 2020/09/05 20:28:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.71 $ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1599593767 2020/09/08 19:36:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -55,10 +55,12 @@ endif #-INCLUDE multiw-2.2020 -CFLAGS+=-I../include -DNOTPARMDECL +# MORECFLAGS is eventually appended to CFLAGS +MORECFLAGS=-I../include -DNOTPARMDECL + ifndef WANT_WIN_QT # these are normally used when compiling nethack's core -CFLAGS+=-ansi -pedantic -Wno-long-long +MORECFLAGS+=-ansi -pedantic -Wno-long-long # but -ansi forces -std=c90 for C or -std=c++98 for C++; # win/Qt/qt_*.cpp compiled with C++98 semantics trigger #In file included from .../qt5/include/QtCore/qglobal.h:105: @@ -68,32 +70,30 @@ CFLAGS+=-ansi -pedantic -Wno-long-long endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. -#CFLAGS+=-Wunreachable-code -CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ +#MORECFLAGS+=-Wunreachable-code +MORECFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -CFLAGS+=-DGCC_WARN +MORECFLAGS+=-DGCC_WARN # NetHack sources control -CFLAGS+=-DDLB -CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" -CFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -#CFLAGS+=-DTIMED_DELAY -#CFLAGS+=-DDUMPLOG -#CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE -CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" -#CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" -# older binaries use NOCLIPPING, but that disables SIGWINCH -#CFLAGS+=-DNOCLIPPING -CFLAGS+=-DNOMAIL -#CFLAGS+=-DEXTRA_SANITY_CHECKS -#CFLAGS+=-DEDIT_GETLIN -#CFLAGS+=-DSCORE_ON_BOTL -#CFLAGS+=-DMSGHANDLER -#CFLAGS+=-DTTY_TILES_ESCCODES -#CFLAGS+=-DTTY_SOUND_ESCCODES +MORECFLAGS+=-DDLB +MORECFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +MORECFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB +MORECFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +#MORECFLAGS+=-DTIMED_DELAY +#MORECFLAGS+=-DDUMPLOG +#MORECFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +MORECFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#MORECFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +MORECFLAGS+=-DNOMAIL +#MORECFLAGS+=-DEXTRA_SANITY_CHECKS +#MORECFLAGS+=-DEDIT_GETLIN +#MORECFLAGS+=-DSCORE_ON_BOTL +#MORECFLAGS+=-DMSGHANDLER +#MORECFLAGS+=-DTTY_TILES_ESCCODES +#MORECFLAGS+=-DTTY_SOUND_ESCCODES -CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 +MORECFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 VARDATND = VARDATND0 = @@ -127,7 +127,7 @@ X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XPM -CFLAGS += -DUSE_XPM +MORECFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif @@ -165,6 +165,14 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) +# if CFLAGS=foo was specified on the command line, CFLAGS+=$(MORECFLAGS) +# would be ignored without 'override'; we want to allow CFLAGS=-g vs -O +# on the command line without having to specify all the other stuff +# +override CFLAGS+=$(MORECFLAGS) +# + + WANT_BUNDLE=1 ifdef WANT_SHARE_INSTALL # if $GAMEUID is root, we install into roughly proper Mac locations, otherwise From d3181e20baeca508eb705b5c4b9e3dbf3f1cda5c Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Sep 2020 13:26:13 -0700 Subject: [PATCH 181/708] qt_map.cpp source formatting Clean up the Qt code a bit. The only intended change is to use a different check for being polymorphed. --- win/Qt/qt_map.cpp | 98 ++++++++++++++++++++++++++++++----------------- 1 file changed, 63 insertions(+), 35 deletions(-) diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 2e507e691..bb208d243 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -153,11 +153,12 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) ); } #ifdef TEXTCOLOR - if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { + if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); - } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { + } else if ((special & MG_OBJPILE) != 0 + && ::iflags.hilite_pile) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); @@ -177,11 +178,12 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) mapglyph(g, &ch, &color, &special, i, j, 0); qt_settings->glyphs().drawCell(painter, g, i, j); #ifdef TEXTCOLOR - if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { + if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); - } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { + } else if ((special & MG_OBJPILE) != 0 + && ::iflags.hilite_pile) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); @@ -201,32 +203,42 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) } else { int hp100; - if (u.mtimedone) { + if (Upolyd) { hp100=u.mhmax ? u.mh*100/u.mhmax : 100; } else { hp100=u.uhpmax ? u.uhp*100/u.uhpmax : 100; } - if (hp100 > 75) painter.setPen(Qt::white); - else if (hp100 > 50) painter.setPen(Qt::yellow); - else if (hp100 > 25) painter.setPen(QColor(0xff,0xbf,0x00)); // orange - else if (hp100 > 10) painter.setPen(Qt::red); - else painter.setPen(Qt::magenta); + if (hp100 > 75) + painter.setPen(Qt::white); + else if (hp100 > 50) + painter.setPen(Qt::yellow); + else if (hp100 > 25) + painter.setPen(QColor(0xff, 0xbf, 0x00)); // orange + else if (hp100 > 10) + painter.setPen(Qt::red); + else + painter.setPen(Qt::magenta); } - painter.drawRect( - cursor.x()*qt_settings->glyphs().width(),cursor.y()*qt_settings->glyphs().height(), - qt_settings->glyphs().width()-1,qt_settings->glyphs().height()-1); + painter.drawRect(cursor.x() * qt_settings->glyphs().width(), + cursor.y() * qt_settings->glyphs().height(), + qt_settings->glyphs().width() - 1, + qt_settings->glyphs().height() - 1); } #if 0 if (area.intersects(messages_rect)) { painter.setPen(Qt::black); - painter.drawText(viewport.contentsX()+1,viewport.contentsY()+1, - viewport.width(),0, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft|Qt::TextDontClip, messages); + painter.drawText(viewport.contentsX() + 1, viewport.contentsY() + 1, + viewport.width(), 0, + (Qt::TextWordWrap | Qt::AlignTop + | Qt::AlignLeft | Qt::TextDontClip), messages); painter.setPen(Qt::white); - painter.drawText(viewport.contentsX(),viewport.contentsY(), - viewport.width(),0, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft|Qt::TextDontClip, messages); + painter.drawText(viewport.contentsX(), viewport.contentsY(), + viewport.width(), 0, + (Qt::TextWordWrap | Qt::AlignTop + | Qt::AlignLeft | Qt::TextDontClip), messages); } #endif @@ -696,7 +708,11 @@ void NetHackQtMapWindow::putMessage(int attr, const QString& text) messages += "\n"; messages += QString(text).replace(QChar(0x200B), ""); QFontMetrics fm = fontMetrics(); - messages_rect = fm.boundingRect(viewport.contentsX(),viewport.contentsY(),viewport.width(),0, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft|Qt::TextDontClip, messages); + messages_rect = fm.boundingRect(viewport.contentsX(), viewport.contentsY(), + viewport.width(), 0, + (Qt::TextWordWrap | Qt::AlignTop + | Qt::AlignLeft | Qt::TextDontClip), + messages); update(messages_rect); } @@ -849,11 +865,12 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) QString(QChar(ch)).left(1) ); #ifdef TEXTCOLOR - if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { + if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); - } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { + } else if ((special & MG_OBJPILE) != 0 + && ::iflags.hilite_pile) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); @@ -873,11 +890,12 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) mapglyph(g, &ch, &color, &special, i, j, 0); qt_settings->glyphs().drawCell(painter, g, i, j); #ifdef TEXTCOLOR - if (((special & MG_PET) != 0) && ::iflags.hilite_pet) { + if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pet_annotation); - } else if (((special & MG_OBJPILE) != 0) && ::iflags.hilite_pile) { + } else if ((special & MG_OBJPILE) != 0 + && ::iflags.hilite_pile) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), j*qt_settings->glyphs().height()), pile_annotation); @@ -897,31 +915,41 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) } else { int hp100; - if (u.mtimedone) { + if (Upolyd) { hp100=u.mhmax ? u.mh*100/u.mhmax : 100; } else { hp100=u.uhpmax ? u.uhp*100/u.uhpmax : 100; } - if (hp100 > 75) painter.setPen(Qt::white); - else if (hp100 > 50) painter.setPen(Qt::yellow); - else if (hp100 > 25) painter.setPen(QColor(0xff,0xbf,0x00)); // orange - else if (hp100 > 10) painter.setPen(Qt::red); - else painter.setPen(Qt::magenta); + if (hp100 > 75) + painter.setPen(Qt::white); + else if (hp100 > 50) + painter.setPen(Qt::yellow); + else if (hp100 > 25) + painter.setPen(QColor(0xff, 0xbf, 0x00)); // orange + else if (hp100 > 10) + painter.setPen(Qt::red); + else + painter.setPen(Qt::magenta); } - painter.drawRect( - cursor.x()*qt_settings->glyphs().width(),cursor.y()*qt_settings->glyphs().height(), - qt_settings->glyphs().width()-1,qt_settings->glyphs().height()-1); + painter.drawRect(cursor.x() * qt_settings->glyphs().width(), + cursor.y() * qt_settings->glyphs().height(), + qt_settings->glyphs().width() - 1, + qt_settings->glyphs().height() - 1); } if (area.intersects(messages_rect)) { painter.setPen(Qt::black); - painter.drawText(viewport.contentsX()+1,viewport.contentsY()+1, - viewport.width(),0, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft|Qt::TextDontClip, messages); + painter.drawText(viewport.contentsX() + 1, viewport.contentsY() + 1, + viewport.width(), 0, + (Qt::TextWordWrap | Qt::AlignTop + | Qt::AlignLeft | Qt::TextDontClip), messages); painter.setPen(Qt::white); - painter.drawText(viewport.contentsX(),viewport.contentsY(), - viewport.width(),0, Qt::TextWordWrap|Qt::AlignTop|Qt::AlignLeft|Qt::TextDontClip, messages); + painter.drawText(viewport.contentsX(), viewport.contentsY(), + viewport.width(), 0, + (Qt::TextWordWrap | Qt::AlignTop + | Qt::AlignLeft | Qt::TextDontClip), messages); } painter.end(); From e9df383bd682e202a944e19383bf277e3f2fa665 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Sep 2020 14:19:48 -0700 Subject: [PATCH 182/708] boolean option processing In addition to 'true', 'yes', 'on' and 'false', 'no', 'off', accept 1 and 0 for the value of a boolean option. Other numeric values are rejected rather than treated as non-zero. Relax the parsing for true, false, yes, no to accept one or more letters instead of requiring at least three for true and false and full word for yes and no. Full word is still required for on and off. Don't report two errors for the same mistake: |% NETHACKOPTIONS='legacy:flase' ./nethack | * Illegal parameter for a boolean. | * Unknown option 'legacy:flase'. |2 errors in NETHACKOPTIONS. is changed to | * 'legacy:flase' is not valid for a boolean. |1 error in NETHACKOPTIONS. --- doc/fixes37.0 | 4 ++-- src/options.c | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 94944bd90..d0dc6f856 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.299 $ $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ General Fixes and Modified Features ----------------------------------- @@ -507,7 +507,7 @@ new monsters: displacer beast ('f') and genetic engineer ('Q') make camera flash which reveals previously unseen map features or objects or monsters record those on the hero's map; monsters revert to 'unseen' boolean options can optionally have the form "name:value" with value taken - from among "true", "yes", "on", or "false", "no", "off" + from among "true", "yes", "on", or 1 and "false", "no", "off", or 0 record number of wishes and artifact wishes in xlogfile give feedback for '#chat' directed at walls add 'Sokoban' conduct, tracking the number of times the special Sokoban rules diff --git a/src/options.c b/src/options.c index 236e04ff5..07a38f97c 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1597357458 2020/08/13 22:24:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.470 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.471 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4445,6 +4445,8 @@ char *op; return optn_ok; } if (req == do_set) { + boolean nosexchange = FALSE; + if (!allopt[optidx].addr) return optn_ok; /* silent retreat */ @@ -4460,18 +4462,23 @@ char *op; config_error_add( "Negated boolean '%s' should not have a parameter", allopt[optidx].name); - return optn_err; + return optn_silenterr; } + /* length is greater than 0 or we wouldn't have gotten here */ ln = (int) strlen(op); - if (!strncmpi(op, "true", max(ln, 3)) - || !strcmpi(op, "yes") || !strcmpi(op, "on")) { + if (!strncmpi(op, "true", ln) + || !strncmpi(op, "yes", ln) + || !strcmpi(op, "on") + || (digit(*op) && atoi(op) == 1)) { negated = FALSE; - } else if (!strncmpi(op, "false", max(ln, 3)) - || !strcmpi(op, "no") || !strcmpi(op, "off")) { + } else if (!strncmpi(op, "false", ln) + || !strncmpi(op, "no", ln) + || !strcmpi(op, "off") + || (digit(*op) && atoi(op) == 0)) { negated = TRUE; } else if (!allopt[optidx].valok) { - config_error_add("Illegal parameter for a boolean"); - return optn_err; + config_error_add("'%s' is not valid for a boolean", opts); + return optn_silenterr; } } if (iflags.debug_fuzzer && !g.opt_initial) { @@ -4484,8 +4491,7 @@ char *op; case opt_female: if (!strncmpi(opts, "female", 3)) { if (!g.opt_initial && flags.female == negated) { - config_error_add("That is not anatomically possible."); - return optn_err; + nosexchange = TRUE; } else { flags.initgend = flags.female = !negated; return optn_ok; @@ -4493,8 +4499,7 @@ char *op; } if (!strncmpi(opts, "male", 3)) { if (!g.opt_initial && flags.female != negated) { - config_error_add("That is not anatomically possible."); - return optn_err; + nosexchange = TRUE; } else { flags.initgend = flags.female = negated; return optn_ok; @@ -4502,6 +4507,19 @@ char *op; } break; } + /* this dates from when 'O' prompted for a line of options text + rather than use a menu to control access to which options can + be modified during play; it was possible to attempt to use + 'O' to specify female or negate male when playing as male or + to specify male or negate female when playing as female; + options processing rejects that for !opt_initial; not possible + now but kept in case someone brings the old 'O' behavior back */ + if (nosexchange) { + /* can't arbitrarily change sex after game has started; + magic (amulet or polymorph) is required for that */ + config_error_add("'%s' is not anatomically possible.", opts); + return optn_silenterr; + } *(allopt[optidx].addr) = !negated; /* <==== SET IT HERE */ From 5772069fb790ed42ea3d78d3eb45a53f8371b148 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Sep 2020 14:40:22 -0700 Subject: [PATCH 183/708] hints/*.2020 vs CFLAGS, take 3... Avoid use of GNU make's 'override' feature by requiring 'make CCFLAGS=-O' to replace -g from the make command line instead of 'make CFLAGS=-O'. Note the extra 'C' in the spelling. Revert the previous umpteen MORECFLAGS+= back to normal CFLAGS+=. --- sys/unix/hints/linux.2020 | 68 ++++++++++++++++++--------------------- sys/unix/hints/macOS.2020 | 68 ++++++++++++++++++--------------------- 2 files changed, 64 insertions(+), 72 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index e5cefb777..6928df837 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 linux.2020 $NHDT-Date: 1599593762 2020/09/08 19:36:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ +# NetHack 3.7 linux.2020 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. # NetHack may be freely redistributed. See license for details. # @@ -16,12 +16,16 @@ # linux.2020 hints file provides a single-user build for Linux (such # as Ubuntu focal). -# compiler flags: various -I, -D, and -W get appended below; +# compiler flags: CCFLAGS is used to construct a value for CFLAGS with +# various -I, -D, and -W settings appended below; # these are the settings of most interest for an end-user build # (clang doesn't support '-Og', gcc needs 4.x or later) -CFLAGS = -g -#CFLAGS = -g -Og -#CFLAGS = -O2 +CCFLAGS = -g +#CCFLAGS = -g -Og +#CCFLAGS = -O2 +# Note: this is not the usual 'CFLAGS' which is used in default +# rules for compiling C code; specifying a value for that on the +# 'make' command line should be avoided. # note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 3 #-INCLUDE multiw-1.2020 @@ -53,42 +57,41 @@ GAMEGRP = games #-INCLUDE multiw-2.2020 -# MORECFLAGS is eventually appended to CFLAGS -MORECFLAGS=-I../include -DNOTPARMDECL +CFLAGS=$(CCFLAGS) -I../include -DNOTPARMDECL ifeq "$(CCISCLANG)" "" # get the version of gcc GCCGTEQ9 := $(shell expr `$(CC) -dumpversion | cut -f1 -d.` \>= 9) ifeq "$(GCCGTEQ9)" "1" -MORECFLAGS+=-Wno-format-overflow +CFLAGS+=-Wno-format-overflow endif #gcc version greater than or equal to 9 endif #not clang # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. -#MORECFLAGS+=-Wunreachable-code -#MORECFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ +#CFLAGS+=-Wunreachable-code +#CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ # -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -#MORECFLAGS+=-DGCC_WARN +#CFLAGS+=-DGCC_WARN # NetHack sources control -MORECFLAGS+=-DDLB -MORECFLAGS+=-DHACKDIR=\"$(HACKDIR)\" -MORECFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -MORECFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -MORECFLAGS+=-DTIMED_DELAY -MORECFLAGS+=-DDUMPLOG -MORECFLAGS+=-DCONFIG_ERROR_SECURE=FALSE -#MORECFLAGS+=-DGREPPATH=\"/usr/bin/grep\" -MORECFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" -#MORECFLAGS+=-DNOMAIL -#MORECFLAGS+=-DEXTRA_SANITY_CHECKS -#MORECFLAGS+=-DEDIT_GETLIN -#MORECFLAGS+=-DSCORE_ON_BOTL -#MORECFLAGS+=-DMSGHANDLER -#MORECFLAGS+=-DTTY_TILES_ESCCODES -#MORECFLAGS+=-DTTY_SOUND_ESCCODES +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +CFLAGS+=-DTIMED_DELAY +CFLAGS+=-DDUMPLOG +CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +#CFLAGS+=-DNOMAIL +#CFLAGS+=-DEXTRA_SANITY_CHECKS +#CFLAGS+=-DEDIT_GETLIN +#CFLAGS+=-DSCORE_ON_BOTL +#CFLAGS+=-DMSGHANDLER +#CFLAGS+=-DTTY_TILES_ESCCODES +#CFLAGS+=-DTTY_SOUND_ESCCODES -MORECFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 +CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 VARDATND = VARDATND0 = @@ -122,7 +125,7 @@ X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XPM -MORECFLAGS += -DUSE_XPM +CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif @@ -161,13 +164,6 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) -# if CFLAGS=foo was specified on the command line, CFLAGS+=$(MORECFLAGS) -# would be ignored without 'override'; we want to allow CFLAGS=-g vs -O -# on the command line without having to specify all the other stuff -# -override CFLAGS+=$(MORECFLAGS) -# - #PREFIX=/usr PREFIX=$(wildcard ~)/nh/install diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 212c8581b..937e55151 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -1,4 +1,4 @@ -# NetHack 3.7 macOS.2020 $NHDT-Date: 1599593767 2020/09/08 19:36:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1599687615 2020/09/09 21:40:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.73 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. # NetHack may be freely redistributed. See license for details. # @@ -16,12 +16,16 @@ # macOS X hints file # -# compiler flags: various -I, -D, and -W get appended below; +# compiler flags: CCFLAGS is used to construct a value for CFLAGS with +# various -I, -D, and -W settings appended below; # these are the settings of most interest for an end-user build # (clang doesn't support '-Og', gcc needs 4.x or later) -CFLAGS = -g -#CFLAGS = -g -Og -#CFLAGS = -O2 +CCFLAGS = -g +#CCFLAGS = -g -Og +#CCFLAGS = -O2 +# Note: this is not the usual 'CFLAGS' which is used in default +# rules for compiling C code; specifying a value for that on the +# 'make' command line should be avoided. # note: '#-INCLUDE' is not just a comment; multiw-1 contains sections 1 to 3 #-INCLUDE multiw-1.2020 @@ -55,12 +59,11 @@ endif #-INCLUDE multiw-2.2020 -# MORECFLAGS is eventually appended to CFLAGS -MORECFLAGS=-I../include -DNOTPARMDECL +CFLAGS=$(CCFLAGS) -I../include -DNOTPARMDECL ifndef WANT_WIN_QT # these are normally used when compiling nethack's core -MORECFLAGS+=-ansi -pedantic -Wno-long-long +CFLAGS+=-ansi -pedantic -Wno-long-long # but -ansi forces -std=c90 for C or -std=c++98 for C++; # win/Qt/qt_*.cpp compiled with C++98 semantics trigger #In file included from .../qt5/include/QtCore/qglobal.h:105: @@ -70,30 +73,30 @@ MORECFLAGS+=-ansi -pedantic -Wno-long-long endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. -#MORECFLAGS+=-Wunreachable-code -MORECFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ +#CFLAGS+=-Wunreachable-code +CFLAGS+=-Wall -Wextra -Wno-missing-field-initializers -Wimplicit \ -Wreturn-type -Wunused -Wformat -Wswitch -Wshadow -Wwrite-strings -MORECFLAGS+=-DGCC_WARN +CFLAGS+=-DGCC_WARN # NetHack sources control -MORECFLAGS+=-DDLB -MORECFLAGS+=-DHACKDIR=\"$(HACKDIR)\" -MORECFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB -MORECFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -#MORECFLAGS+=-DTIMED_DELAY -#MORECFLAGS+=-DDUMPLOG -#MORECFLAGS+=-DCONFIG_ERROR_SECURE=FALSE -MORECFLAGS+=-DGREPPATH=\"/usr/bin/grep\" -#MORECFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" -MORECFLAGS+=-DNOMAIL -#MORECFLAGS+=-DEXTRA_SANITY_CHECKS -#MORECFLAGS+=-DEDIT_GETLIN -#MORECFLAGS+=-DSCORE_ON_BOTL -#MORECFLAGS+=-DMSGHANDLER -#MORECFLAGS+=-DTTY_TILES_ESCCODES -#MORECFLAGS+=-DTTY_SOUND_ESCCODES +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDEFAULT_WINDOW_SYS=\"$(WANT_DEFAULT)\" -DDLB +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +#CFLAGS+=-DTIMED_DELAY +#CFLAGS+=-DDUMPLOG +#CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +CFLAGS+=-DNOMAIL +#CFLAGS+=-DEXTRA_SANITY_CHECKS +#CFLAGS+=-DEDIT_GETLIN +#CFLAGS+=-DSCORE_ON_BOTL +#CFLAGS+=-DMSGHANDLER +#CFLAGS+=-DTTY_TILES_ESCCODES +#CFLAGS+=-DTTY_SOUND_ESCCODES -MORECFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 +CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 VARDATND = VARDATND0 = @@ -127,7 +130,7 @@ X11CFLAGS = -I/opt/X11/include # avoid repeated complaints about _X_NONNULL(args...) in X11CFLAGS += -Wno-variadic-macros ifdef USE_XPM -MORECFLAGS += -DUSE_XPM +CFLAGS += -DUSE_XPM WINX11LIB += -lXpm VARDATND0 += rip.xpm endif @@ -165,13 +168,6 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) -# if CFLAGS=foo was specified on the command line, CFLAGS+=$(MORECFLAGS) -# would be ignored without 'override'; we want to allow CFLAGS=-g vs -O -# on the command line without having to specify all the other stuff -# -override CFLAGS+=$(MORECFLAGS) -# - WANT_BUNDLE=1 ifdef WANT_SHARE_INSTALL From 239b7aaf66a33e64be0b4375e270a314912c48ae Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Sep 2020 16:01:18 -0700 Subject: [PATCH 184/708] pick-a-color in color Similar to how the pick-an-attribute menu for menu colors and status highlights shows the attribute names using the attribute so that you can see how it looks (or whether it is supported), have the pick-a-color menu show the color names in the corresponding color. Does so by temporarily removing any user-specified menu colors and setting up another list of such for matching color names. Forces the 'menucolors' option On while the pick-a-color menu is in use, then restores the previous setting along with the user's menu colorings. Might need some way to avoid setting that for a configuration where colors don't work. --- doc/fixes37.0 | 4 +- include/decl.h | 50 +++++++++++++----------- src/decl.c | 17 +++++---- src/options.c | 101 +++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 127 insertions(+), 45 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d0dc6f856..f03cb4676 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ General Fixes and Modified Features ----------------------------------- @@ -521,6 +521,8 @@ add section marker [] support to run-time config file; CHOOSE section1,section2 file to be part of the last section; that still works the same, but [] can be used to terminate the last section and revert to common options for the remainder of the file +render the color names in the corresponding color when using the pick-a-color + menu for adding status highlights or menu colors via 'O' Platform- and/or Interface-Specific New Features diff --git a/include/decl.h b/include/decl.h index b4f7f0dc1..453b450ae 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1596498532 2020/08/03 23:48:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.240 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -639,12 +639,7 @@ struct _create_particular_data { boolean sleeping, saddled, invisible, hidden; }; -/* instance_globals holds engine state that does not need to be - * persisted upon game exit. The initialization state is well defined - * an set in decl.c during early early engine initialization. - * - * unlike instance_flags, values in the structure can be of any type. */ - +/* some array sizes for 'g' */ #define BSIZE 20 #define WIZKIT_MAX 128 #define CVT_BUF_SIZE 64 @@ -652,6 +647,16 @@ struct _create_particular_data { #define LUA_VER_BUFSIZ 20 #define LUA_COPYRIGHT_BUFSIZ 120 +/* + * 'g' -- instance_globals holds engine state that does not need to be + * persisted upon game exit. The initialization state is well defined + * and set in decl.c during early early engine initialization. + * + * Unlike instance_flags, values in the structure can be of any type. + * + * Pulled from other files to be grouped in one place. Some comments + * which came with them don't make much sense out of their original context. + */ struct instance_globals { /* apply.c */ @@ -684,12 +689,12 @@ struct instance_globals { /* cmd.c */ struct cmd Cmd; /* flag.h */ - /* Provide a means to redo the last command. The flag `in_doagain' is set - * to true while redoing the command. This flag is tested in commands that - * require additional input (like `throw' which requires a thing and a - * direction), and the input prompt is not shown. Also, while in_doagain is - * TRUE, no keystrokes can be saved into the saveq. - */ + /* Provide a means to redo the last command. The flag `in_doagain' + (decl.c below) is set to true while redoing the command. This flag + is tested in commands that require additional input (like `throw' + which requires a thing and a direction), and the input prompt is + not shown. Also, while in_doagain is TRUE, no keystrokes can be + saved into the saveq. */ char pushq[BSIZE]; char saveq[BSIZE]; int phead; @@ -999,34 +1004,35 @@ struct instance_globals { /* objname.c */ /* distantname used by distant_name() to pass extra information to xname_flags(); it would be much cleaner if this were a parameter, - but that would require all of the xname() and doname() calls to be - modified */ + but that would require all xname() and doname() calls to be modified */ int distantname; /* options.c */ struct symsetentry *symset_list; /* files.c will populate this with - list of available sets */ - /* - * Allow the user to map incoming characters to various menu commands. - * The accelerator list must be a valid C string. - */ + * list of available sets */ + /* Allow the user to map incoming characters to various menu commands. */ char mapped_menu_cmds[MAX_MENU_MAPPED_CMDS + 1]; /* exported */ char mapped_menu_op[MAX_MENU_MAPPED_CMDS + 1]; short n_menu_mapped; + /* options processing */ boolean opt_initial; boolean opt_from_file; boolean opt_need_redraw; /* for doset() */ + /* use menucolors to show colors in the pick-a-color menu */ + boolean save_menucolors; /* copy of iflags.use_menu_colors */ + struct menucoloring *save_colorings; /* copy of g.menu_colorings */ + struct menucoloring *color_colorings; /* alternate set of menu colors */ /* pickup.c */ int oldcap; /* last encumberance */ /* current_container is set in use_container(), to be used by the callback routines in_container() and out_container() from askchain() - and use_container(). Also used by menu_loot() and container_gone(). */ + and use_container(). Also used by menu_loot() and container_gone(). */ struct obj *current_container; boolean abort_looting; /* Value set by query_objlist() for n_or_more(). */ long val_for_n_or_more; - /* list of valid menu classes for query_objlist() and allow_category callback + /* list of menu classes for query_objlist() and allow_category callback (with room for all object classes, 'u'npaid, BUCX, and terminator) */ char valid_menu_classes[MAXOCLASSES + 1 + 4 + 1]; boolean class_filter; diff --git a/src/decl.c b/src/decl.c index 5d528df33..7bcf2501a 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1596498154 2020/08/03 23:42:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.216 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.217 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -526,17 +526,20 @@ const struct instance_globals g_init = { 0, /* distantname */ /* options.c */ - NULL, /* symset_list */ + (struct symsetentry *) 0, /* symset_list */ UNDEFINED_VALUES, /* mapped_menu_cmds */ UNDEFINED_VALUES, /* mapped_menu_op */ 0, /* n_menu_mapped */ - UNDEFINED_VALUE, /* opt_initial */ - UNDEFINED_VALUE, /* opt_from_file */ - UNDEFINED_VALUE, /* opt_need_redraw */ + FALSE, /* opt_initial */ + FALSE, /* opt_from_file */ + FALSE, /* opt_need_redraw */ + FALSE, /* save_menucolors */ + (struct menucoloring *) 0, /* save_colorings */ + (struct menucoloring *) 0, /* color_colorings */ /* pickup.c */ 0, /* oldcap */ - UNDEFINED_PTR, /* current_container */ + (struct obj *) 0, /* current_container */ UNDEFINED_VALUE, /* abort_looting */ UNDEFINED_VALUE, /* val_for_n_or_more */ UNDEFINED_VALUES, /* valid_menu_classes */ @@ -551,7 +554,7 @@ const struct instance_globals g_init = { 0, /* saved_pline_index */ UNDEFINED_VALUES, #endif - NULL, /* you_buf */ + (char *) 0, /* you_buf */ 0, /* you_buf_siz */ /* polyself.c */ diff --git a/src/options.c b/src/options.c index 07a38f97c..cea11d4b8 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1599686385 2020/09/09 21:19:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.471 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1599778431 2020/09/10 22:53:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.472 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -235,13 +235,14 @@ static int FDECL(check_misc_menu_command, (char *, char *)); int FDECL(spcfn_misc_menu_cmd, (int, int, BOOLEAN_P, char *, char *)); static const char *FDECL(attr2attrname, (int)); +static void FDECL(basic_menu_colors, (BOOLEAN_P)); static const char * FDECL(msgtype2name, (int)); static int NDECL(query_msgtype); static boolean FDECL(msgtype_add, (int, char *)); static void FDECL(free_one_msgtype, (int)); static int NDECL(msgtype_count); static boolean FDECL(test_regex_pattern, (const char *, const char *)); -static boolean FDECL(add_menu_coloring_parsed, (char *, int, int)); +static boolean FDECL(add_menu_coloring_parsed, (const char *, int, int)); static void FDECL(free_one_menu_coloring, (int)); static int NDECL(count_menucolors); static boolean FDECL(parse_role_opts, (int, BOOLEAN_P, const char *, @@ -6402,9 +6403,9 @@ char* bindings; * */ -static const struct { +static const struct color_names { const char *name; - const int color; + int color; } colornames[] = { { "black", CLR_BLACK }, { "red", CLR_RED }, @@ -6435,9 +6436,9 @@ static const struct { { "bright cyan", CLR_BRIGHT_CYAN } }; -static const struct { +static const struct attr_names { const char *name; - const int attr; + int attr; } attrnames[] = { { "none", ATR_NONE }, { "bold", ATR_BOLD }, @@ -6520,6 +6521,61 @@ boolean complain; return a; } +extern const char regex_id[]; /* from sys/share/regex.{c,cpp} */ + +/* True: temporarily replace menu color entries with a fake set of menu + colors, { "light blue"=light_blue, "blue"=blue, "red"=red, &c }, that + illustrates most colors for use when the pick-a-color menu is rendered; + suppresses black and white because one of those will likely be invisible + due to matching the background; False: restore user-specified colorings */ +static void +basic_menu_colors(load_colors) +boolean load_colors; +{ + if (load_colors) { + /* replace normal menu colors with a set specifically for colors */ + g.save_menucolors = iflags.use_menu_color; + g.save_colorings = g.menu_colorings; + + iflags.use_menu_color = TRUE; + if (g.color_colorings) { + /* use the alternate colorings which were set up previously */ + g.menu_colorings = g.color_colorings; + } else { + /* create the alternate colorings once */ + char cnm[QBUFSZ]; + int i, c; + boolean pmatchregex = !strcmpi(regex_id, "pmatchregex"); + + /* menu_colorings pointer has been saved; clear it in order + to add the alternate entries as if from scratch */ + g.menu_colorings = (struct menucoloring *) 0; + + /* this orders the patterns last-in/first-out; that means + that the "light " variations come before the basic + "" ones, which is exactly what we want */ + for (i = 0; i < SIZE(colornames); ++i) { + if (!colornames[i].name) /* first alias entry has no name */ + break; + c = colornames[i].color; + if (c == CLR_BLACK || c == CLR_WHITE || c == NO_COLOR) + continue; /* skip these */ + Sprintf(cnm, pmatchregex ? "*%s" : "%s", colornames[i].name); + add_menu_coloring_parsed(dupstr(cnm), c, ATR_NONE); + } + + /* right now, menu_colorings contains the alternate color list; + remember that list for future pick-a-color instances and + also keep it as is for this instance */ + g.color_colorings = g.menu_colorings; + } + } else { + /* restore normal user-specific menu colors */ + iflags.use_menu_color = g.save_menucolors; + g.menu_colorings = g.save_colorings; + } +} + int query_color(prompt) const char *prompt; @@ -6529,6 +6585,9 @@ const char *prompt; int i, pick_cnt; menu_item *picks = (menu_item *) 0; + /* replace user patterns with color name ones and force 'menucolors' On */ + basic_menu_colors(TRUE); + tmpwin = create_nhwindow(NHW_MENU); start_menu(tmpwin, MENU_BEHAVE_STANDARD); any = cg.zeroany; @@ -6543,6 +6602,11 @@ const char *prompt; end_menu(tmpwin, (prompt && *prompt) ? prompt : "Pick a color"); pick_cnt = select_menu(tmpwin, PICK_ONE, &picks); destroy_nhwindow(tmpwin); + + /* remove temporary color name patterns and restore user-specified ones; + reset 'menucolors' option to its previous value */ + basic_menu_colors(FALSE); + if (pick_cnt > 0) { i = colornames[picks[0].item.a_int - 1].color; /* pick_cnt==2: explicitly picked something other than the @@ -6876,7 +6940,7 @@ const char *errmsg; static boolean add_menu_coloring_parsed(str, c, a) -char *str; +const char *str; int c, a; { static const char re_error[] = "Menucolor regex error"; @@ -6970,20 +7034,27 @@ int *color, *attr; return FALSE; } +/* release all menu color patterns */ void free_menu_coloring() { - struct menucoloring *tmp, *tmp2; + /* either menu_colorings or color_colorings or both might need to + be freed or already be Null; do-loop will iterate at most twice */ + do { + struct menucoloring *tmp, *tmp2; - for (tmp = g.menu_colorings; tmp; tmp = tmp2) { - tmp2 = tmp->next; - regex_free(tmp->match); - free((genericptr_t) tmp->origstr); - free((genericptr_t) tmp); - } - g.menu_colorings = (struct menucoloring *) 0; + for (tmp = g.menu_colorings; tmp; tmp = tmp2) { + tmp2 = tmp->next; + regex_free(tmp->match); + free((genericptr_t) tmp->origstr); + free((genericptr_t) tmp); + } + g.menu_colorings = g.color_colorings; + g.color_colorings = (struct menucoloring *) 0; + } while (g.menu_colorings); } +/* release a specific menu color pattern; not used for color_colorings */ static void free_one_menu_coloring(idx) int idx; /* 0 .. */ From a3be3f79b6131892fc18fd3b73a5950764f181eb Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 12 Sep 2020 00:32:05 -0400 Subject: [PATCH 185/708] syntax bit --- src/restore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/restore.c b/src/restore.c index 3f4505e5e..816ca3f8e 100644 --- a/src/restore.c +++ b/src/restore.c @@ -830,7 +830,7 @@ NHFILE *nhfp; #ifdef AMII_GRAPHICS { extern struct window_procs amii_procs; - if (WINDOWPORT("amii") { + if (WINDOWPORT("amii")) { extern winid WIN_BASE; clear_nhwindow(WIN_BASE); /* hack until there's a hook for this */ } From ba4a639de03c60f5cf0826f9a2da471a0fa5f3ba Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Sep 2020 23:59:20 -0700 Subject: [PATCH 186/708] pick-a-color tweak Move a minor conditional out of a short loop. I only bothered because I wanted to fix a comment. --- src/options.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/options.c b/src/options.c index cea11d4b8..199fa3ca0 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1599778431 2020/09/10 22:53:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.472 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1599893947 2020/09/12 06:59:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.473 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6546,6 +6546,7 @@ boolean load_colors; char cnm[QBUFSZ]; int i, c; boolean pmatchregex = !strcmpi(regex_id, "pmatchregex"); + const char *patternfmt = pmatchregex ? "*%s" : "%s"; /* menu_colorings pointer has been saved; clear it in order to add the alternate entries as if from scratch */ @@ -6560,7 +6561,7 @@ boolean load_colors; c = colornames[i].color; if (c == CLR_BLACK || c == CLR_WHITE || c == NO_COLOR) continue; /* skip these */ - Sprintf(cnm, pmatchregex ? "*%s" : "%s", colornames[i].name); + Sprintf(cnm, patternfmt, colornames[i].name); add_menu_coloring_parsed(dupstr(cnm), c, ATR_NONE); } @@ -6570,7 +6571,7 @@ boolean load_colors; g.color_colorings = g.menu_colorings; } } else { - /* restore normal user-specific menu colors */ + /* restore normal user-specified menu colors */ iflags.use_menu_color = g.save_menucolors; g.menu_colorings = g.save_colorings; } From c36b948b2117fcf62896babd2069308821d9a7af Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:23:13 -0700 Subject: [PATCH 187/708] add helpers and constants --- sys/lib/libnethackmain.c | 214 +++++++++++++++++++++++++-------------- 1 file changed, 138 insertions(+), 76 deletions(-) diff --git a/sys/lib/libnethackmain.c b/sys/lib/libnethackmain.c index 5f000847f..da39ee02e 100644 --- a/sys/lib/libnethackmain.c +++ b/sys/lib/libnethackmain.c @@ -19,6 +19,9 @@ /* for cross-compiling to WebAssembly (WASM) */ #ifdef __EMSCRIPTEN__ #include +void js_helpers_init(); +void js_constants_init(); +void js_globals_init(); #endif #if !defined(_BULL_SOURCE) && !defined(__sgi) && !defined(_M_UNIX) @@ -74,46 +77,13 @@ char *argv[]; boolean exact_username; boolean resuming = FALSE; /* assume new game */ boolean plsel_once = FALSE; - int i; - - for (i = 0; i < argc; i++) { - printf ("argv[%d]: %s\n", i, argv[i]); - } + // int i; + // for (i = 0; i < argc; i++) { + // printf ("argv[%d]: %s\n", i, argv[i]); + // } early_init(); -#if 0 /* __APPLE__ */ - { -/* special hack to change working directory to a resource fork when - running from finder --sam */ -#define MAC_PATH_VALUE ".app/Contents/MacOS/" - char mac_cwd[1024], *mac_exe = argv[0], *mac_tmp; - int arg0_len = strlen(mac_exe), mac_tmp_len, mac_lhs_len = 0; - getcwd(mac_cwd, 1024); - if (mac_exe[0] == '/' && !strcmp(mac_cwd, "/")) { - if ((mac_exe = strrchr(mac_exe, '/'))) - mac_exe++; - else - mac_exe = argv[0]; - mac_tmp_len = (strlen(mac_exe) * 2) + strlen(MAC_PATH_VALUE); - if (mac_tmp_len <= arg0_len) { - mac_tmp = malloc(mac_tmp_len + 1); - sprintf(mac_tmp, "%s%s%s", mac_exe, MAC_PATH_VALUE, mac_exe); - if (!strcmp(argv[0] + (arg0_len - mac_tmp_len), mac_tmp)) { - mac_lhs_len = - (arg0_len - mac_tmp_len) + strlen(mac_exe) + 5; - if (mac_lhs_len > mac_tmp_len - 1) - mac_tmp = realloc(mac_tmp, mac_lhs_len); - strncpy(mac_tmp, argv[0], mac_lhs_len); - mac_tmp[mac_lhs_len] = '\0'; - chdir(mac_tmp); - } - free(mac_tmp); - } - } - } -#endif /* __APPLE__ */ - g.hname = argv[0]; g.hackpid = getpid(); (void) umask(0777 & ~FCMASK); @@ -230,6 +200,11 @@ char *argv[]; process_options(argc, argv); /* command line options */ #ifdef WINCHAIN commit_windowchain(); +#endif +#ifdef __EMSCRIPTEN__ + js_helpers_init(); + js_constants_init(); + js_globals_init(); #endif init_nhwindows(&argc, argv); /* now we can set up window system */ #ifdef _M_UNIX @@ -260,9 +235,11 @@ char *argv[]; /* use character name rather than lock letter for file names */ g.locknum = 0; } else { +#ifndef NO_SIGNAL /* suppress interrupts while processing lock file */ (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGINT, SIG_IGN); +#endif } dlb_init(); /* must be before newgame() */ @@ -748,44 +725,6 @@ get_login_name() return buf; } -#if 0 /* __APPLE__ */ -extern int errno; - -void -port_insert_pastebuf(buf) -char *buf; -{ - /* This should be replaced when there is a Cocoa port. */ - const char *errfmt; - size_t len; - FILE *PB = popen("/usr/bin/pbcopy", "w"); - - if (!PB) { - errfmt = "Unable to start pbcopy (%d)\n"; - goto error; - } - - len = strlen(buf); - /* Remove the trailing \n, carefully. */ - if (buf[len - 1] == '\n') - len--; - - /* XXX Sorry, I'm too lazy to write a loop for output this short. */ - if (len != fwrite(buf, 1, len, PB)) { - errfmt = "Error sending data to pbcopy (%d)\n"; - goto error; - } - - if (pclose(PB) != -1) { - return; - } - errfmt = "Error finishing pbcopy (%d)\n"; - - error: - raw_printf(errfmt, strerror(errno)); -} -#endif /* __APPLE__ */ - unsigned long sys_random_seed() { @@ -818,4 +757,127 @@ sys_random_seed() return seed; } -/*unixmain.c*/ +#ifdef __EMSCRIPTEN__ +/*** + * Helpers + ***/ +EM_JS(void, js_helpers_init, (), { + globalThis.nethackGlobal = globalThis.nethackGlobal || {}; + globalThis.nethackGlobal.helpers = globalThis.nethackGlobal.helpers || {}; + + installHelper(mapglyphHelper); + installHelper(displayInventory); + + // used by print_glyph + function mapglyphHelper(glyph, x, y, mgflags) { + let ochar = _malloc(4); + let ocolor = _malloc(4); + let ospecial = _malloc(4); + + _mapglyph(glyph, ochar, ocolor, ospecial, x, y, mgflags); + + let ch = getValue(ochar, "i32"); + let color = getValue(ocolor, "i32"); + let special = getValue(ospecial, "i32"); + + _free (ochar); + _free (ocolor); + _free (ospecial); + + return { + glyph, + ch, + color, + special, + x, + y, + mgflags + }; + } + + // used by update_inventory + function displayInventory() { + // Asyncify.handleAsync(async () => { + return _display_inventory(0, 0); + console.log ("displayInventory done"); + // }); + } + + function installHelper(fn, name) { + name = name || fn.name; + globalThis.nethackGlobal.helpers[name] = fn; + } +}) + +/*** + * Constants + ***/ +#define SET_CONSTANT(scope, name) set_const(scope, #name, name); +EM_JS(void, set_const, (char *scope_str, char *name_str, int num), { + let scope = UTF8ToString(scope_str); + let name = UTF8ToString(name_str); + globalThis.nethackGlobal.constants[scope] = globalThis.nethackGlobal.constants[scope] || {}; + globalThis.nethackGlobal.constants[scope][name] = num; + globalThis.nethackGlobal.constants[scope][num] = name; +}); + +void js_constants_init() { + EM_ASM({ + globalThis.nethackGlobal = globalThis.nethackGlobal || {}; + globalThis.nethackGlobal.constants = globalThis.nethackGlobal.constants || {}; + }); + + // create_nhwindow + SET_CONSTANT("WIN_TYPE", NHW_MESSAGE) + SET_CONSTANT("WIN_TYPE", NHW_STATUS) + SET_CONSTANT("WIN_TYPE", NHW_MAP) + SET_CONSTANT("WIN_TYPE", NHW_MENU) + SET_CONSTANT("WIN_TYPE", NHW_TEXT) + + // status_update + SET_CONSTANT("STATUS_FIELD", BL_CHARACTERISTICS) + SET_CONSTANT("STATUS_FIELD", BL_RESET) + SET_CONSTANT("STATUS_FIELD", BL_FLUSH) + SET_CONSTANT("STATUS_FIELD", BL_TITLE) + SET_CONSTANT("STATUS_FIELD", BL_STR) + SET_CONSTANT("STATUS_FIELD", BL_DX) + SET_CONSTANT("STATUS_FIELD", BL_CO) + SET_CONSTANT("STATUS_FIELD", BL_IN) + SET_CONSTANT("STATUS_FIELD", BL_WI) + SET_CONSTANT("STATUS_FIELD", BL_CH) + SET_CONSTANT("STATUS_FIELD", BL_ALIGN) + SET_CONSTANT("STATUS_FIELD", BL_SCORE) + SET_CONSTANT("STATUS_FIELD", BL_CAP) + SET_CONSTANT("STATUS_FIELD", BL_GOLD) + SET_CONSTANT("STATUS_FIELD", BL_ENE) + SET_CONSTANT("STATUS_FIELD", BL_ENEMAX) + SET_CONSTANT("STATUS_FIELD", BL_XP) + SET_CONSTANT("STATUS_FIELD", BL_AC) + SET_CONSTANT("STATUS_FIELD", BL_HD) + SET_CONSTANT("STATUS_FIELD", BL_TIME) + SET_CONSTANT("STATUS_FIELD", BL_HUNGER) + SET_CONSTANT("STATUS_FIELD", BL_HP) + SET_CONSTANT("STATUS_FIELD", BL_HPMAX) + SET_CONSTANT("STATUS_FIELD", BL_LEVELDESC) + SET_CONSTANT("STATUS_FIELD", BL_EXP) + SET_CONSTANT("STATUS_FIELD", BL_CONDITION) + SET_CONSTANT("STATUS_FIELD", MAXBLSTATS) +} + +/*** + * Globals + ***/ +void js_globals_init() { + // printf("js_globals_init\n"); + + // player name + // g.plname + + // bottom line stats + // g.blstats + // g.now_or_before_idx +} + +#endif + +/*libnethack.c*/ From fc2e6b0b6dd10263382365fed2432c5f072fd3dc Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:24:06 -0700 Subject: [PATCH 188/708] initial commit --- sys/lib/npm-package/package-lock.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 sys/lib/npm-package/package-lock.json diff --git a/sys/lib/npm-package/package-lock.json b/sys/lib/npm-package/package-lock.json new file mode 100644 index 000000000..fb5f7b7e1 --- /dev/null +++ b/sys/lib/npm-package/package-lock.json @@ -0,0 +1,5 @@ +{ + "name": "@neth4ck/neth4ck", + "version": "1.0.0", + "lockfileVersion": 1 +} From 233c68391215e7b4a4a3111ceead69a299083a9a Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:24:12 -0700 Subject: [PATCH 189/708] add keywords --- sys/lib/npm-package/package.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json index b4e931559..79b445e17 100644 --- a/sys/lib/npm-package/package.json +++ b/sys/lib/npm-package/package.json @@ -13,7 +13,12 @@ "nethack", "rogue", "rogue-like", - "game" + "roguelike", + "dungeon", + "dungeons", + "game", + "rpg", + "dnd" ], "author": "Adam Powers ", "license": "SEE LICENSE IN LICENSE.md" From 4e38d8f3297b3ecaaa634204b8c917aed82a79e3 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:27:04 -0700 Subject: [PATCH 190/708] fix reentry and types, enhance debugging, delinting --- win/shim/winshim.c | 131 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index eec616f4f..8218b7382 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -51,6 +51,7 @@ ret_type name fn_args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_callback_name) return ret; \ local_callback(shim_callback_name, #name, (void *)&ret, fmt, args); \ + debugf("SHIM GRAPHICS: " #name " done.\n"); \ return ret; \ } @@ -60,6 +61,7 @@ void name fn_args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_callback_name) return; \ local_callback(shim_callback_name, #name, NULL, fmt, args); \ + debugf("SHIM GRAPHICS: " #name " done.\n"); \ } #else /* !__EMSCRIPTEN__ */ @@ -81,6 +83,7 @@ ret_type name fn_args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return ret; \ shim_graphics_callback(#name, (void *)&ret, fmt, ## __VA_ARGS__); \ + debugf("SHIM GRAPHICS: " #name " done.\n"); \ return ret; \ } @@ -89,6 +92,7 @@ void name fn_args { \ debugf("SHIM GRAPHICS: " #name "\n"); \ if (!shim_graphics_callback) return; \ shim_graphics_callback(#name, NULL, fmt, ## __VA_ARGS__); \ + debugf("SHIM GRAPHICS: " #name " done.\n"); \ } #endif /* __EMSCRIPTEN__ */ @@ -133,9 +137,9 @@ VDECLCB(shim_add_menu, "viipiiisi", A2P window, A2P glyph, P2V identifier, A2P ch, A2P gch, A2P attr, P2V str, A2P itemflags) VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt) -DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiip", A2P window, A2P how, P2V menu_list) +/* XXX: shim_select_menu menu_list is an output */ +DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiio", A2P window, A2P how, P2V menu_list) DECLCB(char, shim_message_menu,(CHAR_P let, int how, const char *mesg), "ciis", A2P let, A2P how, P2V mesg) -VDECLCB(shim_update_inventory,(void), "v") VDECLCB(shim_mark_synch,(void), "v") VDECLCB(shim_wait_synch,(void), "v") VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) @@ -144,11 +148,11 @@ VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiii VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) DECLCB(int, shim_nhgetch,(void), "i") -DECLCB(int, shim_nh_poskey,(int *x, int *y, int *mod), "ippp", P2V x, P2V y, P2V mod) +DECLCB(int, shim_nh_poskey,(int *x, int *y, int *mod), "iooo", P2V x, P2V y, P2V mod) VDECLCB(shim_nhbell,(void), "v") DECLCB(int, shim_doprev_message,(void),"iv") DECLCB(char, shim_yn_function,(const char *query, const char *resp, CHAR_P def), "cssi", P2V query, P2V resp, A2P def) -VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp) +VDECLCB(shim_getlin,(const char *query, char *bufp), "vso", P2V query, P2V bufp) DECLCB(int,shim_get_ext_cmd,(void),"iv") VDECLCB(shim_number_pad,(int state), "vi", A2P state) VDECLCB(shim_delay_output,(void), "v") @@ -168,11 +172,24 @@ VDECLCB(shim_status_enablefield, (int fieldidx, const char *nm, const char *fmt, BOOLEAN_P enable), "vippi", A2P fieldidx, P2V nm, P2V fmt, A2P enable) +/* XXX: the second argument to shim_status_update is sometimes an integer and sometimes a pointer */ VDECLCB(shim_status_update, (int fldidx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks), - "vipiiip", + "vioiiip", A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks) +#ifdef __EMSCRIPTEN__ +/* XXX: calling display_inventory() from shim_update_inventory() causes reentrancy that breaks emscripten Asyncify */ +/* this should be fine since according to windows.doc, the only purpose of shim_update_inventory() is to call display_inventory() */ +void shim_update_inventory() { + if(iflags.perm_invent) { + display_inventory(NULL, FALSE); + } +} +#else /* !__EMSCRIPTEN__ */ +VDECLCB(shim_update_inventory,(void), "v") +#endif + /* Interface definition used in windows.c */ struct window_procs shim_procs = { "shim", @@ -234,13 +251,19 @@ struct window_procs shim_procs = { #ifdef __EMSCRIPTEN__ /* convert the C callback to a JavaScript callback */ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *ret_ptr, const char *fmt_str, void *args), { - Asyncify.handleAsync(async () => { + // Asyncify.handleAsync() is the more logical choice here; however, the stack unrolling in Asyncify is performed by + // function call analysis during compilation. Since we are using an indirect callback (cb_name), it can't predict the stack + // unrolling and it crashes. Thus we use Asyncify.handleSleep() and wakeUp() to make sure that async doesn't break + // Asyncify. For details, see: https://emscripten.org/docs/porting/asyncify.html#optimizing + Asyncify.handleSleep(wakeUp => { // convert callback arguments to proper JavaScript varaidic arguments - let name = Module.UTF8ToString(shim_name); - let fmt = Module.UTF8ToString(fmt_str); - let cbName = Module.UTF8ToString(cb_name); + let name = UTF8ToString(shim_name); + let fmt = UTF8ToString(fmt_str); + let cbName = UTF8ToString(cb_name); // console.log("local_callback:", cbName, fmt, name); + reentryMutexLock(name); + let argTypes = fmt.split(""); let retType = argTypes.shift(); @@ -252,49 +275,81 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r jsArgs.push(val); } + decodeArgs(name, jsArgs); + // do the callback let userCallback = globalThis[cbName]; - let retVal = await runJsLoop(() => userCallback(name, ... jsArgs)); + runJsEventLoop(() => userCallback.call(this, name, ... jsArgs)).then((retVal) => { + // save the return value + setReturn(name, ret_ptr, retType, retVal); + // return + setTimeout(() => { + reentryMutexUnlock(); + wakeUp(); + }, 0); + }); - // save the return value - setReturn(name, ret_ptr, retType, retVal); // convert 'ptr' to the type indicated by 'type' function typeLookup(type, ptr) { switch(type) { case "s": // string - return Module.UTF8ToString(Module.getValue(ptr, "*")); + return UTF8ToString(getValue(ptr, "*")); case "p": // pointer - ptr = Module.getValue(ptr, "*"); + ptr = getValue(ptr, "*"); if(!ptr) return 0; // null pointer - return Module.getValue(ptr, "*"); + return getValue(ptr, "*"); case "c": // char - return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + return String.fromCharCode(getValue(getValue(ptr, "*"), "i8")); case "0": /* 2^0 = 1 byte */ - return Module.getValue(Module.getValue(ptr, "*"), "i8"); + return getValue(getValue(ptr, "*"), "i8"); case "1": /* 2^1 = 2 bytes */ - return Module.getValue(Module.getValue(ptr, "*"), "i16"); + return getValue(getValue(ptr, "*"), "i16"); case "2": /* 2^2 = 4 bytes */ case "i": // integer case "n": // number - return Module.getValue(Module.getValue(ptr, "*"), "i32"); + return getValue(getValue(ptr, "*"), "i32"); case "f": // float - return Module.getValue(Module.getValue(ptr, "*"), "float"); + return getValue(getValue(ptr, "*"), "float"); case "d": // double - return Module.getValue(Module.getValue(ptr, "*"), "double"); + return getValue(getValue(ptr, "*"), "double"); + case "o": // overloaded: multiple types + return ptr; default: throw new TypeError ("unknown type:" + type); } } - // setTimeout() with value of '0' is similar to setImmediate() (which isn't standard) + // make callback arguments friendly: convert numbers to strings where possible + function decodeArgs(name, args) { + // if (!globalThis.nethackGlobal.makeArgsFriendly) return; + + switch(name) { + case "shim_create_nhwindow": + args[0] = globalThis.nethackGlobal.constants["WIN_TYPE"][args[0]]; + break; + case "shim_status_update": + // which field is being updated? + args[0] = globalThis.nethackGlobal.constants["STATUS_FIELD"][args[0]]; + // arg[1] is a string unless it is BL_CONDITION, BL_RESET, BL_FLUSH, BL_CHARACTERISTICS + if(["BL_CONDITION", "BL_RESET", "BL_FLUSH", "BL_CHARACTERISTICS"].indexOf(args[0] && args[1]) < 0) { + args[1] = typeLookup("s", args[1]); + } else { + args[1] = typeLookup("p", args[1]); + } + break; + } + } + + // setTimeout() with value of '0' is similar to setImmediate() (but setImmediate isn't standard) // this lets the JS loop run for a tick so that other events can occur // XXX: I also tried replacing the for(;;) in allmain.c:moveloop() with emscripten_set_main_loop() - // unfortunately that won't work -- if the simulate_infinite_loop arg is false, it falls through; + // unfortunately that won't work -- if the simulate_infinite_loop arg is false, it falls through + // and the program ends; // if is true, it throws an exception to break out of main(), but doesn't get caught because // the stack isn't running under main() anymore... - // I think this is suboptimal, but we will have to live with it - async function runJsLoop(cb) { + // I think this is suboptimal, but we will have to live with it (for now?) + async function runJsEventLoop(cb) { return new Promise((resolve) => { setTimeout(() => { resolve(cb()); @@ -311,29 +366,29 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r if(typeof value !== "string") throw new TypeError(`expected ${name} return type to be string`); value=value?value:"(no value)"; - var strPtr = Module.getValue(ptr, "i32"); - Module.stringToUTF8(value, strPtr, 1024); + var strPtr = getValue(ptr, "i32"); + stringToUTF8(value, strPtr, 1024); break; case "i": if(typeof value !== "number" || !Number.isInteger(value)) throw new TypeError(`expected ${name} return type to be integer`); - Module.setValue(ptr, value, "i32"); + setValue(ptr, value, "i32"); break; case "c": if(typeof value !== "number" || value < 0 || value > 128) throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); - Module.setValue(ptr, value, "i8"); + setValue(ptr, value, "i8"); break; case "f": if(typeof value !== "number" || isFloat(value)) throw new TypeError(`expected ${name} return type to be float`); // XXX: I'm not sure why 'double' works and 'float' doesn't - Module.setValue(ptr, value, "double"); + setValue(ptr, value, "double"); break; case "d": if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be float`); - Module.setValue(ptr, value, "double"); + throw new TypeError(`expected ${name} return type to be double`); + setValue(ptr, value, "double"); break; case "v": break; @@ -345,6 +400,18 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r return n === +n && n !== (n|0) && !Number.isInteger(n); } } + + function reentryMutexLock(name) { + globalThis.nethackGlobal = globalThis.nethackGlobal || {}; + if(globalThis.nethackGlobal.shimPreventReentry) { + throw new Error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimPreventReentry}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); + } + globalThis.nethackGlobal.shimPreventReentry = name; + } + + function reentryMutexUnlock() { + globalThis.nethackGlobal.shimPreventReentry = null; + } }); }) #endif /* __EMSCRIPTEN__ */ From c602ecc5a2c548a19444d19698a0fe54b535b410 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:27:29 -0700 Subject: [PATCH 191/708] default is a permenant inventory window --- sys/lib/sysconf | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/lib/sysconf b/sys/lib/sysconf index 77b4c383f..2e1b66e12 100644 --- a/sys/lib/sysconf +++ b/sys/lib/sysconf @@ -146,5 +146,6 @@ PANICTRACE_LIBC=0 # option settings via NETHACKOPTIONS in their environment or via # ~/.nethackrc run-time configuration file. #OPTIONS=!autopickup,fruit:tomato,symset:DECgraphics +OPTIONS=perm_invent #eof From 34e4b1fae9252296b51bd22256c158d30f20ffa2 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:34:45 -0700 Subject: [PATCH 192/708] js test code --- sys/lib/npm-package/test/test.js | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 sys/lib/npm-package/test/test.js diff --git a/sys/lib/npm-package/test/test.js b/sys/lib/npm-package/test/test.js new file mode 100644 index 000000000..3032399e3 --- /dev/null +++ b/sys/lib/npm-package/test/test.js @@ -0,0 +1,55 @@ +let nethackStart = require("../src/nethackShim.js"); +Error.stackTraceLimit = 20; + +// debugging to make sure the JavaScript event loop isn't blocked +// const {performance} = require("perf_hooks"); +// let currentTime = 0; +// let lastTime = 0; +// setInterval(() => { +// lastTime = currentTime; +// currentTime = performance.now(); +// console.log("Time since last JavaScript loop:", currentTime-lastTime); +// }, 10); + +let Module = {}; +let winCount = 0; + +/* global globalThis */ +nethackStart(async function (name, ... args) { + switch(name) { + case "shim_init_nhwindows": + console.log("globalThis.nethackGlobal", globalThis.nethackGlobal); + break; + case "shim_create_nhwindow": + winCount++; + console.log("creating window", args, "returning", winCount); + return winCount; + case "shim_print_glyph": + var x = args[1]; + var y = args[2]; + var glyph = args[3]; + + var ret = globalThis.nethackGlobal.helpers.mapglyphHelper(glyph, x, y, 0); + console.log(`GLYPH (${x},${y}): ${String.fromCharCode(ret.ch)}`); + return; + // case "shim_update_inventory": + // globalThis.nethackGlobal.helpers.displayInventory(); + // return; + case "shim_select_menu": + return await selectMenu(...args); + case "shim_yn_function": + case "shim_message_menu": + return 121; // 'y' + case "shim_nhgetch": + case "shim_nh_poskey": + return 0; + default: + console.log(`called doGraphics: ${name} [${args}]`); + return 0; + } +}, Module); + +async function selectMenu(window, how, selected) { + Module.setValue(selected, 0, "*"); + return -1; +} \ No newline at end of file From 6fcb7c3db3281b75b76b6aa896d08833b37ab861 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:35:01 -0700 Subject: [PATCH 193/708] fix ignored files --- .gitignore | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 030d3d92e..fb74047b9 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ Release/ binary/ build/ ipch/ -lib/* +/lib Nethack.sln Nethack.sdf Nethack.opensdf @@ -88,9 +88,9 @@ src/nethack.wasm src/nethack.js src/wasm-data src/libnethack.a -libtest.c -nhlibtest -run.sh -test.js +/libtest.c +/nhlibtest +/run.sh +/test.js sys/lib/npm-package/build/nethack.js sys/lib/npm-package/build/nethack.wasm From d2fdc6f5826204efc725d431a47b1c19ed2611b9 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:40:04 -0700 Subject: [PATCH 194/708] add new exports, cleaner debugging options --- sys/lib/hints/wasm | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm index 7f85090af..681c1e693 100644 --- a/sys/lib/hints/wasm +++ b/sys/lib/hints/wasm @@ -18,7 +18,7 @@ EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' EMCC_LFLAGS+=-O3 EMCC_LFLAGS+=-s MODULARIZE -EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' +EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback", "_mapglyph", "_display_inventory"]' EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue", "setValue"]' EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 EMCC_LFLAGS+=--embed-file wasm-data@/ @@ -31,22 +31,35 @@ EMCC_CFLAGS= EMCC_CFLAGS+=-Wall EMCC_CFLAGS+=-Werror #EMCC_CFLAGS+=-s DISABLE_EXCEPTION_CATCHING=0 -EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 -#EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=2 +#EMCC_CFLAGS+=-s NO_EXIT_RUNTIME=1 +EMCC_CFLAGS+=-s EXIT_RUNTIME=1 +# if INVOKE_RUN=0, you must Module.callMain() with an optional parameter of commandline args +#EMCC_CFLAGS+=-s INVOKE_RUN=0 + +#EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 +EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=2 EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED=1 -#EMCC_DEBUG_CFLAGS+=-s EXCEPTION_DEBUG=1 +EMCC_DEBUG_CFLAGS+=-s EXCEPTION_DEBUG=0 #EMCC_DEBUG_CFLAGS+=-fsanitize=undefined -fsanitize=address -fsanitize=leak -#EMCC_DEBUG_CFLAGS+=-s EXIT_RUNTIME +EMCC_DEBUG_CFLAGS+=--profiling + EMCC_PROD_CFLAGS+=-O3 +ifdef WASM_DEBUG +EMCC_CFLAGS+=$(EMCC_DEBUG_CFLAGS) +else +EMCC_CFLAGS+=$(EMCC_PROD_CFLAGS) +endif + # Nethack C flags CFLAGS+=-DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE CFLAGS+=-g -I../include -DNOTPARMDECL CFLAGS+=-Wall CFLAGS+=-Werror CFLAGS+=-DGCC_WARN +CFLAGS+=-DNO_SIGNAL # NetHack sources control CFLAGS+=-DDLB @@ -55,12 +68,6 @@ CFLAGS+=-DDLB #CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" CFLAGS+=-DNOMAIL -ifdef WASM_DEBUG -EMCC_CFLAGS+=$(EMCC_DEBUG_CFLAGS) -else -EMCC_CFLAGS+=$(EMCC_PROD_CFLAGS) -endif - # installation config # hackdir is the wasm / emscripten embed data root directory HACKDIR=/ @@ -74,4 +81,4 @@ INSTDIR=$(HACKDIR) VARDIR=$(HACKDIR) #-POST -# no post \ No newline at end of file +# no post From 176f553b6e54177c21fbeb744bec17cc681805ae Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:48:13 -0700 Subject: [PATCH 195/708] remove stray debug message --- sys/lib/libnethackmain.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/lib/libnethackmain.c b/sys/lib/libnethackmain.c index da39ee02e..83899acb9 100644 --- a/sys/lib/libnethackmain.c +++ b/sys/lib/libnethackmain.c @@ -799,7 +799,6 @@ EM_JS(void, js_helpers_init, (), { function displayInventory() { // Asyncify.handleAsync(async () => { return _display_inventory(0, 0); - console.log ("displayInventory done"); // }); } From 1c23434de6710ed89b4f8e978dcde165e8571530 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:48:28 -0700 Subject: [PATCH 196/708] update docs --- sys/lib/npm-package/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/lib/npm-package/README.md b/sys/lib/npm-package/README.md index e39db8292..2c9b96938 100644 --- a/sys/lib/npm-package/README.md +++ b/sys/lib/npm-package/README.md @@ -15,6 +15,11 @@ The main module returns a setup function: `startNethack(uiCallback, moduleOption * `moduleOptions` - An optional [emscripten Module object](https://emscripten.org/docs/api_reference/module.html) for configuring the WASM that will be run. * `Module.arguments` - Of note is the [arguments property](https://emscripten.org/docs/api_reference/module.html#Module.arguments) which gets passed to NetHack as its [command line parameters](https://nethackwiki.com/wiki/Options). +There are a number of auxilary functions and variables that may help with building your applications. All of these are under `globalThis.nethackOptions`. Use `console.log(globalThis.nethackOptions)` for a full list of options. Some worth mentioning are: +* `globalThis.nethackOptions.helpers` - Helper functions that are useful for NetHack windowing ports + * `globalThis.nethackOptions.mapglyphHelper` - Converts an integer glyph into a character to be displayed. Useful if you are using ASCII characters for representing NetHack (as opposed to tiles). Interface is `mapglyphHelper(glyph, x, y, mgflags)` and will typically be called as part of the `shim_print_glyph` function. +* `globalThis.nethackOptions.constants` - A Object full of constants that are `#define`'d in NetHack's C code. Useful for translating to / from numbers in the APIs and return values. + ## Example ``` js let nethackStart = require("nethack"); From 5462072ceb2eef1922bcb08ef695a49aab0f908a Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 12 Sep 2020 12:49:10 -0700 Subject: [PATCH 197/708] bump version for minor improvements --- sys/lib/npm-package/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json index 79b445e17..e39a7d201 100644 --- a/sys/lib/npm-package/package.json +++ b/sys/lib/npm-package/package.json @@ -1,6 +1,6 @@ { "name": "@neth4ck/neth4ck", - "version": "1.0.0", + "version": "1.0.1", "description": "The original NetHack rogue-like game built as a WebAssembly module", "main": "src/nethackShim.js", "scripts": { From 33964801c8155421615ed5650644e76e5c5baa1e Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 15 Sep 2020 03:51:20 -0700 Subject: [PATCH 198/708] history formatting Qt's text window for 'history' was unexpectedly wide and it turned out that that was to fit in one excessively wide line. tty has been formatting it by splitting it into one normal sized line followed by an excessively short line. --- dat/history | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dat/history b/dat/history index 547103dd5..1651f7d3b 100644 --- a/dat/history +++ b/dat/history @@ -190,11 +190,11 @@ resurrected it for 3.3.1. The release of NetHack 3.4.3 in December 2003 marked the beginning 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 continued 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 +NetHack Development Team slowly and quietly continued 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. From eaf2af0b58e9318636bb9a19c3a109032a1fca6d Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 15 Sep 2020 07:26:42 -0700 Subject: [PATCH 199/708] unexplored terrain on Qt map Qt's map hadn't been updated to draw unexplored locations with the unexplored glyph so was still using solid stone instead. Column 0 should be removed but I'll leave that for someone more adventurous; I did it for curses and for X11 but am going to pass here. It's very noticable after magic mapping but is only "bad" (by wasting space) if clipping is being performed. --- doc/fixes37.0 | 3 ++- win/Qt/qt_map.cpp | 68 +++++++++++++++++++++++++---------------------- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f03cb4676..4e7535c4d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.302 $ $NHDT-Date: 1600179998 2020/09/15 14:26:38 $ General Fixes and Modified Features ----------------------------------- @@ -404,6 +404,7 @@ Qt: update message window's last message with player's response if it's a prompt string for a single-character of input (ynaq or invent letter) Qt: for line input, display the prompt+response in the message window Qt: enable the popup_dialog WC option (result is a bit flakey but usable) +Qt: 3.6 catchup - show unexplored locations as unexplored rather than as stone Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index bb208d243..0bb96d673 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -31,26 +31,31 @@ namespace nethack_qt_ { #ifdef TEXTCOLOR static const QPen& nhcolor_to_pen(int c) { - static QPen* pen=0; - if ( !pen ) { - pen = new QPen[17]; - pen[0] = QColor(64,64,64); - pen[1] = QColor(Qt::red); - pen[2] = QColor(0,191,0); - pen[3] = QColor(127,127,0); - pen[4] = QColor(Qt::blue); - pen[5] = QColor(Qt::magenta); - pen[6] = QColor(Qt::cyan); - pen[7] = QColor(Qt::gray); - pen[8] = QColor(Qt::white); // no color - pen[9] = QColor(255,127,0); - pen[10] = QColor(127,255,127); - pen[11] = QColor(Qt::yellow); - pen[12] = QColor(127,127,255); - pen[13] = QColor(255,127,255); - pen[14] = QColor(127,255,255); - pen[15] = QColor(Qt::white); - pen[16] = QColor(Qt::black); + static QPen *pen = (QPen *) 0; + if (!pen) { + pen = new QPen[17]; + // + // FIXME: these are duplicated in qt_menu.cpp + // + pen[ 0] = QColor(64, 64, 64); // black + pen[ 1] = QColor(Qt::red); + pen[ 2] = QColor(0, 191, 0); // green + pen[ 3] = QColor(127, 127, 0); // brownish + pen[ 4] = QColor(Qt::blue); + pen[ 5] = QColor(Qt::magenta); + pen[ 6] = QColor(Qt::cyan); + pen[ 7] = QColor(Qt::gray); + // on tty, "light" variations are "bright" instead; here they're paler + pen[ 8] = QColor(Qt::white); // no color + pen[ 9] = QColor(255, 127, 0); // orange + pen[10] = QColor(127, 255, 127); // light green + pen[11] = QColor(Qt::yellow); + pen[12] = QColor(127, 127, 255); // light blue + pen[13] = QColor(255, 127, 255); // light magenta + pen[14] = QColor(127, 255, 255); // light cyan + pen[15] = QColor(Qt::white); + // ? out of range for 0..15 + pen[16] = QColor(Qt::black); } return pen[c]; @@ -502,12 +507,13 @@ void NetHackQtMapViewport::clickCursor() void NetHackQtMapViewport::Clear() { - unsigned short stone=cmap_to_glyph(S_stone); - - for (int j=0; j Date: Wed, 16 Sep 2020 02:04:15 -0700 Subject: [PATCH 200/708] new file win/Qt/Qt-issues.txt Record a bunch of Qt stuff before I forget it all. It's probably too late: I'll bet I've left some things out. Doesn't include several menu problems that I've already fixed but not checked in yet. (I don't have any other Qt changes pending.) --- win/Qt/Qt-issues.txt | 55 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 win/Qt/Qt-issues.txt diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt new file mode 100644 index 000000000..a4405b4a7 --- /dev/null +++ b/win/Qt/Qt-issues.txt @@ -0,0 +1,55 @@ +Qt-NetHack issues +----- + +Urgent: if the program crashes on OSX, a dialog box asking the user +whether to [ignore], [report], or [restart] will eventually appear +(it's slow). That should be repressed even if the report choice could +be directed at nethack.org. + +Urgent: launching Qt nethack as a synchronous subprocess (ie, no +trailing '&') from a Terminal window, changing focus back to that +terminal after NetHack has started, and typing ^C sends the program +into an endless loop with repeated messages to stderr (the terminal) +complaining that the event loop is already running. + +On OSX, if the program is run from nethackdir/nethack rather than from +NetHack.app/Contents/MacOS/nethack (plus having NetHack.app/Contents/ +Info.plist containing pertinent information) then the menu bar at the +top of the screen won't accept mouse clicks and the application menu +entry in that menu bar will show as "nethack" (filename) rather than +"NetHack" (intended application name). The click issue can be worked +around by giving focus to some other application (which will put up +its own menu bar) and then back to nethack (thereby reloading nethack's +menu bar). + +Sometimes scrolling a menu leaves the displayed text not matching what +nethack thinks is displayed, so making a selection by mouse click may +occasionally pick the wrong item. There's usually a visual clue when +this happens. As long as it's not a pick-one menu, scrolling up and +down or back and worth a few times will usually get things back in +sync, then you can click on the wrong entry to uncheck it and then on +the right entry to check that. Making a selection by typing its +letter doesn't suffer from this, but isn't always possible (ie, long +menu like 'O's where first 52 items have letters but remainder don't). + +On OSX, command+Q while a menu (which has its own key event handler) +is popped up gets ignored. It should at least close the popup like +ESC and maybe also initiate quitting. + +On the map, ^V is a dead key (at least on OSX; all other ASCII control +characters from ^A through ^U, ^W through ^Z, and ^[, ^\, ^], ^^, ^_ +work; no attempt to have ^@ generate NUL has been made). + +The save file selection widget at start of game issues a complaint to +stderr about adding a layout to a dialog which already has a layout, +similar to ones that YnDialog used to give for the count widget in +yn#aq dialogs. (That was resolved by inserting count in the middle +instead of trying to append to the end [without figuring out why Qt +was complaining--no doubt a Qt 2/3/4/5 issue], which is not a viable +solution for save file selection.) It also clobbers an existing save +file if you use a different name when starting a new game, then save. + +Map column #0, which the core reserves for its own purposes and isn't +intended to be displayed, is displayed (as blank terrain). + +----- From 5401d18c4bc966d6a0c6e20b9b08675106426f12 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 16 Sep 2020 15:51:33 -0700 Subject: [PATCH 201/708] Qt menu overhaul handle preselected item in pick-one menu; picking it returns that item rather than toggling it off and returning nothing, picking something else only returns the other thing (was returning first of the chosen item or the preselected item, foiling core's attempt to deal with both and giving wrong result whenever the preselected one came first--like pick-an-attribute for menu colors); when handling typed input, check selector letters before menu command keys so that special "letters" '-' (fingers, hands, self) and ':' (look inside container) that are specified by a few menus can be chosen by keyboard; menus were using default line heights which are excessively tall, effectively making them be double spaced and using more screen space than should have been needed; reduce height to 60% of what it was, still a bit taller than regular spacing; look at ^X--which is rendered via menu--before and after to see the difference; start with count column empty instead of 6 spaces; grow it as counts get entered; reset to empty if [all], [none], or [invert] is used; treat intermediate counts as long rather than int; right justify formatted count values; simplify creating menu return data (pick-one doesn't need separate handling); for pick-one menus, enable [ok] button if there is one preselected item, enable [all] button if there is only one item (may never happen), enable [none] if there is a preselected item (menu remains active if [none] is used to clear the preselection); enable [invert] if there is one item (may never happen; should allow two items if one of them is preselected--definitely does happen--but that wouldn't work as intended without code changes); honor pending count if an item is selected by clicking its checkbox (already done for typing its letter or for clicking another part of item's menu line); accept / in addition to when backing out a digit as a count is being typed; accept ^[ as well as ESC key for cancelling count or entire menu; honor 'menucolors'=false to ignore any defined menu color patterns. --- win/Qt/qt_menu.cpp | 798 +++++++++++++++++++++++++++++---------------- win/Qt/qt_menu.h | 40 ++- 2 files changed, 543 insertions(+), 295 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index a90cb7d9b..d14f19338 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -4,6 +4,20 @@ // qt_menu.cpp -- a menu or text-list widget +// +// TODO: +// search behaves weirdly unless you click in the line-edit dialog box +// after clicking on the [search] button to pop that up; +// implement next_page, prev_page, first_page, and last_page to work +// like they do for X11: scroll menu window as if it were paginated; +// entering a count that uses more digits than the previous biggest count +// widens count field but fails to widen the whole menu so a horizontal +// scrollbar might appear; +// create and use custom check-box icons to visually distinguish +// pre-selected entries and numeric subset entries from ordinary select +// and unselected. +// + extern "C" { #include "hack.h" } @@ -25,6 +39,7 @@ extern "C" { extern "C" int qt_compact_mode; // end temporary +/* for documentation rather than necessity; hack.h -> decl.h declares this */ extern "C" struct menucoloring *menu_colorings; namespace nethack_qt_ { @@ -67,20 +82,20 @@ QSize NetHackQtMenuListBox::sizeHint() const return QSize(TotalWidth()+hsize, TotalHeight()+hsize); } -// Table view columns: +// Table view columns (0..4): // -// [pick-count] [accel] [glyph] [string] +// [pick-count] [check-box] [glyph] [accel] [string] // -// Maybe accel should be near string. We'll see. -// pick-count normally blank. -// double-clicking or click-on-count gives pop-up entry -// string is green when selected +// pick-count is normally empty and gets wider as needed. // NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : QDialog(parent), table(new NetHackQtMenuListBox()), prompt(0), - counting(false) + biggestcount(0L), // largest subset amount that user has entered + countdigits(0), // number of digits needed by biggestcount + counting(false), // user has typed a digit and more might follow + searching(false) { // setFont() was in SelectMenu(), in time to be rendered but too late // when measuring the width and height that will be needed @@ -90,7 +105,7 @@ NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : QGridLayout *grid = new QGridLayout(); table->setColumnCount(5); table->setFrameStyle(QFrame::Panel|QFrame::Sunken); - table->setLineWidth(2); + table->setLineWidth(2); // note: this is not row spacing table->setShowGrid(false); table->horizontalHeader()->hide(); table->verticalHeader()->hide(); @@ -131,7 +146,7 @@ NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : setFocusPolicy(Qt::StrongFocus); table->setFocusPolicy(Qt::NoFocus); connect(table, SIGNAL(cellClicked(int,int)), - this, SLOT(cellToggleSelect(int,int))); + this, SLOT(TableCellClicked(int,int))); setLayout(grid); } @@ -158,13 +173,15 @@ NetHackQtMenuWindow::MenuItem::~MenuItem() { } -void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, - char ch, char gch, int attr, const QString& str, unsigned itemflags) +void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P *identifier, + char ch, char gch, int attr, + const QString& str, unsigned itemflags) { bool presel = (itemflags & MENU_ITEMFLAGS_SELECTED) != 0; if (!ch && identifier->a_void!=0) { // Supply a keyboard accelerator. Limited supply. - static char accel[]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; + static char accel[] + = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; if (accel[next_accel]) { ch=accel[next_accel++]; } @@ -173,15 +190,15 @@ void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, if ((int)itemlist.size() < itemcount+1) { itemlist.resize(itemcount*4+10); } - itemlist[itemcount].glyph=glyph; - itemlist[itemcount].identifier=*identifier; - itemlist[itemcount].ch=ch; - itemlist[itemcount].gch=gch; - itemlist[itemcount].attr=attr; - itemlist[itemcount].str=str; - itemlist[itemcount].selected=presel; - itemlist[itemcount].itemflags=itemflags; - itemlist[itemcount].count=-1; + itemlist[itemcount].glyph = glyph; + itemlist[itemcount].identifier = *identifier; + itemlist[itemcount].ch = ch; + itemlist[itemcount].gch = gch; + itemlist[itemcount].attr = attr; + itemlist[itemcount].str = str; + itemlist[itemcount].selected = itemlist[itemcount].preselected = presel; + itemlist[itemcount].itemflags = itemflags; + itemlist[itemcount].count = -1L; itemlist[itemcount].color = -1; // Display the boulder symbol correctly if (str.left(8) == "boulder\t") { @@ -193,14 +210,15 @@ void NetHackQtMenuWindow::AddMenu(int glyph, const ANY_P* identifier, } } int mcolor, mattr; - if (attr == 0 + if (attr == 0 && ::iflags.use_menu_color && get_menu_coloring(str.toLatin1().constData(), &mcolor, &mattr)) { itemlist[itemcount].attr = mattr; itemlist[itemcount].color = mcolor; } ++itemcount; - if (glyph!=NO_GLYPH) has_glyphs=true; + if (glyph != NO_GLYPH) + has_glyphs = true; } void NetHackQtMenuWindow::EndMenu(const QString& p) @@ -215,136 +233,247 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) how=h; - ok->setEnabled(how!=PICK_ONE); ok->setDefault(how!=PICK_ONE); + int presel_ct = 0; + for (int i = 0; i < itemcount; ++i) + if (itemlist[i].preselected) + ++presel_ct; + bool ok_ok = (how != PICK_ONE || presel_ct == 1); + ok->setEnabled(ok_ok); ok->setDefault(ok_ok); cancel->setEnabled(true); - all->setEnabled(how==PICK_ANY); - none->setEnabled(how==PICK_ANY); - invert->setEnabled(how==PICK_ANY); - search->setEnabled(how!=PICK_NONE); + all->setEnabled(how == PICK_ANY || (how == PICK_ONE && itemcount == 1)); + none->setEnabled(how == PICK_ANY || (how == PICK_ONE && presel_ct == 1)); + invert->setEnabled(how == PICK_ANY || (how == PICK_ONE && itemcount == 1)); + search->setEnabled(how != PICK_NONE); setResult(-1); // Set contents of table QFontMetrics fm(table->font()); - for (int i = 0; i < 5; i++) { - table->setColumnWidth(i, 0); + for (int col = 0; col < 5; ++col) { + table->setColumnWidth(col, 0); } - for (int i = 0; i < itemcount; i++) { - AddRow(i, itemlist[i]); + // default height is way too big; rows end up being double-spaced with it + int rowheight = fm.height() * 3 / 5; + for (int row = 0; row < itemcount; ++row) { + AddRow(row, itemlist[row]); + table->setRowHeight(row, rowheight); } + PadMenuColumns(::iflags.menu_tab_sep ? true : false); -#define MENU_WIDTH_SLOP 10 /* this should not be necessary */ - // Determine column widths - std::vector col_widths; - for (std::size_t i = 0; i < (size_t) itemlist.size(); ++i) { - QStringList columns = itemlist[i].str.split("\t"); - if (!itemlist[i].Selectable() && columns.size() == 1) { - // Nonselectable line with no column dividers. - // Assume this is a section header - // or ordinary text (^X feedback, for instance) rendered in - // a menu because tty's paginated menus can be used to go - // backward, unlike text windows which can only go forward. - QTableWidgetItem *twi = table->item(i, 4); - if (twi) { - QString text = twi->text(); - WidenColumn(4, fm.width(text)); - } - continue; - } - for (std::size_t j = 0U; j < (size_t) columns.size(); ++j) { - int w = fm.width(columns[j] + " \t"); - if (j >= col_widths.size()) { - col_widths.push_back(w); - } else if (col_widths[j] < w) { - col_widths[j] = w; - } - } - } - - // Pad each column to its column width - for (std::size_t i = 0U; i < (size_t) itemlist.size(); ++i) { - QTableWidgetItem *twi = table->item(i, 4); - if (twi == NULL) { continue; } - QString text = twi->text(); - QStringList columns = text.split("\t"); - for (std::size_t j = 0U; j+1U < (size_t) columns.size(); ++j) { - columns[j] += "\t"; - int width = col_widths[j]; - while (fm.width(columns[j]) < width) { - columns[j] += "\t"; - } - } - text = columns.join(""); - twi->setText(text); - WidenColumn(4, fm.width(text) + MENU_WIDTH_SLOP); - } - - // FIXME: size for compact mode + //old FIXME: size for compact mode //resize(this->width(), parent()->height()*7/8); move(0, 0); adjustSize(); centerOnMain(this); - exec(); - int result=this->result(); - *menu_list=0; - if (result>0 && how!=PICK_NONE) { - if (how==PICK_ONE) { - int i; - for (i=0; iresult(); + + *menu_list = (MENU_ITEM_P *) 0; + if (result > 0 && how != PICK_NONE) { + int n = 0; + for (int i = 0; i < itemcount; ++i) + if (itemlist[i].selected) + ++n; + if (n) { + *menu_list = (MENU_ITEM_P *) alloc(n * sizeof(MENU_ITEM_P)); + n = 0; + for (int i = 0; i < itemcount; ++i) { + if (itemlist[i].selected) { + (*menu_list)[n].item = itemlist[i].identifier; + (*menu_list)[n].count = count(i); + ++n; + } + } + } + return n; } else { return -1; } } +// pad the menu columns so that they all line up +void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) +{ + QFontMetrics fm(table->font()); + QString col0width_str = ""; + if (biggestcount > 0L) + col0width_str.sprintf("%*ld", std::max(countdigits, 1), biggestcount); + int col0width_int = (int) fm.width(col0width_str) + MENU_WIDTH_SLOP; + if (col0width_int > table->columnWidth(0)) + WidenColumn(0, col0width_int); + + // If the description (column 4) is a tab separated list, split + // it into fields and figure out how wide each field should be. + // Needs to be done at most once for any given menu instantiation. + std::vector col_widths(1, 0); // start with 1 element init'd to 0 + if (split_descr) { + for (int row = 0; row < itemcount; ++row) { + QTableWidgetItem *twi = table->item(row, 4); // description + if (twi == NULL) + 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.width(columns[fld] + (lastcol ? "" : " ")); + if (fld >= (int) col_widths.size()) { + col_widths.push_back(w); // add another element + } else if (col_widths[fld] < w) { + col_widths[fld] = w; + } + } + } + } // split_descr + + // Reformat all counts so that they line up right justified and + // pad each field within description to fill that field's width. + int widest4 = 0; + for (int row = 0; row < (int) itemlist.size(); ++row) { + // column 0 (subset count); format as right-justified number + QTableWidgetItem *cnt = table->item(row, 0); + if (cnt != NULL) { + QString Amt = ""; + long amt = count(row); // fetch item(i,0) as a number + if (amt > 0L) + Amt.sprintf("%*ld", countdigits, amt); + cnt->setText(Amt); + } + + // column 4 (item description) + QTableWidgetItem *twi = table->item(row, 4); + if (twi == NULL) + continue; + QString text = twi->text(); + if (split_descr) { + QStringList columns = text.split("\t"); + for (int fld = 0; fld < (int) columns.size() - 1; ++fld) { + //columns[j] += "\t"; + int width = col_widths[fld]; + while (fm.width(columns[fld]) < width) + columns[fld] += " "; //"\t"; + } + text = columns.join(""); + twi->setText(text); + } + // TODO? if description needs to wrap, increase the height of this row + int wid = fm.width(text) + MENU_WIDTH_SLOP; + if (wid > widest4) + widest4 = wid; + } + if (widest4 > table->columnWidth(4)) + WidenColumn(4, widest4); +} + +// got a bigger count than previously; might need to widen column 0 +// (or possibly had all counts removed and need to shrink column 0) +void NetHackQtMenuWindow::UpdateCountColumn(long newcount) +{ + if (newcount < 0L) { + // this will happen if user clicks on [all],[none],[invert] buttons; + // they clear all pending counts while selecting or unselecting + biggestcount = 0L; + countdigits = 0; + table->setColumnWidth(0, 0); + WidenColumn(0, MENU_WIDTH_SLOP); + } else { + biggestcount = std::max(biggestcount, newcount); + QString num; + num.sprintf("%*ld", std::max(countdigits, 1), biggestcount); + int numlen = (int) num.length(); + if (numlen % 2) + ++numlen; + if (numlen <= countdigits) + return; + countdigits = numlen; + // FIXME: neither adjusting the table size (below) nor the + // menu widget size (also below) is making the menu widget + // bigger after the count column has been expanded + } + + PadMenuColumns(false); + + // Temporary? workaround for scrolling becoming wedged if using + // all/none/invert removes all counts so we narrow a non-empty + // count column to empty. [That can take away the horizontal + // scroll bar but should not be affecting the vertical one, yet + // is (Qt 5.11.3).] Typing any digit restored normal scrolling + // and the only significant thing about that is that it updates + // the prompt line which is outside the table of menu items where + // scrolling takes place. Oddly, both prompt changes are needed + // (possibly the unnecessary space in the first is being optimized + // away but the second call to remove it isn't aware of that). + prompt.setText(promptstr + " "); + prompt.setText(promptstr); + + // when this was just 'adjustSize()', our sizeHints() was not + // being called so explicitly indicate the table widget + table->adjustSize(); + this->adjustSize(); + table->repaint(); +} + +struct qcolor { + QColor q; + const char *nm; +}; +// these match the tty colors, or better versions of same; +// [0] is used for black, and [8] (the first white) corresponds to "no color" +static const struct qcolor colors[] = { + { QColor(64, 64, 64), "64,64,64" }, // black + { QColor(Qt::red), "red" }, + { QColor(0, 191, 0), "0,191,0" }, // green + { QColor(127, 127, 0), "127,127,0" }, // brownish + { QColor(Qt::blue), "blue" }, + { QColor(Qt::magenta), "magenta" }, + { QColor(Qt::cyan), "cyan" }, + { QColor(Qt::gray), "gray" }, + // on tty, the "light" variations are "bright" instead; here they're paler + { QColor(Qt::white), "white" }, // no-color, so not rendered + { QColor(255, 127, 0), "255,127,0" }, // orange + { QColor(127, 255, 127), "127,255,127" }, // light green + { QColor(Qt::yellow), "yellow" }, + { QColor(127, 127, 255), "127,127,255" }, // light blue + { QColor(255, 127, 255), "255,127,255" }, // light magenta + { QColor(127, 255, 255), "127,255,255" }, // light cyan + { QColor(Qt::white), "white" }, +}; + +#if 0 /* available for debugging */ +static const char *color_name(const QColor q) +{ + for (int i = 0; i < SIZE(colors); ++i) + if (q == colors[i].q) + return colors[i].nm; + // these are all the enum GlobalColor values ; + // black and white have been moved in front of color0 and color1 here + const char *nm = (q == Qt::black) ? "black" + : (q == Qt::white) ? "white" + : (q == Qt::color0) ? "color0" // doesn't duplicate white? + : (q == Qt::color1) ? "color1" // does duplicate black + : (q == Qt::darkGray) ? "darkGray" + : (q == Qt::gray) ? "gray" + : (q == Qt::lightGray) ? "lightGray" + : (q == Qt::red) ? "red" + : (q == Qt::green) ? "green" + : (q == Qt::blue) ? "blue" + : (q == Qt::cyan) ? "cyan" + : (q == Qt::magenta) ? "magenta" + : (q == Qt::yellow) ? "yellow" + : (q == Qt::darkRed) ? "darkRed" + : (q == Qt::darkGreen) ? "darkGreen" + : (q == Qt::darkBlue) ? "darkBlue" + : (q == Qt::darkCyan) ? "darkCyan" + : (q == Qt::darkMagenta) ? "darkMagenta" + : (q == Qt::darkYellow) ? "darkYellow" + : (q == Qt::transparent) ? "transparent" + : "other"; + return nm; +} +#endif + void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) { - static const QColor colors[] = { - QColor(64, 64, 64), - QColor(Qt::red), - QColor(0, 191, 0), - QColor(127, 127, 0), - QColor(Qt::blue), - QColor(Qt::magenta), - QColor(Qt::cyan), - QColor(Qt::gray), - QColor(Qt::white), - QColor(255, 127, 0), - QColor(127, 255, 127), - QColor(Qt::yellow), - QColor(127, 127, 255), - QColor(255, 127, 255), - QColor(127, 255, 255), - QColor(Qt::white) - }; QFontMetrics fm(table->font()); QTableWidgetItem *twi; @@ -353,13 +482,19 @@ void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) twi = new QTableWidgetItem(""); table->setItem(row, 0, twi); twi->setFlags(Qt::ItemIsEnabled); - WidenColumn(0, fm.width("999999")); - // Check box, set if selected +#if 0 // active count field now widened as needed rather than preset + WidenColumn(0, fm.width("999999") + MENU_WIDTH_SLOP); +#else + WidenColumn(0, MENU_WIDTH_SLOP); +#endif + + // Check box, set if pre-selected QCheckBox *cb = new QCheckBox(); - cb->setChecked(mi.selected); + cb->setChecked(mi.preselected ? Qt::Checked : Qt::Unchecked); cb->setFocusPolicy(Qt::NoFocus); - if (how == PICK_ONE) - connect(cb, SIGNAL(clicked(bool)), this, SLOT(DoSelection(bool))); + // CheckboxClicked() will call ToggleSelect() for item whose checkbox + // gets clicked upon + connect(cb, SIGNAL(clicked(bool)), this, SLOT(CheckboxClicked(bool))); table->setCellWidget(row, 1, cb); WidenColumn(1, cb->width()); } @@ -371,12 +506,12 @@ void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) twi->setFlags(Qt::ItemIsEnabled); WidenColumn(2, pm.width()); } + QString letter, text(mi.str); if (mi.ch != 0) { // Letter specified letter = QString(mi.ch) + " - "; - } - else { + } else { // Letter is left blank, except for skills display when # and * are // presented if (text.startsWith(" ")) { @@ -393,47 +528,54 @@ void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) table->setItem(row, 3, twi); table->item(row, 3)->setFlags(Qt::ItemIsEnabled); WidenColumn(3, fm.width(letter)); + twi = new QTableWidgetItem(text); table->setItem(row, 4, twi); table->item(row, 4)->setFlags(Qt::ItemIsEnabled); WidenColumn(4, fm.width(text)); if ((int) mi.color != -1) { - twi->setForeground(colors[mi.color]); + twi->setForeground(colors[mi.color].q); } - QFont itemfont(table->font()); - switch (mi.attr) { - case ATR_BOLD: - itemfont.setWeight(QFont::Bold); - twi->setFont(itemfont); - break; - - case ATR_DIM: - twi->setFlags(Qt::NoItemFlags); - break; - - case ATR_ULINE: - itemfont.setUnderline(true); - twi->setFont(itemfont); - break; - - case ATR_INVERSE: - { - QBrush fg = twi->foreground(); - QBrush bg = twi->background(); - if (fg == bg) { - // default foreground and background come up the same for - // some unknown reason - twi->setForeground(Qt::white); - twi->setBackground(Qt::black); - } else { - twi->setForeground(bg); - twi->setBackground(fg); - } - } - break; - } + if (mi.attr != ATR_NONE) { + QFont itemfont(table->font()); + switch (mi.attr) { + case ATR_BOLD: + itemfont.setWeight(QFont::Bold); + twi->setFont(itemfont); + break; + case ATR_DIM: + twi->setFlags(Qt::NoItemFlags); + break; + case ATR_ULINE: + itemfont.setUnderline(true); + twi->setFont(itemfont); + break; + case ATR_INVERSE: { + QBrush fg = twi->foreground(); + QBrush bg = twi->background(); + if (fg.color() == bg.color()) { + // default foreground and background come up the same for + // some unknown reason + //[pr: both are set to 'Qt::color1' which has same RGB + // value as 'Qt::black'; X11 on OSX behaves similarly] + if (fg.color() == Qt::color1) { + fg = Qt::black; + bg = Qt::white; + } else { + fg = (bg.color() == Qt::white) ? Qt::black : Qt::white; + } + } + twi->setForeground(bg); + twi->setBackground(fg); + break; + } + case ATR_BLINK: + // not supported + break; + } /* switch */ + } /* if mi.attr != ATR_NONE */ } void NetHackQtMenuWindow::WidenColumn(int column, int width) @@ -447,18 +589,14 @@ void NetHackQtMenuWindow::WidenColumn(int column, int width) void NetHackQtMenuWindow::InputCount(char key) { - if (key == '\b') - { - if (counting) - { + if (key == '\b' || key == '\177') { + if (counting) { if (countstr.isEmpty()) ClearCount(); else countstr = countstr.mid(0, countstr.size() - 1); } - } - else - { + } else { counting = true; countstr += QChar(key); } @@ -473,162 +611,260 @@ void NetHackQtMenuWindow::ClearCount(void) countstr = ""; } -void NetHackQtMenuWindow::keyPressEvent(QKeyEvent* event) +void NetHackQtMenuWindow::keyPressEvent(QKeyEvent *key_event) { - QString text = event->text(); + // key_event manipulation derived from NetHackQtBind::notify() + const int k = key_event->key(); + Qt::KeyboardModifiers mod = key_event->modifiers(); + QChar ch = !key_event->text().isEmpty() ? key_event->text().at(0) : 0; + if (ch > 128) + ch = 0; + // on OSX, ascii control codes are not sent, force them + if (ch == 0 && (mod & Qt::ControlModifier) != 0) { + if (k >= Qt::Key_A && k <= Qt::Key_Underscore) + ch = (QChar) (k - (Qt::Key_A - 1)); + } + uchar key = (char) ch.cell(); - const QChar *uni = text.unicode(); - for (unsigned k = 0; uni[k] != 0; k++) { - unsigned key = uni[k].unicode(); - if (key=='\033') { - if (counting) - ClearCount(); - else - reject(); - } else if (key=='\r' || key=='\n' || key==' ') - accept(); - else if (key==MENU_SEARCH) - Search(); - else if (key==MENU_SELECT_ALL || key==MENU_SELECT_PAGE) - All(); - else if (key==MENU_INVERT_ALL || key==MENU_INVERT_PAGE) - Invert(); - else if (key==MENU_UNSELECT_ALL || key==MENU_UNSELECT_PAGE) - ChooseNone(); - else if (('0' <= key && key <= '9') || key == '\b') - InputCount(key); - else { - for (int i=0; iitem(i, 0); - if (count != NULL) count->setText(""); + if (counting) + ClearCount(); // discard any pending count + for (int row = 0; row < itemcount; ++row) { + itemlist[row].selected = itemlist[row].preselected = false; + if (!itemlist[row].Selectable()) + continue; + itemlist[row].selected = true; - QCheckBox *cb = dynamic_cast(table->cellWidget(i, 1)); - if (cb != NULL) { - cb->setChecked(true); - didcheck = true; + QTableWidgetItem *count = table->item(row, 0); + if (count != NULL) { + count->setText(""); + } + QCheckBox *cb = dynamic_cast (table->cellWidget(row, 1)); + if (cb != NULL) { + cb->setChecked(Qt::Checked); } } - if (didcheck) + if (biggestcount > 0L) { // counts got cleared when entries became checked + UpdateCountColumn(-1L); + } else { table->repaint(); + } } + void NetHackQtMenuWindow::ChooseNone() { - if (how != PICK_ANY) + if (how == PICK_NONE) return; - bool diduncheck = false; - for (int i=0; iitem(i, 0); - if (count != NULL) count->setText(""); - - QCheckBox *cb = dynamic_cast(table->cellWidget(i, 1)); - if (cb != NULL) { - cb->setChecked(false); - diduncheck = true; - } - } - if (diduncheck) - table->repaint(); -} -void NetHackQtMenuWindow::Invert() -{ - if (how != PICK_ANY) - return; - - boolean didtoggle = false; - for (int i=0; iitem(i, 0); - if (count != NULL) count->setText(""); - - QCheckBox *cb = dynamic_cast(table->cellWidget(i, 1)); - if (cb != NULL) { - cb->setChecked(cb->checkState() == Qt::Unchecked); - didtoggle = true; + QTableWidgetItem *count = table->item(row, 0); + if (count != NULL) { + count->setText(""); + } + QCheckBox *cb = dynamic_cast (table->cellWidget(row, 1)); + if (cb != NULL) { + cb->setChecked(Qt::Unchecked); } } - if (didtoggle) + if (biggestcount > 0L) { // all counts have been removed + UpdateCountColumn(-1L); + } else { table->repaint(); + } } + +void NetHackQtMenuWindow::Invert() +{ + if (how == PICK_NONE) + return; + + if (counting) + ClearCount(); // discard any pending count + for (int row = 0; row < itemcount; ++row) { + if (!menuitem_invert_test(0, itemlist[row].itemflags, + itemlist[row].preselected)) + continue; + ToggleSelect(row, false); + } + if (biggestcount > 0L) { // all entries with counts are now unchecked + UpdateCountColumn(-1L); + } else { + table->repaint(); + } +} + void NetHackQtMenuWindow::Search() { if (how == PICK_NONE) return; + searching = true; NetHackQtStringRequestor requestor(this, "Search for:"); char line[256]; line[0] = '\0'; /* for EDIT_GETLIN */ if (requestor.Get(line)) { for (int i=0; i(table->cellWidget(i, 1)); - if (cb == NULL) return; + searching = false; +} - cb->setChecked((counting && !countstr.isEmpty()) - || cb->checkState() == Qt::Unchecked); +void NetHackQtMenuWindow::ToggleSelect(int row, bool already_checked) +{ + if (itemlist[row].Selectable()) { + QCheckBox *cb = dynamic_cast (table->cellWidget(row, 1)); + if (cb == NULL) + return; - QTableWidgetItem *count = table->item(i, 0); - if (count != NULL) count->setText(countstr); - - ClearCount(); - - if (how==PICK_ONE) { - accept(); + if (how == PICK_ONE) { + // explicitly picking a preselected item in a pick-one menu + // chooses that item rather than toggling preselection off; + // by clearing whole menu, the code below will select item #i + ChooseNone(); + already_checked = false; + // FIXME? this won't handle a pending count properly; + // are there any pick-one menus with preselected choice + // where a count is useful? } else { + itemlist[row].preselected = false; // flag is now out-of-date + } + + QTableWidgetItem *countfield = table->item(row, 0); + if (!counting) { + if (!already_checked) + cb->setChecked((cb->checkState() == Qt::Unchecked) // toggle + ? Qt::Checked : Qt::Unchecked); + itemlist[row].selected = (cb->checkState() != Qt::Unchecked); + if (countfield != NULL) + countfield->setText(""); + } else { + long amt = 1L; + if (countfield != NULL) { + countfield->setText(countstr); // store in item(row,0) + amt = count(row); // fetch item(row,0) as a number + QString Amt = ""; + if (amt > 0L) + Amt.sprintf("%*ld", countdigits, amt); + countfield->setText(Amt); // store right-justified value + } + ClearCount(); // blank out 'countstr' and reset 'counting' + + // TODO: use a custom icon for check mark, like tty's '#' vs '+' + // [maybe not necessary since unlike tty menus, count is visible] + + // uncheck if count is explicitly 0, otherwise check + cb->setChecked((amt > 0L) ? Qt::Checked : Qt::Unchecked); + itemlist[row].selected = (cb->checkState() != Qt::Unchecked); + + // if this count is larger than the biggest we've seen + // so far, it might need more digits to render; if so, + // all pending counts should be reformatted with new width + if (amt > biggestcount) + UpdateCountColumn(amt); + } + + if (how == PICK_ONE && isSelected(row)) + accept(); + else table->repaint(); + } +} + +// table cell click handler for cells (*,col) where col != 1 +void NetHackQtMenuWindow::TableCellClicked(int row, int col UNUSED) +{ + ToggleSelect(row, false); +} + +// checkbox click handler for table cells (*,1); +// presence of a checkbox in the clicked cell prevents the table cell click +// handler above from being called even if this handler doesn't get set up +void NetHackQtMenuWindow::CheckboxClicked(bool on_off UNUSED) +{ + // find which checkbox just got toggled by looking for one whose + // check state doesn't match corresponding itemlist[].selected flag + // [there's got to be a more direct way of achieving this...] + for (int row = 0; row < itemcount; ++row) { + // for pick-one menu, ToggleSelect() will return to menu's caller + if (itemlist[row].Selectable()) { + if (!isSelected(row) ^ !itemlist[row].selected) { + // signal dispatcher has already checked or unchecked this box + ToggleSelect(row, true); + return; + } } } -} - -void NetHackQtMenuWindow::cellToggleSelect(int i, int j UNUSED) -{ - ToggleSelect(i); -} - -void NetHackQtMenuWindow::DoSelection(bool) -{ - if (how == PICK_ONE) { - accept(); - } + // didn't find any changed checkbox; should never happen; what to do? } bool NetHackQtMenuWindow::isSelected(int row) { - QCheckBox *cb = dynamic_cast(table->cellWidget(row, 1)); - return cb != NULL && cb->checkState() != Qt::Unchecked; + QCheckBox *cb = dynamic_cast (table->cellWidget(row, 1)); + return cb ? (cb->checkState() != Qt::Unchecked) : false; } -int NetHackQtMenuWindow::count(int row) +// convert text count to numeric for final result +long NetHackQtMenuWindow::count(int row) { QTableWidgetItem *count = table->item(row, 0); - if (count == NULL) return -1; + if (count == NULL) + return -1L; QString cstr = count->text(); - return cstr.isEmpty() ? -1 : cstr.toInt(); + return cstr.isEmpty() ? -1L : cstr.toLong(); } NetHackQtTextWindow::NetHackQtTextWindow(QWidget *parent) : diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index 7aa5c2b8d..a6aadf51c 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -10,6 +10,9 @@ #include "qt_win.h" #include "qt_rip.h" +// some menu fields aren't wide enough even though sized for measured text +#define MENU_WIDTH_SLOP 10 /* this should not be necessary */ + namespace nethack_qt_ { class NetHackQtTextListBox : public QListWidget { @@ -54,8 +57,9 @@ public: virtual QWidget* Widget(); virtual void StartMenu(); - virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, unsigned itemflags); + virtual void AddMenu(int glyph, const ANY_P *identifier, + char ch, char gch, int attr, + const QString& str, unsigned itemflags); virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); @@ -65,9 +69,9 @@ public slots: void Invert(); void Search(); - void ToggleSelect(int); - void cellToggleSelect(int, int); - void DoSelection(bool); + void ToggleSelect(int row, bool alyready_checked); + void TableCellClicked(int row, int col); + void CheckboxClicked(bool on_off); protected: virtual void keyPressEvent(QKeyEvent*); @@ -81,10 +85,11 @@ private: ANY_P identifier; int attr; QString str; - int count; + long count; char ch; char gch; - bool selected; + bool selected; // True if checkbox is set + bool preselected; // True if caller told us to set checkbox unsigned itemflags; unsigned color; @@ -108,19 +113,25 @@ private: // Count replaces prompt while it is being input QString promptstr; QString countstr; - bool counting; + long biggestcount; // determines width of field #0 + int countdigits; // number of digits to format biggestcount + bool counting; // in midst of entering a count + bool searching; // in midst of entering a search string void InputCount(char key); void ClearCount(void); - int how; - - bool has_glyphs; + int how; // pick-none, pick-one, pick-any + bool has_glyphs; // at least one item specified a glyph bool isSelected(int row); - int count(int row); + long count(int row); void AddRow(int row, const MenuItem& mi); void WidenColumn(int column, int width); + void PadMenuColumns(bool split_descr); + void UpdateCountColumn(long newcount); + + void ClearSearch(); }; class NetHackQtTextWindow : public QDialog, public NetHackQtWindow { @@ -172,8 +183,9 @@ public: // Menu virtual void StartMenu(); - virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, unsigned itemflags); + virtual void AddMenu(int glyph, const ANY_P *identifier, + char ch, char gch, int attr, + const QString& str, unsigned itemflags); virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); From 82689eb048e3bc934da389a00b2d85f295e7b840 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Sep 2020 02:49:37 -0700 Subject: [PATCH 202/708] silence a Qt complaint The save file selection widget was issuing a complaint to stderr: |QLayout: Attempting to add QLayout "" to QDialog "", which already | has a layout This shuts that up, but doesn't fix the broken save file selection so I haven't added a fixes37.0 entry. --- win/Qt/Qt-issues.txt | 21 +++++++++++++-------- win/Qt/qt_svsel.cpp | 32 +++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index a4405b4a7..612180399 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -40,16 +40,21 @@ On the map, ^V is a dead key (at least on OSX; all other ASCII control characters from ^A through ^U, ^W through ^Z, and ^[, ^\, ^], ^^, ^_ work; no attempt to have ^@ generate NUL has been made). -The save file selection widget at start of game issues a complaint to -stderr about adding a layout to a dialog which already has a layout, -similar to ones that YnDialog used to give for the count widget in -yn#aq dialogs. (That was resolved by inserting count in the middle -instead of trying to append to the end [without figuring out why Qt -was complaining--no doubt a Qt 2/3/4/5 issue], which is not a viable -solution for save file selection.) It also clobbers an existing save -file if you use a different name when starting a new game, then save. +The save file selection widget writes all the file name selection +buttons on top of each other, with the last one added being the only +one visible. Clicking on it seems to be picking the first one instead. +If you pick "new game" and use a different character name then +eventually save, it clobbers the last one in the list (rather, warns +the player that a save file exists and asks whether to overwrite it; +answering yes and then loading the file shows the new character, not +the original one even though the file is still named for that one). 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. + +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_svsel.cpp b/win/Qt/qt_svsel.cpp index f11562c68..11cec2c61 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -26,24 +26,31 @@ NetHackQtSavedGameSelector::NetHackQtSavedGameSelector(const char** saved) : QVBoxLayout *vbl = new QVBoxLayout(this); QHBoxLayout* hb; - QLabel* logo = new QLabel(this); vbl->addWidget(logo); +#if 0 // this works but don't add it until the rest is working as intended + char cvers[BUFSZ]; + QString qvers = QString("NetHack ") + QString(version_string(cvers)); + QLabel* vers = new QLabel(qvers, this); + vers->setAlignment(Qt::AlignCenter); + vbl->addWidget(vers); +#endif + + QLabel* logo = new QLabel(this); logo->setAlignment(Qt::AlignCenter); logo->setPixmap(QPixmap("nhsplash.xpm")); + vbl->addWidget(logo); + QLabel* attr = new QLabel("by the NetHack DevTeam",this); attr->setAlignment(Qt::AlignCenter); vbl->addWidget(attr); vbl->addStretch(2); - /* - QLabel* logo = new QLabel(hb); - hb = new QHBox(this); - vbl->addWidget(hb, Qt::AlignCenter); - logo->setPixmap(QPixmap(nh_icon)); - logo->setAlignment(AlignRight|Qt::AlignVCenter); - new QLabel(nh_attribution,hb); - */ + /* With Qt5, this next line triggers a complaint to stderr: +QLayout: Attempting to add QLayout "" to QDialog "", which already has a layout hb = new QHBoxLayout(this); + */ + hb = new QHBoxLayout((QWidget *) NULL); vbl->addLayout(hb, Qt::AlignCenter); + QPushButton* q = new QPushButton("Quit",this); hb->addWidget(q); connect(q, SIGNAL(clicked()), this, SLOT(reject())); @@ -52,6 +59,13 @@ NetHackQtSavedGameSelector::NetHackQtSavedGameSelector(const char** saved) : connect(c, SIGNAL(clicked()), this, SLOT(accept())); c->setDefault(true); + // + // FIXME! + // The text "Saved Characters" is overwritten by all the + // filename buttons. The last button added is the only one + // visible but clicking on it seems to activate the first + // one instead. + // QGroupBox* box = new QGroupBox("Saved Characters",this); QButtonGroup *bg = new QButtonGroup(this); vbl->addWidget(box); From 4acdbaaf72d75d728813fa21043da167d2dcbf54 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Sep 2020 10:47:33 -0700 Subject: [PATCH 203/708] more Qt menu The #enhance menu revealed a couple of menu problems for Qt. Items flagged with "*" or "#" were showing tiny "..." instead of the flag character. An existing problem rather than something caused by yesterday's overhaul patch. The "(Skills flagged by "*" may be enhanced when you're more experienced.)" legend line was causing the regular entries to be formatted strangely (their skill name column was much too wide). That was caused by me dropping something (special case for header lines during tab-separation handling) in yesterday's patch that I mistakenly thought wasn't needed. --- win/Qt/qt_menu.cpp | 42 +++++++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index d14f19338..1da9426d7 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -312,6 +312,11 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) QTableWidgetItem *twi = table->item(row, 4); // description if (twi == NULL) continue; + // if a header/footnote/&c with no sub-fields, don't inflate + // the size of col_widths[0] + if (!itemlist[row].Selectable() + && !itemlist[row].str.contains(QChar('\t'))) + 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) { @@ -334,7 +339,7 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) QTableWidgetItem *cnt = table->item(row, 0); if (cnt != NULL) { QString Amt = ""; - long amt = count(row); // fetch item(i,0) as a number + long amt = count(row); // fetch item(row,0) as a number if (amt > 0L) Amt.sprintf("%*ld", countdigits, amt); cnt->setText(Amt); @@ -348,7 +353,7 @@ void NetHackQtMenuWindow::PadMenuColumns(bool split_descr) if (split_descr) { QStringList columns = text.split("\t"); for (int fld = 0; fld < (int) columns.size() - 1; ++fld) { - //columns[j] += "\t"; + //columns[fld] += "\t"; /* (used to pad with tabs) */ int width = col_widths[fld]; while (fm.width(columns[fld]) < width) columns[fld] += " "; //"\t"; @@ -513,7 +518,7 @@ void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) letter = QString(mi.ch) + " - "; } else { // Letter is left blank, except for skills display when # and * are - // presented + // presented (note: they're just displayed, not become selectors) if (text.startsWith(" ")) { // If mi.str starts with " ", it's meant to line up with lines // that have a letter; we don't want that here @@ -527,7 +532,14 @@ void NetHackQtMenuWindow::AddRow(int row, const MenuItem& mi) twi = new QTableWidgetItem(letter); table->setItem(row, 3, twi); table->item(row, 3)->setFlags(Qt::ItemIsEnabled); - WidenColumn(3, fm.width(letter)); + // add extra padding because the measured width comes out too narrow; + // for the normal case of "a - ", the trailing space hid the fact that + // the column wasn't wide enough for four characters; for the " #" + // and " *" cases, the last character was replaced by very tiny "..." + int w = (int) fm.width(letter); + if (w) + w += MENU_WIDTH_SLOP / 2; + WidenColumn(3, w); twi = new QTableWidgetItem(text); table->setItem(row, 4, twi); @@ -685,8 +697,8 @@ void NetHackQtMenuWindow::All() cb->setChecked(Qt::Checked); } } - if (biggestcount > 0L) { // counts got cleared when entries became checked - UpdateCountColumn(-1L); + if (biggestcount > 0L) { // had one or more counts + UpdateCountColumn(-1L); // all counts are now gone } else { table->repaint(); } @@ -713,8 +725,8 @@ void NetHackQtMenuWindow::ChooseNone() cb->setChecked(Qt::Unchecked); } } - if (biggestcount > 0L) { // all counts have been removed - UpdateCountColumn(-1L); + if (biggestcount > 0L) { // had one or more counts + UpdateCountColumn(-1L); // all counts are now gone } else { table->repaint(); } @@ -733,8 +745,8 @@ void NetHackQtMenuWindow::Invert() continue; ToggleSelect(row, false); } - if (biggestcount > 0L) { // all entries with counts are now unchecked - UpdateCountColumn(-1L); + if (biggestcount > 0L) { // had one or more counts + UpdateCountColumn(-1L); // all counts are now gone } else { table->repaint(); } @@ -747,7 +759,7 @@ void NetHackQtMenuWindow::Search() searching = true; NetHackQtStringRequestor requestor(this, "Search for:"); - char line[256]; + char line[BUFSZ]; line[0] = '\0'; /* for EDIT_GETLIN */ if (requestor.Get(line)) { for (int i=0; i (table->cellWidget(row, 1)); @@ -773,9 +785,9 @@ void NetHackQtMenuWindow::ToggleSelect(int row, bool already_checked) if (how == PICK_ONE) { // explicitly picking a preselected item in a pick-one menu // chooses that item rather than toggling preselection off; - // by clearing whole menu, the code below will select item #i + // by clearing whole menu, the code below will select item #row ChooseNone(); - already_checked = false; + already_toggled = false; // FIXME? this won't handle a pending count properly; // are there any pick-one menus with preselected choice // where a count is useful? @@ -785,7 +797,7 @@ void NetHackQtMenuWindow::ToggleSelect(int row, bool already_checked) QTableWidgetItem *countfield = table->item(row, 0); if (!counting) { - if (!already_checked) + if (!already_toggled) cb->setChecked((cb->checkState() == Qt::Unchecked) // toggle ? Qt::Checked : Qt::Unchecked); itemlist[row].selected = (cb->checkState() != Qt::Unchecked); From 7592eebdf6f08a07dceaffd49dfc51c6e6cab3d4 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Sep 2020 19:02:23 -0700 Subject: [PATCH 204/708] another Qt "issue" --- win/Qt/Qt-issues.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index 612180399..19b446704 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -57,4 +57,9 @@ intended to be displayed, is displayed (as blank terrain). 3.6 status conditions (Stone, Slime, Strngl, Deaf, Lev, Fly, Ride) have been implemented but need icon artwork (one 40x40 tile for each). +Qt menus which can execute nethack commands do so by stuffing command +keystrokes into the input buffer. If player's run-time config file +has BIND directives after windowtype:Qt (or anywhere if Qt is chosen +by default), menus aren't updated to use the new key assignments. + ----- From 81ec2bfa2a8fe71c60b55a706ed25e2af0b803e0 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Sep 2020 15:34:29 -0700 Subject: [PATCH 205/708] pull request #386 - discovering teleport scroll Since teleporation gives a "you matrialize" message even when arriving close by, the old behavior of not learning a scroll of teleportation when you land quite close to your original spot no longer made sense. Always [almost] discover teleport scroll when reading it. Also adds one-shot teleport control when reading a blessed scroll of teleportation. I changed that to be prevented when hero is stunned, same as with full-fledged teleport control. I reworded or reformatted several of the comments. And removed the EDITLEVEL increment in patchlevel.h; save and bones file contents are not affected. I've also added an unrelated comment about reading mechanics to doread(). Closes #386 --- doc/fixes37.0 | 5 +++- include/decl.h | 3 +-- include/extern.h | 4 ++-- src/decl.c | 3 +-- src/read.c | 28 ++++++++++++++++++++-- src/teleport.c | 62 +++++++++++++++++++----------------------------- 6 files changed, 59 insertions(+), 46 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4e7535c4d..f51073320 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.302 $ $NHDT-Date: 1600179998 2020/09/15 14:26:38 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.303 $ $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ General Fixes and Modified Features ----------------------------------- @@ -330,6 +330,8 @@ change default for lit attribute in special level des.terrain directives to 'unchanged' instead of 'unlit' replace worm tail placement code that reportedly led to a sanity_check warning [no actual code problem found; might be compiler bug for 'xchar'] +learn scroll of teleportation after reading even when random destination is + right by starting spot curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support @@ -524,6 +526,7 @@ add section marker [] support to run-time config file; CHOOSE section1,section2 for the remainder of the file render the color names in the corresponding color when using the pick-a-color menu for adding status highlights or menu colors via 'O' +reading blessed scroll of teleportation confers one-shot teleport control Platform- and/or Interface-Specific New Features diff --git a/include/decl.h b/include/decl.h index 453b450ae..be1d583ac 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.241 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.242 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1147,7 +1147,6 @@ struct instance_globals { unsigned int stealmid; /* monster doing the stealing */ /* teleport.c */ - struct obj *telescroll; /* non-null when teleporting via this scroll */ /* timeout.c */ /* ordered timer list */ diff --git a/include/extern.h b/include/extern.h index c1f2ae298..121117674 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.856 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.857 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2586,7 +2586,7 @@ E void FDECL(teleds, (int, int, int)); E boolean FDECL(safe_teleds, (int)); E boolean FDECL(teleport_pet, (struct monst *, BOOLEAN_P)); E void NDECL(tele); -E boolean FDECL(scrolltele, (struct obj *)); +E void FDECL(scrolltele, (struct obj *)); E int NDECL(dotelecmd); E int FDECL(dotele, (BOOLEAN_P)); E void NDECL(level_tele); diff --git a/src/decl.c b/src/decl.c index 7bcf2501a..4c836bbde 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1599778430 2020/09/10 22:53:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.217 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1600468453 2020/09/18 22:34:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.218 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -646,7 +646,6 @@ const struct instance_globals g_init = { 0, /* stealmid */ /* teleport.c */ - NULL, /* telescroll */ /* timeout.c */ UNDEFINED_PTR, /* timer_base */ diff --git a/src/read.c b/src/read.c index fb2c1ced1..42b1040a2 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1596498202 2020/08/03 23:43:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.201 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1600468453 2020/09/18 22:34:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -217,9 +217,27 @@ doread() register struct obj *scroll; boolean confused, nodisappear; + /* + * Reading while blind is allowed in most cases, including the + * Book of the Dead but not regular spellbooks. For scrolls, the + * description has to have been seen or magically learned (so only + * when scroll->dknown is true): hero recites the label while + * holding the unfurled scroll. We deliberately don't require + * free hands because that would cripple scroll of remove curse, + * but we ought to be requiring hands or at least limbs. The + * recitation could be sub-vocal; actual speech isn't required. + * + * Reading while confused is allowed and can produce alternate + * outcome. + * + * Reading while stunned is currently allowed but probably should + * be prevented.... + */ + g.known = FALSE; if (check_capacity((char *) 0)) return 0; + scroll = getobj(readable, "read"); if (!scroll) return 0; @@ -1358,8 +1376,14 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ case SCR_TELEPORTATION: if (confused || scursed) { level_tele(); + /* gives "materialize on different/same level!" message, must + be a teleport scroll */ + g.known = TRUE; } else { - g.known = scrolltele(sobj); + scrolltele(sobj); + /* this will call learnscroll() as appropriate, and has results + which maybe shouldn't result in the scroll becoming known; + either way, no need to set g.known here */ } break; case SCR_GOLD_DETECTION: diff --git a/src/teleport.c b/src/teleport.c index 9f291af99..f51001a7e 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 teleport.c $NHDT-Date: 1596498216 2020/08/03 23:43:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.126 $ */ +/* NetHack 3.7 teleport.c $NHDT-Date: 1600468454 2020/09/18 22:34:14 $ $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. */ @@ -401,15 +401,6 @@ int teleds_flags; been updated for new location instead of right after u_on_newpos() */ if (levl[u.ux][u.uy].typ != levl[u.ux0][u.uy0].typ) switch_terrain(); - if (g.telescroll) { - /* when teleporting by scroll, we need to handle discovery - now before getting feedback about any objects at our - destination since we might land on another such scroll */ - if (distu(u.ux0, u.uy0) >= 16 || !couldsee(u.ux0, u.uy0)) - learnscroll(g.telescroll); - else - g.telescroll = 0; /* no discovery by scrolltele()'s caller */ - } /* sequencing issue: we want guard's alarm, if any, to occur before room entry message, if any, so need to check for vault exit prior to spoteffects; but spoteffects() sets up new value for u.urooms @@ -493,26 +484,22 @@ boolean force_it; void tele() { - (void) scrolltele((struct obj *) 0); + scrolltele((struct obj *) 0); } -/* teleport the hero; return true if scroll of teleportation should become - discovered; teleds() will usually do the actual discovery, since the - outcome sometimes depends upon destination and discovery needs to be - performed before arrival, in case we land on another teleport scroll */ -boolean +/* teleport the hero; usually discover scroll of teleporation if via scroll */ +void scrolltele(scroll) struct obj *scroll; { coord cc; - boolean result = FALSE; /* don't learn scroll */ /* Disable teleportation in stronghold && Vlad's Tower */ - if (noteleport_level(&g.youmonst)) { - if (!wizard) { - pline("A mysterious force prevents you from teleporting!"); - return TRUE; - } + if (noteleport_level(&g.youmonst) && !wizard) { + pline("A mysterious force prevents you from teleporting!"); + if (scroll) + learnscroll(scroll); /* this is obviously a teleport scroll */ + return; } /* don't show trap if "Sorry..." */ @@ -521,11 +508,13 @@ struct obj *scroll; if ((u.uhave.amulet || On_W_tower_level(&u.uz)) && !rn2(3)) { You_feel("disoriented for a moment."); + /* don't discover the scroll [at least not yet for wizard override]; + disorientation doesn't reveal that this is a teleport attempt */ if (!wizard || yn("Override?") != 'y') - return FALSE; + return; } - if ((Teleport_control && !Stunned) || (scroll && scroll->blessed) - || wizard) { + if (((Teleport_control || (scroll && scroll->blessed)) && !Stunned) + || wizard) { if (unconscious()) { pline("Being unconscious, you cannot control your teleport."); } else { @@ -535,32 +524,31 @@ struct obj *scroll; if (u.usteed) Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed)); pline("Where do %s want to be teleported?", whobuf); + if (scroll) + learnscroll(scroll); cc.x = u.ux; cc.y = u.uy; if (getpos(&cc, TRUE, "the desired position") < 0) - return TRUE; /* abort */ + return; /* abort */ /* possible extensions: introduce a small error if magic power is low; allow transfer to solid rock */ if (teleok(cc.x, cc.y, FALSE)) { /* for scroll, discover it regardless of destination */ - if (scroll) - learnscroll(scroll); teleds(cc.x, cc.y, TELEDS_TELEPORT); - return TRUE; + return; } pline("Sorry..."); - result = TRUE; } } - g.telescroll = scroll; + /* we used to suppress discovery if hero teleported to a nearby + spot which was already within view, but now there is always a + "materialize" message regardless of how far you teleported so + discovery of scroll type is unconditional */ + if (scroll) + learnscroll(scroll); + (void) safe_teleds(TELEDS_TELEPORT); - /* teleds() will leave g.telescroll intact iff random destination - is far enough away for scroll discovery to be warranted */ - if (g.telescroll) - result = TRUE; - g.telescroll = 0; /* reset */ - return result; } /* ^T command; 'm ^T' == choose among several teleport modes */ From 239620ffd713802497b432f1495c1bb9634a89af Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Sep 2020 15:53:43 -0700 Subject: [PATCH 206/708] fix pull request #386 - monster interaction The previous teleport scroll fix was mislabeled with this pull request number. Too late to fix that now; should have been Closes #307 Now... Interaction between voluntarily busy hero (resting, searching, and so on) with approaching monsters to decide whether to stop had some inconsistencies. Really closes #386 --- doc/fixes37.0 | 3 ++- src/hack.c | 8 ++++---- src/monmove.c | 14 ++++++++------ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f51073320..481ba0066 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.303 $ $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ $NHDT-Date: 1600469617 2020/09/18 22:53:37 $ General Fixes and Modified Features ----------------------------------- @@ -250,6 +250,7 @@ end of game inventory disclosure passed an inappropriate argument to the turning into slime rendered hero as slime one turn too soon avoid potential infinite loop if hangup occurs at ring "right or left?" prompt randomize the turns where accessories and extrinsics affect nutrition +handle being interrupted by approaching monsters more consistently Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/hack.c b/src/hack.c index 583689adf..941643a12 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1596498171 2020/08/03 23:42:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.267 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1600469617 2020/09/18 22:53:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.268 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2971,10 +2971,10 @@ monster_nearby() continue; if ((mtmp = m_at(x, y)) && M_AP_TYPE(mtmp) != M_AP_FURNITURE && M_AP_TYPE(mtmp) != M_AP_OBJECT - && (!mtmp->mpeaceful || Hallucination) + && (Hallucination + || (!mtmp->mpeaceful && !noattacks(mtmp->data))) && (!is_hider(mtmp->data) || !mtmp->mundetected) - && !noattacks(mtmp->data) && mtmp->mcanmove - && !mtmp->msleeping /* aplvax!jcn */ + && mtmp->mcanmove && !mtmp->msleeping /* aplvax!jcn */ && !onscary(u.ux, u.uy, mtmp) && canspotmon(mtmp)) return 1; } diff --git a/src/monmove.c b/src/monmove.c index 87af97796..8842f1b66 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monmove.c $NHDT-Date: 1596498186 2020/08/03 23:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.142 $ */ +/* NetHack 3.7 monmove.c $NHDT-Date: 1600469618 2020/09/18 22:53:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -114,16 +114,18 @@ register struct monst *mtmp; /* a similar check is in monster_nearby() in hack.c */ /* check whether hero notices monster and stops current activity */ - if (g.occupation && !rd && !Confusion && (!mtmp->mpeaceful || Hallucination) + if (g.occupation && !rd + /* monster is hostile and can attack (or hallu distorts knowledge) */ + && (Hallucination || (!mtmp->mpeaceful && !noattacks(mtmp->data))) /* it's close enough to be a threat */ - && distu(x, y) <= (BOLT_LIM + 1) * (BOLT_LIM + 1) + && distu(mtmp->mx, mtmp->my) <= (BOLT_LIM + 1) * (BOLT_LIM + 1) /* and either couldn't see it before, or it was too far away */ && (!already_saw_mon || !couldsee(x, y) || distu(x, y) > (BOLT_LIM + 1) * (BOLT_LIM + 1)) /* can see it now, or sense it and would normally see it */ - && (canseemon(mtmp) || (sensemon(mtmp) && couldsee(x, y))) - && mtmp->mcanmove && !noattacks(mtmp->data) - && !onscary(u.ux, u.uy, mtmp)) + && canspotmon(mtmp) && couldsee(mtmp->mx, mtmp->my) + /* monster isn't paralyzed or afraid (scare monster/Elbereth) */ + && mtmp->mcanmove && !onscary(u.ux, u.uy, mtmp)) stop_occupation(); return rd; From 101940f7d1531d5f3e17c46a54c65d86d986b723 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Sep 2020 17:30:48 -0700 Subject: [PATCH 207/708] Qt non-issue Any key bindings in player's run-time config file will already be in place by the time the Qt menus are constructed. Those menus will use the new key assignments rather than the defaults, so not a bug. --- win/Qt/Qt-issues.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index 19b446704..612180399 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -57,9 +57,4 @@ intended to be displayed, is displayed (as blank terrain). 3.6 status conditions (Stone, Slime, Strngl, Deaf, Lev, Fly, Ride) have been implemented but need icon artwork (one 40x40 tile for each). -Qt menus which can execute nethack commands do so by stuffing command -keystrokes into the input buffer. If player's run-time config file -has BIND directives after windowtype:Qt (or anywhere if Qt is chosen -by default), menus aren't updated to use the new key assignments. - ----- From cf482f1f4283b35c9aad9441d6c33d52ebd709cf Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 20 Sep 2020 18:38:31 -0700 Subject: [PATCH 208/708] fix #K2203 - animals can talk The code for peaceful monsters witnessing the hero attack another peaceful monster and getting angry had a 20% of making them gasp in surprise or exclaim "why?" in shock. It was only requiring them to have humanoid shape rather than checking for speech capability, so peaceful zruty or minotaur, possibly other animals, could exclaim comprehensibly. Other things which shouldn't talk, like mummies, would behave similarly. This categorizes how a bunch of MS_foo types should react. It has only been lightly tested. --- doc/fixes37.0 | 5 +++- include/extern.h | 3 +- src/mon.c | 14 ++++------ src/sounds.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 481ba0066..5329e9833 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ $NHDT-Date: 1600469617 2020/09/18 22:53:37 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.305 $ $NHDT-Date: 1600652305 2020/09/21 01:38:25 $ General Fixes and Modified Features ----------------------------------- @@ -251,6 +251,9 @@ turning into slime rendered hero as slime one turn too soon avoid potential infinite loop if hangup occurs at ring "right or left?" prompt randomize the turns where accessories and extrinsics affect nutrition handle being interrupted by approaching monsters more consistently +if hero attacked a peaceful monster, some other peaceful monsters with humanoid + shape (minotaur, zruty, perhaps others) that witnessed it but which + shouldn't be capable of normal speech expressed their surprise audibly Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 121117674..014487499 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.857 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1600652305 2020/09/21 01:38:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.858 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2442,6 +2442,7 @@ E void FDECL(growl, (struct monst *)); E void FDECL(yelp, (struct monst *)); E void FDECL(whimper, (struct monst *)); E void FDECL(beg, (struct monst *)); +E boolean FDECL(maybe_gasp, (struct monst *)); E int NDECL(dotalk); E int NDECL(tiphat); #ifdef USER_SOUNDS diff --git a/src/mon.c b/src/mon.c index 2df04ef29..e3d800b4c 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1599559379 2020/09/08 10:02:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.346 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1600652305 2020/09/21 01:38:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -84,6 +84,8 @@ const char *msg; } if (chk_geno && (g.mvitals[mndx].mvflags & G_GENOD) != 0) impossible("genocided %s in play (%s)", mons[mndx].mname, msg); + if (mtmp->mtame && !mtmp->mpeaceful) + impossible("tame %s is not peaceful (%s)", mons[mndx].mname, msg); } if (mtmp->isshk && !has_eshk(mtmp)) impossible("shk without eshk (%s)", msg); @@ -3182,9 +3184,6 @@ boolean via_attack; /* make other peaceful monsters react */ if (!g.context.mon_moving) { - static const char *const Exclam[] = { - "Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?", - }; struct monst *mon; int mndx = monsndx(mtmp->data); @@ -3205,8 +3204,7 @@ boolean via_attack; (void) angry_guards(!!Deaf); } else { if (!rn2(5)) { - verbalize("%s", Exclam[mon->m_id % SIZE(Exclam)]); - exclaimed = TRUE; + exclaimed = maybe_gasp(mon); } /* shopkeepers and temple priests might gasp in surprise, but they won't become angry here */ @@ -3218,8 +3216,8 @@ boolean via_attack; exclaimed = TRUE; } if (mon->mtame) { - /* mustn't set mpeaceful to 0 as below; - perhaps reduce tameness? */ + ; /* mustn't set mpeaceful to 0 as below; + * perhaps reduce tameness? */ } else { mon->mpeaceful = 0; adjalign(-1); diff --git a/src/sounds.c b/src/sounds.c index 806d25129..0059743ce 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sounds.c $NHDT-Date: 1596498211 2020/08/03 23:43:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.101 $ */ +/* NetHack 3.7 sounds.c $NHDT-Date: 1600652306 2020/09/21 01:38:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ /* Copyright (c) 1989 Janet Walz, Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -479,6 +479,75 @@ register struct monst *mtmp; } } +/* hero has attacked a peaceful monster within 'mon's view */ +boolean +maybe_gasp(mon) +struct monst *mon; +{ + static const char *const Exclam[] = { + "Gasp!", "Uh-oh.", "Oh my!", "What?", "Why?", + }; + struct permonst *mptr = mon->data; + int msound = mptr->msound; + boolean dogasp = FALSE; + + /* other roles' guardians and cross-aligned priests don't gasp */ + if ((msound == MS_GUARDIAN && mptr != &mons[g.urole.guardnum]) + || (msound == MS_PRIEST && !p_coaligned(mon))) + msound = MS_SILENT; + /* co-aligned angels do gasp */ + else if (msound == MS_CUSS && has_emin(mon) + && (p_coaligned(mon) ? !EMIN(mon)->renegade : EMIN(mon)->renegade)) + msound = MS_HUMANOID; + + /* + * Only called for humanoids so animal noise handling is ignored. + */ + switch (msound) { + case MS_HUMANOID: + case MS_ARREST: /* Kops */ + case MS_SOLDIER: /* solider, watchman */ + case MS_GUARD: /* vault guard */ + case MS_NURSE: + case MS_SEDUCE: /* nymph, succubus/incubus */ + case MS_LEADER: /* quest leader */ + case MS_GUARDIAN: /* leader's guards */ + case MS_SELL: /* shopkeeper */ + case MS_ORACLE: + case MS_PRIEST: /* temple priest, roaming aligned priest (not mplayer) */ + case MS_BOAST: /* giants */ + case MS_IMITATE: /* doppelganger, leocrotta, Aleax */ + dogasp = TRUE; + break; + /* issue comprehensible word(s) if hero is similar type of creature */ + case MS_ORC: /* used to be synonym for MS_GRUNT */ + case MS_GRUNT: /* ogres, trolls, gargoyles, one or two others */ + case MS_LAUGH: /* leprechaun, gremlin */ + case MS_ROAR: /* dragon, xorn, owlbear */ + /* capable of speech but only do so if hero is similar type */ + case MS_DJINNI: + 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 == g.youmonst.data->mlet); + break; + /* capable of speech but don't care if you attack peacefuls */ + case MS_BRIBE: + case MS_CUSS: + case MS_RIDER: + case MS_NEMESIS: + /* can't speak */ + case MS_SILENT: + default: + break; + } + if (dogasp) { + verbalize("%s", Exclam[mon->m_id % SIZE(Exclam)]); + return TRUE; + } + return FALSE; +} + /* return True if mon is a gecko or seems to look like one (hallucination) */ static boolean mon_is_gecko(mon) From 1a0ee44760c4353128da223a83319cc0bcb97047 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 22 Sep 2020 09:03:15 -0400 Subject: [PATCH 209/708] unique temp files for makedefs invocations (GitHub issue #391) As reported in https://github.com/NetHack/NetHack/issues/391 if make was invoked with -j, makedefs instances could end up running in parallel and could trample on each other's grep.tmp tempory files. Default to using mkstemp(); allow a port runtime library implementation that lacks mkstemp() to define HAS_NO_MKSTEMP to revert to the old behaviour. Provide a work-alike mkstemp() implementation for windows Visual Studio build in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there. Fixes #391 --- doc/fixes37.0 | 6 ++++ src/mdlib.c | 24 ++++++++++++++ util/makedefs.c | 87 +++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 99 insertions(+), 18 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 5329e9833..96d26a53d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -254,6 +254,12 @@ handle being interrupted by approaching monsters more consistently if hero attacked a peaceful monster, some other peaceful monsters with humanoid shape (minotaur, zruty, perhaps others) that witnessed it but which shouldn't be capable of normal speech expressed their surprise audibly +when make was invoked with -j makedefs instances could end up running in + parallel and could trample on each other's temp files; default to + using mkstemp(); allow a port runtime library implementation that lacks + mkstemp() to define HAS_NO_MKSTEMP to revert to the old behaviour; + provide a work-alike mkstemp() implementation for windows visual studio + in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mdlib.c b/src/mdlib.c index 59b94b459..79a748710 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -66,7 +66,14 @@ static char *FDECL(eos, (char *)); #if 0 static char *FDECL(mdlib_strsubst, (char *, const char *, const char *)); #endif + +#ifndef HAS_NO_MKSTEMP +#ifdef _MSC_VER +static int FDECL(mkstemp, (char *)); +#endif +#endif #endif /* MAKEDEFS_C || FOR_RUNTIME */ + #if !defined(MAKEDEFS_C) && defined(WIN32) extern int GUILaunched; #endif @@ -319,6 +326,23 @@ const char *build_date; return outbuf; } +#ifndef HAS_NO_MKSTEMP +#ifdef _MSC_VER +int +mkstemp(template) +char *template; +{ + int err; + + err = _mktemp_s(template, strlen(template) + 1); + if( err != 0 ) + return -1; + return _open(template, + _O_RDWR | _O_BINARY | _O_TEMPORARY | _O_CREAT, + _S_IREAD | _S_IWRITE); +} +#endif /* _MSC_VER */ +#endif /* HAS_NO_MKSTEMP */ #endif /* MAKEDEFS_C || FOR_RUNTIME */ static int diff --git a/util/makedefs.c b/util/makedefs.c index 8b5179c1b..0cf4b09e3 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -124,6 +124,7 @@ static struct version_info version; /* Use this as an out-of-bound value in the close table. */ #define CLOSE_OFF_TABLE_STRING "99" /* for the close table */ #define FAR_OFF_TABLE_STRING "0xff" /* for the far table */ +#define FLG_TEMPFILE 0x01 /* flag for temp file */ #define sign(z) ((z) < 0 ? -1 : ((z) ? 1 : 0)) #ifdef VISION_TABLES @@ -165,7 +166,7 @@ extern void NDECL(objects_globals_init); /* objects.c */ static char *FDECL(name_file, (const char *, const char *)); static void FDECL(delete_file, (const char *template, const char *)); -static FILE *FDECL(getfp, (const char *, const char *, const char *)); +static FILE *FDECL(getfp, (const char *, const char *, const char *, int)); static void FDECL(do_ext_makedefs, (int, char **)); static char *FDECL(xcrypt, (const char *)); static unsigned long FDECL(read_rumors_file, @@ -393,17 +394,40 @@ const char *tag; } static FILE * -getfp(template, tag, mode) +getfp(template, tag, mode, flg) const char *template; const char *tag; const char *mode; +#ifndef HAS_NO_MKSTEMP +int flg; +#else +int flg UNUSED; +#endif { char *name = name_file(template, tag); - FILE *rv = fopen(name, mode); + FILE *rv = (FILE *) 0; +#ifndef HAS_NO_MKSTEMP + boolean istemp = (flg & FLG_TEMPFILE) != 0; + char tmpfbuf[MAXFNAMELEN]; + int tmpfd; +#endif +#ifndef HAS_NO_MKSTEMP + if (istemp) { + (void) snprintf(tmpfbuf, sizeof tmpfbuf, DATA_TEMPLATE, "mdXXXXXX"); + tmpfd = mkstemp(tmpfbuf); + if (tmpfd >= 0) + rv = fdopen(tmpfd, WRTMODE); /* temp file is always read+write */ + } else +#endif + rv = fopen(name, mode); if (!rv) { - Fprintf(stderr, "Can't open '%s'.\n", name); - exit(EXIT_FAILURE); + Fprintf(stderr, "Can't open '%s'.\n", +#ifndef HAS_NO_MKSTEMP + istemp ? tmpfbuf : +#endif + name); + exit(EXIT_FAILURE); } return rv; } @@ -426,7 +450,7 @@ static int FDECL(grep_check_id, (const char *)); static void FDECL(grep_show_wstack, (const char *)); static char *FDECL(do_grep_control, (char *)); static void NDECL(do_grep); -static void FDECL(grep0, (FILE *, FILE *)); +static void FDECL(grep0, (FILE *, FILE *, int)); static int grep_trace = 0; @@ -775,7 +799,7 @@ char *buf; } #endif -static void grep0(FILE *, FILE *); +static void grep0(FILE *, FILE *, int); static void do_grep() @@ -790,14 +814,26 @@ do_grep() exit(EXIT_FAILURE); } - grep0(inputfp, outputfp); + grep0(inputfp, outputfp, 0); } static void -grep0(inputfp0, outputfp0) +grep0(inputfp0, outputfp0, flg) FILE *inputfp0; FILE *outputfp0; +#ifndef HAS_NO_MKSTEMP +int flg; +#else +int flg UNUSED; +#endif { +#ifndef HAS_NO_MKSTEMP + /* if grep0 is passed FLG_TEMPFILE flag, it will + leave the output file open when it returns. + The caller will have to take care of calling + fclose() when it is done with the file */ + boolean istemp = (flg & FLG_TEMPFILE) != 0; +#endif char buf[16384]; /* looong, just in case */ while (!feof(inputfp0) && !ferror(inputfp0)) { @@ -837,7 +873,12 @@ FILE *outputfp0; exit(EXIT_FAILURE); } fclose(inputfp0); - fclose(outputfp0); +#ifndef HAS_NO_MKSTEMP + if (istemp) + rewind(outputfp0); + else +#endif + fclose(outputfp0); if (grep_sp) { Fprintf(stderr, "%d unterminated conditional level%s\n", grep_sp, grep_sp == 1 ? "" : "s"); @@ -967,10 +1008,13 @@ const char *deflt_content; more likely to be picked than normal but it's nothing to worry about */ (void) fputs(xcrypt(deflt_content), ofp); - tfp = getfp(DATA_TEMPLATE, "grep.tmp", WRTMODE); - grep0(ifp, tfp); - ifp = getfp(DATA_TEMPLATE, "grep.tmp", RDTMODE); - + tfp = getfp(DATA_TEMPLATE, "grep.tmp", WRTMODE, FLG_TEMPFILE); + grep0(ifp, tfp, FLG_TEMPFILE); +#ifndef HAS_NO_MKSTEMP + ifp = tfp; +#else + ifp = getfp(DATA_TEMPLATE, "grep.tmp", RDTMODE, 0); +#endif while ((line = fgetline(ifp)) != 0) { if (line[0] != '#' && line[0] != '\n') (void) fputs(xcrypt(line), ofp); @@ -979,7 +1023,9 @@ const char *deflt_content; Fclose(ifp); Fclose(ofp); +#ifdef HAS_NO_MKSTEMP delete_file(DATA_TEMPLATE, "grep.tmp"); +#endif return; } @@ -1747,10 +1793,13 @@ do_dungeon() } Fprintf(ofp, "%s", Dont_Edit_Data); - tfp = getfp(DATA_TEMPLATE, "grep.tmp", WRTMODE); - grep0(ifp, tfp); - ifp = getfp(DATA_TEMPLATE, "grep.tmp", RDTMODE); - + tfp = getfp(DATA_TEMPLATE, "grep.tmp", WRTMODE, FLG_TEMPFILE); + grep0(ifp, tfp, FLG_TEMPFILE); +#ifndef HAS_NO_MKSTEMP + ifp = tfp; +#else + ifp = getfp(DATA_TEMPLATE, "grep.tmp", RDTMODE, 0); +#endif while ((line = fgetline(ifp)) != 0) { SpinCursor(3); @@ -1764,7 +1813,9 @@ do_dungeon() Fclose(ifp); Fclose(ofp); +#ifdef HAS_NO_MKSTEMP delete_file(DATA_TEMPLATE, "grep.tmp"); +#endif return; } From 29c558ed1236674f2416741aecc63d6db3ef7b90 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 22 Sep 2020 10:11:51 -0400 Subject: [PATCH 210/708] follow-up bit; ensure the mkstemp() file is unlinked --- util/makedefs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/util/makedefs.c b/util/makedefs.c index 0cf4b09e3..147164fde 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -416,8 +416,10 @@ int flg UNUSED; if (istemp) { (void) snprintf(tmpfbuf, sizeof tmpfbuf, DATA_TEMPLATE, "mdXXXXXX"); tmpfd = mkstemp(tmpfbuf); - if (tmpfd >= 0) + if (tmpfd >= 0) { rv = fdopen(tmpfd, WRTMODE); /* temp file is always read+write */ + Unlink(tmpfbuf); + } } else #endif rv = fopen(name, mode); From c1ebfb730c7693fe43af0112dea9aad66c17759e Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 22 Sep 2020 10:28:22 -0400 Subject: [PATCH 211/708] whitespace bit --- util/makedefs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/makedefs.c b/util/makedefs.c index 147164fde..b12689a3f 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -419,7 +419,7 @@ int flg UNUSED; if (tmpfd >= 0) { rv = fdopen(tmpfd, WRTMODE); /* temp file is always read+write */ Unlink(tmpfbuf); - } + } } else #endif rv = fopen(name, mode); From 5346d8f9e981b7e38bced95dd98d00b63a60bd84 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Sep 2020 03:03:46 -0700 Subject: [PATCH 212/708] makedefs: hide conditionally unused routine Avoid a new build warning for the default configuration. --- util/makedefs.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/util/makedefs.c b/util/makedefs.c index b12689a3f..96e13afaa 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makedefs.c $NHDT-Date: 1596498258 2020/08/03 23:44:18 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.184 $ */ +/* NetHack 3.7 makedefs.c $NHDT-Date: 1600855420 2020/09/23 10:03:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -165,7 +165,6 @@ extern void NDECL(monst_globals_init); /* monst.c */ extern void NDECL(objects_globals_init); /* objects.c */ static char *FDECL(name_file, (const char *, const char *)); -static void FDECL(delete_file, (const char *template, const char *)); static FILE *FDECL(getfp, (const char *, const char *, const char *, int)); static void FDECL(do_ext_makedefs, (int, char **)); static char *FDECL(xcrypt, (const char *)); @@ -383,6 +382,9 @@ const char *tag; return namebuf; } +#ifdef HAS_NO_MKSTEMP +static void FDECL(delete_file, (const char *template, const char *)); + static void delete_file(template, tag) const char *template; @@ -392,6 +394,7 @@ const char *tag; Unlink(name); } +#endif static FILE * getfp(template, tag, mode, flg) @@ -410,9 +413,7 @@ int flg UNUSED; boolean istemp = (flg & FLG_TEMPFILE) != 0; char tmpfbuf[MAXFNAMELEN]; int tmpfd; -#endif -#ifndef HAS_NO_MKSTEMP if (istemp) { (void) snprintf(tmpfbuf, sizeof tmpfbuf, DATA_TEMPLATE, "mdXXXXXX"); tmpfd = mkstemp(tmpfbuf); From b67251151331e4a27882cb7da5b8dc94eeb3a10c Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Sep 2020 05:21:31 -0700 Subject: [PATCH 213/708] Qt status fix: 'showexp' For Qt, experience points weren't shown when enabling 'showexp' option because they were conditional upon '#if EXP_ON_BOTL'. That got eliminated prior to 3.6.0 so wasn't defined for qt_stat.cpp. When displayed, show Exp as Level:Xp/Exp instead of as a separate status field. This has the intentional side-effect of omitting it when hero is polymorphed and status shows HD instead of Xp. Label the six characteristics in mixed case instead of all upper case: Str, Dex, and so forth. --- doc/fixes37.0 | 4 +- win/Qt/qt_stat.cpp | 105 ++++++++++++++++++++++++--------------------- win/Qt/qt_stat.h | 9 ++-- 3 files changed, 65 insertions(+), 53 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 96d26a53d..f343ce0c8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.305 $ $NHDT-Date: 1600652305 2020/09/21 01:38:25 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ $NHDT-Date: 1600863687 2020/09/23 12:21:27 $ General Fixes and Modified Features ----------------------------------- @@ -417,6 +417,8 @@ Qt: update message window's last message with player's response if it's a Qt: for line input, display the prompt+response in the message window Qt: enable the popup_dialog WC option (result is a bit flakey but usable) Qt: 3.6 catchup - show unexplored locations as unexplored rather than as stone +Qt: tried to honor 'showexp' but the value was unintentionally supressed by + [lack of] obsolete conditional EXP_ON_BOTL Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 2a8c262ea..b71ab4364 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -32,18 +32,18 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : // Blank value is 0 and should never change. name(this,"(name)"), dlevel(this,"(dlevel)"), - str(this,"STR"), - dex(this,"DEX"), - con(this,"CON"), - intel(this,"INT"), - wis(this,"WIS"), - cha(this,"CHA"), + str(this, "Str"), + dex(this, "Dex"), + con(this, "Con"), + intel(this, "Int"), + wis(this, "Wis"), + cha(this, "Cha"), gold(this,"Gold"), hp(this,"Hit Points"), power(this,"Power"), ac(this,"Armour Class"), level(this,"Level"), - exp(this,"Experience"), + exp(this, "_"), // exp displayed as Xp/Exp but exp widget used for padding align(this,"Alignment"), time(this,"Time"), score(this,"Score"), @@ -208,7 +208,7 @@ void NetHackQtStatusWindow::doUpdate() power.setFont(normal); ac.setFont(normal); level.setFont(normal); - exp.setFont(normal); + //exp.setFont(normal); align.setFont(normal); time.setFont(normal); score.setFont(normal); @@ -297,7 +297,7 @@ void NetHackQtStatusWindow::resizeEvent(QResizeEvent*) power.setGeometry(x,y,iw,lh); x+=iw; ac.setGeometry(x,y,iw,lh); x+=iw; level.setGeometry(x,y,iw,lh); x+=iw; - exp.setGeometry(x,y,iw,lh); x+=iw; + //exp.setGeometry(x,y,iw,lh); x+=iw; x=0; y+=lh; lh=int(h*SP_hln3); @@ -367,7 +367,7 @@ void NetHackQtStatusWindow::fadeHighlighting() power.dissipateHighlight(); ac.dissipateHighlight(); level.dissipateHighlight(); - exp.dissipateHighlight(); + //exp.dissipateHighlight(); align.dissipateHighlight(); time.dissipateHighlight(); @@ -413,22 +413,23 @@ void NetHackQtStatusWindow::updateStats() if (cursy != 0) return; /* do a complete update when line 0 is done */ - if (ACURR(A_STR) > 118) { - buf.sprintf("STR:%d",ACURR(A_STR)-100); - } else if (ACURR(A_STR)==118) { - buf.sprintf("STR:18/**"); - } else if(ACURR(A_STR) > 18) { - buf.sprintf("STR:18/%02d",ACURR(A_STR)-18); + int st = ACURR(A_STR); + if (st > STR18(100)) { + buf.sprintf("Str:%d", st - 100); // 19..25 + } else if (st == STR18(100)) { + buf.sprintf("Str:18/**"); // 18/100 + } else if (st > 18) { + buf.sprintf("Str:18/%02d", st - 18); // 18/01..18/99 } else { - buf.sprintf("STR:%d",ACURR(A_STR)); + buf.sprintf("Str:%d", st); // 3..18 } - str.setLabel(buf,NetHackQtLabelledIcon::NoNum,ACURR(A_STR)); + str.setLabel(buf, NetHackQtLabelledIcon::NoNum, (long) st); + dex.setLabel("Dex:", (long) ACURR(A_DEX)); + con.setLabel("Con:", (long) ACURR(A_CON)); + intel.setLabel("Int:", (long) ACURR(A_INT)); + wis.setLabel("Wis:", (long) ACURR(A_WIS)); + cha.setLabel("Cha:", (long) ACURR(A_CHA)); - dex.setLabel("DEX:",(long)ACURR(A_DEX)); - con.setLabel("CON:",(long)ACURR(A_CON)); - intel.setLabel("INT:",(long)ACURR(A_INT)); - wis.setLabel("WIS:",(long)ACURR(A_WIS)); - cha.setLabel("CHA:",(long)ACURR(A_CHA)); const char* hung=hu_stat[u.uhs]; if (hung[0]==' ') { hunger.hide(); @@ -479,7 +480,7 @@ void NetHackQtStatusWindow::updateStats() if (Flying) fly.show(); else fly.hide(); if (u.usteed) ride.show(); else ride.hide(); - if (u.mtimedone) { + if (Upolyd) { buf = nh_capitalize_words(mons[u.umonnum].mname); } else { buf = rank_of(u.ulevel, g.pl_character[0], ::flags.female); @@ -498,30 +499,35 @@ void NetHackQtStatusWindow::updateStats() gold.setLabel("Au:", money_cnt(g.invent)); - if (u.mtimedone) { - // You're a monster! - - buf.sprintf("/%d", u.mhmax); - hp.setLabel("HP:", u.mh > 0 ? u.mh : 0, buf); - level.setLabel("HD:",(long)mons[u.umonnum].mlevel); + if (Upolyd) { + // You're a monster! + buf.sprintf("/%d", u.mhmax); + hp.setLabel("HP:", std::max((long) u.mh, 0L), buf); + level.setLabel("HD:", (long) mons[u.umonnum].mlevel); // hit dice + // Exp points are not shown when HD is displayed instead of Xp level } else { - // You're normal. - - buf.sprintf("/%d", u.uhpmax); - hp.setLabel("HP:", u.uhp > 0 ? u.uhp : 0, buf); - level.setLabel("Level:",(long)u.ulevel); + // You're normal. + buf.sprintf("/%d", u.uhpmax); + hp.setLabel("HP:", std::max((long) u.uhp, 0L), buf); + // if Exp points are to be displayed, append them to Xp level; + // up/down highlighting becomes tricky--don't try very hard + if (::flags.showexp) { + buf.sprintf("%ld/%ld", (long) u.ulevel, (long) u.uexp); + level.setLabel("Level:" + buf, + NetHackQtLabelledIcon::NoNum, (long) u.uexp); + } else { + level.setLabel("Level:", (long) u.ulevel); + } } buf.sprintf("/%d", u.uenmax); power.setLabel("Pow:", u.uen, buf); ac.setLabel("AC:",(long)u.uac); -#ifdef EXP_ON_BOTL - if (::flags.showexp) { - exp.setLabel("Exp:",(long)u.uexp); - } else -#endif - { - exp.setLabel(""); - } + //if (::flags.showexp) { + // exp.setLabel("Exp:", (long) u.uexp); + //} else { + // 'exp' now only used to pad the line that Xp/Exp is displayed on + exp.setLabel(""); + //} if (u.ualign.type==A_CHAOTIC) { align.setIcon(p_chaotic); text = "Chaotic"; @@ -534,11 +540,13 @@ void NetHackQtStatusWindow::updateStats() } align.setLabel(text); - if (::flags.time) time.setLabel("Time:",(long)g.moves); - else time.setLabel(""); + if (::flags.time) + time.setLabel("Time:", (long) g.moves); + else + time.setLabel(""); #ifdef SCORE_ON_BOTL if (::flags.showscore) { - score.setLabel("Score:",(long)botl_score()); + score.setLabel("Score:", (long) botl_score()); } else #endif { @@ -564,10 +572,11 @@ void NetHackQtStatusWindow::updateStats() power.highlightWhenChanging(); ac.highlightWhenChanging(); ac.lowIsGood(); level.highlightWhenChanging(); - exp.highlightWhenChanging(); + //exp.highlightWhenChanging(); -- 'exp' is just padding align.highlightWhenChanging(); - //time.highlightWhenChanging(); + // don't highlight 'time' because it changes almost continuously + //time.highlightWhenChanging(); score.highlightWhenChanging(); hunger.highlightWhenChanging(); diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index 0f50eb6de..2b7382289 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -78,10 +78,11 @@ private: NetHackQtLabelledIcon hp; NetHackQtLabelledIcon power; NetHackQtLabelledIcon ac; - NetHackQtLabelledIcon level; - NetHackQtLabelledIcon exp; - NetHackQtLabelledIcon align; - + NetHackQtLabelledIcon level; // Xp level + NetHackQtLabelledIcon exp; // appended to Xp rather than separate + // but still used to pad their line + NetHackQtLabelledIcon align; // alignment is on Conditions line + // because it has an icon above it NetHackQtLabelledIcon time; NetHackQtLabelledIcon score; From 10d80eb1505c2744a7bd9cfbe06f600047c6a02c Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Sep 2020 16:40:26 -0700 Subject: [PATCH 214/708] Qt's 3.6 status conditions Replace the blank placeholder icon with individual placeholders for Stone, Slime, Strngl, Deaf, Lev, Fly, and Ride. They're just 40x40 tiles showing solid color (different for each) holding white block letters spelling the condition. For the first four of those, the text runs from upper-left to lower-right, for Lev and Fly the text runs from lower-left towards upper-right, and for Ride it's horizontal. Not particularly exciting but better than blank. We still need real artwork to make them be similar to the older conditions. Also moves the two petmarks and the pilemark from qt_xpms.h to qt_map.cpp. The marks and the assorted status icons are all static arrays, and including that header in two source files meant that they were all duplicated unless the compiler or linker was smart enough to discard the unused ones. --- sys/unix/Makefile.src | 7 +- win/Qt/qt_map.cpp | 49 +++++- win/Qt/qt_stat.cpp | 14 +- win/Qt/qt_xpms.h | 382 +++++++++++++++++++++++++++++++++++++----- 4 files changed, 402 insertions(+), 50 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 065f986f6..790084bd3 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.7 Makefile.src $NHDT-Date: 1597704252 2020/08/17 22:44:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ +# NetHack 3.7 Makefile.src $NHDT-Date: 1600904413 2020/09/23 23:40:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.108 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -900,9 +900,8 @@ qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_pre.h \ qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ - ../win/Qt/qt_glyph.h ../win/Qt/qt_xpms.h ../win/Qt/qt_set.h \ - ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ - ../win/Qt/qt_str.h + ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_bind.h \ + ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 0bb96d673..f55e023c8 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -18,10 +18,57 @@ extern "C" { #include "qt_map.moc" #include "qt_click.h" #include "qt_glyph.h" -#include "qt_xpms.h" #include "qt_set.h" #include "qt_str.h" +// pet- and pile-mark xpm arrays moved out of qt_xpms.h so that we don't +// include it here anymore; including that header in two files resulted in +// two copies of all the static xpm data and all the rest is for qt_stat.cpp +// +/* XPM */ +static const char *pet_mark_xpm[] = { +/* width height ncolors chars_per_pixel */ +"8 7 2 1", +/* colors */ +". c None", +" c #FF0000", +/* pixels */ +"........", +".. . .", +". ", +". ", +".. .", +"... ..", +".... ..." +}; +/* XPM */ +static const char *pet_mark_small_xpm[] = { +/* width height ncolors chars_per_pixel */ +"5 5 2 1", +/* colors */ +". c None", +"X c #FF0000", +/* pixels */ +".X.X.", +"XXXXX", +".XXX.", +"..X.." +}; +/* XPM */ +static const char *pile_mark_xpm[] = { +/* width height ncolors chars_per_pixel */ +"5 5 2 1", +/* colors */ +". c None", +"X c #00FF00", +/* pixels */ +"..X..", +"..X..", +"XXXXX", +"..X..", +"..X.." +}; + // temporary extern int qt_compact_mode; // end temporary diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index b71ab4364..7ba03c549 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -88,19 +88,19 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : p_encumber[3] = QPixmap(ext_enc_xpm); p_encumber[4] = QPixmap(ovr_enc_xpm); - p_stoned = QPixmap(blank_xpm); // placeholder icon - p_slimed = QPixmap(blank_xpm); // placeholder icon - p_strngld = QPixmap(blank_xpm); // placeholder icon + p_stoned = QPixmap(stone_xpm); + p_slimed = QPixmap(slime_xpm); + p_strngld = QPixmap(strngl_xpm); p_sick_fp = QPixmap(sick_fp_xpm); p_sick_il = QPixmap(sick_il_xpm); p_stunned = QPixmap(stunned_xpm); p_confused = QPixmap(confused_xpm); p_hallu = QPixmap(hallu_xpm); p_blind = QPixmap(blind_xpm); - p_deaf = QPixmap(blank_xpm); // placeholder icon - p_lev = QPixmap(blank_xpm); // placeholder icon - p_fly = QPixmap(blank_xpm); // placeholder icon - p_ride = QPixmap(blank_xpm); // placeholder icon + p_deaf = QPixmap(deaf_xpm); + p_lev = QPixmap(lev_xpm); + p_fly = QPixmap(fly_xpm); + p_ride = QPixmap(ride_xpm); str.setIcon(p_str); dex.setIcon(p_dex); diff --git a/win/Qt/qt_xpms.h b/win/Qt/qt_xpms.h index 3f674ceb3..df0540ad9 100644 --- a/win/Qt/qt_xpms.h +++ b/win/Qt/qt_xpms.h @@ -1,4 +1,9 @@ +// qt_xpms.h - static xpm arrays for use in status display +// +// In alhpabetical order by array name. Probably not the best ordering... + /* clang-format off */ +#if 0 // blank icon for use as placeholder /* XPM */ static const char *blank_xpm[] = { /* width height ncolors chars_per_pixel */ @@ -52,6 +57,7 @@ static const char *blank_xpm[] = { "........................................", "........................................" }; +#endif static const char *blind_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 5 1", @@ -391,6 +397,55 @@ static const char *confused_xpm[] = { #endif }; /* XPM */ +static const char *deaf_xpm[] = { // placeholder for Deaf condition +/* width height ncolors chars_per_pixel */ +"40 40 2 1", +/* colors */ +"X c None", +"o c #dfdf40", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooXXXXooooooooooooooooooooooooooooX", +"XooooooXoooXoooooooooooooooooooooooooooX", +"XooooooXoooXoooooooooooooooooooooooooooX", +"XooooooXoooXoooooooooooooooooooooooooooX", +"XooooooXoooXoooooooooooooooooooooooooooX", +"XooooooXoooXooXXXXXooooooooooooooooooooX", +"XooooooXXXXoooXooooooooooooooooooooooooX", +"XoooooooooooooXooooooooooooooooooooooooX", +"XoooooooooooooXXXXoooooooooooooooooooooX", +"XoooooooooooooXooooooooooooooooooooooooX", +"XoooooooooooooXooooooooXoooooooooooooooX", +"XoooooooooooooXXXXXoooXoXooooooooooooooX", +"XooooooooooooooooooooXoooXoooooooooooooX", +"XooooooooooooooooooooXoooXoooooooooooooX", +"XooooooooooooooooooooXXXXXoooooooooooooX", +"XooooooooooooooooooooXoooXooXXXXXooooooX", +"XooooooooooooooooooooXoooXooXooooooooooX", +"XoooooooooooooooooooooooooooXooooooooooX", +"XoooooooooooooooooooooooooooXXXXoooooooX", +"XoooooooooooooooooooooooooooXooooooooooX", +"XoooooooooooooooooooooooooooXooooooooooX", +"XoooooooooooooooooooooooooooXooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; +/* XPM */ static const char *dex_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 19 1", @@ -517,6 +572,104 @@ static const char *ext_enc_xpm[] = { "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" }; /* XPM */ +static const char *fly_xpm[] = { // placeholder for Flying condition +/* width height ncolors chars_per_pixel */ +"40 40 2 1", +/* colors */ +"X c None", +"o c #7fefef", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooXoooXoooooooooooX", +"XooooooooooooooooooooooXoooXoooooooooooX", +"XoooooooooooooooooXoooooXoXooooooooooooX", +"XoooooooooooooooooXoooooXoXooooooooooooX", +"XooooooooooXXXXXooXooooooXoooooooooooooX", +"XooooooooooXooooooXooooooXoooooooooooooX", +"XooooooooooXooooooXooooooXoooooooooooooX", +"XooooooooooXXXXoooXooooooooooooooooooooX", +"XooooooooooXooooooXXXXoooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; +/* XPM */ +static const char *lev_xpm[] = { // placeholder for Levitating condition +/* width height ncolors chars_per_pixel */ +"40 40 2 1", +/* colors */ +"X c None", +"o c #df1010", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooXoooooXoooooooooX", +"XooooooooooooooooooooooXoooooXoooooooooX", +"XoooooooooooooooXXXXXoooXoooXooooooooooX", +"XoooooooooooooooXoooooooXoooXooooooooooX", +"XoooooooooXoooooXooooooooXoXoooooooooooX", +"XoooooooooXoooooXXXXoooooXoXoooooooooooX", +"XoooooooooXoooooXoooooooooXooooooooooooX", +"XoooooooooXoooooXooooooooooooooooooooooX", +"XoooooooooXoooooXXXXXooooooooooooooooooX", +"XoooooooooXooooooooooooooooooooooooooooX", +"XoooooooooXXXXoooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; +/* XPM */ static const char *hallu_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 30 1", @@ -1013,47 +1166,53 @@ static const char *ovr_enc_xpm[] = { "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" }; /* XPM */ -static const char *pet_mark_xpm[] = { +static const char *ride_xpm[] = { // placeholder for Riding condition /* width height ncolors chars_per_pixel */ -"8 7 2 1", +"40 40 2 1", /* colors */ -". c None", -" c #FF0000", +"X c None", +"o c #df7f00", /* pixels */ -"........", -".. . .", -". ", -". ", -".. .", -"... ..", -".... ..." -}; -/* XPM */ -static const char *pet_mark_small_xpm[] = { -/* width height ncolors chars_per_pixel */ -"5 5 2 1", -/* colors */ -". c None", -"X c #FF0000", -/* pixels */ -".X.X.", -"XXXXX", -".XXX.", -"..X.." -}; -/* XPM */ -static const char *pile_mark_xpm[] = { -/* width height ncolors chars_per_pixel */ -"5 5 2 1", -/* colors */ -". c None", -"X c #00FF00", -/* pixels */ -"..X..", -"..X..", -"XXXXX", -"..X..", -"..X.." +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XoooooooXXXXoooXXXooXXXXoooXXXXXoooooooX", +"XoooooooXoooXoooXoooXoooXooXoooooooooooX", +"XoooooooXoooXoooXoooXoooXooXoooooooooooX", +"XoooooooXXXXooooXoooXoooXooXXXXooooooooX", +"XoooooooXoXoooooXoooXoooXooXoooooooooooX", +"XoooooooXooXooooXoooXoooXooXoooooooooooX", +"XoooooooXoooXooXXXooXXXXoooXXXXXoooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }; /* XPM */ static const char *satiated_xpm[] = { @@ -1273,6 +1432,55 @@ static const char *sick_il_xpm[] = { "#################$#$####################" }; /* XPM */ +static const char *slime_xpm[] = { // placeholder for Slimed condition +/* width height ncolors chars_per_pixel */ +"40 40 2 1", +/* colors */ +"X c None", +"o c #40df40", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooXXXoooooooooooooooooooooooooooooooX", +"XoooXooooooooooooooooooooooooooooooooooX", +"XoooXooooooooooooooooooooooooooooooooooX", +"XooooXXXoooooooooooooooooooooooooooooooX", +"XoooooooXooooooooooooooooooooooooooooooX", +"XoooooooXooXoooooooooooooooooooooooooooX", +"XooooXXXoooXoooooooooooooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooXooooooXXXooooooooooooooooooX", +"XooooooooooXoooooooXoooooooooooooooooooX", +"XooooooooooXXXXXoooXoooooooooooooooooooX", +"XooooooooooooooooooXoooooooooooooooooooX", +"XooooooooooooooooooXoooooooooooooooooooX", +"XooooooooooooooooooXoooXoooooXoooooooooX", +"XoooooooooooooooooXXXooXXoooXXoooooooooX", +"XooooooooooooooooooooooXXXoXXXoooooooooX", +"XooooooooooooooooooooooXoXXXoXoooooooooX", +"XooooooooooooooooooooooXooXooXoooooooooX", +"XooooooooooooooooooooooXoooooXooXXXXXooX", +"XooooooooooooooooooooooXoooooXooXooooooX", +"XoooooooooooooooooooooooooooooooXooooooX", +"XoooooooooooooooooooooooooooooooXXXXoooX", +"XoooooooooooooooooooooooooooooooXooooooX", +"XoooooooooooooooooooooooooooooooXooooooX", +"XoooooooooooooooooooooooooooooooXXXXXooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; +/* XPM */ static const char *slt_enc_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 13 1", @@ -1333,6 +1541,55 @@ static const char *slt_enc_xpm[] = { "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" }; /* XPM */ +static const char *stone_xpm[] = { // placeholder for Stoned condition +/* width height ncolors chars_per_pixel */ +"40 40 2 1", +/* colors */ +"X c None", +"o c #6c91b6", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooXXXoooooooooooooooooooooooooooooooX", +"XoooXooooooooooooooooooooooooooooooooooX", +"XoooXooooooooooooooooooooooooooooooooooX", +"XooooXXXoooooooooooooooooooooooooooooooX", +"XoooooooXooooooooooooooooooooooooooooooX", +"XoooooooXooXXXXXoooooooooooooooooooooooX", +"XooooXXXoooooXoooooooooooooooooooooooooX", +"XooooooooooooXoooooooooooooooooooooooooX", +"XooooooooooooXoooooooooooooooooooooooooX", +"XooooooooooooXooooXXXooooooooooooooooooX", +"XooooooooooooXoooXoooXoooooooooooooooooX", +"XooooooooooooXoooXoooXoooooooooooooooooX", +"XooooooooooooooooXoooXoooooooooooooooooX", +"XooooooooooooooooXoooXoooooooooooooooooX", +"XooooooooooooooooXoooXooXoooXooooooooooX", +"XoooooooooooooooooXXXoooXXooXooooooooooX", +"XoooooooooooooooooooooooXXooXooooooooooX", +"XoooooooooooooooooooooooXoXoXooooooooooX", +"XoooooooooooooooooooooooXooXXooooooooooX", +"XoooooooooooooooooooooooXooXXooXXXXXoooX", +"XoooooooooooooooooooooooXoooXooXoooooooX", +"XooooooooooooooooooooooooooooooXoooooooX", +"XooooooooooooooooooooooooooooooXXXXooooX", +"XooooooooooooooooooooooooooooooXoooooooX", +"XooooooooooooooooooooooooooooooXoooooooX", +"XooooooooooooooooooooooooooooooXXXXXoooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; +/* XPM */ static const char *str_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 17 1", @@ -1397,6 +1654,55 @@ static const char *str_xpm[] = { "++++++++++++++++++++++++++++++++++++++++" }; /* XPM */ +static const char *strngl_xpm[] = { // placeholder for Strangled condition +/* width height ncolors chars_per_pixel */ +"40 40 2 1", +/* colors */ +"X c None", +"o c #bf40ff", +/* pixels */ +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooXXXoooooooooooooooooooooooooooooooooX", +"XoXooooooooooooooooooooooooooooooooooooX", +"XoXooooooooooooooooooooooooooooooooooooX", +"XoXXXXoooooooooooooooooooooooooooooooooX", +"XoooooXooooooooooooooooooooooooooooooooX", +"XoooooXooXXXXXoooooooooooooooooooooooooX", +"XooXXXoooooXoooooooooooooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooXoooooooooooooooooooooooooooX", +"XooooooooooXooXXXXoooooooooooooooooooooX", +"XooooooooooXooXoooXooooooooooooooooooooX", +"XoooooooooooooXoooXooooooooooooooooooooX", +"XoooooooooooooXXXXoooooooooooooooooooooX", +"XoooooooooooooXoXooooooooooooooooooooooX", +"XoooooooooooooXooXoooXoooXoooooooooooooX", +"XoooooooooooooXoooXooXXooXoooooooooooooX", +"XooooooooooooooooooooXXooXoooooooooooooX", +"XooooooooooooooooooooXoXoXoooooooooooooX", +"XooooooooooooooooooooXooXXoooooooooooooX", +"XooooooooooooooooooooXooXXoooXXXoooooooX", +"XooooooooooooooooooooXoooXooXooooooooooX", +"XoooooooooooooooooooooooooooXooooooooooX", +"XoooooooooooooooooooooooooooXoXXXooooooX", +"XoooooooooooooooooooooooooooXoooXooooooX", +"XoooooooooooooooooooooooooooXoooXooXoooX", +"XooooooooooooooooooooooooooooXXXoooXoooX", +"XooooooooooooooooooooooooooooooooooXoooX", +"XooooooooooooooooooooooooooooooooooXoooX", +"XooooooooooooooooooooooooooooooooooXoooX", +"XooooooooooooooooooooooooooooooooooXoooX", +"XooooooooooooooooooooooooooooooooooXXXXX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XooooooooooooooooooooooooooooooooooooooX", +"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +}; +/* XPM */ static const char *stunned_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 12 1", From 9faaa1b25d9ba85dfca44fa3f73c751fa26d0171 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Sep 2020 17:57:19 -0700 Subject: [PATCH 215/708] pull request #345 - theme room dimensions "When a room is created and passed down to a contents function in Lua, the width and height properties of that room are computed by subtracting lx from hx and ly from hy, which means e.g. a room which is 8 floor squares wide and 5 tall appears to the contents function as having a width of 7 and height of 4. This patch fixes that off-by-one." I don't understand the details here: should a room's dimensions include its boundary walls or just the inner amount? This change didn't seem to cause any problems so I've put it in. Closes #345 --- dat/themerms.lua | 23 +++++++++++++---------- doc/fixes37.0 | 3 ++- src/sp_lev.c | 5 +++-- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/dat/themerms.lua b/dat/themerms.lua index acb826cee..4b3947fe4 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -80,8 +80,8 @@ themerooms = { function() des.room({ type = "themed", contents = function(rm) - for x = 0, rm.width do - for y = 0, rm.height do + for x = 0, rm.width - 1 do + for y = 0, rm.height - 1 do if (percent(30)) then if (percent(50)) then des.object("boulder"); @@ -99,8 +99,8 @@ themerooms = { function() des.room({ type = "themed", contents = function(rm) - for x = 0, rm.width do - for y = 0, rm.height do + for x = 0, rm.width - 1 do + for y = 0, rm.height - 1 do if (percent(30)) then des.trap("web", x, y); end @@ -118,8 +118,8 @@ themerooms = { "land mine", "sleep gas", "rust", "anti magic" }; shuffle(traps); - for x = 0, rm.width do - for y = 0, rm.height do + for x = 0, rm.width - 1 do + for y = 0, rm.height - 1 do if (percent(30)) then des.trap(traps[1], x, y); end @@ -169,8 +169,8 @@ themerooms = { contents = function(rm) local terr = { "-", "-", "-", "-", "L", "P", "T" }; shuffle(terr); - for x = 0, (rm.width - 3) / 4 do - for y = 0, (rm.height - 3) / 4 do + for x = 0, (rm.width / 4) - 1 do + for y = 0, (rm.height / 4) - 1 do des.terrain({ x = x * 4 + 2, y = y * 4 + 2, typ = terr[1], lit = -2 }); des.terrain({ x = x * 4 + 3, y = y * 4 + 2, typ = terr[1], lit = -2 }); des.terrain({ x = x * 4 + 2, y = y * 4 + 3, typ = terr[1], lit = -2 }); @@ -219,7 +219,9 @@ themerooms = { function() des.room({ type = "themed", w = 5 + nh.rn2(3)*2, h = 5 + nh.rn2(3)*2, contents = function(rm) - des.room({ type = "themed", x = (rm.width / 2), y = (rm.height / 2), w = 1, h = 1, joined = 0, + des.room({ type = "themed", + x = (rm.width - 1) / 2, y = (rm.height - 1) / 2, + w = 1, h = 1, joined = 0, contents = function() if (percent(50)) then local mons = { "M", "V", "L", "Z" }; @@ -245,7 +247,8 @@ themerooms = { contents = function(rm) local feature = { "C", "L", "I", "P", "T" }; shuffle(feature); - des.terrain(rm.width / 2, rm.height / 2, feature[1]); + des.terrain((rm.width - 1) / 2, (rm.height - 1) / 2, + feature[1]); end }); end, diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f343ce0c8..c0fc2b284 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ $NHDT-Date: 1600863687 2020/09/23 12:21:27 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.308 $ $NHDT-Date: 1600909016 2020/09/24 00:56:56 $ General Fixes and Modified Features ----------------------------------- @@ -342,6 +342,7 @@ replace worm tail placement code that reportedly led to a sanity_check warning [no actual code problem found; might be compiler bug for 'xchar'] learn scroll of teleportation after reading even when random destination is right by starting spot +fix off-by-one bug in dimensions of theme rooms curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/sp_lev.c b/src/sp_lev.c index d08888028..5d63476c2 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.c $NHDT-Date: 1599434249 2020/09/06 23:17:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */ +/* NetHack 3.7 sp_lev.c $NHDT-Date: 1600909016 2020/09/24 00:56:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.203 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -3844,7 +3844,8 @@ lua_State *L; lua_getfield(L, 1, "contents"); if (lua_type(L, -1) == LUA_TFUNCTION) { lua_remove(L, -2); - l_push_wid_hei_table(L, tmpcr->hx - tmpcr->lx, tmpcr->hy - tmpcr->ly); + l_push_wid_hei_table(L, 1 + tmpcr->hx - tmpcr->lx, + 1 + tmpcr->hy - tmpcr->ly); lua_call(L, 1, 0); } else lua_pop(L, 1); From 5df5079700b5394467cda98545537c5390f59e15 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 24 Sep 2020 00:44:07 -0700 Subject: [PATCH 216/708] peacefuls witnessing attack against peaceful mon The short exclamations ("Gasp!", "Why?", &c) led to ambiguity about which monster was vocalizing them. Use full sentences which refer to the speaker. It can become quite a bit more verbose but is less likely to lead to confusion. Perhaps it should cut those off after a modest number of them have been issued? --- doc/fixes37.0 | 4 +++- include/extern.h | 4 ++-- include/flag.h | 3 ++- src/mon.c | 52 +++++++++++++++++++++++++++++++++++++++--------- src/sounds.c | 10 +++++----- 5 files changed, 55 insertions(+), 18 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c0fc2b284..ed3b14e18 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.308 $ $NHDT-Date: 1600909016 2020/09/24 00:56:56 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.309 $ $NHDT-Date: 1600933440 2020/09/24 07:44:00 $ General Fixes and Modified Features ----------------------------------- @@ -254,6 +254,8 @@ handle being interrupted by approaching monsters more consistently if hero attacked a peaceful monster, some other peaceful monsters with humanoid shape (minotaur, zruty, perhaps others) that witnessed it but which shouldn't be capable of normal speech expressed their surprise audibly +make gasp/exclamation message from peaceful monsters be more verbose to + indicate which monster is doing the gasping or exclaiming when make was invoked with -j makedefs instances could end up running in parallel and could trample on each other's temp files; default to using mkstemp(); allow a port runtime library implementation that lacks diff --git a/include/extern.h b/include/extern.h index 014487499..1366ec92e 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1600652305 2020/09/21 01:38:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.858 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1600933440 2020/09/24 07:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.859 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2442,7 +2442,7 @@ E void FDECL(growl, (struct monst *)); E void FDECL(yelp, (struct monst *)); E void FDECL(whimper, (struct monst *)); E void FDECL(beg, (struct monst *)); -E boolean FDECL(maybe_gasp, (struct monst *)); +E const char *FDECL(maybe_gasp, (struct monst *)); E int NDECL(dotalk); E int NDECL(tiphat); #ifdef USER_SOUNDS diff --git a/include/flag.h b/include/flag.h index 6750e336f..ddb86720d 100644 --- a/include/flag.h +++ b/include/flag.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 flag.h $NHDT-Date: 1593953335 2020/07/05 12:48:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */ +/* NetHack 3.7 flag.h $NHDT-Date: 1600933440 2020/09/24 07:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -408,6 +408,7 @@ enum plnmsg_types { PLNMSG_OBJNAM_ONLY, /* xname/doname only, for #tip */ PLNMSG_OK_DONT_DIE, /* overriding death in explore/wizard mode */ PLNMSG_BACK_ON_GROUND, /* leaving water */ + PLNMSG_GROWL, /* growl() gave some message */ PLNMSG_enum /* allows inserting new entries with unconditional trailing comma */ }; diff --git a/src/mon.c b/src/mon.c index e3d800b4c..c90ddcb28 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1600652305 2020/09/21 01:38:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1600933441 2020/09/24 07:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3138,6 +3138,9 @@ boolean via_attack; mtmp->mstrategy &= ~STRAT_WAITMASK; if (!mtmp->mpeaceful) return; + /* [FIXME: this logic seems wrong; peaceful humanoids gasp or exclaim + when they see you attack a peaceful monster but they just casually + look the other way when you attack a pet?] */ if (mtmp->mtame) return; mtmp->mpeaceful = 0; @@ -3196,25 +3199,50 @@ boolean via_attack; if (!mindless(mon->data) && mon->mpeaceful && couldsee(mon->mx, mon->my) && !mon->msleeping && mon->mcansee && m_canseeu(mon)) { - boolean exclaimed = FALSE; + char buf[BUFSZ]; + boolean exclaimed = FALSE, needpunct = FALSE, alreadyfleeing; + buf[0] = '\0'; if (humanoid(mon->data) || mon->isshk || mon->ispriest) { if (is_watch(mon->data)) { verbalize("Halt! You're under arrest!"); (void) angry_guards(!!Deaf); } else { - if (!rn2(5)) { - exclaimed = maybe_gasp(mon); + if (!Deaf && !rn2(5)) { + const char *gasp = maybe_gasp(mon); + + if (gasp) { + if (!strncmpi(gasp, "gasp", 4)) { + Sprintf(buf, "%s gasps", Monnam(mon)); + needpunct = TRUE; + } else { + Sprintf(buf, "%s exclaims \"%s\"", + Monnam(mon), gasp); + } + exclaimed = TRUE; + } } /* shopkeepers and temple priests might gasp in surprise, but they won't become angry here */ - if (mon->isshk || mon->ispriest) + if (mon->isshk || mon->ispriest) { + if (exclaimed) + pline("%s%s", buf, " then shrugs."); continue; + } if (mon->data->mlevel < rn2(10)) { + alreadyfleeing = (mon->mflee || mon->mfleetim); monflee(mon, rn2(50) + 25, TRUE, !exclaimed); - exclaimed = TRUE; + if (exclaimed) { + if (flags.verbose && !alreadyfleeing) { + Strcat(buf, " and then turns to flee."); + needpunct = FALSE; + } + } else + exclaimed = TRUE; /* got msg from monflee() */ } + if (*buf) + pline("%s%s", buf, needpunct ? "." : ""); if (mon->mtame) { ; /* mustn't set mpeaceful to 0 as below; * perhaps reduce tameness? */ @@ -3228,12 +3256,18 @@ boolean via_attack; } else if (mon->data->mlet == mtmp->data->mlet && big_little_match(mndx, monsndx(mon->data)) && !rn2(3)) { - if (!rn2(4)) { + if (!Deaf && !rn2(4)) { growl(mon); - exclaimed = TRUE; + exclaimed = (iflags.last_msg == PLNMSG_GROWL); } - if (rn2(6)) + if (rn2(6)) { + alreadyfleeing = (mon->mflee || mon->mfleetim); monflee(mon, rn2(25) + 15, TRUE, !exclaimed); + if (exclaimed && !alreadyfleeing) + /* word like a separate sentence so that we + don't have to poke around inside growl() */ + pline("And then starts to flee."); + } } } } diff --git a/src/sounds.c b/src/sounds.c index 0059743ce..75b0de790 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sounds.c $NHDT-Date: 1600652306 2020/09/21 01:38:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ +/* NetHack 3.7 sounds.c $NHDT-Date: 1600933442 2020/09/24 07:44:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.103 $ */ /* Copyright (c) 1989 Janet Walz, Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -369,6 +369,7 @@ register struct monst *mtmp; growl_verb = growl_sound(mtmp); if (growl_verb) { pline("%s %s!", Monnam(mtmp), vtense((char *) 0, growl_verb)); + iflags.last_msg = PLNMSG_GROWL; if (g.context.run) nomul(0); wake_nearto(mtmp->mx, mtmp->my, mtmp->data->mlevel * 18); @@ -480,7 +481,7 @@ register struct monst *mtmp; } /* hero has attacked a peaceful monster within 'mon's view */ -boolean +const char * maybe_gasp(mon) struct monst *mon; { @@ -542,10 +543,9 @@ struct monst *mon; break; } if (dogasp) { - verbalize("%s", Exclam[mon->m_id % SIZE(Exclam)]); - return TRUE; + return Exclam[rn2(SIZE(Exclam))]; /* [mon->m_id % SIZE(Exclam)]; */ } - return FALSE; + return (const char *) 0; } /* return True if mon is a gecko or seems to look like one (hallucination) */ From 87e2d974efef7025b639bdf536f463d96528f10a Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 26 Sep 2020 19:35:37 -0700 Subject: [PATCH 217/708] Qt popup_dialog tinkering Some changes to the YnDialog widget used when popup_dialog is On. If a button is labelled with a space, it just looks like an unlabelled button. Switch to "Spc" for space, "Ent" for \n and "Ret" for \r. (The last two aren't completely logical but I haven't seen any dialogs that need them and they'll be better than "^J" and "^M" if there are such.) For yn#aq dialogs, preload a grayed-out "#" in the count widget. Just for show; has no tangible effect. The count widget should return long rather than plain int. --- win/Qt/qt_yndlg.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 3924050da..110f2b784 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -160,6 +160,18 @@ char NetHackQtYnDialog::Exec() int butheight = fontMetrics().height() * 2 + 5, butwidth = (butheight - 5) * ((is_ynq || is_lr) ? 3 : is_yn ? 2 : 1) + 5; + if (butwidth == butheight) { // square, room for one character or ^c + // some characters will be labelled by name rather than by + // keystroke so will need wider buttons + for (int i = 0; i < nchoices; ++i) { + if (ch[i] == '\033') + break; // ESC and anything after are hidden + if (ch[i] == ' ' || ch[i] == '\n' || ch[i] == '\r') { + butwidth = (butheight - 5) * 2 + 5; + break; + } + } + } QPushButton *button; for (int i = 0; i < nchoices; ++i) { @@ -191,6 +203,26 @@ char NetHackQtYnDialog::Exec() button_name = "Right"; break; } + } else { + // special characters usually aren't listed among choices + // but if they are, label the buttons for them with sensible + // names; we want to avoid "^J" and "^M" for \n and \r; + // and are equivalent to each other but + // labelling \n as newline or line-feed seems confusing; + switch (ch[i].cell()) { + case ' ': + button_name = "Spc"; + break; + case '\n': + button_name = "Ent"; + break; + case '\r': + button_name = "Ret"; + break; + case '\033': // won't happen; ESC is hidden + button_name = "Esc"; + break; + } } button=new QPushButton(button_name); if (!enable.isNull()) { @@ -223,6 +255,7 @@ char NetHackQtYnDialog::Exec() groupbox->insertWidget(1, lb); // [n] button is item #1 le = new QLineEdit(); groupbox->insertWidget(2, le); // [n] became #2, Count label #1 + le->setPlaceholderText(QString("#")); // grayed out } // add an invisible right-most field to left justify the buttons groupbox->addStretch(80); @@ -271,6 +304,7 @@ char NetHackQtYnDialog::Exec() // 0 will be preselected; typing anything replaces it le->insert(QString("0")); } else { +#if 1 le->insert(QString(choice)); // // FIXME: despite the documentation claiming that @@ -281,6 +315,13 @@ char NetHackQtYnDialog::Exec() // right-arrow to move the cursor. // le->end(false); +#else + // this also claims to cancel any selection and + // position the cursor after the text but actually + // leaves the digit selected, ready to be overwritten + le->setText(QString(choice)); + le->setModified(true); +#endif } // (don't know whether this actually does anything useful) le->setAttribute(Qt::WA_KeyboardFocusChange, true); @@ -290,9 +331,10 @@ char NetHackQtYnDialog::Exec() } } while (retry); - // non-Null 'le' implies 'allow_count' + // non-Null 'le' implies 'allow_count'; having a grayed-out '#' + // present in the QLineEdit widget doesn't affect its isEmpty() test if (le && !le->text().isEmpty()) { - ::yn_number = le->text().toInt(); + ::yn_number = le->text().toLong(); choice = '#'; } keypress = choice; From 3e0c0f6f0f793e86d84a3c0ae3411ac2465e2e37 Mon Sep 17 00:00:00 2001 From: copperwater Date: Fri, 18 Sep 2020 19:10:54 -0400 Subject: [PATCH 218/708] Fix the "stuck pets" bug (github issue #329) This commit is intended to fix the bug where a pet will get fixated on an unmoving monster and stop moving itself. I described the cause in the github issue; the gist is that the pet AI chooses the unmoving monster as its ranged target, doesn't do anything when it calls mattackm (because it doesn't have ranged attacks), then returns a value indicating it didn't move and can't take further actions. I initially implemented a fix that refactored mattackm to distinguish between "attacker missed" and "attacker did nothing", which the pet AI could then use to determine whether the pet could continue doing things. But then I realized that if mattackm is called with non-adjacent monsters, a return of MM_MISS more or less unambiguously indicates that the attacker did nothing (because the ranged functions it calls like breamm don't actually check to see whether the target was hit, just whether the monster initiated the attack.) So, this only really needed to check whether mattackm returned with MM_MISS. I also found a probable bug in mattackm, in that the thrwmm call isn't treated the same as breamm or spitmm. In the latter two, mattackm returns MM_HIT even though it doesn't check whether the ranged attack actually hit its target. But there was no logic doing the same for thrwmm, so this commit also adds that. (Otherwise, a pet could possibly use a ranged weapon attack and then get to keep moving on its turn.) --- src/dogmove.c | 21 +++++++++++++++++++-- src/mhitm.c | 3 +++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/dogmove.c b/src/dogmove.c index ad24f9674..30a2f8725 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1156,11 +1156,17 @@ int after; /* this is extra fast monster movement */ /* Hungry pets are unlikely to use breath/spit attacks */ if (mtarg && (!hungry || !rn2(5))) { - int mstatus; + int mstatus = MM_MISS; if (mtarg == &g.youmonst) { if (mattacku(mtmp)) return 2; + /* Treat this as the pet having initiated an attack even if it + * didn't, so it will lose its move. This isn't entirely fair, + * but mattacku doesn't distinguish between "did not attack" and + * "attacked but didn't die" cases, and this is preferable to + * letting the pet attack the player and continuing to move */ + mstatus = MM_HIT; } else { mstatus = mattackm(mtmp, mtarg); @@ -1187,7 +1193,18 @@ int after; /* this is extra fast monster movement */ } } } - return 3; + /* Only return 3 if the pet actually made a ranged attack, and thus + * should lose the rest of its move. + * There's a chain of assumptions here: + * 1. score_targ and best_target will never select a monster that + * can be attacked in melee, so the mattackm call can only ever + * try ranged options + * 2. if the only attacks available to mattackm are ranged options, + * and the monster cannot make a ranged attack, it will return + * MM_MISS. + */ + if (mstatus != MM_MISS) + return 3; } } diff --git a/src/mhitm.c b/src/mhitm.c index 37cf537eb..e848c1d99 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -368,6 +368,9 @@ register struct monst *magr, *mdef; if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1) { /* D: Do a ranged attack here! */ strike = thrwmm(magr, mdef); + if (strike) + /* We don't really know if we hit or not; pretend we did. */ + res[i] |= MM_HIT; if (DEADMONSTER(mdef)) res[i] = MM_DEF_DIED; if (DEADMONSTER(magr)) From 0b2b0965a8d4e4cafe9fd1bb1f8f0d20230b1e30 Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 17 May 2020 21:21:10 -0400 Subject: [PATCH 219/708] Allow themed room subrooms to be filled I noticed that any subrooms created within a themed room were bare - they never had any monsters, objects, traps, or anything really, regardless of whether filled = 1 was set on them. As a result, they're pretty boring. It turns out that the code in makelevel() responsible for stocking ordinary rooms with stuff only looped through g.rooms, and completely ignored subrooms. (Subrooms would not get stocked with items by virtue of being part of the larger room; I tested this by dialing the item generation in rooms way up, and none of those items ever got placed in a subroom.) To fix this, I've extracted the code that populates an ordinary room into its own function, fill_ordinary_room, and made it recurse into its own subrooms. (I also renamed fill_rooms and fill_room to include the word "special" in their names, because they only deal with special rooms.) Note that since special rooms follow a separate codepath, an ordinary subroom of a special room won't get stocked; perhaps these functions should be unified in the future. The fill_ordinary_room code is pretty much a verbatim cut and paste from makelevel, so there is not currently any consideration for the size of the subroom or the fact that it is a subroom with respect to how many monsters, traps, objects, etc get placed. I'm not sure whether other things such as stair selection will ever select themed room subrooms, or whether they too only look at g.rooms. --- include/extern.h | 2 +- src/mklev.c | 195 ++++++++++++++++++++++++++--------------------- src/sp_lev.c | 12 +-- 3 files changed, 114 insertions(+), 95 deletions(-) diff --git a/include/extern.h b/include/extern.h index 1366ec92e..79708ebfe 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2467,7 +2467,7 @@ E boolean FDECL(create_room, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); E void FDECL(create_secret_door, (struct mkroom *, XCHAR_P)); E boolean FDECL(dig_corridor, (coord *, coord *, BOOLEAN_P, SCHAR_P, SCHAR_P)); -E void FDECL(fill_room, (struct mkroom *, BOOLEAN_P)); +E void FDECL(fill_special_room, (struct mkroom *, BOOLEAN_P)); E boolean FDECL(load_special, (const char *)); E xchar FDECL(selection_getpoint, (int, int, struct selectionvar *)); E struct selectionvar *NDECL(selection_new); diff --git a/src/mklev.c b/src/mklev.c index 7f316b8db..b4d7efe07 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -19,6 +19,7 @@ static void FDECL(mkaltar, (struct mkroom *)); static void FDECL(mkgrave, (struct mkroom *)); static void NDECL(makevtele); void NDECL(clear_level_structures); +static void FDECL(fill_ordinary_room, (struct mkroom *)); static void NDECL(makelevel); static boolean FDECL(bydoor, (XCHAR_P, XCHAR_P)); static struct mkroom *FDECL(find_branch_room, (coord *)); @@ -734,13 +735,114 @@ clear_level_structures() } } +/* Fill a "random" room (i.e. a typical non-special room in the Dungeons of + * Doom) with random monsters, objects, and dungeon features. + */ +static void +fill_ordinary_room(croom) +struct mkroom *croom; +{ + int trycnt = 0; + coord pos; + struct monst *tmonst; /* always put a web with a spider */ + int x, y; + + if (croom->rtype != OROOM && croom->rtype != THEMEROOM) + return; + + /* If there are subrooms, fill them now - we don't want an outer room + * that's specified to be unfilled to block an inner subroom that's + * specified to be filled. */ + for (x = 0; x < croom->nsubrooms; ++x) { + fill_ordinary_room(croom->sbrooms[x]); + } + + if (!croom->needfill) + return; + + /* put a sleeping monster inside */ + /* Note: monster may be on the stairs. This cannot be + avoided: maybe the player fell through a trap door + while a monster was on the stairs. Conclusion: + we have to check for monsters on the stairs anyway. */ + + if ((u.uhave.amulet || !rn2(3)) && somexyspace(croom, &pos)) { + tmonst = makemon((struct permonst *) 0, pos.x, pos.y, MM_NOGRP); + if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] + && !occupied(pos.x, pos.y)) + (void) maketrap(pos.x, pos.y, WEB); + } + /* put traps and mimics inside */ + x = 8 - (level_difficulty() / 6); + if (x <= 1) + x = 2; + while (!rn2(x) && (++trycnt < 1000)) + mktrap(0, 0, croom, (coord *) 0); + if (!rn2(3) && somexyspace(croom, &pos)) + (void) mkgold(0L, pos.x, pos.y); + if (Is_rogue_level(&u.uz)) + goto skip_nonrogue; + if (!rn2(10)) + mkfount(0, croom); + if (!rn2(60)) + mksink(croom); + if (!rn2(60)) + mkaltar(croom); + x = 80 - (depth(&u.uz) * 2); + if (x < 2) + x = 2; + if (!rn2(x)) + mkgrave(croom); + + /* put statues inside */ + if (!rn2(20) && somexyspace(croom, &pos)) + (void) mkcorpstat(STATUE, (struct monst *) 0, + (struct permonst *) 0, pos.x, + pos.y, CORPSTAT_INIT); + /* put box/chest inside; + * 40% chance for at least 1 box, regardless of number + * of rooms; about 5 - 7.5% for 2 boxes, least likely + * when few rooms; chance for 3 or more is negligible. + */ + if (!rn2(g.nroom * 5 / 2) && somexyspace(croom, &pos)) + (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, + pos.x, pos.y, TRUE, FALSE); + + /* maybe make some graffiti */ + if (!rn2(27 + 3 * abs(depth(&u.uz)))) { + char buf[BUFSZ]; + const char *mesg = random_engraving(buf); + + if (mesg) { + do { + somexyspace(croom, &pos); + x = pos.x; + y = pos.y; + } while (levl[x][y].typ != ROOM && !rn2(40)); + if (!(IS_POOL(levl[x][y].typ) + || IS_FURNITURE(levl[x][y].typ))) + make_engr_at(x, y, mesg, 0L, MARK); + } + } + + skip_nonrogue: + if (!rn2(3) && somexyspace(croom, &pos)) { + (void) mkobj_at(0, pos.x, pos.y, TRUE); + trycnt = 0; + while (!rn2(5)) { + if (++trycnt > 100) { + impossible("trycnt overflow4"); + break; + } + (void) mkobj_at(0, pos.x, pos.y, TRUE); + } + } +} + static void makelevel() { register struct mkroom *croom; - register int tryct; - register int x, y; - struct monst *tmonst; /* always put a web with a spider */ branch *branchp; int room_threshold; @@ -814,7 +916,7 @@ makelevel() TRUE, VAULT, FALSE); g.level.flags.has_vault = 1; ++room_threshold; - fill_room(&g.rooms[g.nroom - 1], FALSE); + fill_special_room(&g.rooms[g.nroom - 1], FALSE); mk_knox_portal(g.vault_x + w, g.vault_y + h); if (!g.level.flags.noteleport && !rn2(3)) makevtele(); @@ -868,90 +970,7 @@ makelevel() /* for each room: put things inside */ for (croom = g.rooms; croom->hx > 0; croom++) { - int trycnt = 0; - coord pos; - if (croom->rtype != OROOM && croom->rtype != THEMEROOM) - continue; - if (!croom->needfill) - continue; - - /* put a sleeping monster inside */ - /* Note: monster may be on the stairs. This cannot be - avoided: maybe the player fell through a trap door - while a monster was on the stairs. Conclusion: - we have to check for monsters on the stairs anyway. */ - - if ((u.uhave.amulet || !rn2(3)) && somexyspace(croom, &pos)) { - tmonst = makemon((struct permonst *) 0, pos.x, pos.y, MM_NOGRP); - if (tmonst && tmonst->data == &mons[PM_GIANT_SPIDER] - && !occupied(pos.x, pos.y)) - (void) maketrap(pos.x, pos.y, WEB); - } - /* put traps and mimics inside */ - x = 8 - (level_difficulty() / 6); - if (x <= 1) - x = 2; - while (!rn2(x) && (++trycnt < 1000)) - mktrap(0, 0, croom, (coord *) 0); - if (!rn2(3) && somexyspace(croom, &pos)) - (void) mkgold(0L, pos.x, pos.y); - if (Is_rogue_level(&u.uz)) - goto skip_nonrogue; - if (!rn2(10)) - mkfount(0, croom); - if (!rn2(60)) - mksink(croom); - if (!rn2(60)) - mkaltar(croom); - x = 80 - (depth(&u.uz) * 2); - if (x < 2) - x = 2; - if (!rn2(x)) - mkgrave(croom); - - /* put statues inside */ - if (!rn2(20) && somexyspace(croom, &pos)) - (void) mkcorpstat(STATUE, (struct monst *) 0, - (struct permonst *) 0, pos.x, - pos.y, CORPSTAT_INIT); - /* put box/chest inside; - * 40% chance for at least 1 box, regardless of number - * of rooms; about 5 - 7.5% for 2 boxes, least likely - * when few rooms; chance for 3 or more is negligible. - */ - if (!rn2(g.nroom * 5 / 2) && somexyspace(croom, &pos)) - (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, - pos.x, pos.y, TRUE, FALSE); - - /* maybe make some graffiti */ - if (!rn2(27 + 3 * abs(depth(&u.uz)))) { - char buf[BUFSZ]; - const char *mesg = random_engraving(buf); - - if (mesg) { - do { - somexyspace(croom, &pos); - x = pos.x; - y = pos.y; - } while (levl[x][y].typ != ROOM && !rn2(40)); - if (!(IS_POOL(levl[x][y].typ) - || IS_FURNITURE(levl[x][y].typ))) - make_engr_at(x, y, mesg, 0L, MARK); - } - } - - skip_nonrogue: - if (!rn2(3) && somexyspace(croom, &pos)) { - (void) mkobj_at(0, pos.x, pos.y, TRUE); - tryct = 0; - while (!rn2(5)) { - if (++tryct > 100) { - impossible("tryct overflow4"); - break; - } - (void) mkobj_at(0, pos.x, pos.y, TRUE); - } - } + fill_ordinary_room(croom); } } diff --git a/src/sp_lev.c b/src/sp_lev.c index 5d63476c2..bf6096e32 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -40,7 +40,7 @@ static void NDECL(remove_boundary_syms); static void FDECL(set_door_orientation, (int, int)); static void FDECL(maybe_add_door, (int, int, struct mkroom *)); static void NDECL(link_doors_rooms); -static void NDECL(fill_rooms); +static void NDECL(fill_special_rooms); static int NDECL(rnddoor); static int NDECL(rndtrap); static void FDECL(get_location, (schar *, schar *, int, struct mkroom *)); @@ -1036,16 +1036,16 @@ link_doors_rooms() } static void -fill_rooms() +fill_special_rooms() { int tmpi, m; for (tmpi = 0; tmpi < g.nroom; tmpi++) { if (g.rooms[tmpi].needfill) - fill_room(&g.rooms[tmpi], (g.rooms[tmpi].needfill == 2)); + fill_special_room(&g.rooms[tmpi], (g.rooms[tmpi].needfill == 2)); for (m = 0; m < g.rooms[tmpi].nsubrooms; m++) if (g.rooms[tmpi].sbrooms[m]->needfill) - fill_room(g.rooms[tmpi].sbrooms[m], FALSE); + fill_special_room(g.rooms[tmpi].sbrooms[m], FALSE); } } @@ -2682,7 +2682,7 @@ corridor *c; * Fill a room (shop, zoo, etc...) with appropriate stuff. */ void -fill_room(croom, prefilled) +fill_special_room(croom, prefilled) struct mkroom *croom; boolean prefilled; { @@ -6419,7 +6419,7 @@ const char *name; goto give_up; link_doors_rooms(); - fill_rooms(); + fill_special_rooms(); remove_boundary_syms(); /* TODO: ensure_way_out() needs rewrite */ From f57588cef1d5a3b75dfd0d21a298e630e9eda8f6 Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 17 May 2020 21:47:10 -0400 Subject: [PATCH 220/708] Make fill_special_room avoid themed rooms No code in this function would actually do anything if it were called on a themed room, but since it is pretty clearly intended for the "regular" special rooms, it's probably best to explicitly avoid themed rooms as well. --- src/sp_lev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index bf6096e32..b3b369c73 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -2686,7 +2686,7 @@ fill_special_room(croom, prefilled) struct mkroom *croom; boolean prefilled; { - if (!croom || croom->rtype == OROOM) + if (!croom || croom->rtype == OROOM || croom->rtype == THEMEROOM) return; if (!prefilled) { From 0fef8fce9ffab9b0378ff1af3493c470d6d0ad17 Mon Sep 17 00:00:00 2001 From: copperwater Date: Tue, 19 May 2020 00:13:41 -0400 Subject: [PATCH 221/708] Unify all special level filling options The existing system was a confusing mess of competing names (filled, needfill, prefilled, etc) that had varying semantics, with prefilled being the worst offender as it meant at least three different things in various contexts. This commit unifies everything in the code under "needfill", and everything in Lua under "filled", which defaults to 0 everywhere. This also removes the second argument to fill_special_room; that function now just checks the needfill of the room it's passed. As before, a filled == 2 value is used for a special room to indicate that the room should set the appropriate level flag, but shouldn't actually be stocked with anything (for instance, King Arthur's throne room); the difference is that this now comes directly from the lua script instead of being manipulated within sp_lev.c. The prefilled argument had one use case that is occasionally used in the level files: if the level designer had specified an ordinary region with prefilled = 1, it would become a room to control monster arrivals on a level -- monsters that arrive within the bounds of a room are supposed to stay there. However, not all of the places where the comments indicated this was being used were using it correctly; I tested this by letting a few monsters fall through the knox portal (they're supposed to be constrained to the entry room) and waiting a hundred turns, then going through the portal; they were not constrained to the room and had "wandered" through its walls. Instead of trying to maintain this special case, I have added an optional "arrival_room" boolean argument to des.region, which forces it to create a room for the purposes of constraining monster arrival. I have gone through and replaced occurrences of prefilled in lua files with the appropriate filled option (or arrival, as needed). In some cases, that resulted in questionable regions such as a filled ordinary area in a non-themeroom (I just dropped the filled=1), or an area which didn't do anything, not even lighting (which I deleted). --- dat/Arc-goal.lua | 2 +- dat/Arc-loca.lua | 14 ++++++------- dat/Cav-loca.lua | 2 +- dat/Cav-strt.lua | 14 ++++++------- dat/Kni-strt.lua | 2 +- dat/Pri-loca.lua | 10 ++++----- dat/Sam-strt.lua | 2 +- dat/Tou-loca.lua | 16 +++++++-------- dat/Tou-strt.lua | 2 +- dat/Wiz-loca.lua | 10 ++++----- dat/Wiz-strt.lua | 2 +- dat/astral.lua | 6 +++--- dat/castle.lua | 6 +++--- dat/fakewiz1.lua | 2 +- dat/fakewiz2.lua | 1 - dat/knox.lua | 8 ++++---- dat/medusa-1.lua | 4 ++-- dat/medusa-2.lua | 5 +++-- dat/medusa-3.lua | 2 +- dat/medusa-4.lua | 1 - dat/minend-1.lua | 4 ++-- dat/minetn-5.lua | 8 ++++---- dat/minetn-6.lua | 10 ++++----- dat/orcus.lua | 6 +++--- dat/sanctum.lua | 2 +- dat/soko1-1.lua | 3 +-- dat/soko1-2.lua | 3 +-- dat/themerms.lua | 39 +++++++++++++++++------------------ dat/valley.lua | 6 +++--- dat/wizard1.lua | 4 ++-- dat/wizard2.lua | 4 ++-- dat/wizard3.lua | 7 +++---- doc/lua.adoc | 8 ++++---- include/extern.h | 2 +- include/mkroom.h | 8 ++++++++ include/sp_lev.h | 2 +- src/mklev.c | 4 ++-- src/sp_lev.c | 52 ++++++++++++++++++++++++----------------------- test/test_des.lua | 4 ++-- 39 files changed, 146 insertions(+), 141 deletions(-) diff --git a/dat/Arc-goal.lua b/dat/Arc-goal.lua index ba3a00555..8cdf65e8c 100644 --- a/dat/Arc-goal.lua +++ b/dat/Arc-goal.lua @@ -52,7 +52,7 @@ des.region(selection.area(35,16,36,17), "unlit") des.region(selection.area(38,13,38,17), "unlit") des.region(selection.area(40,13,41,14), "unlit") des.region(selection.area(40,16,41,17), "unlit") -des.region({ region={43,13, 50,15}, lit=0, type="temple", prefilled=0 }) +des.region({ region={43,13, 50,15}, lit=0, type="temple", filled=2 }) des.region(selection.area(52,13,52,15), "unlit") -- Stairs des.stair("up", 38,10) diff --git a/dat/Arc-loca.lua b/dat/Arc-loca.lua index 31776ac52..93ab61fee 100644 --- a/dat/Arc-loca.lua +++ b/dat/Arc-loca.lua @@ -31,18 +31,18 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") -des.region({ region={25,04, 28,07}, lit=1, type="temple", prefilled=0 }) -des.region({ region={25,09, 28,11}, lit=0, type="temple", prefilled=0 }) -des.region({ region={25,13, 28,16}, lit=1, type="temple", prefilled=0 }) +des.region({ region={25,04, 28,07}, lit=1, type="temple", filled=2 }) +des.region({ region={25,09, 28,11}, lit=0, type="temple", filled=2 }) +des.region({ region={25,13, 28,16}, lit=1, type="temple", filled=2 }) des.region(selection.area(30,04,30,16), "lit") des.region(selection.area(32,04,32,16), "unlit") -des.region({ region={33,04, 53,04}, lit=0, type="ordinary", prefilled=0, irregular=1 }) +des.region({ region={33,04, 53,04}, lit=0, type="ordinary", irregular=1 }) des.region(selection.area(36,10,37,10), "unlit") des.region(selection.area(39,09,39,11), "unlit") -des.region({ region={36,06, 42,08}, lit=0, type="ordinary", prefilled=0, irregular=1 }) -des.region({ region={36,12, 42,14}, lit=0, type="ordinary", prefilled=0, irregular=1 }) +des.region({ region={36,06, 42,08}, lit=0, type="ordinary", irregular=1 }) +des.region({ region={36,12, 42,14}, lit=0, type="ordinary", irregular=1 }) des.region(selection.area(46,06,51,09), "unlit") -des.region({ region={46,11, 49,11}, lit=0, type="ordinary", prefilled=0, irregular=1 }) +des.region({ region={46,11, 49,11}, lit=0, type="ordinary", irregular=1 }) des.region(selection.area(48,13,51,14), "unlit") -- Doors des.door("closed",31,04) diff --git a/dat/Cav-loca.lua b/dat/Cav-loca.lua index 8406a5dd6..a9dfe1a07 100644 --- a/dat/Cav-loca.lua +++ b/dat/Cav-loca.lua @@ -31,7 +31,7 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "unlit") -des.region({ region={52,06, 73,15}, lit=1, type="ordinary", prefilled=0, irregular=1 }) +des.region({ region={52,06, 73,15}, lit=1, type="ordinary", irregular=1 }) -- Doors des.door("locked",28,11) -- Stairs diff --git a/dat/Cav-strt.lua b/dat/Cav-strt.lua index 1dfe83628..83c071d0c 100644 --- a/dat/Cav-strt.lua +++ b/dat/Cav-strt.lua @@ -37,14 +37,14 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "unlit") -des.region({ region={13,01, 40,05}, lit=1, type="temple", prefilled=0, irregular=1 }) +des.region({ region={13,01, 40,05}, lit=1, type="temple", filled=1, irregular=1 }) -- The occupied rooms. -des.region({ region={02,01, 08,03}, lit=1, type="ordinary", prefilled=0, irregular=1 }) -des.region({ region={01,11, 06,14}, lit=1, type="ordinary", prefilled=0, irregular=1 }) -des.region({ region={13,08, 18,10}, lit=1, type="ordinary", prefilled=0, irregular=1 }) -des.region({ region={05,17, 14,18}, lit=1, type="ordinary", prefilled=0, irregular=1 }) -des.region({ region={17,16, 23,18}, lit=1, type="ordinary", prefilled=0, irregular=1 }) -des.region({ region={35,16, 44,18}, lit=1, type="ordinary", prefilled=0, irregular=1 }) +des.region({ region={02,01, 08,03}, lit=1, type="ordinary", irregular=1 }) +des.region({ region={01,11, 06,14}, lit=1, type="ordinary", irregular=1 }) +des.region({ region={13,08, 18,10}, lit=1, type="ordinary", irregular=1 }) +des.region({ region={05,17, 14,18}, lit=1, type="ordinary", irregular=1 }) +des.region({ region={17,16, 23,18}, lit=1, type="ordinary", irregular=1 }) +des.region({ region={35,16, 44,18}, lit=1, type="ordinary", irregular=1 }) -- Stairs des.stair("down", 02,03) -- Portal arrival point diff --git a/dat/Kni-strt.lua b/dat/Kni-strt.lua index 7d43f61c4..4442d93a7 100644 --- a/dat/Kni-strt.lua +++ b/dat/Kni-strt.lua @@ -36,7 +36,7 @@ des.map([[ -- Dungeon Description des.region(selection.area(00,00,49,15), "lit") des.region(selection.area(04,04,45,11), "unlit") -des.region({ region={06,06,22,09}, lit=1, type="throne", prefilled=1 }) +des.region({ region={06,06,22,09}, lit=1, type="throne", filled=2 }) des.region(selection.area(27,06,43,09), "lit") -- Portal arrival point des.levregion({ region = {20,14,20,14}, type="branch" }) diff --git a/dat/Pri-loca.lua b/dat/Pri-loca.lua index 9ebd55300..5583ac270 100644 --- a/dat/Pri-loca.lua +++ b/dat/Pri-loca.lua @@ -26,11 +26,11 @@ des.map([[ ........................................ ]]); -- Dungeon Description -des.region({ region={00,00, 09,13}, lit=0, type="morgue", prefilled=0 }) -des.region({ region={09,00, 30,01}, lit=0, type="morgue", prefilled=0 }) -des.region({ region={09,12, 30,13}, lit=0, type="morgue", prefilled=0 }) -des.region({ region={31,00, 39,13}, lit=0, type="morgue", prefilled=0 }) -des.region({ region={11,03, 29,10}, lit=1, type="temple", prefilled=0, irregular=1 }) +des.region({ region={00,00, 09,13}, lit=0, type="morgue", filled=1 }) +des.region({ region={09,00, 30,01}, lit=0, type="morgue", filled=1 }) +des.region({ region={09,12, 30,13}, lit=0, type="morgue", filled=1 }) +des.region({ region={31,00, 39,13}, lit=0, type="morgue", filled=1 }) +des.region({ region={11,03, 29,10}, lit=1, type="temple", filled=1, irregular=1 }) -- The altar inside the temple des.altar({ x=20,y=07, align="noalign", type="shrine" }) des.monster({ id = "aligned priest", x=20, y=07, align="noalign", peaceful = 0 }) diff --git a/dat/Sam-strt.lua b/dat/Sam-strt.lua index ec865ab5d..8186c3cb4 100644 --- a/dat/Sam-strt.lua +++ b/dat/Sam-strt.lua @@ -37,7 +37,7 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") -des.region({ region={18,03, 26,07}, lit=1, type="throne", prefilled=1 }) +des.region({ region={18,03, 26,07}, lit=1, type="throne", filled=2 }) -- Portal arrival zone des.levregion({ region = {62,12,70,17}, type="branch" }) -- Stairs diff --git a/dat/Tou-loca.lua b/dat/Tou-loca.lua index d32a7911f..808d45faa 100644 --- a/dat/Tou-loca.lua +++ b/dat/Tou-loca.lua @@ -32,14 +32,14 @@ des.map([[ des.region(selection.area(00,00,75,19), "lit") des.non_diggable(selection.area(00,00,75,19)) -- -des.region({ region={01,01, 04,05}, lit=0, type="morgue", prefilled = 0 }) -des.region({ region={15,03, 20,05}, lit=1, type="shop", prefilled = 0 }) -des.region({ region={62,03, 71,04}, lit=1, type="shop", prefilled = 0 }) -des.region({ region={01,17, 11,18}, lit=1, type="barracks", prefilled = 0 }) -des.region({ region={12,09, 20,10}, lit=1, type="barracks", prefilled = 0 }) -des.region({ region={53,11, 59,14}, lit=1, type="zoo", prefilled = 0 }) -des.region({ region={63,14, 72,16}, lit=1, type="barracks", prefilled = 0 }) -des.region({ region={32,14, 40,16}, lit=1, type="temple", prefilled = 0 }) +des.region({ region={01,01, 04,05}, lit=0, type="morgue", filled=1 }) +des.region({ region={15,03, 20,05}, lit=1, type="shop", filled=1 }) +des.region({ region={62,03, 71,04}, lit=1, type="shop", filled=1 }) +des.region({ region={01,17, 11,18}, lit=1, type="barracks", filled=1 }) +des.region({ region={12,09, 20,10}, lit=1, type="barracks", filled=1 }) +des.region({ region={53,11, 59,14}, lit=1, type="zoo", filled=1 }) +des.region({ region={63,14, 72,16}, lit=1, type="barracks", filled=1 }) +des.region({ region={32,14, 40,16}, lit=1, type="temple", filled=1 }) -- des.region({ region = {06,01,11,02}, type = "ordinary" }) des.region({ region = {24,01,29,02}, type = "ordinary" }) diff --git a/dat/Tou-strt.lua b/dat/Tou-strt.lua index 60891c8c4..c5efa0d29 100644 --- a/dat/Tou-strt.lua +++ b/dat/Tou-strt.lua @@ -36,7 +36,7 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") -des.region({ region={14,01, 20,03}, lit=0, type="morgue", prefilled=0 }) +des.region({ region={14,01, 20,03}, lit=0, type="morgue", filled=1 }) des.region(selection.area(07,10,11,12), "unlit") des.region(selection.area(04,16,08,18), "unlit") des.region(selection.area(17,16,21,18), "unlit") diff --git a/dat/Wiz-loca.lua b/dat/Wiz-loca.lua index 6acc15da6..7197f1856 100644 --- a/dat/Wiz-loca.lua +++ b/dat/Wiz-loca.lua @@ -36,18 +36,18 @@ des.replace_terrain({ region = {34, 1,68,19}, fromterrain="}", toterrain=".", ch -- Dungeon Description des.region(selection.area(00,00,75,20), "lit") -des.region({ region={37,04,65,16}, lit=0, type="ordinary", prefilled=1, irregular=1, +des.region({ region={37,04,65,16}, lit=0, type="ordinary", irregular=1, contents = function() des.door({ state="secret", wall="random" }) end }) -des.region({ region={39,06,63,14}, lit=0, type="ordinary", prefilled=1, irregular=1, +des.region({ region={39,06,63,14}, lit=0, type="ordinary", irregular=1, contents = function() des.door({ state="secret", wall="random" }) end }) -des.region({ region={41,08,46,12}, lit=1, type="ordinary", prefilled=1, irregular=1, +des.region({ region={41,08,46,12}, lit=1, type="ordinary", irregular=1, contents = function() local walls = { "north", "south", "west" } local widx = math.random(1, #walls) @@ -55,7 +55,7 @@ des.region({ region={41,08,46,12}, lit=1, type="ordinary", prefilled=1, irregula end }) -des.region({ region={56,08,61,12}, lit=1, type="ordinary", prefilled=1, irregular=1, +des.region({ region={56,08,61,12}, lit=1, type="ordinary", irregular=1, contents = function() local walls = { "north", "south", "east" } local widx = math.random(1, #walls) @@ -66,7 +66,7 @@ des.region({ region={56,08,61,12}, lit=1, type="ordinary", prefilled=1, irregula des.region(selection.area(48,08,54,08), "unlit") des.region(selection.area(48,12,54,12), "unlit") -des.region({ region={48,10,54,10}, lit=0, type="ordinary", prefilled=1, irregular=1, +des.region({ region={48,10,54,10}, lit=0, type="ordinary", irregular=1, contents = function() des.door({ state="secret", wall="random" }) end diff --git a/dat/Wiz-strt.lua b/dat/Wiz-strt.lua index fdc9ae531..715cb5744 100644 --- a/dat/Wiz-strt.lua +++ b/dat/Wiz-strt.lua @@ -44,7 +44,7 @@ des.replace_terrain({ region={13,5, 33,15}, fromterrain="C", toterrain=".", chan des.region(selection.area(00,00,75,19), "lit") des.region(selection.area(35,00,49,03), "unlit") des.region(selection.area(43,12,49,16), "unlit") -des.region({ region={19,11,33,15}, lit=0, type="ordinary", prefilled=0, irregular=1 }) +des.region({ region={19,11,33,15}, lit=0, type="ordinary", irregular=1 }) des.region(selection.area(30,10,31,10), "unlit") -- Stairs des.stair("down", 30,10) diff --git a/dat/astral.lua b/dat/astral.lua index 7085eba78..cfe22dd78 100644 --- a/dat/astral.lua +++ b/dat/astral.lua @@ -76,9 +76,9 @@ place:set(51,9); -- Where the player will land on arrival des.teleport_region({ region = {29,15,45,15}, exclude = {30,15,44,15} }) -- Lit courts -des.region({ region={01,05,16,14},lit=1,type="ordinary",prefilled=1,irregular=1 }) -des.region({ region={31,01,44,10},lit=1,type="ordinary",prefilled=1,irregular=1 }) -des.region({ region={61,05,74,14},lit=1,type="ordinary",prefilled=1,irregular=1 }) +des.region({ region={01,05,16,14},lit=1,type="ordinary",irregular=1 }) +des.region({ region={31,01,44,10},lit=1,type="ordinary",irregular=1 }) +des.region({ region={61,05,74,14},lit=1,type="ordinary",irregular=1 }) -- A Sanctum for each alignment -- The shrines' alignments are shuffled for -- each game diff --git a/dat/castle.lua b/dat/castle.lua index 4c614f550..c2f05f02f 100644 --- a/dat/castle.lua +++ b/dat/castle.lua @@ -230,7 +230,7 @@ des.region(selection.area(00,00,62,16),"unlit") des.region(selection.area(00,05,05,11),"lit") des.region(selection.area(57,05,62,11),"lit") -- Throne room -des.region({ region={27,05, 37,11},lit=1,type="throne", prefilled=1 }) +des.region({ region={27,05, 37,11},lit=1,type="throne", filled=2 }) -- Antechamber des.region(selection.area(07,05,14,11),"lit") -- Storerooms @@ -244,8 +244,8 @@ des.region(selection.area(56,02,60,03),"lit") des.region(selection.area(02,13,06,14),"lit") des.region(selection.area(56,13,60,14),"lit") -- Barracks -des.region({ region={16,05, 25,06},lit=1,type="barracks", prefilled=0 }) -des.region({ region={16,10, 25,11},lit=1,type="barracks", prefilled=0 }) +des.region({ region={16,05, 25,06},lit=1,type="barracks", filled=1 }) +des.region({ region={16,10, 25,11},lit=1,type="barracks", filled=1 }) -- Hallways des.region(selection.area(08,03,54,03),"unlit") des.region(selection.area(08,13,54,13),"unlit") diff --git a/dat/fakewiz1.lua b/dat/fakewiz1.lua index 6576176e2..906d7f97c 100644 --- a/dat/fakewiz1.lua +++ b/dat/fakewiz1.lua @@ -23,7 +23,7 @@ des.levregion({ region={01,00,79,20}, region_islev=1, exclude={0,0,8,7}, type="b des.teleport_region({ region={01,00,79,20}, region_islev=1,exclude={2,2,6,6} }) des.levregion({ region={4,4,4,4}, type="portal", name="wizard3" }) des.mazewalk(08,05,"east") -des.region({ region={04,03,06,06},lit=0,type="ordinary",prefilled=0,irregular=1 }) +des.region({ region={04,03,06,06},lit=0,type="ordinary",irregular=1,arrival_room=true }) des.monster("L",04,04) des.monster("vampire lord",03,04) des.monster("kraken",06,06) diff --git a/dat/fakewiz2.lua b/dat/fakewiz2.lua index f34d00af0..ae14a6966 100644 --- a/dat/fakewiz2.lua +++ b/dat/fakewiz2.lua @@ -22,7 +22,6 @@ des.levregion({ region={01,00,79,20}, region_islev=1, exclude={0,0,8,7}, type="s des.levregion({ region={01,00,79,20}, region_islev=1, exclude={0,0,8,7}, type="branch" }); des.teleport_region({ region={01,00,79,20}, region_islev=1,exclude={2,2,6,6} }) des.mazewalk(08,05,"east") -des.region({ region={04,03,06,06},lit=0,type="ordinary",prefilled=0,irregular=1 }) des.monster("L",04,04) des.monster("vampire lord",03,04) des.monster("kraken",06,06) diff --git a/dat/knox.lua b/dat/knox.lua index c1b4c204b..e9603e866 100644 --- a/dat/knox.lua +++ b/dat/knox.lua @@ -39,7 +39,7 @@ des.levregion({ region = {08,16,08,16}, type="branch" }); des.teleport_region({ region = {06,15,09,16}, dir="up" }) des.teleport_region({ region = {06,15,09,16}, dir="down" }) -- Throne room, with Croesus on the throne -des.region({ x1=37,y1=08,x2=46,y2=11, lit=1, type="throne", prefilled=0 }) +des.region({ x1=37,y1=08,x2=46,y2=11, lit=1, type="throne", filled=1 }) -- 50% chance each to move throne and/or fort's entry secret door up one row if percent(50) then des.monster({ id = "Croesus", x=43, y=10, peaceful = 0 }) @@ -80,10 +80,10 @@ des.region(selection.area(46,06,48,06),"lit") des.region(selection.area(19,13,21,13),"lit") des.region(selection.area(46,13,48,13),"lit") -- A welcoming committee -des.region({ region={03,10,07,13},lit=1,type="zoo",prefilled=0,irregular=1 }) +des.region({ region={03,10,07,13},lit=1,type="zoo",filled=1,irregular=1 }) -- arrival chamber; needs to be a real room to control migrating monsters, -- and `unfilled' is a kludge to force an ordinary room to remain a room -des.region({ region={06,15,09,16},lit=0,type="ordinary",prefilled=0 }) +des.region({ region={06,15,09,16},lit=0,type="ordinary",arrival_room=true }) -- 3.6.2: Entering level carrying a lit candle would show the whole entry -- chamber except for its top right corner even though some of the revealed @@ -109,7 +109,7 @@ des.region(selection.area(05,14,09,14),"unlit") -- it is expected to work.) -- Barracks -des.region({ region={62,03,71,04},lit=1,type="barracks",prefilled=0,irregular=1 }) +des.region({ region={62,03,71,04},lit=1,type="barracks",filled=1,irregular=1 }) -- Doors des.door("closed",06,14) des.door("closed",09,03) diff --git a/dat/medusa-1.lua b/dat/medusa-1.lua index 63a471904..f97100811 100644 --- a/dat/medusa-1.lua +++ b/dat/medusa-1.lua @@ -36,8 +36,8 @@ des.map([[ -- Dungeon Description des.region(selection.area(00,00,74,19),"lit") des.region(selection.area(31,07,45,07),"unlit") --- (must maintain one room definition; `filled=0' forces its room to be kept) -des.region({ region={35,09, 41,10}, lit = 0, type="ordinary", prefilled = 1 }) +-- make the downstairs room a real room to control arriving monsters +des.region({ region={35,09, 41,10}, lit = 0, type="ordinary", arrival_room=true }) des.region(selection.area(31,12,45,12),"unlit") -- Teleport: down to up stairs island, up to Medusa's island des.teleport_region({ region = {01,01,05,17}, dir="down" }) diff --git a/dat/medusa-2.lua b/dat/medusa-2.lua index 4b03631e7..017b9b4b3 100644 --- a/dat/medusa-2.lua +++ b/dat/medusa-2.lua @@ -32,9 +32,10 @@ des.map([[ -- Dungeon Description des.region(selection.area(00,00,74,19),"lit") des.region(selection.area(02,03,05,16),"unlit") -des.region({ region={61,03, 72,16}, lit=0, type="ordinary", prefilled = 1,irregular = 1 }) +des.region({ region={61,03, 72,16}, lit=0, type="ordinary",irregular = 1 }) des.region(selection.area(71,08,72,11),"unlit") -des.region(selection.area(67,08,69,11),"lit") +-- make the downstairs area a real room to control arriving monsters +des.region({ region={67,08,69,11}, lit=1, type="ordinary", arrival_room=true }) -- Teleport: down to up stairs island, up to Medusa's island des.teleport_region({ region = {02,03,05,16}, dir="down" }) des.teleport_region({ region = {61,03,72,16}, dir="up" }) diff --git a/dat/medusa-3.lua b/dat/medusa-3.lua index 221cb8172..56f37c1c7 100644 --- a/dat/medusa-3.lua +++ b/dat/medusa-3.lua @@ -37,7 +37,7 @@ place:set(66,05); place:set(46,15); des.region(selection.area(00,00,74,19),"lit") -des.region({ region={49,14, 51,16}, lit=-1, type="ordinary", prefilled = 1 }); +des.region({ region={49,14, 51,16}, lit=-1, type="ordinary" }); des.region(selection.area(07,05,09,07),"unlit") des.region(selection.area(65,04,67,06),"unlit") des.region(selection.area(45,14,47,16),"unlit") diff --git a/dat/medusa-4.lua b/dat/medusa-4.lua index c5f8e206d..7df55430c 100644 --- a/dat/medusa-4.lua +++ b/dat/medusa-4.lua @@ -40,7 +40,6 @@ place:set(10,08); place:set(10,12); -- des.region(selection.area(00,00,74,19),"lit") -des.region({ region={13,03, 18,13}, lit=1, type="ordinary", prefilled=1 }) -- des.teleport_region({ region = {64,01,74,17}, dir="down" }); des.teleport_region({ region = {02,02,18,13}, dir="up" }); diff --git a/dat/minend-1.lua b/dat/minend-1.lua index 30e1a23d7..f86140518 100644 --- a/dat/minend-1.lua +++ b/dat/minend-1.lua @@ -35,8 +35,8 @@ des.map([[ local place = { {08,16},{13,07},{21,08},{41,14},{50,04},{50,16},{66,01} } shuffle(place) -des.region({ region={26,01,32,01}, lit=0, type="ordinary", - prefilled=0, irregular=1 }) +-- make the entry chamber a real room; it affects monster arrival +des.region({ region={26,01,32,01}, lit=0, type="ordinary", irregular=1, arrival_room=true }) des.region(selection.area(20,08,21,08),"unlit") des.region(selection.area(23,08,25,08),"unlit"); -- Secret doors diff --git a/dat/minetn-5.lua b/dat/minetn-5.lua index 5faac05a1..8160cef07 100644 --- a/dat/minetn-5.lua +++ b/dat/minetn-5.lua @@ -95,13 +95,13 @@ des.monster("dwarf") des.monster("dwarf") -- The shops -des.region({ region={25,17, 28,19}, lit=1, type="candle shop", prefilled=0 }) +des.region({ region={25,17, 28,19}, lit=1, type="candle shop", filled=1 }) des.door("closed",24,18) -des.region({ region={59, 9, 67,10}, lit=1, type="shop", prefilled=0 }) +des.region({ region={59, 9, 67,10}, lit=1, type="shop", filled=1 }) des.door("closed",66,08) -des.region({ region={57,13, 60,15}, lit=1, type="tool shop", prefilled=0 }) +des.region({ region={57,13, 60,15}, lit=1, type="tool shop", filled=1 }) des.door("closed",56,14) -des.region({ region={05,09, 08,10}, lit=1, type=monkfoodshop(), prefilled=0 }) +des.region({ region={05,09, 08,10}, lit=1, type=monkfoodshop(), filled=1 }) des.door("closed",07,11) -- Gnome homes des.door("closed",04,14) diff --git a/dat/minetn-6.lua b/dat/minetn-6.lua index 7e3c88131..ba642c625 100644 --- a/dat/minetn-6.lua +++ b/dat/minetn-6.lua @@ -36,11 +36,11 @@ des.levregion({ type="stair-down", region={61,03,75,19}, region_islev=1, exclude des.feature("fountain" ,22,07) des.feature("fountain", 09,13) des.region(selection.area(13,5,14,6),"unlit") -des.region({ region={09,07, 11,09}, lit=1, type="candle shop", prefilled=0 }) -des.region({ region={16,04, 18,06}, lit=1, type="tool shop", prefilled=0 }) -des.region({ region={23,01, 25,03}, lit=1, type="shop", prefilled=0 }) -des.region({ region={22,12, 24,13}, lit=1, type=monkfoodshop(), prefilled=0 }) -des.region({ region={31,12, 36,14}, lit=1, type="temple", prefilled=0 }) +des.region({ region={09,07, 11,09}, lit=1, type="candle shop", filled=1 }) +des.region({ region={16,04, 18,06}, lit=1, type="tool shop", filled=1 }) +des.region({ region={23,01, 25,03}, lit=1, type="shop", filled=1 }) +des.region({ region={22,12, 24,13}, lit=1, type=monkfoodshop(), filled=1 }) +des.region({ region={31,12, 36,14}, lit=1, type="temple", filled=1 }) des.altar({ x=35,y=13,align=align[1],type="shrine"}) des.door("closed",5,2) diff --git a/dat/orcus.lua b/dat/orcus.lua index b04247491..109053c3d 100644 --- a/dat/orcus.lua +++ b/dat/orcus.lua @@ -77,9 +77,9 @@ des.door("open",26,14) des.door("closed",06,15) -- Special rooms des.altar({ x=24,y=07,align="noalign",type="sanctum" }) -des.region({ region={22,12,25,16},lit=0,type="morgue", prefilled=0 }) -des.region({ region={32,09,37,12},lit=1,type="shop",prefilled=0 }) -des.region({ region={12,00,15,04},lit=1,type="shop",prefilled=0 }) +des.region({ region={22,12,25,16},lit=0,type="morgue",filled=1 }) +des.region({ region={32,09,37,12},lit=1,type="shop",filled=1 }) +des.region({ region={12,00,15,04},lit=1,type="shop",filled=1 }) -- Some traps. des.trap("spiked pit") des.trap("sleep gas") diff --git a/dat/sanctum.lua b/dat/sanctum.lua index c99eff81d..84f7f7f99 100644 --- a/dat/sanctum.lua +++ b/dat/sanctum.lua @@ -36,7 +36,7 @@ des.region({ region={15,07, 21,10}, lit=1, type="temple", contents = function() des.door({ wall = "random", state = "secret" }); end }) des.altar({ x=18, y=08, align="noalign", type="sanctum" }) -des.region({ region={41,06, 48,11}, lit=0, type="morgue", prefilled=0, irregular=1 }) +des.region({ region={41,06, 48,11}, lit=0, type="morgue", filled=1, irregular=1 }) -- Non diggable walls des.non_diggable(selection.area(00,00,75,19)) -- Invisible barrier separating the left & right halves of the level diff --git a/dat/soko1-1.lua b/dat/soko1-1.lua index f38667960..1d6b7c09b 100644 --- a/dat/soko1-1.lua +++ b/dat/soko1-1.lua @@ -94,8 +94,7 @@ des.door("closed", 17, 11); des.door("closed", 17, 13); des.door("closed", 17, 15); -des.region({ region={18,10, 22,16}, lit = 1, type = "zoo", - prefilled = 0, irregular = 1 }); +des.region({ region={18,10, 22,16}, lit = 1, type = "zoo", filled = 1, irregular = 1 }); px, py = selection.rndcoord(place); if percent(75) then diff --git a/dat/soko1-2.lua b/dat/soko1-2.lua index 48305895e..3b54a231e 100644 --- a/dat/soko1-2.lua +++ b/dat/soko1-2.lua @@ -96,8 +96,7 @@ des.door("locked",23,12) des.door("closed",17,10) des.door("closed",17,12) des.door("closed",17,14) -des.region({ region={18,09, 22,15}, lit = 1, type = "zoo", - prefilled = 0, irregular = 1 }); +des.region({ region={18,09, 22,15}, lit = 1, type = "zoo", filled = 1, irregular = 1 }); px, py = selection.rndcoord(place); if percent(25) then diff --git a/dat/themerms.lua b/dat/themerms.lua index 4b3947fe4..85c3e18f4 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -12,7 +12,6 @@ -- core calls themerooms_generate() multiple times per level -- to generate a single themed room. - themerooms = { { -- the "default" room @@ -263,7 +262,7 @@ themerooms = { |......| |......| |......| ---------]], contents = function(m) des.region({ region={1,1,3,3}, type="ordinary", irregular=true, prefilled=true }); end }); +--------]], contents = function(m) des.region({ region={1,1,3,3}, type="ordinary", irregular=true, filled=1 }); end }); end, -- L-shaped, rot 1 @@ -276,7 +275,7 @@ xxx|...| |......| |......| |......| ---------]], contents = function(m) des.region({ region={5,1,5,3}, type="ordinary", irregular=true, prefilled=true }); end }); +--------]], contents = function(m) des.region({ region={5,1,5,3}, type="ordinary", irregular=true, filled=1 }); end }); end, -- L-shaped, rot 2 @@ -289,7 +288,7 @@ xxx|...| ----...| xxx|...| xxx|...| -xxx-----]], contents = function(m) des.region({ region={1,1,2,2}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx-----]], contents = function(m) des.region({ region={1,1,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, -- L-shaped, rot 3 @@ -302,7 +301,7 @@ xxx-----]], contents = function(m) des.region({ region={1,1,2,2}, type="ordinary |...---- |...|xxx |...|xxx ------xxx]], contents = function(m) des.region({ region={1,1,2,2}, type="ordinary", irregular=true, prefilled=true }); end }); +-----xxx]], contents = function(m) des.region({ region={1,1,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Blocked center @@ -324,7 +323,7 @@ if (percent(30)) then shuffle(terr); des.replace_terrain({ region = {1,1, 9,9}, fromterrain = "L", toterrain = terr[1] }); end -des.region({ region={1,1,2,2}, type="ordinary", irregular=true, prefilled=true }); +des.region({ region={1,1,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, @@ -337,7 +336,7 @@ x--.--x |.....| --...-- x--.--x -xx---xx]], contents = function(m) des.region({ region={3,3,3,3}, type="ordinary", irregular=true, prefilled=true }); end }); +xx---xx]], contents = function(m) des.region({ region={3,3,3,3}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Circular, medium @@ -351,7 +350,7 @@ x--...--x |.......| --.....-- x--...--x -xx-----xx]], contents = function(m) des.region({ region={4,4,4,4}, type="ordinary", irregular=true, prefilled=true }); end }); +xx-----xx]], contents = function(m) des.region({ region={4,4,4,4}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Circular, big @@ -367,7 +366,7 @@ x-.......-x --.......-- x-.......-x x---...---x -xxx-----xxx]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx-----xxx]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, filled=1 }); end }); end, -- T-shaped @@ -380,7 +379,7 @@ xxx|...|xxx |.........| |.........| |.........| ------------]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, prefilled=true }); end }); +-----------]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, filled=1 }); end }); end, -- T-shaped, rot 1 @@ -396,7 +395,7 @@ xxx|...|xxx |...---- |...|xxx |...|xxx ------xxx]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, prefilled=true }); end }); +-----xxx]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, -- T-shaped, rot 2 @@ -409,7 +408,7 @@ xxx|...|xxx ----...---- xxx|...|xxx xxx|...|xxx -xxx-----xxx]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx-----xxx]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, -- T-shaped, rot 3 @@ -425,7 +424,7 @@ xxx|...| ----...| xxx|...| xxx|...| -xxx-----]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx-----]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, filled=1 }); end }); end, -- S-shaped @@ -441,7 +440,7 @@ xxx-----]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary ----...| xxx|...| xxx|...| -xxx-----]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx-----]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, -- S-shaped, rot 1 @@ -454,7 +453,7 @@ xxx|......| |......---- |......|xxx |......|xxx ---------xxx]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, prefilled=true }); end }); +--------xxx]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Z-shaped @@ -470,7 +469,7 @@ xxx|...| |...---- |...|xxx |...|xxx ------xxx]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, prefilled=true }); end }); +-----xxx]], contents = function(m) des.region({ region={5,5,5,5}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Z-shaped, rot 1 @@ -483,7 +482,7 @@ xxx|...| ----......| xxx|......| xxx|......| -xxx--------]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx--------]], contents = function(m) des.region({ region={2,2,2,2}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Cross @@ -499,7 +498,7 @@ xxx|...|xxx ----...---- xxx|...|xxx xxx|...|xxx -xxx-----xxx]], contents = function(m) des.region({ region={6,6,6,6}, type="ordinary", irregular=true, prefilled=true }); end }); +xxx-----xxx]], contents = function(m) des.region({ region={6,6,6,6}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Four-leaf clover @@ -515,7 +514,7 @@ xx|.....|xx |.........| |...---...| |...|x|...| ------x-----]], contents = function(m) des.region({ region={6,6,6,6}, type="ordinary", irregular=true, prefilled=true }); end }); +-----x-----]], contents = function(m) des.region({ region={6,6,6,6}, type="ordinary", irregular=true, filled=1 }); end }); end, -- Water-surrounded vault @@ -526,7 +525,7 @@ xx|.....|xx }|..|} }|..|} }----} -}}}}}}]], contents = function(m) des.region({ region={3,3,3,3}, type="themed", irregular=true, prefilled=false, joined=false }); +}}}}}}]], contents = function(m) des.region({ region={3,3,3,3}, type="themed", irregular=true, filled=0, joined=false }); local nasty_undead = { "giant zombie", "ettin zombie", "vampire lord" }; des.object("chest", 2, 2); des.object("chest", 3, 2); diff --git a/dat/valley.lua b/dat/valley.lua index f283cb415..b030925f7 100644 --- a/dat/valley.lua +++ b/dat/valley.lua @@ -53,9 +53,9 @@ end -- The shrine to Moloch. des.region({ region={01,06, 05,14},lit=1,type="temple" }) -- The Morgues -des.region({ region={19,01, 24,08},lit=0,type="morgue",prefilled=0,irregular=1 }) -des.region({ region={09,14, 16,18},lit=0,type="morgue",prefilled=0,irregular=1 }) -des.region({ region={37,09, 43,14},lit=0,type="morgue",prefilled=0,irregular=1 }) +des.region({ region={19,01, 24,08},lit=0,type="morgue",filled=1,irregular=1 }) +des.region({ region={09,14, 16,18},lit=0,type="morgue",filled=1,irregular=1 }) +des.region({ region={37,09, 43,14},lit=0,type="morgue",filled=1,irregular=1 }) -- Stairs des.stair("down", 01,01) -- Branch location diff --git a/dat/wizard1.lua b/dat/wizard1.lua index 3a40d6ae9..2e4a0af79 100644 --- a/dat/wizard1.lua +++ b/dat/wizard1.lua @@ -28,12 +28,12 @@ des.levregion({ type="stair-up", region={01,00,79,20}, region_islev=1, exclude={ des.levregion({ type="stair-down", region={01,00,79,20}, region_islev=1, exclude={0,0,28,12} }) des.levregion({ type="branch", region={01,00,79,20}, region_islev=1, exclude={0,0,28,12} }) des.teleport_region({ region={01,00,79,20}, region_islev=1, exclude={0,0,27,12} }) -des.region({ region={12,01, 20,09}, lit=0, type="morgue", prefilled=1, contents=function() +des.region({ region={12,01, 20,09}, lit=0, type="morgue", filled=2, contents=function() local sdwall = { "south", "west", "east" }; des.door({ wall = sdwall[math.random(1, #sdwall)], state = "secret" }); end }) -- another region to constrain monster arrival -des.region({ region={01,01, 10,11}, lit=0, type="ordinary", prefilled=0 }) +des.region({ region={01,01, 10,11}, lit=0, type="ordinary", arrival_room=true }) des.mazewalk(28,05,"east") des.ladder("down", 06,05) -- Non diggable walls diff --git a/dat/wizard2.lua b/dat/wizard2.lua index d9fd181a0..825f2f342 100644 --- a/dat/wizard2.lua +++ b/dat/wizard2.lua @@ -26,8 +26,8 @@ des.levregion({ type="stair-down", region={01,00,79,20}, region_islev=1, exclude des.levregion({ type="branch", region={01,00,79,20}, region_islev=1, exclude={0,0,28,12} }) des.teleport_region({ region={01,00,79,20}, region_islev=1, exclude={0,0,27,12} }) -- entire tower in a region, constrains monster migration -des.region({ region={01,01, 26,11}, lit=0, type="ordinary", prefilled=1 }) -des.region({ region={09,03, 17,09}, lit=0, type="zoo", prefilled=0 }) +des.region({ region={01,01, 26,11}, lit=0, type="ordinary", arrival_room=true }) +des.region({ region={09,03, 17,09}, lit=0, type="zoo", filled=1 }) des.door("closed",15,02) des.door("closed",11,10) des.mazewalk(28,05,"east") diff --git a/dat/wizard3.lua b/dat/wizard3.lua index 60e9dd014..4f0baf922 100644 --- a/dat/wizard3.lua +++ b/dat/wizard3.lua @@ -27,11 +27,10 @@ des.levregion({ type="branch", region={01,00,79,20}, region_islev=1, exclude={0, des.teleport_region({ region={01,00,79,20}, region_islev=1, exclude={0,0,27,12} }) des.levregion({ region={25,11,25,11}, type="portal", name="fakewiz1" }); des.mazewalk(28,09,"east") -des.region({ region={07,03, 15,11}, lit=0 ,type="morgue",prefilled=1 }) +des.region({ region={07,03, 15,11}, lit=0 ,type="morgue", filled=2 }) des.region({ region={17,06, 18,11}, lit=0, type="beehive" }) --- make the entry chamber a real room; it affects monster arrival; --- `unfilled' is a kludge to force an ordinary room to remain a room -des.region({ region={20,06,26,11},lit=0,type="ordinary",prefilled=1, +-- make the entry chamber a real room; it affects monster arrival +des.region({ region={20,06,26,11},lit=0,type="ordinary",arrival_room=true, contents = function() local w = "north"; if percent(50) then w = "west" end diff --git a/doc/lua.adoc b/doc/lua.adoc index 27da21ed9..cc4835d7b 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -304,13 +304,13 @@ Set flags for this level. | nommap | Prevents magic mapping | shortsighted | Prevents monsters from seeing the hero from far away | arboreal | Notionally an outdoor map; replaces solid stone with trees -| mazelevel | +| mazelevel | | shroud | Unseen locations on the level will not be remembered by the hero, instead of rendering as out-of-sight map, trap, and object glyphs like they normally do. | graveyard | Treats the level as a graveyard level (causes graveyard sounds and undead have a reduced chance of leaving corpses). | icedpools | Ice generated with the level will be treated as frozen pools instead of frozen moats. -| corrmaze | +| corrmaze | | premapped | Map, including traps and boulders, is revealed on entrance. -| solidify | Areas outside the specified level map are made undiggable and unphaseable. +| solidify | Areas outside the specified level map are made undiggable and unphaseable. | inaccessibles | If inaccessible areas are generated, generate ways for them to connect to the "accessible" area. | noflip | Prevent flipping the level. | noflipx | Prevent flipping the level horizontally. @@ -471,7 +471,7 @@ Example: Example: des.region(selection, lit); - des.region({ x1=NN, y1=NN, x2=NN, y2=NN, lit=BOOL, type=ROOMTYPE, joined=BOOL, irregular=BOOL, prefilled=BOOL [ , contents = FUNCTION ] }); + des.region({ x1=NN, y1=NN, x2=NN, y2=NN, lit=BOOL, type=ROOMTYPE, joined=BOOL, irregular=BOOL, filled=NN [ , contents = FUNCTION ] }); des.region({ region={x1,y1, x2,y2}, type="ordinary" }); === replace_terrain diff --git a/include/extern.h b/include/extern.h index 79708ebfe..60c44d2fd 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2467,7 +2467,7 @@ E boolean FDECL(create_room, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); E void FDECL(create_secret_door, (struct mkroom *, XCHAR_P)); E boolean FDECL(dig_corridor, (coord *, coord *, BOOLEAN_P, SCHAR_P, SCHAR_P)); -E void FDECL(fill_special_room, (struct mkroom *, BOOLEAN_P)); +E void FDECL(fill_special_room, (struct mkroom *)); E boolean FDECL(load_special, (const char *)); E xchar FDECL(selection_getpoint, (int, int, struct selectionvar *)); E struct selectionvar *NDECL(selection_new); diff --git a/include/mkroom.h b/include/mkroom.h index e7bd874ea..e707aa695 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -90,6 +90,14 @@ enum roomtype_types { #define ROOMOFFSET 3 /* (levl[x][y].roomno - ROOMOFFSET) gives g.rooms[] index, * for inside-squares and non-shared boundaries */ +/* Values for needfill */ +#define FILL_NONE 0 /* do not fill this room with anything */ +#define FILL_NORMAL 1 /* fill the room normally (OROOM or THEMEROOM gets + fill_ordinary_room; any other room type gets stocked + with its usual monsters/objects/terrain) */ +#define FILL_LVFLAGS 2 /* special rooms only; set the room's rtype and level + flags as appropriate, but do not put anything in it */ + #define IS_ROOM_PTR(x) ((x) >= g.rooms && (x) < g.rooms + MAXNROFROOMS) #define IS_ROOM_INDEX(x) ((x) >= 0 && (x) < MAXNROFROOMS) #define IS_SUBROOM_PTR(x) ((x) >= g.subrooms && (x) < g.subrooms + MAXNROFROOMS) diff --git a/include/sp_lev.h b/include/sp_lev.h index 821359907..cf86388e3 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -185,7 +185,7 @@ typedef struct _room { Str_or_Len parent; xchar x, y, w, h; xchar xalign, yalign; - xchar rtype, chance, rlit, filled, joined; + xchar rtype, chance, rlit, needfill, joined; } room; struct mapfragment { diff --git a/src/mklev.c b/src/mklev.c index b4d7efe07..670f8760a 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -757,7 +757,7 @@ struct mkroom *croom; fill_ordinary_room(croom->sbrooms[x]); } - if (!croom->needfill) + if (croom->needfill != FILL_NORMAL) return; /* put a sleeping monster inside */ @@ -916,7 +916,7 @@ makelevel() TRUE, VAULT, FALSE); g.level.flags.has_vault = 1; ++room_threshold; - fill_special_room(&g.rooms[g.nroom - 1], FALSE); + fill_special_room(&g.rooms[g.nroom - 1]); mk_knox_portal(g.vault_x + w, g.vault_y + h); if (!g.level.flags.noteleport && !rn2(3)) makevtele(); diff --git a/src/sp_lev.c b/src/sp_lev.c index b3b369c73..258fa8f66 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1042,10 +1042,10 @@ fill_special_rooms() for (tmpi = 0; tmpi < g.nroom; tmpi++) { if (g.rooms[tmpi].needfill) - fill_special_room(&g.rooms[tmpi], (g.rooms[tmpi].needfill == 2)); + fill_special_room(&g.rooms[tmpi]); for (m = 0; m < g.rooms[tmpi].nsubrooms; m++) if (g.rooms[tmpi].sbrooms[m]->needfill) - fill_special_room(g.rooms[tmpi].sbrooms[m], FALSE); + fill_special_room(g.rooms[tmpi].sbrooms[m]); } } @@ -2682,14 +2682,14 @@ corridor *c; * Fill a room (shop, zoo, etc...) with appropriate stuff. */ void -fill_special_room(croom, prefilled) +fill_special_room(croom) struct mkroom *croom; -boolean prefilled; { - if (!croom || croom->rtype == OROOM || croom->rtype == THEMEROOM) + if (!croom || croom->rtype == OROOM || croom->rtype == THEMEROOM + || croom->needfill == FILL_NONE) return; - if (!prefilled) { + if (croom->needfill == FILL_NORMAL) { int x, y; /* Shop ? */ @@ -2770,7 +2770,7 @@ struct mkroom *mkr; #else topologize(aroom); /* set roomno */ #endif - aroom->needfill = r->filled; + aroom->needfill = r->needfill; aroom->needjoining = r->joined; return aroom; } @@ -3831,7 +3831,8 @@ lua_State *L; tmproom.rtype = get_table_roomtype_opt(L, "type", OROOM); tmproom.chance = get_table_int_opt(L, "chance", 100); tmproom.rlit = get_table_int_opt(L, "lit", -1); - tmproom.filled = get_table_int_opt(L, "filled", g.in_mk_themerooms ? 0 : 1); + /* theme rooms default to unfilled */ + tmproom.needfill = get_table_int_opt(L, "filled", g.in_mk_themerooms ? 0 : 1); tmproom.joined = get_table_int_opt(L, "joined", 1); if (!g.coder->failed_room[g.coder->n_subroom - 1]) { @@ -5599,7 +5600,7 @@ genericptr_t arg; } /* region(selection, lit); */ -/* region({ x1=NN, y1=NN, x2=NN, y2=NN, lit=BOOL, type=ROOMTYPE, joined=BOOL, irregular=BOOL, prefilled=BOOL [ , contents = FUNCTION ] }); */ +/* region({ x1=NN, y1=NN, x2=NN, y2=NN, lit=BOOL, type=ROOMTYPE, joined=BOOL, irregular=BOOL, filled=NN [ , contents = FUNCTION ] }); */ /* region({ region={x1,y1, x2,y2}, type="ordinary" }); */ int lspo_region(L) @@ -5607,9 +5608,9 @@ lua_State *L; { xchar dx1, dy1, dx2, dy2; register struct mkroom *troom; - boolean prefilled = FALSE, room_not_needed, + boolean do_arrival_room = FALSE, room_not_needed, irregular = FALSE, joined = TRUE; - int rtype = OROOM, rlit = 1; + int rtype = OROOM, rlit = 1, needfill = 0; int argc = lua_gettop(L); create_des_coder(); @@ -5617,13 +5618,12 @@ lua_State *L; if (argc <= 1) { lcheck_param_table(L); - /* TODO: check the prefilled, what was the default in lev_comp? */ - /* "unfilled" == 0, "filled" == 1, missing = "filled" */ - - /* TODO: "unfilled" ==> prefilled=1 */ - prefilled = get_table_boolean_opt(L, "prefilled", 0); + /* TODO: "unfilled" ==> filled=0, "filled" ==> filled=1, and + * "lvflags_only" ==> filled=2, probably in a get_table_needfill_opt */ + needfill = get_table_int_opt(L, "filled", 0); irregular = get_table_boolean_opt(L, "irregular", 0); joined = get_table_boolean_opt(L, "joined", 1); + do_arrival_room = get_table_boolean_opt(L, "arrival_room", 0); rtype = get_table_roomtype_opt(L, "type", OROOM); rlit = get_table_int_opt(L, "lit", -1); dx1 = get_table_int_opt(L, "x1", -1); /* TODO: area */ @@ -5668,10 +5668,16 @@ lua_State *L; get_location(&dx1, &dy1, ANY_LOC, (struct mkroom *) 0); get_location(&dx2, &dy2, ANY_LOC, (struct mkroom *) 0); - /* for an ordinary room, `prefilled' is a flag to force - an actual room to be created (such rooms are used to - control placement of migrating monster arrivals) */ - room_not_needed = (rtype == OROOM && !irregular && !prefilled && !g.in_mk_themerooms); + /* Many regions are simple, rectangular areas that just need to set lighting + * in an area. In that case, we don't need to do anything complicated by + * creating a room. The exceptions are: + * - Special rooms (which usually need to be filled). + * - Irregular regions (more convenient to use the room-making code). + * - Themed room regions (which often have contents). + * - When a room is desired to constrain the arrival of migrating monsters + * (see the mon_arrive function for details). + */ + room_not_needed = (rtype == OROOM && !irregular && !do_arrival_room && !g.in_mk_themerooms); if (room_not_needed || g.nroom >= MAXNROFROOMS) { region tmpregion; if (!room_not_needed) @@ -5689,8 +5695,7 @@ lua_State *L; troom = &g.rooms[g.nroom]; /* mark rooms that must be filled, but do it later */ - if (rtype != OROOM) - troom->needfill = (prefilled ? 2 : 1); + troom->needfill = needfill; troom->needjoining = joined; @@ -5711,9 +5716,6 @@ lua_State *L; #endif } - if (g.in_mk_themerooms && prefilled) - troom->needfill = 1; - if (!room_not_needed) { if (g.coder->n_subroom > 1) impossible("region as subroom"); diff --git a/test/test_des.lua b/test/test_des.lua index 8cb281bce..9275d801a 100644 --- a/test/test_des.lua +++ b/test/test_des.lua @@ -324,8 +324,8 @@ end function test_region() des.region(selection.area(08,03,54,03),"unlit") des.region(selection.area(56,02,60,03),"lit") - des.region({ region={16,05, 25,06}, lit=1, type="barracks", prefilled=0 }) - des.region({ region={1,5, 3,7}, lit=1, irregular=true, prefilled=true, joined=false }) + des.region({ region={16,05, 25,06}, lit=1, type="barracks", filled=0 }) + des.region({ region={1,5, 3,7}, lit=1, irregular=true, filled=1, joined=false }) end function test_door() From f8ff58ed7ebc46a565a9a2fa8fd4c52a73619392 Mon Sep 17 00:00:00 2001 From: copperwater Date: Thu, 21 May 2020 08:48:24 -0400 Subject: [PATCH 222/708] Fill special rooms recursively rather than only at top level The fill_special_rooms function was only stocking two types of rooms: top-level rooms in g.rooms, and their immediate subrooms. If there were a special room 2 or more levels down, it would not get filled. (No special levels currently define such a special room, so this bug is latent.) To address this, I changed fill_special_rooms to iterate only through the top level rooms, and fill_special_room to recurse through all of its subrooms (if any) before filling itself. --- src/sp_lev.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index 258fa8f66..39e2e037d 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1041,11 +1041,7 @@ fill_special_rooms() int tmpi, m; for (tmpi = 0; tmpi < g.nroom; tmpi++) { - if (g.rooms[tmpi].needfill) - fill_special_room(&g.rooms[tmpi]); - for (m = 0; m < g.rooms[tmpi].nsubrooms; m++) - if (g.rooms[tmpi].sbrooms[m]->needfill) - fill_special_room(g.rooms[tmpi].sbrooms[m]); + fill_special_room(&g.rooms[tmpi]); } } @@ -2685,6 +2681,15 @@ void fill_special_room(croom) struct mkroom *croom; { + int i; + + /* First recurse into subrooms. We don't want to block an ordinary room with + * a special subroom from having the subroom filled, or an unfilled outer + * room preventing a special subroom from being filled. */ + for (i = 0; i < croom->nsubrooms; ++i) { + fill_special_room(croom->sbrooms[i]); + } + if (!croom || croom->rtype == OROOM || croom->rtype == THEMEROOM || croom->needfill == FILL_NONE) return; From 5d73b2be0842033354a3f1ec31526eb133e7b24e Mon Sep 17 00:00:00 2001 From: copperwater Date: Thu, 21 May 2020 13:23:41 -0400 Subject: [PATCH 223/708] Adjust rooms in Medusa levels to account for player monster statues There is code in fixup_special for stocking Medusa's lair with statues of players from the leaderboard. It makes two assumptions: that there will always be at least one room defined on Medusa's level, and that the statues should be placed in the first room defined. In the process of removing prefilled, some of these rooms suddenly became non-rooms, and this caused problems. This commit ensures that the regions for turning into rooms to hold the statues are present and come first. In the process of writing this commit, I discovered a bug: the statue stocking code for medusa in fixup_special naively chooses the spot at which to place its final statue by selecting independent x and y coordinates with somex and somey. This is responsible for a statue occasionally being embedded in a wall or in iron bars on medusa-2 and medusa-4: the rooms defined to receive statues are irregular, and some of the possible coordinates happen to be walls, bars, and water. The proper fix here is to add lua functionality so that the level designer can specify that they want a leaderboard corpse or statue, and remove the medusa special case from fixup_special, but that's rather out of scope for what I'm doing here. --- dat/medusa-1.lua | 4 +++- dat/medusa-2.lua | 2 ++ dat/medusa-3.lua | 5 ++++- dat/medusa-4.lua | 4 ++++ src/mkmaze.c | 2 +- 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/dat/medusa-1.lua b/dat/medusa-1.lua index f97100811..85f053a06 100644 --- a/dat/medusa-1.lua +++ b/dat/medusa-1.lua @@ -36,7 +36,9 @@ des.map([[ -- Dungeon Description des.region(selection.area(00,00,74,19),"lit") des.region(selection.area(31,07,45,07),"unlit") --- make the downstairs room a real room to control arriving monsters +-- make the downstairs room a real room to control arriving monsters, +-- and also as a fixup_special hack; the first room defined on Medusa's level +-- receives some statues des.region({ region={35,09, 41,10}, lit = 0, type="ordinary", arrival_room=true }) des.region(selection.area(31,12,45,12),"unlit") -- Teleport: down to up stairs island, up to Medusa's island diff --git a/dat/medusa-2.lua b/dat/medusa-2.lua index 017b9b4b3..5fc0886ea 100644 --- a/dat/medusa-2.lua +++ b/dat/medusa-2.lua @@ -32,6 +32,8 @@ des.map([[ -- Dungeon Description des.region(selection.area(00,00,74,19),"lit") des.region(selection.area(02,03,05,16),"unlit") +-- fixup_special hack: the first room defined on a Medusa level gets some +-- leaderboard statues; setting the region as irregular makes it a room des.region({ region={61,03, 72,16}, lit=0, type="ordinary",irregular = 1 }) des.region(selection.area(71,08,72,11),"unlit") -- make the downstairs area a real room to control arriving monsters diff --git a/dat/medusa-3.lua b/dat/medusa-3.lua index 56f37c1c7..65da48b76 100644 --- a/dat/medusa-3.lua +++ b/dat/medusa-3.lua @@ -37,7 +37,10 @@ place:set(66,05); place:set(46,15); des.region(selection.area(00,00,74,19),"lit") -des.region({ region={49,14, 51,16}, lit=-1, type="ordinary" }); +-- fixup_special hack: the first room defined on a Medusa level gets some +-- leaderboard statues, use arrival_room to force it to be a room even though +-- monsters won't arrive within it +des.region({ region={49,14, 51,16}, lit=-1, type="ordinary", arrival_room=true }); des.region(selection.area(07,05,09,07),"unlit") des.region(selection.area(65,04,67,06),"unlit") des.region(selection.area(45,14,47,16),"unlit") diff --git a/dat/medusa-4.lua b/dat/medusa-4.lua index 7df55430c..75e910bf5 100644 --- a/dat/medusa-4.lua +++ b/dat/medusa-4.lua @@ -40,6 +40,10 @@ place:set(10,08); place:set(10,12); -- des.region(selection.area(00,00,74,19),"lit") +-- fixup_special hack: The first "room" region in Medusa levels gets filled with +-- some leaderboard statues, so this needs to be a room; setting irregular=1 +-- will force this +des.region({ region={13,03, 18,13}, lit=1, type="ordinary", irregular=1 }) -- des.teleport_region({ region = {64,01,74,17}, dir="down" }); des.teleport_region({ region = {02,02,18,13}, dir="up" }); diff --git a/src/mkmaze.c b/src/mkmaze.c index ae8e7636b..8987cda95 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -541,7 +541,7 @@ fixup_special() struct obj *otmp; int tryct; - croom = &g.rooms[0]; /* only one room on the medusa level */ + croom = &g.rooms[0]; /* the first room defined on the medusa level */ for (tryct = rnd(4); tryct; tryct--) { x = somex(croom); y = somey(croom); From a35cbf3816e01248f31776c4591b9a24675fc2e3 Mon Sep 17 00:00:00 2001 From: copperwater Date: Thu, 21 May 2020 21:04:06 -0400 Subject: [PATCH 224/708] Move Orcus shopkeeper removal from fixup_special into stock_room The plan is to unify special room filling code and cause special rooms to be filled as the very last stage of level creation. Since this will occur after fixup_special, it was necessary to address the one remaining piece of code in there that affects special room filling. (The Medusa code remaining in there doesn't have to do with special rooms.) --- src/mkmaze.c | 9 --------- src/shknam.c | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/mkmaze.c b/src/mkmaze.c index 8987cda95..16c92a8e3 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -574,15 +574,6 @@ fixup_special() g.level.flags.graveyard = 1; } else if (Is_stronghold(&u.uz)) { g.level.flags.graveyard = 1; - } else if (on_level(&u.uz, &orcus_level)) { - struct monst *mtmp, *mtmp2; - - /* it's a ghost town, get rid of shopkeepers */ - for (mtmp = fmon; mtmp; mtmp = mtmp2) { - mtmp2 = mtmp->nmon; - if (mtmp->isshk) - mongone(mtmp); - } } else if (on_level(&u.uz, &baalzebub_level)) { /* custom wallify the "beetle" potion of the level */ baalz_fixup(); diff --git a/src/shknam.c b/src/shknam.c index fe9a0d989..69b217ffb 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -774,6 +774,12 @@ register struct mkroom *sroom; * monsters will sit on top of objects and not the other way around. */ + /* Hack for Orcus's level: it's a ghost town, get rid of shopkeepers */ + if (on_level(&u.uz, &orcus_level)) { + struct monst* mtmp = shop_keeper(rmno); + mongone(mtmp); + } + g.level.flags.has_shop = TRUE; } From 3d03a472f6c0029009ddf970b08d9bc9727467d7 Mon Sep 17 00:00:00 2001 From: copperwater Date: Fri, 22 May 2020 00:02:51 -0400 Subject: [PATCH 225/708] Stock all special rooms at the end of level creation This unifies the two separate special-room-stocking code paths, one in the standard dungeon generator and one in the special level generator (neither of which reacted to themed rooms, which is the reason for this commit) into the end of makelevel(), placing the special room stocking as the very last step of level creation. Under the new system, when a regular or special level decides to create a special room, it sets that room's rtype, but the room is not stocked until later. It already worked this way for special levels, so the main difference here is in the normal level generation, where the mkroom family of functions identifies and marks a room as a special room, but stops short of filling it. (I suppose perhaps the mkroom, mkzoo, mkshop family of functions would be better off changing their names to "pickroom" and so on.) This also restructures makelevel() itself a bit, but the only real change is that the paths that call makemaz don't return immediately afterward; they continue to the special room stocking code. Also, this code was lifted from fill_special_rooms, which is now not used anywhere, so it has been deleted. I don't really like how fill_ordinary_room is in mklev.c and fill_special_room is in sp_lev.c; they seem like they'd be better off in mkroom.c, but in the interest of not making unnecessary code changes, I'll just recommend it. --- src/mklev.c | 166 +++++++++++++++++++++++++-------------------------- src/mkroom.c | 12 +++- src/sp_lev.c | 12 ---- 3 files changed, 91 insertions(+), 99 deletions(-) diff --git a/src/mklev.c b/src/mklev.c index 670f8760a..8a6e5f4c7 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -845,94 +845,87 @@ makelevel() register struct mkroom *croom; branch *branchp; int room_threshold; + register s_level *slev = Is_special(&u.uz); + int i; if (wiz1_level.dlevel == 0) init_dungeons(); oinit(); /* assign level dependent obj probabilities */ clear_level_structures(); - { - register s_level *slev = Is_special(&u.uz); + /* check for special levels */ + if (slev && !Is_rogue_level(&u.uz)) { + makemaz(slev->proto); + } else if (g.dungeons[u.uz.dnum].proto[0]) { + makemaz(""); + } else if (g.dungeons[u.uz.dnum].fill_lvl[0]) { + makemaz(g.dungeons[u.uz.dnum].fill_lvl); + } else if (In_quest(&u.uz)) { + char fillname[9]; + s_level *loc_lev; - /* check for special levels */ - if (slev && !Is_rogue_level(&u.uz)) { - makemaz(slev->proto); - return; - } else if (g.dungeons[u.uz.dnum].proto[0]) { - makemaz(""); - return; - } else if (g.dungeons[u.uz.dnum].fill_lvl[0]) { - makemaz(g.dungeons[u.uz.dnum].fill_lvl); - return; - } else if (In_quest(&u.uz)) { - char fillname[9]; - s_level *loc_lev; + Sprintf(fillname, "%s-loca", g.urole.filecode); + loc_lev = find_level(fillname); - Sprintf(fillname, "%s-loca", g.urole.filecode); - loc_lev = find_level(fillname); - - Sprintf(fillname, "%s-fil", g.urole.filecode); - Strcat(fillname, - (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b"); - makemaz(fillname); - return; - } else if (In_hell(&u.uz) - || (rn2(5) && u.uz.dnum == medusa_level.dnum - && depth(&u.uz) > depth(&medusa_level))) { - makemaz(""); - return; - } - } - - /* otherwise, fall through - it's a "regular" level. */ - - if (Is_rogue_level(&u.uz)) { - makeroguerooms(); - makerogueghost(); - } else - makerooms(); - sort_rooms(); - - generate_stairs(); /* up and down stairs */ - - branchp = Is_branchlev(&u.uz); /* possible dungeon branch */ - room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed - to allow a random special room */ - if (Is_rogue_level(&u.uz)) - goto skip0; - makecorridors(); - make_niches(); - - /* make a secret treasure vault, not connected to the rest */ - if (do_vault()) { - xchar w, h; - - debugpline0("trying to make a vault..."); - w = 1; - h = 1; - if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE)) { - fill_vault: - add_room(g.vault_x, g.vault_y, g.vault_x + w, g.vault_y + h, - TRUE, VAULT, FALSE); - g.level.flags.has_vault = 1; - ++room_threshold; - fill_special_room(&g.rooms[g.nroom - 1]); - mk_knox_portal(g.vault_x + w, g.vault_y + h); - if (!g.level.flags.noteleport && !rn2(3)) - makevtele(); - } else if (rnd_rect() && create_vault()) { - g.vault_x = g.rooms[g.nroom].lx; - g.vault_y = g.rooms[g.nroom].ly; - if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE)) - goto fill_vault; - else - g.rooms[g.nroom].hx = -1; - } - } - - { + Sprintf(fillname, "%s-fil", g.urole.filecode); + Strcat(fillname, + (u.uz.dlevel < loc_lev->dlevel.dlevel) ? "a" : "b"); + makemaz(fillname); + } else if (In_hell(&u.uz) + || (rn2(5) && u.uz.dnum == medusa_level.dnum + && depth(&u.uz) > depth(&medusa_level))) { + makemaz(""); + } else { + /* otherwise, fall through - it's a "regular" level. */ register int u_depth = depth(&u.uz); + if (Is_rogue_level(&u.uz)) { + makeroguerooms(); + makerogueghost(); + } else + makerooms(); + sort_rooms(); + + generate_stairs(); /* up and down stairs */ + + branchp = Is_branchlev(&u.uz); /* possible dungeon branch */ + room_threshold = branchp ? 4 : 3; /* minimum number of rooms needed + to allow a random special room */ + if (Is_rogue_level(&u.uz)) + goto skip0; + makecorridors(); + make_niches(); + + /* make a secret treasure vault, not connected to the rest */ + if (do_vault()) { + xchar w, h; + + debugpline0("trying to make a vault..."); + w = 1; + h = 1; + if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE)) { + fill_vault: + add_room(g.vault_x, g.vault_y, g.vault_x + w, g.vault_y + h, + TRUE, VAULT, FALSE); + g.level.flags.has_vault = 1; + ++room_threshold; + fill_special_room(&g.rooms[g.nroom - 1]); + mk_knox_portal(g.vault_x + w, g.vault_y + h); + if (!g.level.flags.noteleport && !rn2(3)) + makevtele(); + } else if (rnd_rect() && create_vault()) { + g.vault_x = g.rooms[g.nroom].lx; + g.vault_y = g.rooms[g.nroom].ly; + if (check_room(&g.vault_x, &w, &g.vault_y, &h, TRUE)) + goto fill_vault; + else + g.rooms[g.nroom].hx = -1; + } + } + + /* make up to 1 special room, with type dependent on depth; + * note that mkroom doesn't guarantee a room gets created, and that this + * step only sets the room's rtype - it doesn't fill it yet. */ if (wizard && nh_getenv("SHOPTYPE")) mkroom(SHOPBASE); else if (u_depth > 1 && u_depth < depth(&medusa_level) @@ -962,15 +955,20 @@ makelevel() else if (u_depth > 16 && !rn2(8) && !(g.mvitals[PM_COCKATRICE].mvflags & G_GONE)) mkroom(COCKNEST); - } skip0: - /* Place multi-dungeon branch. */ - place_branch(branchp, 0, 0); + /* Place multi-dungeon branch. */ + place_branch(branchp, 0, 0); - /* for each room: put things inside */ - for (croom = g.rooms; croom->hx > 0; croom++) { - fill_ordinary_room(croom); + /* for each room: put things inside */ + for (croom = g.rooms; croom->hx > 0; croom++) { + fill_ordinary_room(croom); + } + } + /* Fill all special rooms now, regardless of whether this is a special + * level, proto level, or ordinary level. */ + for (i = 0; i < g.nroom; ++i) { + fill_special_room(&g.rooms[i]); } } diff --git a/src/mkroom.c b/src/mkroom.c index 7fb8874fe..b8df0ffa5 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -199,8 +199,10 @@ gottype: topologize(sroom); #endif - /* stock the room with a shopkeeper and artifacts */ - stock_room(i, sroom); + /* The shop used to be stocked here, but this no longer happens - all we do + * is set its rtype, and it gets stocked at the end of makelevel() along + * with other special rooms. */ + sroom->needfill = FILL_NORMAL; } /* pick an unused room, preferably with only one door */ @@ -237,7 +239,9 @@ int type; if ((sroom = pick_room(FALSE)) != 0) { sroom->rtype = type; - fill_zoo(sroom); + /* room does not get stocked at this time - it will get stocked at the + * end of makelevel() */ + sroom->needfill = FILL_NORMAL; } } @@ -271,6 +275,8 @@ struct mkroom *sroom; int rmno = (int) ((sroom - g.rooms) + ROOMOFFSET); coord mm; + /* Note: This doesn't check needfill; it assumes the caller has already done + * that. */ sh = sroom->fdoor; switch (type) { case COURT: diff --git a/src/sp_lev.c b/src/sp_lev.c index 39e2e037d..446e78258 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -40,7 +40,6 @@ static void NDECL(remove_boundary_syms); static void FDECL(set_door_orientation, (int, int)); static void FDECL(maybe_add_door, (int, int, struct mkroom *)); static void NDECL(link_doors_rooms); -static void NDECL(fill_special_rooms); static int NDECL(rnddoor); static int NDECL(rndtrap); static void FDECL(get_location, (schar *, schar *, int, struct mkroom *)); @@ -1035,16 +1034,6 @@ link_doors_rooms() } } -static void -fill_special_rooms() -{ - int tmpi, m; - - for (tmpi = 0; tmpi < g.nroom; tmpi++) { - fill_special_room(&g.rooms[tmpi]); - } -} - /* * Choose randomly the state (nodoor, open, closed or locked) for a door */ @@ -6426,7 +6415,6 @@ const char *name; goto give_up; link_doors_rooms(); - fill_special_rooms(); remove_boundary_syms(); /* TODO: ensure_way_out() needs rewrite */ From 441bb345d77294a0bf7e409f0dd41bcbfea2b1b7 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 27 Sep 2020 22:26:39 +0300 Subject: [PATCH 226/708] Fixes doc of the recent pull requests --- doc/fixes37.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index ed3b14e18..35b411933 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -585,6 +585,8 @@ correct the Guidebook descriptions for msdos video_width and video_height to described there forces the 640x480x16 mode where video_width and video_height don't operate (github #294) redo rndmonst() to operate in a single pass (github pull request #286) +fix the "stuck pets" issue (github #329) +allow themed room subrooms to be filled (github #347) Code Cleanup and Reorganization From 78d46b3a76ff69b607faceb308fbbe18b067e2b9 Mon Sep 17 00:00:00 2001 From: copperwater Date: Wed, 16 Sep 2020 21:12:51 -0400 Subject: [PATCH 227/708] Fix: missing filled flags in various levels This is an omission in the filled/prefilled unification. The default for filled on regions now being 0 meant that regions that had previously had no need for any fill declaration at all (regions' prefilled defaulted to 0 before this, the effect being to fill them) now failed to get filled. The rule of thumb is that all des.regions with a type for which filled is meaningful (e.g. special rooms) should declare the fill status. I added it to a bunch of temples even though this doesn't really seem to affect anything there (the priest and altar come with the altar definition). I assigned temples filled=1 and filled=2 loosely based on if there is ever being some other generation that would put other furniture or items in a temple, but the distinction should not affect anything right now. Cases fixed where non-temple regions weren't getting filled: - Barracks, a graveyard, and shops in Tou-goal - The beehive in the Wizard's Tower --- dat/Hea-loca.lua | 2 +- dat/Kni-loca.lua | 2 +- dat/Pri-strt.lua | 2 +- dat/Tou-goal.lua | 12 ++++++------ dat/Wiz-goal.lua | 2 +- dat/astral.lua | 6 +++--- dat/juiblex.lua | 2 +- dat/minetn-5.lua | 2 +- dat/sanctum.lua | 2 +- dat/valley.lua | 2 +- dat/wizard3.lua | 2 +- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/dat/Hea-loca.lua b/dat/Hea-loca.lua index 7723bdbf5..e79666897 100644 --- a/dat/Hea-loca.lua +++ b/dat/Hea-loca.lua @@ -23,7 +23,7 @@ PPPPPPPPPPP........PPPPPPPPPPPP ]]); -- Dungeon Description des.region(selection.area(00,00,30,09), "lit") -des.region({ region={12,03, 20,06}, lit=1, type="temple" }) +des.region({ region={12,03, 20,06}, lit=1, type="temple", filled=1 }) -- Doors des.door("closed",09,04) des.door("closed",09,05) diff --git a/dat/Kni-loca.lua b/dat/Kni-loca.lua index 6c9480b26..7d77598e6 100644 --- a/dat/Kni-loca.lua +++ b/dat/Kni-loca.lua @@ -27,7 +27,7 @@ xxxxxxxxx.......xxxxxx.....xxxxxxxxxxxxx -- The Isle of Glass is a Tor rising out of the swamps surrounding it. des.region(selection.area(00,00,39,11), "lit") -- The top area of the Tor is a holy site. -des.region({ region={09,02, 27,09}, lit=1, type="temple" }) +des.region({ region={09,02, 27,09}, lit=1, type="temple", filled=2 }) -- Stairs des.stair("up", 38,0) des.stair("down", 18,05) diff --git a/dat/Pri-strt.lua b/dat/Pri-strt.lua index 3b4be1ac7..480a6276d 100644 --- a/dat/Pri-strt.lua +++ b/dat/Pri-strt.lua @@ -37,7 +37,7 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") -des.region({ region={24,06, 33,13}, lit=1, type="temple" }) +des.region({ region={24,06, 33,13}, lit=1, type="temple", filled=2 }) des.replace_terrain({ region={00,00, 10,19}, fromterrain=".", toterrain="T", chance=10 }) des.replace_terrain({ region={65,00, 75,19}, fromterrain=".", toterrain="T", chance=10 }) diff --git a/dat/Tou-goal.lua b/dat/Tou-goal.lua index 5cf5abd6f..2fc3de33c 100644 --- a/dat/Tou-goal.lua +++ b/dat/Tou-goal.lua @@ -33,7 +33,7 @@ des.map([[ des.region(selection.area(00,00,75,19), "lit") -- The Inn des.region(selection.area(01,01,09,02), "lit") -des.region({ region = {01,04,09,05}, lit=1, type = "barracks" }) +des.region({ region = {01,04,09,05}, lit=1, type = "barracks", filled = 1 }) des.region(selection.area(01,07,02,10), "unlit") des.region(selection.area(07,07,09,10), "unlit") des.region(selection.area(01,14,02,15), "unlit") @@ -41,9 +41,9 @@ des.region(selection.area(07,14,09,15), "unlit") des.region(selection.area(01,17,02,18), "unlit") des.region(selection.area(07,17,09,18), "unlit") -- -des.region({ region = {11,01,19,02}, lit = 0, type = "barracks" }) +des.region({ region = {11,01,19,02}, lit = 0, type = "barracks", filled = 1 }) des.region(selection.area(21,01,30,02), "unlit") -des.region({ region = {11,17,19,18}, lit = 0, type = "barracks" }) +des.region({ region = {11,17,19,18}, lit = 0, type = "barracks", filled = 1 }) des.region(selection.area(21,17,30,18), "unlit") -- Police Station des.region(selection.area(18,07,25,11), "lit") @@ -53,12 +53,12 @@ des.region(selection.area(24,13,25,13), "unlit") -- The town itself des.region(selection.area(42,03,47,06), "unlit") des.region(selection.area(42,08,50,11), "unlit") -des.region({ region = {37,16,41,18}, lit = 0, type = "morgue" }) +des.region({ region = {37,16,41,18}, lit = 0, type = "morgue", filled = 1 }) des.region(selection.area(47,16,55,18), "unlit") des.region(selection.area(55,01,62,03), "unlit") des.region(selection.area(64,01,71,03), "unlit") -des.region({ region = {60,14,71,15}, lit = 1, type = "shop" }) -des.region({ region = {60,17,71,18}, lit = 1, type = "shop" }) +des.region({ region = {60,14,71,15}, lit = 1, type = "shop", filled = 1 }) +des.region({ region = {60,17,71,18}, lit = 1, type = "shop", filled = 1 }) -- Non diggable walls des.non_diggable(selection.area(00,00,75,19)) -- Stairs diff --git a/dat/Wiz-goal.lua b/dat/Wiz-goal.lua index c243da4f7..3620c42e4 100644 --- a/dat/Wiz-goal.lua +++ b/dat/Wiz-goal.lua @@ -29,7 +29,7 @@ des.map([[ ]]); -- Dungeon Description -des.region({ region={13,10,18,12}, lit=0, type="temple" }) +des.region({ region={13,10,18,12}, lit=0, type="temple", filled=2 }) des.region(selection.area(13,06,18,08), "lit") des.region(selection.area(20,04,30,14), "unlit") des.region(selection.area(32,06,33,07), "unlit") diff --git a/dat/astral.lua b/dat/astral.lua index cfe22dd78..398ffe2ba 100644 --- a/dat/astral.lua +++ b/dat/astral.lua @@ -82,9 +82,9 @@ des.region({ region={61,05,74,14},lit=1,type="ordinary",irregular=1 }) -- A Sanctum for each alignment -- The shrines' alignments are shuffled for -- each game -des.region({ region={04,07,10,11},lit=1,type="temple" }) -des.region({ region={34,03,40,07},lit=1,type="temple" }) -des.region({ region={64,07,70,11},lit=1,type="temple" }) +des.region({ region={04,07,10,11},lit=1,type="temple",filled=2 }) +des.region({ region={34,03,40,07},lit=1,type="temple",filled=2 }) +des.region({ region={64,07,70,11},lit=1,type="temple",filled=2 }) des.altar({ x=07, y=09, align=align[1],type="sanctum" }) des.altar({ x=37, y=05, align=align[2],type="sanctum" }) diff --git a/dat/juiblex.lua b/dat/juiblex.lua index 98bc89bde..2eff9ec79 100644 --- a/dat/juiblex.lua +++ b/dat/juiblex.lua @@ -56,7 +56,7 @@ place:set(04,15); place:set(46,15); -- Dungeon description -des.region({ region={00,00,50,17}, lit=0, type="swamp" }) +des.region({ region={00,00,50,17}, lit=0, type="swamp", filled=2 }) des.levregion({ region = {01,00,11,20}, region_islev=1, exclude={0,0,50,17}, type="stair-down" }); des.levregion({ region = {69,00,79,20}, region_islev=1, exclude={0,0,50,17}, type="stair-up" }); des.levregion({ region = {01,00,11,20}, region_islev=1, exclude={0,0,50,17}, type="branch" }); diff --git a/dat/minetn-5.lua b/dat/minetn-5.lua index 8160cef07..f08a19007 100644 --- a/dat/minetn-5.lua +++ b/dat/minetn-5.lua @@ -132,6 +132,6 @@ des.door("locked",50,06) des.object("(", 50, 03) des.object({ id = "statue", x=38, y=15, montype="gnome king", historic=1 }) -- Temple -des.region({ region={29,02, 33,04}, lit=1, type="temple" }) +des.region({ region={29,02, 33,04}, lit=1, type="temple", filled=1 }) des.door("closed",31,05) des.altar({ x=31,y=03, align=align[1], type="shrine" }) diff --git a/dat/sanctum.lua b/dat/sanctum.lua index 84f7f7f99..d4594fe40 100644 --- a/dat/sanctum.lua +++ b/dat/sanctum.lua @@ -32,7 +32,7 @@ des.map([[ | ------------- ----- ------- | ---------------------------------------------------------------------------- ]]); -des.region({ region={15,07, 21,10}, lit=1, type="temple", contents = function() +des.region({ region={15,07, 21,10}, lit=1, type="temple", filled=2, contents = function() des.door({ wall = "random", state = "secret" }); end }) des.altar({ x=18, y=08, align="noalign", type="sanctum" }) diff --git a/dat/valley.lua b/dat/valley.lua index b030925f7..47f6c44df 100644 --- a/dat/valley.lua +++ b/dat/valley.lua @@ -51,7 +51,7 @@ end -- Dungeon Description -- The shrine to Moloch. -des.region({ region={01,06, 05,14},lit=1,type="temple" }) +des.region({ region={01,06, 05,14},lit=1,type="temple",filled=2 }) -- The Morgues des.region({ region={19,01, 24,08},lit=0,type="morgue",filled=1,irregular=1 }) des.region({ region={09,14, 16,18},lit=0,type="morgue",filled=1,irregular=1 }) diff --git a/dat/wizard3.lua b/dat/wizard3.lua index 4f0baf922..6c439c190 100644 --- a/dat/wizard3.lua +++ b/dat/wizard3.lua @@ -28,7 +28,7 @@ des.teleport_region({ region={01,00,79,20}, region_islev=1, exclude={0,0,27,12} des.levregion({ region={25,11,25,11}, type="portal", name="fakewiz1" }); des.mazewalk(28,09,"east") des.region({ region={07,03, 15,11}, lit=0 ,type="morgue", filled=2 }) -des.region({ region={17,06, 18,11}, lit=0, type="beehive" }) +des.region({ region={17,06, 18,11}, lit=0, type="beehive", filled=1 }) -- make the entry chamber a real room; it affects monster arrival des.region({ region={20,06,26,11},lit=0,type="ordinary",arrival_room=true, contents = function() From 8ae51f94e1a355a06c8d50cea15064ed67ea1255 Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 2 Sep 2018 14:55:03 -0400 Subject: [PATCH 228/708] You can reread a spellbook to refresh your memory at any time Aimed at fixing the problem where the player knows they're going to forget a spell in a few thousand turns, so they go back and get the book... only to find out that they "know it quite well already", and need to wait an indeterminate amount of time until they are on the verge of forgetting it (< 2000 turns) before the book will let them read it again. This commit simply removes that 2000 turn limit, so the player can fully restore their memory at any time with the spellbook. Naturally, this still consumes a read charge, so the book won't ultimately last as long if you keep rereading it early. If you do have more than 2000 turns left, the game will prompt you to confirm that you do want to refresh your memory anyway. As before, rereading with fewer turns will not prompt. --- src/spell.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/spell.c b/src/spell.c index 4b509c61c..312ca4475 100644 --- a/src/spell.c +++ b/src/spell.c @@ -393,10 +393,7 @@ learn(VOID_ARGS) book->otyp = booktype = SPE_BLANK_PAPER; /* reset spestudied as if polymorph had taken place */ book->spestudied = rn2(book->spestudied); - } else if (spellknow(i) > KEEN / 10) { - You("know %s quite well already.", splname); - costly = FALSE; - } else { /* spellknow(i) <= KEEN/10 */ + } else { Your("knowledge of %s is %s.", splname, spellknow(i) ? "keener" : "restored"); incrnknow(i, 1); @@ -443,7 +440,7 @@ int study_book(spellbook) register struct obj *spellbook; { - int booktype = spellbook->otyp; + int booktype = spellbook->otyp, i; boolean confused = (Confusion != 0); boolean too_hard = FALSE; @@ -529,6 +526,16 @@ register struct obj *spellbook; return 0; } + /* check to see if we already know it and want to refresh our memory */ + for (i = 0; i < MAXSPELL; i++) + if (spellid(i) == booktype || spellid(i) == NO_SPELL) + break; + if (spellid(i) == booktype && spellknow(i) > KEEN / 10) { + You("know \"%s\" quite well already.", OBJ_NAME(objects[booktype])); + if (yn("Refresh your memory anyway?") == 'n') + return 0; + } + /* Books are often wiser than their readers (Rus.) */ spellbook->in_use = TRUE; if (!spellbook->blessed && spellbook->otyp != SPE_BOOK_OF_THE_DEAD) { From 6348a53bd88c1820ecadd64a6783ca1d00e23a88 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 28 Sep 2020 18:28:19 +0300 Subject: [PATCH 229/708] Fixes doc --- doc/fixes37.0 | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 35b411933..5465ae338 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -587,6 +587,7 @@ correct the Guidebook descriptions for msdos video_width and video_height to redo rndmonst() to operate in a single pass (github pull request #286) fix the "stuck pets" issue (github #329) allow themed room subrooms to be filled (github #347) +allow rereading spellbooks to refresh memory at any time (github #261) Code Cleanup and Reorganization From b67092b2a05502819acc468c3992d478b73db64a Mon Sep 17 00:00:00 2001 From: copperwater Date: Sat, 23 May 2020 21:38:03 -0400 Subject: [PATCH 230/708] Fix: stairs could generate in themed rooms if others were available This is a simple && vs || bug. The clear intention of the code is that stairs aren't supposed to generate in themed rooms unless there is no other choice. Fixes #348 --- src/mklev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mklev.c b/src/mklev.c index 8a6e5f4c7..61dd00ef0 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1661,7 +1661,7 @@ int phase; && ((croom != g.dnstairs_room && croom != g.upstairs_room) || phase < 1) && (croom->rtype == OROOM - || ((phase < 2) || croom->rtype == THEMEROOM))); + || ((phase < 2) && croom->rtype == THEMEROOM))); } /* find a good room to generate an up or down stairs in */ From cf4f35ea410a7cb87d96f4cee1de0da0197c71b5 Mon Sep 17 00:00:00 2001 From: copperwater Date: Sun, 24 May 2020 14:59:50 -0400 Subject: [PATCH 231/708] Fix: irregular rooms' walls were not part of the room This was leading to problems with special themed rooms which were irregular. Walls of ordinary rooms count as part of the room, and irregular rooms should be no different. This also makes doors on the room edge be considered as part of the room, which affected special room entry messages and filling. All irregular rooms' walls getting marked as SHARED instead of their own room is probably a latent bug in upstream NetHack, but will prevent future issues for when/if themed rooms that involve special rooms/subrooms get added. --- src/mkmap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mkmap.c b/src/mkmap.c index 96e97a333..14f7973d8 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -193,7 +193,10 @@ boolean anyroom; levl[ii][jj].edge = 1; if (lit) levl[ii][jj].lit = lit; - if ((int) levl[ii][jj].roomno != rmno) + + if (levl[ii][jj].roomno == NO_ROOM) + levl[ii][jj].roomno = rmno; + else if ((int) levl[ii][jj].roomno != rmno) levl[ii][jj].roomno = SHARED; } } From 06d1b3353eefbb921f6ae86972b9c93f253262b8 Mon Sep 17 00:00:00 2001 From: copperwater Date: Mon, 1 Jun 2020 10:08:21 -0400 Subject: [PATCH 232/708] Fix: randomly generated vaults weren't being filled This also caused the unexpected "You hear someone searching" message on a level with an unlooted vault. --- src/mklev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mklev.c b/src/mklev.c index 61dd00ef0..07feca909 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -909,6 +909,7 @@ makelevel() TRUE, VAULT, FALSE); g.level.flags.has_vault = 1; ++room_threshold; + g.rooms[g.nroom - 1].needfill = FILL_NORMAL; fill_special_room(&g.rooms[g.nroom - 1]); mk_knox_portal(g.vault_x + w, g.vault_y + h); if (!g.level.flags.noteleport && !rn2(3)) From 9bb515f19614e34908a0669fc334ece30345dabd Mon Sep 17 00:00:00 2001 From: copperwater Date: Mon, 28 Sep 2020 12:48:34 -0400 Subject: [PATCH 233/708] Prevent any type of terrain overwrite from replacing stairs/ladders Consider the following scenario: There's a level where there's a zone of des.replace_terrain() between the stairs and some other objective, and the terrain is something non-walkable like trees. There's a chance that the path is entirely blocked off by random replace_terrain, so you make the level set terrain to '.' along a randline (or normal line, or whatever) between the randomly placed stairs and the other side of the replace_terrain zone. The problem: this overwrote the stairs with a '.' as well. This can be worked around in the lua file by first picking the desired location of the stairs, then setting the terrain that overlaps with the stairs, then doing des.stair() after that, but this is awkward and hard to read. So this makes it impossible for anything calling SET_TYPLIT (only called in sp_lev.c) to overwrite stairs. I can't really think of a situation where a level designer would want to define stairs, then maybe overwrite them. --- include/sp_lev.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/sp_lev.h b/include/sp_lev.h index cf86388e3..ed3e20381 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -196,7 +196,8 @@ struct mapfragment { #define SET_TYPLIT(x, y, ttyp, llit) \ { \ if ((x) >= 1 && (y) >= 0 && (x) < COLNO && (y) < ROWNO) { \ - if ((ttyp) < MAX_TYPE) \ + if ((ttyp) < MAX_TYPE && levl[(x)][(y)].typ != STAIRS \ + && levl[(x)][(y)].typ != LADDER) \ levl[(x)][(y)].typ = (ttyp); \ if ((ttyp) == LAVAPOOL) \ levl[(x)][(y)].lit = 1; \ From b9b4755fe37e05f85fff8d058336f764f576098e Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 16:25:31 -0400 Subject: [PATCH 234/708] expand sys/unix Makefiles scope Expand the use of the sys/unix Makefiles to be used for both normal local builds and installs, as well as cross-compiles for other platforms/targets. Up until now, the primary unix Makefiles have treated util/host-side component compiles, links and target object files just the same as the game component compiles, links, and target object files. Unfortunately, that meant that cross-compile effort typically had to re-invent Makefiles specific to the cross-compile, creating a maintenance burden and deviation from the typical local unix build and providing a daunting obstacle to those that want to establish build for a target environment/platform. This change distinguishes between util/host-side component builds, links, and component builds and targets object files destined for the game (and other target platforms) in the Makefiles. In theory, this will ease the effort for people that want to try to resurrect NetHack perhaps on an old platform where it is no longer viable to build NetHack-3.7 on the platform itself using old, outdated compile tools, possibly with an old, outdated C dialect. Some details: - Game-related targets in the Makefiles (as opposed to util/host-side targets that will be executed on the host), which could be destined for another platform in a cross-compile scenario are prefixed with $(TARGETPFX) so that they are distinguished. The default scenario where no cross-compiler is involved, is to define TARGETPFX to nothing, and therefore meant to have no effect. - Game-related compile and link commands in the Makefiles and their associated command line flags are distinguished from util/host-side compile and link commands in the Makefiles by using $(TARGET_CC), $(TARGET_CFLAGS), $(TARGET_LINK), $(TARGET_LFLAGS), $(TARGET_CXX), $(TARGET_CXXFLAGS), $(TARGET_LIBS). Those are used in the Makefile in place of $(CC), $(CFLAGS), $(LINK), $(LFLAGS), $(CXX), $(CXXFLAGS), $(LIBS). The default scenario where no cross-compiler is involved, defines the TARGET_ version of those Makefile variables to match their typical non-TARGET_ ounterparts. - The dependency lists in the Makefiles includes the $(TARGETPFX) prefix for stuff that would potentially be produced from a cross-compile build. - It adds pregame targets and $(PREGAME) variable, so that hints files can add some additional stuff if required for a cross-compile scenario. The default scenario where no cross-compiler is involved doesn't do anything for $(PREGAME). - It adds $(BUILDMORE) target and variable, so that hints files can add some additional things to be built for a cross-compile scenario. - It adds a "package" target and $(PACKAGE) variable, so that hints files can add steps for the target platform in a cross-compile scenario. The "install" target assumes local build and placement and isn't really applicable to a cross-compile scenario where the results really just need to be bundled up for transport to the target platform. - Also, this adds a pair of include files that can be updated with some cross-compile recipes as they evolve. They are named "cross-pre.2020" (for stuff to be included in the PRE section) and "cross-post.2020" for stuff to be included in the POST section via sys/unix/setup.sh. Those are included in sys/unix/hints/linux.2020 and sys/unix/hints/macOS.2020 hints files. --- include/config1.h | 2 + include/global.h | 2 + include/system.h | 2 +- src/options.c | 7 +- sys/unix/Makefile.src | 736 ++++++++++++++----------- sys/unix/Makefile.top | 3 + sys/unix/Makefile.utl | 66 ++- sys/unix/depend.awk | 15 +- sys/unix/hints/include/cross-post.2020 | 110 ++++ sys/unix/hints/include/cross-pre.2020 | 107 ++++ sys/unix/hints/linux.2020 | 7 + sys/unix/hints/macOS.2020 | 8 +- sys/unix/mkmkfile.sh | 3 +- 13 files changed, 706 insertions(+), 362 deletions(-) create mode 100644 sys/unix/hints/include/cross-post.2020 create mode 100644 sys/unix/hints/include/cross-pre.2020 diff --git a/include/config1.h b/include/config1.h index 986a710c1..e93b98d22 100644 --- a/include/config1.h +++ b/include/config1.h @@ -28,8 +28,10 @@ #ifdef MSDOS #undef UNIX +#ifndef CROSSCOMPILE #define SHORT_FILENAMES #endif +#endif /* * Mac Stuff. diff --git a/include/global.h b/include/global.h index 20939108d..af46502d0 100644 --- a/include/global.h +++ b/include/global.h @@ -213,11 +213,13 @@ extern struct cross_target_s cross_target; #endif #endif +#if !defined(CROSSCOMPILE) #if defined(MICRO) #if !defined(AMIGA) && !defined(TOS) && !defined(OS2_HPFS) #define SHORT_FILENAMES /* filenames are 8.3 */ #endif #endif +#endif #ifdef VMS /* vms_exit() (sys/vms/vmsmisc.c) expects the non-VMS EXIT_xxx values below. diff --git a/include/system.h b/include/system.h index 07c639574..ead454d69 100644 --- a/include/system.h +++ b/include/system.h @@ -339,7 +339,7 @@ E int FDECL(memcmp, (const void *, const void *, size_t)); E void *FDECL(memcpy, (void *, const void *, size_t)); E void *FDECL(memset, (void *, int, size_t)); #else -#if defined(AZTEC_50) || defined(NHSTDC)) +#if defined(AZTEC_50) || defined(NHSTDC) E int FDECL(memcmp, (const void *, const void *, size_t)); E void *FDECL(memcpy, (void *, const void *, size_t)); E void *FDECL(memset, (void *, int, size_t)); diff --git a/src/options.c b/src/options.c index 199fa3ca0..f505b5523 100644 --- a/src/options.c +++ b/src/options.c @@ -1450,14 +1450,15 @@ char *op; if (g.symset[PRIMARY].name) { badflag = TRUE; } else { - g.symset[PRIMARY].name = dupstr(fullname); + g.symset[PRIMARY].name = dupstr(allopt[optidx].name); if (!read_sym_file(PRIMARY)) { badflag = TRUE; clear_symsetentry(PRIMARY, TRUE); } } if (badflag) { - config_error_add("Failure to load symbol set %s.", fullname); + config_error_add("Failure to load symbol set %s.", + allopt[optidx].name); return FALSE; } else { switch_symbols(TRUE); @@ -2440,6 +2441,7 @@ char *op; if (!g.opt_initial) { g.opt_need_redraw = TRUE; } + } #endif /* CHANGE_COLOR */ return optn_ok; } @@ -2455,6 +2457,7 @@ char *op; return optn_ok; } + int optfn_paranoid_confirmation(optidx, req, negated, opts, op) int optidx; diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 790084bd3..cc69e6f5f 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -43,22 +43,29 @@ SHELL=/bin/sh # Usually, the C compiler driver is used for linking: #LINK=$(CC) +# If we're cross-compiling, a hints file will override this +# to a uniq target directory, but otherwise it just goes in +# ../src +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 \ ../sys/unix/unixunix.c ../sys/unix/unixres.c -SYSOBJ = ioctl.o unixmain.o unixtty.o unixunix.o unixres.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 \ # ../sys/share/pctty.c ../sys/share/pcunix.c -# SYSOBJ = tos.o pcmain.o pcsys.o pctty.o pcunix.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 = bemain.o unixtty.o ioctl.o +#SYSOBJ = $(TARGETPFX)bemain.o $(TARGETPFX)unixtty.o $(TARGETPFX)ioctl.o # if you are using gcc as your compiler: @@ -153,7 +160,7 @@ SYSOBJ = ioctl.o unixmain.o unixtty.o unixunix.o unixres.o #CFLAGS = -O -DXCURSES -I../include -I/usr/local/include/pdcurses # Compile against system curses library, such as ncurses #CFLAGS = -O -I../include - +# # files in ../win/X11 (relative to src) are passed $(CFLAGS) $(X11CFLAGS) # and by default will find in /usr/include/X11/foo.h; # can be overridden via hints; post-10.7 OSX with XQuartz uses @@ -180,9 +187,17 @@ CXXFLAGS = $(CFLAGS) -I. -I$(QTDIR)/include $(QTCXXFLAGS) CXX ?= g++ MOC ?= moc #LINK=g++ -# For cross-compiling, eg. with gcc on Linux (see also CC further up): -#CXX=arm-linux-g++ -#LINK=arm-linux-gcc + +# 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) +TARGET_LINK = $(LINK) +TARGET_LFLAGS = $(LFLAGS) +TARGET_CXX = $(CXX) +TARGET_CXXFLAGS = $(CXXFLAGS) +TARGET_LIBS = $(LIBS) # we specify C preprocessor flags via CFLAGS; files built with default rules # might include $(CPPFLAGS) which could get a value from user's environment; @@ -190,9 +205,9 @@ MOC ?= moc CPPFLAGS = # file for regular expression matching -REGEXOBJ = posixregex.o -#REGEXOBJ = pmatchregex.o -#REGEXOBJ = cppregex.o +REGEXOBJ = $(TARGETPFX)posixregex.o +#REGEXOBJ = $(TARGETPFX)pmatchregex.o +#REGEXOBJ = $(TARGETPFX)cppregex.o # Set the WINSRC, WINOBJ, and WINLIB lines to correspond to your desired # combination of windowing systems. Also set windowing systems in config.h. @@ -202,15 +217,18 @@ REGEXOBJ = posixregex.o # files for a straight tty port using no native windowing system WINTTYSRC = ../win/tty/getline.c ../win/tty/termcap.c ../win/tty/topl.c \ ../win/tty/wintty.c -WINTTYOBJ = getline.o termcap.o topl.o wintty.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 \ ../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 = cursmain.o curswins.o cursmisc.o cursdial.o cursstat.o \ - cursinit.o cursmesg.o cursinvt.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) @@ -218,14 +236,17 @@ 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 = Window.o dialogs.o winX.o winmap.o winmenu.o winmesg.o \ - winmisc.o winstat.o wintext.o winval.o tile.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 # # Files for a Qt 3 port (renamed since nethack 3.6.x) # #WINQT3SRC = ../win/Qt3/qt3_win.cpp ../win/Qt3/qt3_clust.cpp \ # ../win/Qt3/qt3tableview.cpp -#WINQT3OBJ = qt3_win.o qt3_clust.o qt3tableview.o tile.o +#WINQT3OBJ = $(TARGETPFX)qt3_win.o $(TARGETPFX)qt3_clust.o \ + $(TARGETPFX)qt3tableview.o $(TARGETPFX)tile.o # empty values for 'make depend' WINQT3SRC = WINQT3OBJ = @@ -242,10 +263,15 @@ 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 -WINQTOBJ = qt_bind.o qt_click.o qt_clust.o qt_delay.o qt_glyph.o qt_icon.o \ - qt_inv.o qt_key.o qt_line.o qt_main.o qt_map.o qt_menu.o qt_msg.o \ - qt_plsel.o qt_rip.o qt_set.o qt_stat.o qt_str.o qt_streq.o qt_svsel.o \ - qt_win.o qt_xcmd.o qt_yndlg.o tile.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 \ + $(TARGETPFX)qt_main.o $(TARGETPFX)qt_map.o $(TARGETPFX)qt_menu.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 # # Files for a Gnome port # @@ -255,9 +281,11 @@ WINQTOBJ = qt_bind.o qt_click.o qt_clust.o qt_delay.o qt_glyph.o qt_icon.o \ # ../win/gnome/gnplayer.c ../win/gnome/gnsignal.c \ # ../win/gnome/gnstatus.c ../win/gnome/gntext.c ../win/gnome/gnyesno.c \ # ../win/gnome/gnworn.c -#WINGNOMEOBJ = gnaskstr.o gnbind.o gnglyph.o gnmain.o gnmap.o gnmenu.o \ -# gnmesg.o gnopts.o gnplayer.o gnsignal.o gnstatus.o gntext.o \ -# gnyesno.o gnworn.o tile.o +#WINGNOMEOBJ = $(TARGETPFX)gnaskstr.o $(TARGETPFX)gnbind.o $(TARGETPFX)gnglyph.o \ +# $(TARGETPFX)gnmain.o $(TARGETPFX)gnmap.o $(TARGETPFX)gnmenu.o \ +# $(TARGETPFX)gnmesg.o $(TARGETPFX)gnopts.o $(TARGETPFX)gnplayer.o \ +# $(TARGETPFX)gnsignal.o $(TARGETPFX)gnstatus.o $(TARGETPFX)gntext.o \ +# $(TARGETPFX)gnyesno.o $(TARGETPFX)gnworn.o $(TARGETPFX)tile.o # empty values for 'make depend' WINGNOMESRC = WINGNOMEOBJ = @@ -266,7 +294,8 @@ WINGNOMEOBJ = # Files for a Gem port #WINGEMSRC = ../win/gem/wingem.c ../win/gem/wingem1.c ../win/gem/load_img.c \ # ../win/gem/gr_rect.c tile.c -#WINGEMOBJ = wingem.o wingem1.o load_img.o gr_rect.o tile.o +#WINGEMOBJ = $(TARGETPFX)wingem.o $(TARGETPFX)wingem1.o \ +# $(TARGETPFX)load_img.o $(TARGETPFX)gr_rect.o $(TARGETPFX)tile.o # empty values for 'make depend' WINGEMSRC = WINGEMOBJ = @@ -277,7 +306,9 @@ WINBESRC = WINBEOBJ = #WINBESRC = ../win/BeOS/winbe.cpp ../win/BeOS/NHWindow.cpp \ # ../win/BeOS/NHMenuWindow.cpp ../win/BeOS/NHMapWindow.cpp tile.c -#WINBEOBJ = winbe.o NHWindow.o NHMenuWindow.o NHMapWindow.o tile.o +#WINBEOBJ = $(TARGETPFX)winbe.o $(TARGETPFX)NHWindow.o \ +# $(TARGETPFX)NHMenuWindow.o $(TARGETPFX)NHMapWindow.o \ +# $(TARGETPFX)tile.o # # #WINSRC = $(WINTTYSRC) @@ -345,6 +376,9 @@ WINCURSESLIB = -lncurses # For Curses #WINLIB = $(WINCURSESLIB) # +# some platforms need to build the support libraries +# BUILDMORE = $(TARGETPFX)pdcurses.a + # any other strange libraries your system needs (for Sysunix only -- the more # specialized targets should already be right) # @@ -378,10 +412,11 @@ WINCURSESLIB = -lncurses # make NetHack GAME = nethack # GAME = nethack.prg +GAMEBIN = $(GAME) # if you defined RANDOM in unixconf.h since your system did not come # with a reasonable random number generator -# RANDOBJ = random.o +# RANDOBJ = $(TARGETPFX)random.o RANDOBJ = @@ -412,6 +447,10 @@ QUIETCC=0 # Other things that have to be reconfigured are in config.h, # {unixconf.h, pcconf.h}, and possibly system.h +# Add rule for possible cross-compiler +$(TARGETPFX)%.o : %.c + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ $< + # Verbosity definitions, begin # Set QUIETCC=1 above to output less feedback while building. # CC and CXX obey verbosity, LD and LINK don't. @@ -492,7 +531,8 @@ 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 \ ../win/chain/wc_trace.c -CHAINOBJ = wc_chainin.o wc_chainout.o wc_trace.o +CHAINOBJ = $(TARGETPFX)wc_chainin.o $(TARGETPFX)wc_chainout.o \ + $(TARGETPFX)wc_trace.o # .c files for this version (for date.h) VERSOURCES = $(HACKCSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) @@ -519,64 +559,95 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h dgn_file.h # the following .o's _must_ be made before any others (for makedefs) -FIRSTOBJ = monst.o objects.o +HOSTOBJ = monst.o objects.o alloc.o drawing.o -HOBJ = $(FIRSTOBJ) allmain.o alloc.o apply.o artifact.o attrib.o ball.o \ - bones.o botl.o cmd.o dbridge.o decl.o detect.o dig.o display.o dlb.o \ - do.o do_name.o do_wear.o dog.o dogmove.o dokick.o dothrow.o \ - drawing.o dungeon.o eat.o end.o engrave.o exper.o explode.o \ - extralev.o files.o fountain.o hack.o hacklib.o \ - insight.o invent.o isaac64.o \ - light.o lock.o mail.o makemon.o mapglyph.o mcastu.o mdlib.o mhitm.o \ - mhitu.o minion.o mklev.o mkmap.o mkmaze.o mkobj.o mkroom.o mon.o \ - mondata.o monmove.o mplayer.o mthrowu.o muse.o music.o \ - nhlua.o nhlsel.o nhlobj.o o_init.o objnam.o options.o \ - pager.o pickup.o pline.o polyself.o potion.o pray.o priest.o \ - quest.o questpgr.o read.o rect.o region.o restore.o rip.o rnd.o \ - role.o rumors.o save.o sfstruct.o \ - shk.o shknam.o sit.o sounds.o sp_lev.o spell.o symbols.o sys.o \ - steal.o steed.o teleport.o timeout.o topten.o track.o trap.o u_init.o \ - uhitm.o vault.o vision.o vis_tab.o weapon.o were.o wield.o windows.o \ - wizard.o worm.o worn.o write.o zap.o \ - $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) version.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)cmd.o $(TARGETPFX)dbridge.o $(TARGETPFX)decl.o \ + $(TARGETPFX)detect.o $(TARGETPFX)dig.o $(TARGETPFX)display.o \ + $(TARGETPFX)dlb.o $(TARGETPFX)do.o $(TARGETPFX)do_name.o \ + $(TARGETPFX)do_wear.o $(TARGETPFX)dog.o $(TARGETPFX)dogmove.o \ + $(TARGETPFX)dokick.o $(TARGETPFX)dothrow.o $(TARGETPFX)drawing.o \ + $(TARGETPFX)dungeon.o $(TARGETPFX)eat.o $(TARGETPFX)end.o \ + $(TARGETPFX)engrave.o $(TARGETPFX)exper.o $(TARGETPFX)explode.o \ + $(TARGETPFX)extralev.o $(TARGETPFX)files.o $(TARGETPFX)fountain.o \ + $(TARGETPFX)hack.o $(TARGETPFX)hacklib.o $(TARGETPFX)insight.o \ + $(TARGETPFX)invent.o $(TARGETPFX)isaac64.o $(TARGETPFX)light.o \ + $(TARGETPFX)lock.o $(TARGETPFX)mail.o $(TARGETPFX)makemon.o \ + $(TARGETPFX)mapglyph.o $(TARGETPFX)mcastu.o $(TARGETPFX)mdlib.o \ + $(TARGETPFX)mhitm.o $(TARGETPFX)mhitu.o $(TARGETPFX)minion.o \ + $(TARGETPFX)mklev.o $(TARGETPFX)mkmap.o $(TARGETPFX)mkmaze.o \ + $(TARGETPFX)mkobj.o $(TARGETPFX)mkroom.o $(TARGETPFX)mon.o \ + $(TARGETPFX)mondata.o $(TARGETPFX)monmove.o $(TARGETPFX)monst.o \ + $(TARGETPFX)mplayer.o $(TARGETPFX)mthrowu.o $(TARGETPFX)muse.o \ + $(TARGETPFX)music.o $(TARGETPFX)nhlua.o $(TARGETPFX)nhlsel.o \ + $(TARGETPFX)nhlobj.o $(TARGETPFX)objects.o $(TARGETPFX)o_init.o \ + $(TARGETPFX)objnam.o $(TARGETPFX)options.o $(TARGETPFX)pager.o \ + $(TARGETPFX)pickup.o $(TARGETPFX)pline.o $(TARGETPFX)polyself.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)restore.o \ + $(TARGETPFX)rip.o $(TARGETPFX)rnd.o $(TARGETPFX)role.o \ + $(TARGETPFX)rumors.o $(TARGETPFX)save.o $(TARGETPFX)sfstruct.o \ + $(TARGETPFX)shk.o $(TARGETPFX)shknam.o $(TARGETPFX)sit.o \ + $(TARGETPFX)sounds.o $(TARGETPFX)sp_lev.o $(TARGETPFX)spell.o \ + $(TARGETPFX)symbols.o $(TARGETPFX)sys.o $(TARGETPFX)steal.o \ + $(TARGETPFX)steed.o $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o \ + $(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \ + $(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)vault.o \ + $(TARGETPFX)vision.o $(TARGETPFX)vis_tab.o $(TARGETPFX)weapon.o \ + $(TARGETPFX)were.o $(TARGETPFX)wield.o $(TARGETPFX)windows.o \ + $(TARGETPFX)wizard.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \ + $(TARGETPFX)write.o $(TARGETPFX)zap.o \ + $(REGEXOBJ) $(RANDOBJ) $(SYSOBJ) $(WINOBJ) $(HINTOBJ) \ + $(TARGETPFX)version.o # the .o files from the HACKCSRC, SYSSRC, and WINSRC lists # first target is also the default target for 'make' without any arguments all: $(GAME) @echo "" -$(GAME): $(SYSTEM) +pregame: + true; $(PREGAME) + +$(GAME): pregame $(SYSTEM) @echo "$(GAME) is up to date." -Sysunix: $(HOBJ) Makefile +Sysunix: $(HOSTOBJ) $(HOBJ) $(BUILDMORE) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) $(LUALIB) + $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ + $(HOBJ) $(WINLIB) $(TARGET_LIBS) $(LUALIB) @touch Sysunix -Sys3B2: $(HOBJ) Makefile +Sys3B2: $(HOSTOBJ) $(HOBJ) $(BUILDMORE) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) -lmalloc + $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ + $(HOBJ) $(WINLIB) $(LUALIB) -lmalloc @touch Sys3B2 -Sysatt: $(HOBJ) Makefile +Sysatt: $(HOSTOBJ) $(HOBJ) $(BUILDMORE) Makefile @echo "Loading $(GAME)." - $(AT)$(LD) $(LFLAGS) /lib/crt0s.o /lib/shlib.ifile -o $(GAME) $(HOBJ) \ - $(LUALIB) + $(AT)$(LD) $(TARGET_LFLAGS) /lib/crt0s.o /lib/shlib.ifile -o $(GAMEBIN) \ + $(HOSTOBJ) $(HOBJ) $(LUALIB) @touch Sysatt -Systos: $(HOBJ) Makefile +Systos: $(HOSTOBJ) $(HOBJ) $(BUILDMORE) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) + $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ + $(HOBJ) $(WINLIB) $(LUALIB) @touch Systos -SysV-AT: DUMB.Setup $(HOBJ) Makefile +SysV-AT: DUMB.Setup $(HOSTOBJ) $(HOBJ) $(BUILDMORE) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LUALIB) + $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ + $(HOBJ) $(WINLIB) $(LUALIB) @touch SysV-AT -SysBe: $(HOBJ) Makefile +SysBe: $(HOSTOBJ) $(HOBJ) $(BUILDMORE) Makefile @echo "Linking $(GAME)." - $(AT)$(LINK) $(LFLAGS) -o $(GAME) $(HOBJ) $(WINLIB) $(LIBS) $(LUALIB) + $(AT)$(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAME) \ + $(HOBJ) $(WINLIB) $(TARGET_LIBS) $(LUALIB) @xres -o $(GAME) ../win/BeOS/nethack.rsrc @mimeset -f $(GAME) @touch SysBe @@ -611,11 +682,11 @@ DUMB.Setup: ../include/extern.h # special rules, to force update of makedefs, real dependencies should be # below in the 'make depend' output. monst.o: - $(CC) $(CFLAGS) -c monst.c + $(CC) $(CFLAGS) -c -o $@ monst.c @rm -f $(MAKEDEFS) objects.o: - $(CC) $(CFLAGS) -c objects.c + $(CC) $(CFLAGS) -c -o $@ objects.c @rm -f $(MAKEDEFS) # Qt 3 windowport meta-object-compiler output @@ -680,7 +751,7 @@ tile.c: ../win/share/tilemap.c $(HACK_H) ../win/gnome/gn_rip.h: ../win/X11/rip.xpm cp ../win/X11/rip.xpm ../win/gnome/gn_rip.h -sfstruct.o: sfstruct.c $(HACK_H) +$(TARGETPFX)sfstruct.o: sfstruct.c $(HACK_H) # date.h should be remade any time any of the source or include code # is modified. Unfortunately, this would make the contents of this @@ -713,14 +784,18 @@ tags: $(CSOURCES) clean: -rm -f *.o $(HACK_H) $(CONFIG_H) + true; $(CLEANMORE) spotless: clean - -rm -f a.out core $(GAME) Sys* + -rm -f a.out core $(GAMEBIN) Sys* -rm -f ../lib/lua/liblua.a ../include/nhlua.h -rm -f ../include/date.h ../include/onames.h ../include/pm.h -rm -f ../include/vis_tab.h vis_tab.c tile.c *.moc -rm -f ../win/gnome/gn_rip.h +package: + true; $(PACKAGE) + @echo packaging complete. depend: ../sys/unix/depend.awk \ $(SYSCSRC) $(WINCSRC) $(SYSCXXSRC) $(WINCXXSRC) \ @@ -766,92 +841,98 @@ $(HACK_H): ../include/hack.h $(CONFIG_H) ../include/lint.h ../include/align.h \ ../include/sys.h ../include/wintty.h ../include/trampoli.h touch $(HACK_H) # -pcmain.o: ../sys/share/pcmain.c $(HACK_H) ../include/dlb.h - $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcmain.c -pcsys.o: ../sys/share/pcsys.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcsys.c -pctty.o: ../sys/share/pctty.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/pctty.c -pcunix.o: ../sys/share/pcunix.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/pcunix.c -pmatchregex.o: ../sys/share/pmatchregex.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/pmatchregex.c -posixregex.o: ../sys/share/posixregex.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/posixregex.c -random.o: ../sys/share/random.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/random.c -ioctl.o: ../sys/share/ioctl.c $(HACK_H) ../include/tcap.h - $(CC) $(CFLAGS) -c -o $@ ../sys/share/ioctl.c -unixtty.o: ../sys/share/unixtty.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/share/unixtty.c -unixmain.o: ../sys/unix/unixmain.c $(HACK_H) ../include/dlb.h - $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixmain.c -unixunix.o: ../sys/unix/unixunix.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixunix.c -unixres.o: ../sys/unix/unixres.c $(CONFIG_H) - $(CC) $(CFLAGS) -c -o $@ ../sys/unix/unixres.c -getline.o: ../win/tty/getline.c $(HACK_H) ../include/func_tab.h - $(CC) $(CFLAGS) -c -o $@ ../win/tty/getline.c -termcap.o: ../win/tty/termcap.c $(HACK_H) ../include/tcap.h - $(CC) $(CFLAGS) -c -o $@ ../win/tty/termcap.c -topl.o: ../win/tty/topl.c $(HACK_H) ../include/tcap.h - $(CC) $(CFLAGS) -c -o $@ ../win/tty/topl.c -wintty.o: ../win/tty/wintty.c $(HACK_H) ../include/dlb.h ../include/tcap.h - $(CC) $(CFLAGS) -c -o $@ ../win/tty/wintty.c -cursmain.o: ../win/curses/cursmain.c $(HACK_H) ../include/wincurs.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursmain.c -curswins.o: ../win/curses/curswins.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/curswins.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/curswins.c -cursmisc.o: ../win/curses/cursmisc.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursmisc.h ../include/func_tab.h ../include/dlb.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursmisc.c -cursdial.o: ../win/curses/cursdial.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursdial.h ../include/func_tab.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursdial.c -cursstat.o: ../win/curses/cursstat.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursstat.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursstat.c -cursinit.o: ../win/curses/cursinit.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursinit.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursinit.c -cursmesg.o: ../win/curses/cursmesg.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursmesg.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursmesg.c -cursinvt.o: ../win/curses/cursinvt.c $(HACK_H) ../include/wincurs.h \ - ../win/curses/cursinvt.h - $(CC) $(CFLAGS) -c -o $@ ../win/curses/cursinvt.c -Window.o: ../win/X11/Window.c ../include/xwindowp.h ../include/xwindow.h \ - $(CONFIG_H) ../include/lint.h ../include/winX.h \ - ../include/color.h ../include/wintype.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/Window.c -dialogs.o: ../win/X11/dialogs.c $(CONFIG_H) ../include/lint.h \ +$(TARGETPFX)pcmain.o: ../sys/share/pcmain.c $(HACK_H) ../include/dlb.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/pcmain.c +$(TARGETPFX)pcsys.o: ../sys/share/pcsys.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/pcsys.c +$(TARGETPFX)pctty.o: ../sys/share/pctty.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/pctty.c +$(TARGETPFX)pcunix.o: ../sys/share/pcunix.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/pcunix.c +$(TARGETPFX)pmatchregex.o: ../sys/share/pmatchregex.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/pmatchregex.c +$(TARGETPFX)posixregex.o: ../sys/share/posixregex.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/posixregex.c +$(TARGETPFX)random.o: ../sys/share/random.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/random.c +$(TARGETPFX)ioctl.o: ../sys/share/ioctl.c $(HACK_H) ../include/tcap.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/ioctl.c +$(TARGETPFX)unixtty.o: ../sys/share/unixtty.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/share/unixtty.c +$(TARGETPFX)unixmain.o: ../sys/unix/unixmain.c $(HACK_H) ../include/dlb.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/unix/unixmain.c +$(TARGETPFX)unixunix.o: ../sys/unix/unixunix.c $(HACK_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/unix/unixunix.c +$(TARGETPFX)unixres.o: ../sys/unix/unixres.c $(CONFIG_H) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../sys/unix/unixres.c +$(TARGETPFX)getline.o: ../win/tty/getline.c $(HACK_H) ../include/func_tab.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/tty/getline.c +$(TARGETPFX)termcap.o: ../win/tty/termcap.c $(HACK_H) ../include/tcap.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/tty/termcap.c +$(TARGETPFX)topl.o: ../win/tty/topl.c $(HACK_H) ../include/tcap.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/tty/topl.c +$(TARGETPFX)wintty.o: ../win/tty/wintty.c $(HACK_H) ../include/dlb.h \ + ../include/tcap.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/tty/wintty.c +$(TARGETPFX)cursmain.o: ../win/curses/cursmain.c $(HACK_H) ../include/wincurs.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursmain.c +$(TARGETPFX)curswins.o: ../win/curses/curswins.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/curswins.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/curswins.c +$(TARGETPFX)cursmisc.o: ../win/curses/cursmisc.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/cursmisc.h \ + ../include/func_tab.h ../include/dlb.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursmisc.c +$(TARGETPFX)cursdial.o: ../win/curses/cursdial.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/cursdial.h \ + ../include/func_tab.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursdial.c +$(TARGETPFX)cursstat.o: ../win/curses/cursstat.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/cursstat.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursstat.c +$(TARGETPFX)cursinit.o: ../win/curses/cursinit.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/cursinit.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursinit.c +$(TARGETPFX)cursmesg.o: ../win/curses/cursmesg.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/cursmesg.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursmesg.c +$(TARGETPFX)cursinvt.o: ../win/curses/cursinvt.c $(HACK_H) \ + ../include/wincurs.h ../win/curses/cursinvt.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/curses/cursinvt.c +$(TARGETPFX)Window.o: ../win/X11/Window.c ../include/xwindowp.h \ + ../include/xwindow.h $(CONFIG_H) ../include/lint.h \ ../include/winX.h ../include/color.h ../include/wintype.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/dialogs.c -winX.o: ../win/X11/winX.c $(HACK_H) ../include/winX.h ../include/dlb.h \ - ../include/xwindow.h ../win/X11/nh72icon ../win/X11/nh56icon \ - ../win/X11/nh32icon - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winX.c -winmap.o: ../win/X11/winmap.c ../include/xwindow.h $(HACK_H) ../include/dlb.h \ - ../include/winX.h ../include/tile2x11.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmap.c -winmenu.o: ../win/X11/winmenu.c $(HACK_H) ../include/winX.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmenu.c -winmesg.o: ../win/X11/winmesg.c ../include/xwindow.h $(HACK_H) ../include/winX.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmesg.c -winmisc.o: ../win/X11/winmisc.c $(HACK_H) ../include/func_tab.h \ + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/Window.c +$(TARGETPFX)dialogs.o: ../win/X11/dialogs.c $(CONFIG_H) ../include/lint.h \ + ../include/winX.h ../include/color.h ../include/wintype.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/dialogs.c +$(TARGETPFX)winX.o: ../win/X11/winX.c $(HACK_H) ../include/winX.h \ + ../include/dlb.h ../include/xwindow.h ../win/X11/nh72icon \ + ../win/X11/nh56icon ../win/X11/nh32icon + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winX.c +$(TARGETPFX)winmap.o: ../win/X11/winmap.c ../include/xwindow.h $(HACK_H) \ + ../include/dlb.h ../include/winX.h ../include/tile2x11.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmap.c +$(TARGETPFX)winmenu.o: ../win/X11/winmenu.c $(HACK_H) ../include/winX.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmenu.c +$(TARGETPFX)winmesg.o: ../win/X11/winmesg.c ../include/xwindow.h $(HACK_H) \ ../include/winX.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmisc.c -winstat.o: ../win/X11/winstat.c $(HACK_H) ../include/winX.h ../include/xwindow.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winstat.c -wintext.o: ../win/X11/wintext.c $(HACK_H) ../include/winX.h ../include/xwindow.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/wintext.c -winval.o: ../win/X11/winval.c $(HACK_H) ../include/winX.h - $(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winval.c -tile.o: tile.c $(HACK_H) -cppregex.o: ../sys/share/cppregex.cpp - $(CXX) $(CXXFLAGS) -c -o $@ ../sys/share/cppregex.cpp -qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmesg.c +$(TARGETPFX)winmisc.o: ../win/X11/winmisc.c $(HACK_H) ../include/func_tab.h \ + ../include/winX.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winmisc.c +$(TARGETPFX)winstat.o: ../win/X11/winstat.c $(HACK_H) ../include/winX.h \ + ../include/xwindow.h + $(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ ../win/X11/winstat.c +$(TARGETPFX)wintext.o: ../win/X11/wintext.c $(HACK_H) ../include/winX.h \ + ../include/xwindow.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)tile.o: tile.c $(HACK_H) +$(TARGETPFX)cppregex.o: ../sys/share/cppregex.cpp + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../sys/share/cppregex.cpp +$(TARGETPFX)qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h ../win/Qt/qt_delay.h \ ../win/Qt/qt_xcmd.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ @@ -860,242 +941,249 @@ qt_bind.o: ../win/Qt/qt_bind.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_svsel.h ../win/Qt/qt_set.h ../win/Qt/qt_stat.h \ ../win/Qt/qt_icon.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_yndlg.h ../win/Qt/qt_str.h ../include/dlb.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_bind.cpp -qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_bind.cpp +$(TARGETPFX)qt_click.o: ../win/Qt/qt_click.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_click.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_click.cpp -qt_clust.o: ../win/Qt/qt_clust.cpp ../win/Qt/qt_clust.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_clust.cpp -qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_click.cpp +$(TARGETPFX)qt_clust.o: ../win/Qt/qt_clust.cpp ../win/Qt/qt_clust.h + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_clust.cpp +$(TARGETPFX)qt_delay.o: ../win/Qt/qt_delay.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_delay.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp -qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) ../include/tile2x11.h \ - ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_glyph.h \ - ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ - ../win/Qt/qt_set.h ../win/Qt/qt_inv.h ../win/Qt/qt_map.h \ - ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp -qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_delay.cpp +$(TARGETPFX)qt_glyph.o: ../win/Qt/qt_glyph.cpp $(HACK_H) \ + ../include/tile2x11.h ../win/Qt/qt_pre.h ../win/Qt/qt_post.h \ + ../win/Qt/qt_glyph.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ + ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h ../win/Qt/qt_inv.h \ + ../win/Qt/qt_map.h ../win/Qt/qt_win.h ../win/Qt/qt_clust.h \ + ../win/Qt/qt_str.h + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_glyph.cpp +$(TARGETPFX)qt_icon.o: ../win/Qt/qt_icon.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_icon.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp -qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_icon.cpp +$(TARGETPFX)qt_inv.o: ../win/Qt/qt_inv.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_inv.h ../win/Qt/qt_glyph.h \ ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp -qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_inv.cpp +$(TARGETPFX)qt_key.o: ../win/Qt/qt_key.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_key.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_key.cpp -qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_key.cpp +$(TARGETPFX)qt_line.o: ../win/Qt/qt_line.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_line.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_line.cpp -qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_line.cpp +$(TARGETPFX)qt_main.o: ../win/Qt/qt_main.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ qt_main.moc ../win/Qt/qt_bind.h ../win/Qt/qt_glyph.h \ ../win/Qt/qt_inv.h ../win/Qt/qt_key.h ../win/Qt/qt_map.h \ ../win/Qt/qt_win.h ../win/Qt/qt_clust.h ../win/Qt/qt_msg.h \ ../win/Qt/qt_set.h ../win/Qt/qt_stat.h ../win/Qt/qt_icon.h \ ../win/Qt/qt_str.h qt_kde0.moc - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_main.cpp -qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_main.cpp +$(TARGETPFX)qt_map.o: ../win/Qt/qt_map.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_map.h ../win/Qt/qt_win.h \ ../win/Qt/qt_clust.h qt_map.moc ../win/Qt/qt_click.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp -qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_map.cpp +$(TARGETPFX)qt_menu.o: ../win/Qt/qt_menu.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_menu.h ../win/Qt/qt_win.h \ ../win/Qt/qt_rip.h qt_menu.moc ../win/Qt/qt_glyph.h \ ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp -qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_menu.cpp +$(TARGETPFX)qt_msg.o: ../win/Qt/qt_msg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_msg.h ../win/Qt/qt_win.h \ qt_msg.moc ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ ../win/Qt/qt_set.h ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp -qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_msg.cpp +$(TARGETPFX)qt_plsel.o: ../win/Qt/qt_plsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_plsel.h qt_plsel.moc \ ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_plsel.cpp -qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_plsel.cpp +$(TARGETPFX)qt_rip.o: ../win/Qt/qt_rip.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_rip.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp -qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_rip.cpp +$(TARGETPFX)qt_set.o: ../win/Qt/qt_set.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_set.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h qt_set.moc \ ../win/Qt/qt_glyph.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp -qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_set.cpp +$(TARGETPFX)qt_stat.o: ../win/Qt/qt_stat.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_stat.h ../win/Qt/qt_win.h \ ../win/Qt/qt_icon.h qt_stat.moc ../win/Qt/qt_set.h \ ../win/Qt/qt_bind.h ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h \ ../win/Qt/qt_str.h ../win/Qt/qt_xpms.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp -qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_str.cpp -qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_stat.cpp +$(TARGETPFX)qt_str.o: ../win/Qt/qt_str.cpp ../win/Qt/qt_str.h + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_str.cpp +$(TARGETPFX)qt_streq.o: ../win/Qt/qt_streq.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_streq.h ../win/Qt/qt_line.h \ ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp -qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_streq.cpp +$(TARGETPFX)qt_svsel.o: ../win/Qt/qt_svsel.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_svsel.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp -qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_svsel.cpp +$(TARGETPFX)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_win.h ../win/Qt/qt_bind.h \ ../win/Qt/qt_main.h ../win/Qt/qt_kde0.h ../win/Qt/qt_click.h \ ../win/Qt/qt_glyph.h ../win/Qt/qt_inv.h ../win/Qt/qt_key.h \ ../win/Qt/qt_icon.h ../win/Qt/qt_map.h ../win/Qt/qt_clust.h \ ../win/Qt/qt_menu.h ../win/Qt/qt_rip.h ../win/Qt/qt_msg.h \ ../win/Qt/qt_set.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_win.cpp -qt_xcmd.o: ../win/Qt/qt_xcmd.cpp $(HACK_H) ../include/func_tab.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_win.cpp +$(TARGETPFX)qt_xcmd.o: ../win/Qt/qt_xcmd.cpp $(HACK_H) ../include/func_tab.h \ ../win/Qt/qt_pre.h ../win/Qt/qt_post.h ../win/Qt/qt_xcmd.h \ qt_xcmd.moc ../win/Qt/qt_bind.h ../win/Qt/qt_main.h \ ../win/Qt/qt_kde0.h ../win/Qt/qt_set.h ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_xcmd.cpp -qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_xcmd.cpp +$(TARGETPFX)qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_post.h ../win/Qt/qt_yndlg.h qt_yndlg.moc \ ../win/Qt/qt_str.h - $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp -wc_chainin.o: ../win/chain/wc_chainin.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_chainin.c -wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) - $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_chainout.c -wc_trace.o: ../win/chain/wc_trace.c $(HACK_H) ../include/func_tab.h - $(CC) $(CFLAGS) -c -o $@ ../win/chain/wc_trace.c -vis_tab.o: vis_tab.c $(CONFIG_H) ../include/vis_tab.h -allmain.o: allmain.c $(HACK_H) -alloc.o: alloc.c $(CONFIG_H) -apply.o: apply.c $(HACK_H) -artifact.o: artifact.c $(HACK_H) ../include/artifact.h ../include/artilist.h -attrib.o: attrib.c $(HACK_H) -ball.o: ball.c $(HACK_H) -bones.o: bones.c $(HACK_H) -botl.o: botl.c $(HACK_H) -cmd.o: cmd.c $(HACK_H) ../include/func_tab.h -dbridge.o: dbridge.c $(HACK_H) -decl.o: decl.c $(HACK_H) -detect.o: detect.c $(HACK_H) ../include/artifact.h -dig.o: dig.c $(HACK_H) -display.o: display.c $(HACK_H) -dlb.o: dlb.c $(CONFIG_H) ../include/dlb.h -do.o: do.c $(HACK_H) -do_name.o: do_name.c $(HACK_H) -do_wear.o: do_wear.c $(HACK_H) -dog.o: dog.c $(HACK_H) -dogmove.o: dogmove.c $(HACK_H) ../include/mfndpos.h -dokick.o: dokick.c $(HACK_H) -dothrow.o: dothrow.c $(HACK_H) -drawing.o: drawing.c $(CONFIG_H) ../include/color.h ../include/rm.h \ - ../include/objclass.h ../include/monsym.h -dungeon.o: dungeon.c $(HACK_H) ../include/dgn_file.h ../include/dlb.h -eat.o: eat.c $(HACK_H) -end.o: end.c $(HACK_H) ../include/dlb.h -engrave.o: engrave.c $(HACK_H) -exper.o: exper.c $(HACK_H) -explode.o: explode.c $(HACK_H) -extralev.o: extralev.c $(HACK_H) -files.o: files.c $(HACK_H) ../include/dlb.h #zlib.h -fountain.o: fountain.c $(HACK_H) -hack.o: hack.c $(HACK_H) -hacklib.o: hacklib.c $(HACK_H) -insight.o: insight.c $(HACK_H) -invent.o: invent.c $(HACK_H) -isaac64.o: isaac64.c $(CONFIG_H) ../include/isaac64.h -light.o: light.c $(HACK_H) -lock.o: lock.c $(HACK_H) -mail.o: mail.c $(HACK_H) ../include/mail.h -makemon.o: makemon.c $(HACK_H) -mapglyph.o: mapglyph.c $(HACK_H) -mcastu.o: mcastu.c $(HACK_H) -mdlib.o: mdlib.c $(CONFIG_H) ../include/permonst.h ../include/align.h \ - ../include/monattk.h ../include/monflag.h \ + $(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp +$(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) + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainout.c +$(TARGETPFX)wc_trace.o: ../win/chain/wc_trace.c $(HACK_H) ../include/func_tab.h + $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_trace.c +$(TARGETPFX)vis_tab.o: vis_tab.c $(CONFIG_H) ../include/vis_tab.h +$(TARGETPFX)allmain.o: allmain.c $(HACK_H) +$(TARGETPFX)alloc.o: alloc.c $(CONFIG_H) +$(TARGETPFX)apply.o: apply.c $(HACK_H) +$(TARGETPFX)artifact.o: artifact.c $(HACK_H) ../include/artifact.h \ + ../include/artilist.h +$(TARGETPFX)attrib.o: attrib.c $(HACK_H) +$(TARGETPFX)ball.o: ball.c $(HACK_H) +$(TARGETPFX)bones.o: bones.c $(HACK_H) +$(TARGETPFX)botl.o: botl.c $(HACK_H) +$(TARGETPFX)cmd.o: cmd.c $(HACK_H) ../include/func_tab.h +$(TARGETPFX)dbridge.o: dbridge.c $(HACK_H) +$(TARGETPFX)decl.o: decl.c $(HACK_H) +$(TARGETPFX)detect.o: detect.c $(HACK_H) ../include/artifact.h +$(TARGETPFX)dig.o: dig.c $(HACK_H) +$(TARGETPFX)display.o: display.c $(HACK_H) +$(TARGETPFX)dlb.o: dlb.c $(CONFIG_H) ../include/dlb.h +$(TARGETPFX)do.o: do.c $(HACK_H) +$(TARGETPFX)do_name.o: do_name.c $(HACK_H) +$(TARGETPFX)do_wear.o: do_wear.c $(HACK_H) +$(TARGETPFX)dog.o: dog.c $(HACK_H) +$(TARGETPFX)dogmove.o: dogmove.c $(HACK_H) ../include/mfndpos.h +$(TARGETPFX)dokick.o: dokick.c $(HACK_H) +$(TARGETPFX)dothrow.o: dothrow.c $(HACK_H) +$(TARGETPFX)drawing.o: drawing.c $(CONFIG_H) ../include/color.h \ + ../include/rm.h ../include/objclass.h ../include/monsym.h +$(TARGETPFX)dungeon.o: dungeon.c $(HACK_H) ../include/dgn_file.h \ + ../include/dlb.h +$(TARGETPFX)eat.o: eat.c $(HACK_H) +$(TARGETPFX)end.o: end.c $(HACK_H) ../include/dlb.h +$(TARGETPFX)engrave.o: engrave.c $(HACK_H) +$(TARGETPFX)exper.o: exper.c $(HACK_H) +$(TARGETPFX)explode.o: explode.c $(HACK_H) +$(TARGETPFX)extralev.o: extralev.c $(HACK_H) +$(TARGETPFX)files.o: files.c $(HACK_H) ../include/dlb.h #zlib.h +$(TARGETPFX)fountain.o: fountain.c $(HACK_H) +$(TARGETPFX)hack.o: hack.c $(HACK_H) +$(TARGETPFX)hacklib.o: hacklib.c $(HACK_H) +$(TARGETPFX)insight.o: insight.c $(HACK_H) +$(TARGETPFX)invent.o: invent.c $(HACK_H) +$(TARGETPFX)isaac64.o: isaac64.c $(CONFIG_H) ../include/isaac64.h +$(TARGETPFX)light.o: light.c $(HACK_H) +$(TARGETPFX)lock.o: lock.c $(HACK_H) +$(TARGETPFX)mail.o: mail.c $(HACK_H) ../include/mail.h +$(TARGETPFX)makemon.o: makemon.c $(HACK_H) +$(TARGETPFX)mapglyph.o: mapglyph.c $(HACK_H) +$(TARGETPFX)mcastu.o: mcastu.c $(HACK_H) +$(TARGETPFX)mdlib.o: mdlib.c $(CONFIG_H) ../include/permonst.h \ + ../include/align.h ../include/monattk.h ../include/monflag.h \ ../include/objclass.h ../include/monsym.h \ ../include/artilist.h ../include/dungeon.h ../include/obj.h \ ../include/monst.h ../include/mextra.h ../include/you.h \ ../include/attrib.h ../include/prop.h ../include/skills.h \ ../include/context.h ../include/flag.h ../include/dlb.h -mhitm.o: mhitm.c $(HACK_H) ../include/artifact.h -mhitu.o: mhitu.c $(HACK_H) ../include/artifact.h -minion.o: minion.c $(HACK_H) -mklev.o: mklev.c $(HACK_H) -mkmap.o: mkmap.c $(HACK_H) ../include/sp_lev.h -mkmaze.o: mkmaze.c $(HACK_H) ../include/sp_lev.h -mkobj.o: mkobj.c $(HACK_H) -mkroom.o: mkroom.c $(HACK_H) -mon.o: mon.c $(HACK_H) ../include/mfndpos.h -mondata.o: mondata.c $(HACK_H) -monmove.o: monmove.c $(HACK_H) ../include/mfndpos.h ../include/artifact.h -monst.o: monst.c $(CONFIG_H) ../include/permonst.h ../include/align.h \ - ../include/monattk.h ../include/monflag.h ../include/monsym.h \ +$(TARGETPFX)mhitm.o: mhitm.c $(HACK_H) ../include/artifact.h +$(TARGETPFX)mhitu.o: mhitu.c $(HACK_H) ../include/artifact.h +$(TARGETPFX)minion.o: minion.c $(HACK_H) +$(TARGETPFX)mklev.o: mklev.c $(HACK_H) +$(TARGETPFX)mkmap.o: mkmap.c $(HACK_H) ../include/sp_lev.h +$(TARGETPFX)mkmaze.o: mkmaze.c $(HACK_H) ../include/sp_lev.h +$(TARGETPFX)mkobj.o: mkobj.c $(HACK_H) +$(TARGETPFX)mkroom.o: mkroom.c $(HACK_H) +$(TARGETPFX)mon.o: mon.c $(HACK_H) ../include/mfndpos.h +$(TARGETPFX)mondata.o: mondata.c $(HACK_H) +$(TARGETPFX)monmove.o: monmove.c $(HACK_H) ../include/mfndpos.h \ + ../include/artifact.h +$(TARGETPFX)monst.o: monst.c $(CONFIG_H) ../include/permonst.h \ + ../include/align.h ../include/monattk.h ../include/monflag.h \ + ../include/monsym.h ../include/color.h +$(TARGETPFX)mplayer.o: mplayer.c $(HACK_H) +$(TARGETPFX)mthrowu.o: mthrowu.c $(HACK_H) +$(TARGETPFX)muse.o: muse.c $(HACK_H) +$(TARGETPFX)music.o: music.c $(HACK_H) +$(TARGETPFX)nhlua.o: nhlua.c $(HACK_H) ../include/dlb.h +$(TARGETPFX)nhlsel.o: nhlsel.c $(HACK_H) ../include/sp_lev.h +$(TARGETPFX)nhlobj.o: nhlobj.c $(HACK_H) ../include/sp_lev.h +$(TARGETPFX)o_init.o: o_init.c $(HACK_H) +$(TARGETPFX)objects.o: objects.c $(CONFIG_H) ../include/obj.h \ + ../include/objclass.h ../include/prop.h ../include/skills.h \ ../include/color.h -mplayer.o: mplayer.c $(HACK_H) -mthrowu.o: mthrowu.c $(HACK_H) -muse.o: muse.c $(HACK_H) -music.o: music.c $(HACK_H) -nhlua.o: nhlua.c $(HACK_H) ../include/dlb.h -nhlsel.o: nhlsel.c $(HACK_H) ../include/sp_lev.h -nhlobj.o: nhlobj.c $(HACK_H) ../include/sp_lev.h -o_init.o: o_init.c $(HACK_H) -objects.o: objects.c $(CONFIG_H) ../include/obj.h ../include/objclass.h \ - ../include/prop.h ../include/skills.h ../include/color.h -objnam.o: objnam.c $(HACK_H) -options.o: options.c $(CONFIG_H) ../include/objclass.h ../include/flag.h \ - $(HACK_H) ../include/tcap.h ../include/optlist.h -pager.o: pager.c $(HACK_H) ../include/dlb.h -pickup.o: pickup.c $(HACK_H) -pline.o: pline.c $(HACK_H) -polyself.o: polyself.c $(HACK_H) -potion.o: potion.c $(HACK_H) -pray.o: pray.c $(HACK_H) -priest.o: priest.c $(HACK_H) ../include/mfndpos.h -quest.o: quest.c $(HACK_H) -questpgr.o: questpgr.c $(HACK_H) ../include/dlb.h -read.o: read.c $(HACK_H) -rect.o: rect.c $(HACK_H) -region.o: region.c $(HACK_H) -restore.o: restore.c $(HACK_H) ../include/tcap.h -rip.o: rip.c $(HACK_H) -rnd.o: rnd.c $(HACK_H) ../include/isaac64.h -role.o: role.c $(HACK_H) -rumors.o: rumors.c $(HACK_H) ../include/dlb.h -save.o: save.c $(HACK_H) -sfstruct.o: sfstruct.c $(HACK_H) -shk.o: shk.c $(HACK_H) -shknam.o: shknam.c $(HACK_H) -sit.o: sit.c $(HACK_H) ../include/artifact.h -sounds.o: sounds.c $(HACK_H) -sp_lev.o: sp_lev.c $(HACK_H) ../include/sp_lev.h -spell.o: spell.c $(HACK_H) -steal.o: steal.c $(HACK_H) -steed.o: steed.c $(HACK_H) -symbols.o: symbols.c $(HACK_H) ../include/tcap.h -sys.o: sys.c $(HACK_H) -teleport.o: teleport.c $(HACK_H) -timeout.o: timeout.c $(HACK_H) -topten.o: topten.c $(HACK_H) ../include/dlb.h -track.o: track.c $(HACK_H) -trap.o: trap.c $(HACK_H) -u_init.o: u_init.c $(HACK_H) -uhitm.o: uhitm.c $(HACK_H) -vault.o: vault.c $(HACK_H) -version.o: version.c $(HACK_H) ../include/dlb.h ../include/date.h -vision.o: vision.c $(HACK_H) ../include/vis_tab.h -weapon.o: weapon.c $(HACK_H) -were.o: were.c $(HACK_H) -wield.o: wield.c $(HACK_H) -windows.o: windows.c $(HACK_H) ../include/wingem.h ../include/winGnome.h -wizard.o: wizard.c $(HACK_H) -worm.o: worm.c $(HACK_H) -worn.o: worn.c $(HACK_H) -write.o: write.c $(HACK_H) -zap.o: zap.c $(HACK_H) +$(TARGETPFX)objnam.o: objnam.c $(HACK_H) +$(TARGETPFX)options.o: options.c $(CONFIG_H) ../include/objclass.h \ + ../include/flag.h $(HACK_H) ../include/tcap.h \ + ../include/optlist.h +$(TARGETPFX)pager.o: pager.c $(HACK_H) ../include/dlb.h +$(TARGETPFX)pickup.o: pickup.c $(HACK_H) +$(TARGETPFX)pline.o: pline.c $(HACK_H) +$(TARGETPFX)polyself.o: polyself.c $(HACK_H) +$(TARGETPFX)potion.o: potion.c $(HACK_H) +$(TARGETPFX)pray.o: pray.c $(HACK_H) +$(TARGETPFX)priest.o: priest.c $(HACK_H) ../include/mfndpos.h +$(TARGETPFX)quest.o: quest.c $(HACK_H) +$(TARGETPFX)questpgr.o: questpgr.c $(HACK_H) ../include/dlb.h +$(TARGETPFX)read.o: read.c $(HACK_H) +$(TARGETPFX)rect.o: rect.c $(HACK_H) +$(TARGETPFX)region.o: region.c $(HACK_H) +$(TARGETPFX)restore.o: restore.c $(HACK_H) ../include/tcap.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) +$(TARGETPFX)rumors.o: rumors.c $(HACK_H) ../include/dlb.h +$(TARGETPFX)save.o: save.c $(HACK_H) +$(TARGETPFX)sfstruct.o: sfstruct.c $(HACK_H) +$(TARGETPFX)shk.o: shk.c $(HACK_H) +$(TARGETPFX)shknam.o: shknam.c $(HACK_H) +$(TARGETPFX)sit.o: sit.c $(HACK_H) ../include/artifact.h +$(TARGETPFX)sounds.o: sounds.c $(HACK_H) +$(TARGETPFX)sp_lev.o: sp_lev.c $(HACK_H) ../include/sp_lev.h +$(TARGETPFX)spell.o: spell.c $(HACK_H) +$(TARGETPFX)steal.o: steal.c $(HACK_H) +$(TARGETPFX)steed.o: steed.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)timeout.o: timeout.c $(HACK_H) +$(TARGETPFX)topten.o: topten.c $(HACK_H) ../include/dlb.h +$(TARGETPFX)track.o: track.c $(HACK_H) +$(TARGETPFX)trap.o: trap.c $(HACK_H) +$(TARGETPFX)u_init.o: u_init.c $(HACK_H) +$(TARGETPFX)uhitm.o: uhitm.c $(HACK_H) +$(TARGETPFX)vault.o: vault.c $(HACK_H) +$(TARGETPFX)version.o: version.c $(HACK_H) ../include/dlb.h ../include/date.h +$(TARGETPFX)vision.o: vision.c $(HACK_H) ../include/vis_tab.h +$(TARGETPFX)weapon.o: weapon.c $(HACK_H) +$(TARGETPFX)were.o: were.c $(HACK_H) +$(TARGETPFX)wield.o: wield.c $(HACK_H) +$(TARGETPFX)windows.o: windows.c $(HACK_H) ../include/wingem.h \ + ../include/winGnome.h +$(TARGETPFX)wizard.o: wizard.c $(HACK_H) +$(TARGETPFX)worm.o: worm.c $(HACK_H) +$(TARGETPFX)worn.o: worn.c $(HACK_H) +$(TARGETPFX)write.o: write.c $(HACK_H) +$(TARGETPFX)zap.o: zap.c $(HACK_H) # DEPENDENCIES MUST END AT END OF FILE # IF YOU PUT STUFF HERE IT WILL GO AWAY # see make depend above diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index b604bb7ef..5d72e4221 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -205,6 +205,9 @@ dlb: ( cd util ; $(MAKE) dlb ) ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) +package: $(GAME) recover $(VARDAT) spec_levs + ( cd src ; $(MAKE) $(PACKAGE) ) + # recover can be used when INSURANCE is defined in include/config.h # and the checkpoint option is true recover: $(GAME) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 2674596f4..751395c7a 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -106,9 +106,6 @@ CPPFLAGS = LIBS = -# If you are cross-compiling, you must use this: -#OBJDIR = . -# otherwise, you can save a little bit of disk space with this: OBJDIR = ../src # if you change this to 1, feedback while building will omit -Dthis -Wthat @@ -186,17 +183,31 @@ RECOVOBJS = recover.o # object files for the data librarian DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) +# Distinguish between the build tools for the native host +# and the build tools for the target environment in commands. +# This allows the same set of Makefiles to be used for native +# builds and for cross-compiles by overriding these in hints +# files or on the command line. + +TARGETPFX= +TARGET_CC = $(CC) +TARGET_CFLAGS = $(CFLAGS) +TARGET_LINK = $(LINK) +TARGET_LFLAGS = $(LFLAGS) +TARGET_CXX = $(CXX) +TARGET_CXXFLAGS = $(CXXFLAGS) # dependencies for makedefs # makedefs: $(MAKEOBJS) mdgrep.h - $(CC) $(LFLAGS) -o makedefs $(MAKEOBJS) + $(LINK) $(LFLAGS) -o makedefs $(MAKEOBJS) makedefs.o: makedefs.c ../src/mdlib.c $(CONFIG_H) ../include/permonst.h \ ../include/objclass.h ../include/monsym.h \ ../include/artilist.h ../include/dungeon.h ../include/obj.h \ ../include/monst.h ../include/you.h ../include/flag.h \ ../include/dlb.h ../include/patchlevel.h + $(CC) $(CFLAGS) -c makedefs.c -o $@ # Don't require perl to build; that is why mdgrep.h is spelled wrong below. mdgreph: mdgrep.pl @@ -222,6 +233,7 @@ lintdefs: # support code used by several of the utility programs (but not makedefs) panic.o: panic.c $(CONFIG_H) + $(CC) $(CFLAGS) -c panic.c -o $@ # with all of extern.h's functions to complain about, we drown in @@ -233,7 +245,7 @@ lintdgn: # dependencies for recover # recover: $(RECOVOBJS) - $(CC) $(LFLAGS) -o recover $(RECOVOBJS) $(LIBS) + $(LINK) $(LFLAGS) -o recover $(RECOVOBJS) $(LIBS) recover.o: recover.c $(CONFIG_H) ../include/date.h @@ -244,8 +256,7 @@ dlb: $(DLBOBJS) $(CC) $(LFLAGS) -o dlb $(DLBOBJS) $(LIBS) dlb_main.o: dlb_main.c $(CONFIG_H) ../include/dlb.h ../include/date.h - $(CC) $(CFLAGS) -c dlb_main.c - + $(CC) $(CFLAGS) -c dlb_main.c -o $@ # dependencies for tile utilities @@ -257,24 +268,24 @@ PPMWRITERS = ppmwrite.o tileutils: tilemap gif2txt txt2ppm tile2x11 gif2txt: $(GIFREADERS) $(TEXT_IO) - $(CC) $(LFLAGS) -o gif2txt $(GIFREADERS) $(TEXT_IO) $(LIBS) + $(LINK) $(LFLAGS) -o gif2txt $(GIFREADERS) $(TEXT_IO) $(LIBS) txt2ppm: $(PPMWRITERS) $(TEXT_IO) - $(CC) $(LFLAGS) -o txt2ppm $(PPMWRITERS) $(TEXT_IO) $(LIBS) + $(LINK) $(LFLAGS) -o txt2ppm $(PPMWRITERS) $(TEXT_IO) $(LIBS) tile2x11: tile2x11.o $(TEXT_IO) - $(CC) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) $(LIBS) + $(LINK) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) $(LIBS) tile2img.ttp: tile2img.o bitmfile.o $(TEXT_IO) - $(CC) $(LFLAGS) -o tile2img.ttp tile2img.o bitmfile.o $(TEXT_IO) $(LIBS) + $(LINK) $(LFLAGS) -o tile2img.ttp tile2img.o bitmfile.o $(TEXT_IO) $(LIBS) tile2bmp: tile2bmp.o $(TEXT_IO) - $(CC) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO) + $(LINK) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO) xpm2img.ttp: xpm2img.o bitmfile.o - $(CC) $(LFLAGS) -o xpm2img.ttp xpm2img.o bitmfile.o $(LIBS) + $(LINK) $(LFLAGS) -o xpm2img.ttp xpm2img.o bitmfile.o $(LIBS) tile2beos: tile2beos.o $(TEXT_IO) - $(CC) $(LFLAGS) -o tile2beos tile2beos.o $(TEXT_IO) -lbe + $(LINK) $(LFLAGS) -o tile2beos tile2beos.o $(TEXT_IO) -lbe #--compiling and linking in one step leaves extra debugging files (in their # own subdirectories!) on OSX; compile and link separately to suppress @@ -282,14 +293,14 @@ tile2beos: tile2beos.o $(TEXT_IO) #tilemap: ../win/share/tilemap.c $(HACK_H) # $(CC) $(CFLAGS) $(LFLAGS) -o tilemap ../win/share/tilemap.c $(LIBS) tilemap: tilemap.o - $(CC) $(LFLAGS) -o tilemap tilemap.o $(LIBS) + $(LINK) $(LFLAGS) -o tilemap tilemap.o $(LIBS) ../src/tile.c: tilemap ./tilemap ../include/tile.h: ../win/share/tile.h cp ../win/share/tile.h ../include/tile.h tiletext.o: ../win/share/tiletext.c $(CONFIG_H) ../include/tile.h - $(CC) $(CFLAGS) -c ../win/share/tiletext.c + $(CC) $(CFLAGS) -c ../win/share/tiletext.c -o $@ tiletxt.c: ./Makefile @echo '/* alternate compilation for tilemap.c to create tiletxt.o' > tiletxt.c @echo ' that does not rely on "cc -c -o tiletxt.o tilemap.c"' >> tiletxt.c @@ -298,32 +309,32 @@ tiletxt.c: ./Makefile echo '#include "../win/share/tilemap.c"' >> tiletxt.c @echo '/*tiletxt.c*/' >> tiletxt.c tiletxt.o: tiletxt.c ../win/share/tilemap.c $(HACK_H) - $(CC) $(CFLAGS) -c tiletxt.c + $(CC) $(CFLAGS) -c tiletxt.c -o $@ tilemap.o: ../win/share/tilemap.c $(HACK_H) - $(CC) $(CFLAGS) -c ../win/share/tilemap.c + $(CC) $(CFLAGS) -c ../win/share/tilemap.c -o $@ gifread.o: ../win/share/gifread.c $(CONFIG_H) ../include/tile.h - $(CC) $(CFLAGS) -c ../win/share/gifread.c + $(CC) $(CFLAGS) -c ../win/share/gifread.c -o $@ ppmwrite.o: ../win/share/ppmwrite.c $(CONFIG_H) ../include/tile.h - $(CC) $(CFLAGS) -c ../win/share/ppmwrite.c + $(CC) $(CFLAGS) -c ../win/share/ppmwrite.c -o $@ tile2bmp.o: ../win/share/tile2bmp.c $(HACK_H) ../include/tile.h - $(CC) $(CFLAGS) -c ../win/share/tile2bmp.c + $(CC) $(CFLAGS) -c ../win/share/tile2bmp.c -o $@ tile2x11.o: ../win/X11/tile2x11.c $(HACK_H) ../include/tile.h \ ../include/tile2x11.h - $(CC) $(CFLAGS) -c ../win/X11/tile2x11.c + $(CC) $(CFLAGS) -c ../win/X11/tile2x11.c -o $@ tile2img.o: ../win/gem/tile2img.c $(HACK_H) ../include/tile.h \ ../include/bitmfile.h - $(CC) $(CFLAGS) -c ../win/gem/tile2img.c + $(CC) $(CFLAGS) -c ../win/gem/tile2img.c -o $@ xpm2img.o: ../win/gem/xpm2img.c $(HACK_H) ../include/bitmfile.h - $(CC) $(CFLAGS) -c ../win/gem/xpm2img.c + $(CC) $(CFLAGS) -c ../win/gem/xpm2img.c -o $@ bitmfile.o: ../win/gem/bitmfile.c ../include/bitmfile.h - $(CC) $(CFLAGS) -c ../win/gem/bitmfile.c + $(CC) $(CFLAGS) -c ../win/gem/bitmfile.c -o $@ tile2beos.o: ../win/BeOS/tile2beos.cpp $(HACK_H) ../include/tile.h - $(CXX) $(CFLAGS) -c ../win/BeOS/tile2beos.cpp + $(CXX) $(CFLAGS) -c ../win/BeOS/tile2beos.cpp -o $@ tileedit: tileedit.cpp $(TEXT_IO) $(QTDIR)/bin/moc -o tileedit.moc tileedit.h @@ -341,8 +352,7 @@ tileedit: tileedit.cpp $(TEXT_IO) # to improvise things not in the instructions, like 'make makedefs' here # in util... -# make sure object files from src are available when needed -# +# make sure host object files from src are available when needed $(OBJDIR)/alloc.o: ../src/alloc.c $(CONFIG_H) $(CC) $(CFLAGS) -c ../src/alloc.c -o $@ $(OBJDIR)/drawing.o: ../src/drawing.c $(CONFIG_H) diff --git a/sys/unix/depend.awk b/sys/unix/depend.awk index ac4416230..a488c5457 100644 --- a/sys/unix/depend.awk +++ b/sys/unix/depend.awk @@ -113,8 +113,13 @@ function output_specials( i, sp, alt_sp) # function format_dep(target, source, col, n, i, list) { + if (substr(target,1,1) == "$") { + prefix = "" + } else { + prefix = "$(TARGETPFX)" + } split("", done) #``for (x in done) delete done[x]'' - printf("%s:", target); col = length(target) + 1 + printf("%s%s:", prefix, target); col = length(target) + 1 + length(prefix) #- printf("\t"); col += 8 - (col % 8); #- if (col == 8) { printf("\t"); col += 8 } source = depend("", source, 0) @@ -132,13 +137,13 @@ function format_dep(target, source, col, n, i, list) source = list[2] if (source ~ /\// && substr(source, 1, 11) != "../include/") { if (source ~ /\.cpp$/ ) - print "\t$(CXX) $(CXXFLAGS) -c -o $@ " source + print "\t$(TARGET_CXX) $(TARGET_CXXFLAGS) -c -o $@ " source else if (source ~ /\/X11\//) # "../win/X11/foo.c" - print "\t$(CC) $(CFLAGS) $(X11CFLAGS) -c -o $@ " source + print "\t$(TARGET_CC) $(TARGET_CFLAGS) $(X11CFLAGS) -c -o $@ " source else if (source ~ /\/gnome\//) # "../win/gnome/foo.c" - print "\t$(CC) $(CFLAGS) $(GNOMEINC) -c -o $@ " source + print "\t$(TARGET_CC) $(TARGET_CFLAGS) $(GNOMEINC) -c -o $@ " source else - print "\t$(CC) $(CFLAGS) -c -o $@ " source + print "\t$(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ " source } } diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 new file mode 100644 index 000000000..14b54fc7b --- /dev/null +++ b/sys/unix/hints/include/cross-post.2020 @@ -0,0 +1,110 @@ +#===============-================================================= +# NetHack 3.7 include/cross-post $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# +# Cross-compiling -POST section + +# +# Lua lib +$(LUACROSSLIB): $(LUALIBOBJS) + if [ -f $@ ]; then rm $@; fi; + $(TARGET_AR) rcS $@ $(LUAOBJFILES1) + $(TARGET_AR) rcS $@ $(LUAOBJFILES2) + $(TARGET_AR) rcS $@ $(LUAOBJFILES3) + $(TARGET_AR) rcs $@ $(LUAOBJFILES4) +ifdef WANT_WIN_CURSES +$(TARGETDIR)/pdclib.a : $(PDCLIBOBJS) $(PDCOBJS) + if [ -f $@ ]; then rm $@; fi; + $(TARGET_AR) rcs $@ $(PDCLIBOBJS) $(PDCOBJS) +endif +# +# Lua src +$(TARGETDIR)/lapi.o : $(LUATOP)/src/lapi.c +$(TARGETDIR)/lauxlib.o : $(LUATOP)/src/lauxlib.c +$(TARGETDIR)/lbaselib.o : $(LUATOP)/src/lbaselib.c +$(TARGETDIR)/lbitlib.o : $(LUATOP)/src/lbitlib.c +$(TARGETDIR)/lcode.o : $(LUATOP)/src/lcode.c +$(TARGETDIR)/lcorolib.o : $(LUATOP)/src/lcorolib.c +$(TARGETDIR)/lctype.o : $(LUATOP)/src/lctype.c +$(TARGETDIR)/ldblib.o : $(LUATOP)/src/ldblib.c +$(TARGETDIR)/ldebug.o : $(LUATOP)/src/ldebug.c +$(TARGETDIR)/ldo.o : $(LUATOP)/src/ldo.c +$(TARGETDIR)/ldump.o : $(LUATOP)/src/ldump.c +$(TARGETDIR)/lfunc.o : $(LUATOP)/src/lfunc.c +$(TARGETDIR)/lgc.o : $(LUATOP)/src/lgc.c +$(TARGETDIR)/linit.o : $(LUATOP)/src/linit.c +$(TARGETDIR)/liolib.o : $(LUATOP)/src/liolib.c +$(TARGETDIR)/llex.o : $(LUATOP)/src/llex.c +$(TARGETDIR)/lmathlib.o : $(LUATOP)/src/lmathlib.c +$(TARGETDIR)/lmem.o : $(LUATOP)/src/lmem.c +$(TARGETDIR)/loadlib.o : $(LUATOP)/src/loadlib.c +$(TARGETDIR)/lobject.o : $(LUATOP)/src/lobject.c +$(TARGETDIR)/lopcodes.o : $(LUATOP)/src/lopcodes.c +$(TARGETDIR)/loslib.o : $(LUATOP)/src/loslib.c +$(TARGETDIR)/lparser.o : $(LUATOP)/src/lparser.c +$(TARGETDIR)/lstate.o : $(LUATOP)/src/lstate.c +$(TARGETDIR)/lstring.o : $(LUATOP)/src/lstring.c +$(TARGETDIR)/lstrlib.o : $(LUATOP)/src/lstrlib.c +$(TARGETDIR)/ltable.o : $(LUATOP)/src/ltable.c +$(TARGETDIR)/ltablib.o : $(LUATOP)/src/ltablib.c +$(TARGETDIR)/ltm.o : $(LUATOP)/src/ltm.c +$(TARGETDIR)/lundump.o : $(LUATOP)/src/lundump.c +$(TARGETDIR)/lutf8lib.o : $(LUATOP)/src/lutf8lib.c +$(TARGETDIR)/lvm.o : $(LUATOP)/src/lvm.c +$(TARGETDIR)/lzio.o : $(LUATOP)/src/lzio.c +# +# PDCurses src +# +$(TARGETDIR)/addch.o : $(PDCTOP)/pdcurses/addch.c +$(TARGETDIR)/addchstr.o : $(PDCTOP)/pdcurses/addchstr.c +$(TARGETDIR)/addstr.o : $(PDCTOP)/pdcurses/addstr.c +$(TARGETDIR)/attr.o : $(PDCTOP)/pdcurses/attr.c +$(TARGETDIR)/beep.o : $(PDCTOP)/pdcurses/beep.c +$(TARGETDIR)/bkgd.o : $(PDCTOP)/pdcurses/bkgd.c +$(TARGETDIR)/border.o : $(PDCTOP)/pdcurses/border.c +$(TARGETDIR)/clear.o : $(PDCTOP)/pdcurses/clear.c +$(TARGETDIR)/color.o : $(PDCTOP)/pdcurses/color.c +$(TARGETDIR)/delch.o : $(PDCTOP)/pdcurses/delch.c +$(TARGETDIR)/deleteln.o : $(PDCTOP)/pdcurses/deleteln.c +$(TARGETDIR)/getch.o : $(PDCTOP)/pdcurses/getch.c +$(TARGETDIR)/getstr.o : $(PDCTOP)/pdcurses/getstr.c +$(TARGETDIR)/getyx.o : $(PDCTOP)/pdcurses/getyx.c +$(TARGETDIR)/inch.o : $(PDCTOP)/pdcurses/inch.c +$(TARGETDIR)/inchstr.o : $(PDCTOP)/pdcurses/inchstr.c +$(TARGETDIR)/initscr.o : $(PDCTOP)/pdcurses/initscr.c +$(TARGETDIR)/inopts.o : $(PDCTOP)/pdcurses/inopts.c +$(TARGETDIR)/insch.o : $(PDCTOP)/pdcurses/insch.c +$(TARGETDIR)/insstr.o : $(PDCTOP)/pdcurses/insstr.c +$(TARGETDIR)/instr.o : $(PDCTOP)/pdcurses/instr.c +$(TARGETDIR)/kernel.o : $(PDCTOP)/pdcurses/kernel.c +$(TARGETDIR)/keyname.o : $(PDCTOP)/pdcurses/keyname.c +$(TARGETDIR)/mouse.o : $(PDCTOP)/pdcurses/mouse.c +$(TARGETDIR)/move.o : $(PDCTOP)/pdcurses/move.c +$(TARGETDIR)/outopts.o : $(PDCTOP)/pdcurses/outopts.c +$(TARGETDIR)/overlay.o : $(PDCTOP)/pdcurses/overlay.c +$(TARGETDIR)/pad.o : $(PDCTOP)/pdcurses/pad.c +$(TARGETDIR)/panel.o : $(PDCTOP)/pdcurses/panel.c +$(TARGETDIR)/printw.o : $(PDCTOP)/pdcurses/printw.c +$(TARGETDIR)/refresh.o : $(PDCTOP)/pdcurses/refresh.c +$(TARGETDIR)/scanw.o : $(PDCTOP)/pdcurses/scanw.c +$(TARGETDIR)/scr_dump.o : $(PDCTOP)/pdcurses/scr_dump.c +$(TARGETDIR)/scroll.o : $(PDCTOP)/pdcurses/scroll.c +$(TARGETDIR)/slk.o : $(PDCTOP)/pdcurses/slk.c +$(TARGETDIR)/termattr.o : $(PDCTOP)/pdcurses/termattr.c +$(TARGETDIR)/touch.o : $(PDCTOP)/pdcurses/touch.c +$(TARGETDIR)/util.o : $(PDCTOP)/pdcurses/util.c +$(TARGETDIR)/window.o : $(PDCTOP)/pdcurses/window.c +$(TARGETDIR)/debug.o : $(PDCTOP)/pdcurses/debug.c +$(TARGETDIR)/pdcclip.o : $(PDCTOP)/dos/pdcclip.c +$(TARGETDIR)/pdcdisp.o : $(PDCTOP)/dos/pdcdisp.c +$(TARGETDIR)/pdcgetsc.o : $(PDCTOP)/dos/pdcgetsc.c +$(TARGETDIR)/pdckbd.o : $(PDCTOP)/dos/pdckbd.c +$(TARGETDIR)/pdcscrn.o : $(PDCTOP)/dos/pdcscrn.c +$(TARGETDIR)/pdcsetsc.o : $(PDCTOP)/dos/pdcsetsc.c +$(TARGETDIR)/pdcutil.o : $(PDCTOP)/dos/pdcutil.c + + +# +# End of cross-compiling -POST section +#===============-================================================= + + diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 new file mode 100644 index 000000000..4fd3b09df --- /dev/null +++ b/sys/unix/hints/include/cross-pre.2020 @@ -0,0 +1,107 @@ +#===============-================================================= +# NetHack 3.7 include/cross-pre $NHDT-Date: 1597332785 2020/08/13 15:33:05 $ $NHDT-Branch: NetHack-3.7 $ +# +# Cross-compiling -PRE section +# +ifdef BUILD_LUA +#===============-================================================= +# LUA library +# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +#================================================================= +LUA_VERSION ?=5.4.0 +LUATOP ?= ../lib/lua-$(LUA_VERSION) +LUASRCDIR ?= $(LUATOP)/src +LUAOBJFILES1 = $(TARGETDIR)/lapi.o $(TARGETDIR)/lauxlib.o \ + $(TARGETDIR)/lbaselib.o $(TARGETDIR)/lcode.o \ + $(TARGETDIR)/lcorolib.o $(TARGETDIR)/lctype.o \ + $(TARGETDIR)/ldblib.o +ifeq "$(LUA_VERSION)" "5.3.5" +LUAOBJFILES1 += $(TARGETDIR)/lbitlib.o +endif +LUAOBJFILES2 = $(TARGETDIR)/ldebug.o $(TARGETDIR)/ldo.o $(TARGETDIR)/ldump.o \ + $(TARGETDIR)/lfunc.o $(TARGETDIR)/lgc.o $(TARGETDIR)/linit.o \ + $(TARGETDIR)/liolib.o $(TARGETDIR)/llex.o +LUAOBJFILES3 = $(TARGETDIR)/lmathlib.o $(TARGETDIR)/lmem.o \ + $(TARGETDIR)/loadlib.o $(TARGETDIR)/lobject.o \ + $(TARGETDIR)/lopcodes.o $(TARGETDIR)/loslib.o \ + $(TARGETDIR)/lparser.o $(TARGETDIR)/lstate.o +LUAOBJFILES4 = $(TARGETDIR)/lstring.o $(TARGETDIR)/lstrlib.o \ + $(TARGETDIR)/ltable.o $(TARGETDIR)/ltablib.o \ + $(TARGETDIR)/ltm.o $(TARGETDIR)/lundump.o \ + $(TARGETDIR)/lutf8lib.o $(TARGETDIR)/lvm.o $(TARGETDIR)/lzio.o +LUALIBOBJS = $(LUAOBJFILES1) $(LUAOBJFILES2) $(LUAOBJFILES3) $(LUAOBJFILES4) +LUACROSSLIB = $(TARGETDIR)/$(O)lua$(subst .,,$(LUA_VERSION)).a +LUAINCL = -I$(LUASRCDIR) +BUILDMORE += $(LUACROSSLIB) +override TARGET_LIBS += $(LUACROSSLIB) -lm +else +LUAINCL= +endif # BUILD_LUA + +ifdef BUILD_PDCURSES +#===============-================================================= +# PD Curses library +#===============-================================================= +ifdef WANT_WIN_CURSES +PDCTOP = ../lib/pdcurses +PDCURSESDEF= -I../lib/pdcurses -I../lib/pdcurses/dos \ + -D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" +PDCLIBOBJ1= $(TARGETDIR)/addch.o $(TARGETDIR)/addchstr.o \ + $(TARGETDIR)/addstr.o $(TARGETDIR)/attr.o \ + $(TARGETDIR)/beep.o $(TARGETDIR)/bkgd.o \ + $(TARGETDIR)/border.o $(TARGETDIR)/clear.o \ + $(TARGETDIR)/color.o $(TARGETDIR)/delch.o \ + $(TARGETDIR)/deleteln.o $(TARGETDIR)/getch.o \ + $(TARGETDIR)/getstr.o $(TARGETDIR)/getyx.o \ + $(TARGETDIR)/inch.o +PDCLIBOBJ2= $(TARGETDIR)/inchstr.o $(TARGETDIR)/initscr.o \ + $(TARGETDIR)/inopts.o $(TARGETDIR)/insch.o \ + $(TARGETDIR)/insstr.o $(TARGETDIR)/instr.o \ + $(TARGETDIR)/kernel.o $(TARGETDIR)/keyname.o \ + $(TARGETDIR)/mouse.o $(TARGETDIR)/move.o \ + $(TARGETDIR)/outopts.o $(TARGETDIR)/overlay.o +PDCLIBOBJ3= $(TARGETDIR)/pad.o $(TARGETDIR)/panel.o $(TARGETDIR)/printw.o \ + $(TARGETDIR)/refresh.o $(TARGETDIR)/scanw.o \ + $(TARGETDIR)/scr_dump.o $(TARGETDIR)/scroll.o \ + $(TARGETDIR)/slk.o $(TARGETDIR)/termattr.o +PDCLIBOBJ4= $(TARGETDIR)/touch.o $(TARGETDIR)/util.o $(TARGETDIR)/window.o \ + $(TARGETDIR)/debug.o +PDCLIBOBJS = $(PDCLIBOBJ1) $(PDCLIBOBJ2) $(PDCLIBOBJ3) $(PDCLIBOBJ4) +PDCLIB = $(TARGETDIR)/pdclib.a +PDCINCL = -I$(PDCTOP) -I$(PDCTOP)/pdcurses +PDCOBJS = $(TARGETDIR)/pdcclip.o $(TARGETDIR)/pdcdisp.o \ + $(TARGETDIR)/pdcgetsc.o $(TARGETDIR)/pdckbd.o \ + $(TARGETDIR)/pdcscrn.o $(TARGETDIR)/pdcsetsc.o \ + $(TARGETDIR)/pdcutil.o +override TARGET_LIBS += $(PDCLIB) +BUILDMORE += $(PDCLIB) +# Rules for PDCurses files +$(TARGETDIR)/%.o : $(PDCTOP)/pdcurses/%.c + $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< +else #WANT_WIN_CURSES +PDCURSESDEF= +PDCLIBOBJS= +PDCOBJS= +PDCLIB= +PDCINCL= +endif # WANT_WIN_CURSES +endif # BUILD_PDCURSES + +ifdef WANT_WIN_CURSES +# rules for pdcurses dos-specific files +$(TARGETDIR)/%.o : $(PDCTOP)/sdl1/%.c + $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< +endif # WANT_WIN_CURSES +# Rule for LUA files +$(TARGETDIR)/%.o : $(LUATOP)/src/%.c + $(TARGET_CC) $(TARGET_CFLAGS) $(LUA_FLAGS) -o$@ $< +ifdef WANT_WIN_CURSES +# Rules for PDCurses files +$(TARGETDIR)/%.o : $(PDCTOP)/pdcurses/%.c + $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< +endif # WANT_WIN_CURSES + +# +# End of cross-compiling -PRE section +#===============-================================================= + diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 6928df837..ff2d0917d 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -204,3 +204,10 @@ CHGRP=true VARDIRPERM = 0755 VARFILEPERM = 0600 GAMEPERM = 0755 +# +#-INCLUDE cross-pre.2020 +# +#-POST +# +#-INCLUDE cross-post.2020 +# diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 937e55151..aeac9d41b 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -274,8 +274,11 @@ VARDIR=$(HACKDIR) # # 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-pre.2020 +# #-POST + ifdef MAKEFILE_TOP ### ### Packaging @@ -456,3 +459,6 @@ else endif # end of build_qt_pkg endif # WANT_WIN_QT for packaging endif # MAKEFILE_TOP +# +#-INCLUDE cross-post.2020 +# diff --git a/sys/unix/mkmkfile.sh b/sys/unix/mkmkfile.sh index 17d56d706..90e134657 100755 --- a/sys/unix/mkmkfile.sh +++ b/sys/unix/mkmkfile.sh @@ -40,5 +40,6 @@ echo "### Start $5 POST" >> $3 echo "###" >> $3 awk '/^#-POST/,/^#-PRE/{ \ if(index($0, "#-POST") == 1) print "# (new segment at source line",NR,")"; \ - if(index($0, "#-P") != 1) print}' $4 >> $3 + if(index($0, "#-INCLUDE") == 1) system("cat hints/include/"$2); \ + else if(index($0, "#-P") != 1) print}' $4 >> $3 echo "### End $5 POST" >> $3 From 14b532bf10813265dda2bcc2b4639b04ad943f15 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 16:28:15 -0400 Subject: [PATCH 235/708] add cross-compile recipe for msdos - If you want to obtain the djgpp cross-compiler and tools/libs for MSDOS, which is available for linux and macOS, you can use the following script to obtain it: sh sys/msdos/fetch-cross-compiler.sh That script won't install anything, it is just file fetches. It will store the cross-compiler in subfolders of lib and the hints files are configured to find it appropriately there. Note: Both the fetch and the msdos cross-compile package target require unzip and zip to be available on your host build system. Cross-compiler bits: https://github.com/andrewwutw/build-djgpp and the pre-built binary for your platform from: https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/ and a DOS-extender (for including in msdos packaging) from http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip and pdcurses from: https://github.com/wmcbrine/PDCurses.git The MSDOS cross-compile can then be carried out by specifying CROSS_TO_MSDOS=1 on the make command line. For example: make CROSS_TO_MSDOS=1 all make CROSS_TO_MSDOS=1 package You can explicitly include tty and curses support if desired, otherwise you'll end up with a tty-only cross-compile build: make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all Also note that building the msdos targets using the make command above, does not preclude you from building local linux or macOS targets as well. Just drop the CROSS_TO_MSDOS=1 from the make command line. The cross-compiler hints additions are enclosed inside ifdef sections and won't interfere with the non-cross-compile build in that case. --- sys/msdos/fetch-cross-compiler.sh | 97 ++++++++++++++++++++++++++ sys/unix/hints/include/cross-post.2020 | 46 ++++++++++++ sys/unix/hints/include/cross-pre.2020 | 80 +++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 sys/msdos/fetch-cross-compiler.sh diff --git a/sys/msdos/fetch-cross-compiler.sh b/sys/msdos/fetch-cross-compiler.sh new file mode 100644 index 000000000..12d861fd3 --- /dev/null +++ b/sys/msdos/fetch-cross-compiler.sh @@ -0,0 +1,97 @@ +#!/bin/sh +#set -x + +if [ -z "$TRAVIS_BUILD_DIR" ]; then + export DJGPP_TOP=$(pwd)/lib/djgpp +else + export DJGPP_TOP="$TRAVIS_BUILD_DIR/lib/djgpp" +fi + +if [ -z "$GCCVER" ]; then + export GCCVER=gcc1010 +fi + +if [ -z "$LUA_VERSION" ]; then + export LUA_VERSION=5.4.0 +fi + +if [ ! -d "$(pwd)/lib" ]; then + echo "Set up for Unix build and 'make fetch-lua' first." + exit 1 +fi + +#DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v2.9/" +DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/" +if [ "$(uname)" = "Darwin" ]; then + #Mac + DJGPP_FILE="djgpp-osx-$GCCVER.tar.bz2" + if [ -z "HINTS" ]; then + export HINTS=macOS.2020 + 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.2020 + fi +elif [ "$(expr substr $(uname -s) 1 10)" = "MINGW32_NT" ]; then + #mingw + DJGPP_FILE="djgpp-mingw-$GCCVER-standalone.zip" +else + echo "No DJGPP release for you, sorry." + exit 1 +fi + +DJGPP_URL="$DJGPP_URL$DJGPP_FILE" + +# export + +if [ ! -d lib ]; then +mkdir -p lib +fi + +cd lib +if [ ! -f "$DJGPP_FILE" ]; then + if [ "$(uname)" = "Darwin" ]; then + #Mac + curl -L $DJGPP_URL -o $DJGPP_FILE + else + wget --no-hsts "$DJGPP_URL" + fi +fi + +if [ ! -d djgpp/i586-pc-msdosdjgpp ]; then + tar xjf "$DJGPP_FILE" + rm -f $DJGPP_FILE +fi + +# DOS-extender for use with djgpp +if [ ! -d djgpp/cwsdpmi ]; then + if [ "$(uname)" = "Darwin" ]; then + #Mac + curl http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip -o csdpmi7b.zip + else + wget --no-hsts http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip + fi + cd djgpp + mkdir -p cwsdpmi + cd cwsdpmi + unzip ../../csdpmi7b.zip + cd ../../ + rm csdpmi7b.zip +fi + +# PDCurses +if [ ! -d "pdcurses" ]; then + echo "Getting ../pdcurses from https://github.com/wmcbrine/PDCurses.git" ; \ + git clone --depth 1 https://github.com/wmcbrine/PDCurses.git pdcurses +fi + +cd ../ + +# Don't fail the build if lua fetch failed because we cannot do anything about it +# but don't bother proceeding forward either +if [ ! -d "lib/lua-$LUA_VERSION/src" ]; then + exit 0 +fi + diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 14b54fc7b..844fa3e2b 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -3,6 +3,52 @@ # # Cross-compiling -POST section +ifdef CROSS_TO_MSDOS +# +$(TARGETDIR)/msdos.o : ../sys/msdos/msdos.c $(HACK_H) +$(TARGETDIR)/pckeys.o : ../sys/msdos/pckeys.c $(HACK_H) +$(TARGETDIR)/pctiles.o : ../sys/msdos/pctiles.c ../sys/msdos/portio.h $(HACK_H) +$(TARGETDIR)/video.o : ../sys/msdos/video.c ../sys/msdos/portio.h $(HACK_H) +$(TARGETDIR)/vidtxt.o : ../sys/msdos/vidtxt.c ../sys/msdos/portio.h \ + ../win/share/tile.h ../include/tileset.h $(HACK_H) +$(TARGETDIR)/vidvga.o : ../sys/msdos/vidvga.c ../sys/msdos/portio.h \ + ../win/share/tile.h ../include/tileset.h $(HACK_H) +$(TARGETDIR)/vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ + ../win/share/tile.h ../include/tileset.h $(HACK_H) +$(TARGETDIR)/vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ + $(HACK_H) +$(TARGETDIR)/tile.o : tile.c +# +#.PHONY: dospkg +dospkg: $(GAMEBIN) $(TARGETDIR)/recover.exe ../dat/nhtiles.bmp + $(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K + mkdir -p $(TARGETDIR)/pkg + cp $(GAMEBIN) $(TARGETDIR)/pkg/NETHACK.EXE + cp ../dat/nhdat $(TARGETDIR)/pkg/NHDAT + cp ../dat/license $(TARGETDIR)/pkg/LICENSE + cp ../dat/nhtiles.bmp $(TARGETDIR)/pkg/NHTILES.BMP + cp ../dat/symbols $(TARGETDIR)/pkg/SYMBOLS + cp ../sys/share/NetHack.cnf $(TARGETDIR)/pkg/NETHACK.CNF + cp ../sys/msdos/sysconf $(TARGETDIR)/pkg/SYSCONF + cp ../doc/nethack.txt $(TARGETDIR)/pkg/NETHACK.TXT + cp ../lib/djgpp/cwsdpmi/bin/CWSDPMI.EXE $(TARGETDIR)/pkg/CWSDPMI.EXE + -touch $(TARGETDIR)/pkg/RECORD + zip -9 $(TARGETDIR)/NH370DOS.ZIP $(TARGETDIR)/pkg/* + @echo msdos package zip file $(TARGETDIR)/NH370DOS.ZIP +endif # CROSS_TO_MSDOS + +# +# shared file dependencies +# +$(TARGETDIR)/pcmain.o : ../sys/share/pcmain.c $(HACK_H) +$(TARGETDIR)/pcsys.o : ../sys/share/pcsys.c $(HACK_H) +$(TARGETDIR)/pctty.o : ../sys/share/pctty.c $(HACK_H) +$(TARGETDIR)/pcunix.o : ../sys/share/pcunix.c $(HACK_H) +$(TARGETDIR)/tileset.o : ../win/share/tileset.c +$(TARGETDIR)/bmptiles.o : ../win/share/bmptiles.c +$(TARGETDIR)/giftiles.o : ../win/share/giftiles.c +$(TARGETDIR)/recover.exe : $(TARGETDIR)/recover.o + # # Lua lib $(LUACROSSLIB): $(LUALIBOBJS) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 4fd3b09df..b3da7e30b 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -3,6 +3,15 @@ # # Cross-compiling -PRE section # + +ifdef CROSS_TO_MSDOS +BUILD_LUA=1 +BUILD_PDCURSES=1 +override TARGET = msdos +override TARGETDIR = ../targets/$(TARGET) +override TARGET_LIBS= +endif + ifdef BUILD_LUA #===============-================================================= # LUA library @@ -74,6 +83,9 @@ PDCOBJS = $(TARGETDIR)/pdcclip.o $(TARGETDIR)/pdcdisp.o \ $(TARGETDIR)/pdcscrn.o $(TARGETDIR)/pdcsetsc.o \ $(TARGETDIR)/pdcutil.o override TARGET_LIBS += $(PDCLIB) +ifdef CROSS_TO_MSDOS +PDCINCL += -I$(PDCTOP)/dos +endif BUILDMORE += $(PDCLIB) # Rules for PDCurses files $(TARGETDIR)/%.o : $(PDCTOP)/pdcurses/%.c @@ -87,6 +99,74 @@ PDCINCL= endif # WANT_WIN_CURSES endif # BUILD_PDCURSES +ifdef CROSS_TO_MSDOS +#===============-================================================= +# MSDOS cross-compile recipe +#===============-================================================= +# Uses an MSDOS djgpp cross-compiler on linux or macos. +# +# 1. You can obtain the cross-compiler for your system via: +# sys/msdos/fetch-cross.sh +# 2. Then +# make CROSS_TO_MSDOS=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 all +# +# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +#================================================================= + +CFLAGS += -DCROSSCOMPILE -DCROSSCOMPILE_HOST + +# +# Override the build tools and some obj files to +# reflect the msdos djgpp cross-compiler. +# +TOOLTOP1 = ../lib/djgpp/bin +TOOLTOP2 = ../lib/djgpp/i586-pc-msdosdjgpp/bin +override TARGET_CC = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc +override TARGET_CXX = $(TOOLTOP2)/g++ +override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar +override TARGET_STUBEDIT = ../lib/djgpp/i586-pc-msdosdjgpp/bin/stubedit +override TARGET_CFLAGS = -c -O -I../include -I../sys/msdos -I../win/share \ + $(LUAINCL) -DDLB $(PDCURSESDEF) \ + -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET +override TARGET_CXXFLAGS = $(TARGET_CFLAGS) +override TARGET_LINK = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc +override TARGET_LFLAGS= +override TARGET_LIBS += -lpc +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 \ + ../win/share/bmptiles.c ../win/share/giftiles.c \ + ../win/share/tileset.c +override SYSOBJ= $(TARGETDIR)/pcmain.o $(TARGETDIR)/msdos.o \ + $(TARGETDIR)/pcsys.o $(TARGETDIR)/pctty.o \ + $(TARGETDIR)/pcunix.o $(TARGETDIR)/video.o \ + $(TARGETDIR)/vidtxt.o $(TARGETDIR)/pckeys.o \ + $(TARGETDIR)/vidvga.o $(TARGETDIR)/vidvesa.o \ + $(TARGETDIR)/bmptiles.o $(TARGETDIR)/giftiles.o \ + $(TARGETDIR)/tileset.o $(TARGETDIR)/tile.o +override WINLIB= +override LUALIB= +override GAMEBIN = $(TARGETDIR)/nethack.exe +override PACKAGE= dospkg +VARDATND += nhtiles.bmp +PREGAME = mkdir -p $(TARGETDIR) +CLEANMORE += rm -r $(TARGETDIR) +BUILDMORE += $(TARGETDIR)/recover.exe +# +ifdef WANT_WIN_CURSES +# rules for pdcurses dos-specific files +$(TARGETDIR)/%.o : $(PDCTOP)/dos/%.c + $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< +endif # WANT_WIN_CURSES +# +# Rule for files in sys/msdos +$(TARGETDIR)/%.o : ../sys/msdos/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< +endif # CROSS_TO_MSDOS +#================================================================= + ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files $(TARGETDIR)/%.o : $(PDCTOP)/sdl1/%.c From cb223271cb910976e0e1be3e36768e468638200a Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 17:30:22 -0400 Subject: [PATCH 236/708] add cross-compile recipe for amiga Disclaimer: This is a minimal recipe, just to get someone else started if they have a desire to get a full cross-compile of NetHack-3.7 going for the Amiga. Some NetHack code bitrot was corrected, and it does seem able to compile the game itself to a point. See caveats below. - If you want to obtain the cross-compiler and tools/libs for Amiga https://github.com/bebbo/amiga-gcc To our knowledge, a pre-built copy isn't available, so you have to obtain the source via git and build it on your system. The build prerequisite packages for Ubuntu are easily obtained: sudo apt install make wget git gcc g++ lhasa libgmp-dev \ libmpfr-dev libmpc-dev flex bison gettext texinfo ncurses-dev \ autoconf rsync The build prerequisite packages for macOS are apparently easily obtained via homebrew, but that was not tested: brew install bash wget make lhasa gmp mpfr libmpc flex gettext \ texinfo gcc make autoconf After installing the prerequite packages and the cross-compiler it was a straightforward build: git clone https://github.com/bebbo/amiga-gcc.git cd amiga-gcc make update [Note that you may have to take ownership of the files in the bebbo repo via chown before succesfully carrying out the next steps] make clean make clean-prefix date; make all -j3 >&b.log; date The compiler pieces are installed in /opt/amiga by default which was satisfactory for our initial attempt, but if you want you can alter the prefix before you build if you want. That is all spelled out on the page at: https://github.com/bebbo/amiga-gcc The Amiga cross-compile can then be carried out by specifying CROSS_TO_AMIGA=1 on the make command line. For example: make CROSS_TO_AMIGA=1 all make CROSS_TO_AMIGA=1 package You can explicitly include tty and curses support if desired, otherwise you'll end up with a tty-only cross-compile build. The SDL1 pdcurses support has not been tested. make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_AMIGA=1 all Also note that building the amiga targets using the make command above, does not preclude you from building local linux or macOS targets as well. Just drop the CROSS_TO_AMIGA=1 from the make command line. The cross-compiler hints additions are enclosed inside ifdef sections and won't interfere with the non-cross-compile build in that case. CAVEATS: The original NetHack Amiga build steps included the source for some utilities that were built and executed on the amiga: txt2iff and xpm2iff as part of the NetHack build procedure on amiga. Those did not compile out-of-the-box on the linux host. They will either have to be: - ported to build and run on the linux or macOS cross-compile host or - their functionality will have to be rolled into amiga NetHack itself and executed on the target Amiga the first time the game is run, perhaps. Good luck amiga aficionados, perhaps you'll be able to take this initial effort forward and get NetHack-3.7 available on the amiga or amiga-emulator. Let us know if you do, and we can roll changes in if you provide them. --- include/dlb.h | 2 +- include/extern.h | 2 + include/global.h | 4 + include/pcconf.h | 10 ++ outdated/include/amiconf.h | 38 ++++++- outdated/sys/amiga/Makefile.agc | 4 +- outdated/sys/amiga/Makefile.ami | 4 +- outdated/sys/amiga/amidos.c | 11 +- outdated/sys/amiga/amigst.c | 6 ++ outdated/sys/amiga/amirip.c | 2 +- outdated/sys/amiga/amiwind.c | 19 +++- outdated/sys/amiga/{winmenu.c => winamenu.c} | 8 +- outdated/sys/amiga/winami.c | 19 +++- outdated/sys/amiga/winchar.c | 12 ++- outdated/sys/amiga/winfuncs.c | 30 +++++- outdated/sys/amiga/winkey.c | 6 ++ outdated/sys/amiga/winproto.h | 2 +- outdated/sys/amiga/winreq.c | 14 +++ outdated/sys/amiga/winstr.c | 21 ++-- sys/share/pcmain.c | 38 ++++++- sys/share/pcsys.c | 8 +- sys/unix/hints/include/cross-post.2020 | 75 ++++++++++++++ sys/unix/hints/include/cross-pre.2020 | 101 +++++++++++++++++++ 23 files changed, 405 insertions(+), 31 deletions(-) rename outdated/sys/amiga/{winmenu.c => winamenu.c} (99%) diff --git a/include/dlb.h b/include/dlb.h index 4f5934b55..4c1e5e583 100644 --- a/include/dlb.h +++ b/include/dlb.h @@ -9,7 +9,7 @@ #ifdef DLB /* implementations */ -#ifdef MAC +#if defined(MAC) && !defined(MAC_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 60c44d2fd..374598ae4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2149,10 +2149,12 @@ E void NDECL(deliver_splev_message); /* ### random.c ### */ #if defined(RANDOM) && !defined(__GO32__) /* djgpp has its own random */ +#ifndef AMIGA_CROSS E void FDECL(srandom, (unsigned)); E char *FDECL(initstate, (unsigned, char *, int)); E char *FDECL(setstate, (char *)); E long NDECL(random); +#endif #endif /* RANDOM */ /* ### read.c ### */ diff --git a/include/global.h b/include/global.h index af46502d0..fbffef7a1 100644 --- a/include/global.h +++ b/include/global.h @@ -166,6 +166,10 @@ extern struct cross_target_s cross_target; #include "ntconf.h" #endif +#ifdef AMIGA +#include "amiconf.h" +#endif + /* Displayable name of this port; don't redefine if defined in *conf.h */ #ifndef PORT_ID #ifdef AMIGA diff --git a/include/pcconf.h b/include/pcconf.h index c0c4786a0..86ce2efe7 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -35,7 +35,9 @@ /*#define OVERLAY */ /* Manual overlay definition (MSC 6.0ax only) */ +#ifndef AMIGA_CROSS #define SHELL /* via exec of COMMAND.COM */ +#endif /* * Screen control options @@ -88,7 +90,9 @@ #define ANSI_DEFAULT #endif +#ifndef AMIGA_CROSS #define RANDOM /* have Berkeley random(3) */ +#endif #define MAIL /* Allows for fake mail daemon to deliver mail */ /* in the MSDOS version. (For AMIGA MAIL see */ @@ -101,6 +105,10 @@ #include /* Provides prototypes of exit(), spawn() */ #endif +#ifdef AMIGA_CROSS +#include +#endif + #if defined(_MSC_VER) && (_MSC_VER >= 7) #include #include @@ -155,7 +163,9 @@ #endif /* MSDOS configuration stuff */ +#ifndef PATHLEN #define PATHLEN 64 /* maximum pathlength */ +#endif #define FILENAME 80 /* maximum filename length (conservative) */ #ifndef MICRO_H #include "micro.h" /* contains necessary externs for [os_name].c */ diff --git a/outdated/include/amiconf.h b/outdated/include/amiconf.h index 122854b4a..5215515d8 100644 --- a/outdated/include/amiconf.h +++ b/outdated/include/amiconf.h @@ -14,6 +14,11 @@ #include /* get time_t defined before use! */ +#ifdef AMIGA_CROSS +#include +#include +#endif + #ifdef __SASC_60 /* since SAS can prevent re-inclusion */ #include /* general things, including builtins */ #include @@ -40,6 +45,8 @@ typedef long off_t; LEVELDIR, SAVEDIR, BONESDIR, DATADIR, \ SCOREDIR, LOCKDIR, CONFIGDIR, and TROUBLEDIR */ +#define PATHLEN 130 + /* data librarian defs */ #ifndef NOCWD_ASSUMPTIONS #define DLBFILE "NetHack:nhdat" /* main library */ @@ -49,7 +56,11 @@ typedef long off_t; #define DLBFILE2 "nhsdat" /* sound library */ #endif +#ifndef AMIGA_CROSS #define FILENAME_CMP stricmp /* case insensitive */ +#else +#define FILENAME_CMP strcmpi /* case insensitive */ +#endif #ifndef __SASC_60 #define O_BINARY 0 @@ -65,7 +76,9 @@ typedef long off_t; #define MFLOPPY /* You'll probably want this; provides assistance \ * for typical personal computer configurations \ */ +#ifndef AMIGA_CROSS #define RANDOM +#endif /* ### amidos.c ### */ @@ -123,8 +136,6 @@ extern FILE *FDECL(freopen, (const char *, const char *, FILE *)); extern char *FDECL(gets, (char *)); #endif -#define msmsg printf - /* * If AZTEC_C we can't use the long cpath in vision.c.... */ @@ -138,7 +149,9 @@ extern char *FDECL(gets, (char *)); #define TEXTCOLOR /* Use colored monsters and objects */ #define HACKFONT /* Use special hack.font */ -#define SHELL /* Have a shell escape command (!) */ +#ifndef AMIGA_CROSS /* 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) */ @@ -186,5 +199,24 @@ void FDECL(amii_setpens, (int)); #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 + int numcols; + 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 +}; +extern struct ami_sysflags sysflags; #endif /* AMICONF_H */ diff --git a/outdated/sys/amiga/Makefile.agc b/outdated/sys/amiga/Makefile.agc index da5b38567..22b1473f6 100644 --- a/outdated/sys/amiga/Makefile.agc +++ b/outdated/sys/amiga/Makefile.agc @@ -184,7 +184,7 @@ MAKEDEFOBJ = \ 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)winmenu.o $(O)winreq.o $(O)winstr.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 = \ @@ -572,7 +572,7 @@ $(O)winfuncs.o: $(AMI)winfuncs.c $(HDEP) $(AMDEP) $(I)patchlevel.h $(O)winkey.o: $(AMI)winkey.c $(HDEP) $(AMDEP) -$(O)winmenu.o: $(AMI)winmenu.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 diff --git a/outdated/sys/amiga/Makefile.ami b/outdated/sys/amiga/Makefile.ami index 7d7f676e4..b3b29e775 100644 --- a/outdated/sys/amiga/Makefile.ami +++ b/outdated/sys/amiga/Makefile.ami @@ -391,7 +391,7 @@ MAKEDEFOBJ = \ 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)winmenu.o $(O)winreq.o $(O)winstr.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 = \ @@ -844,7 +844,7 @@ $(O)winfuncs.o: $(AMI)winfuncs.c $(HDEP) $(AMDEP) $(I)patchlevel.h $(O)winkey.o: $(AMI)winkey.c $(HDEP) $(AMDEP) -$(O)winmenu.o: $(AMI)winmenu.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 diff --git a/outdated/sys/amiga/amidos.c b/outdated/sys/amiga/amidos.c index 926948946..4f2413008 100644 --- a/outdated/sys/amiga/amidos.c +++ b/outdated/sys/amiga/amidos.c @@ -29,12 +29,19 @@ #endif /* Prototypes */ -#include "NH:sys/amiga/winami.p" +#ifndef AMIGA_CROSS #include "NH:sys/amiga/amiwind.p" +#include "NH:sys/amiga/winami.p" #include "NH:sys/amiga/amidos.p" +#else +#include "winami.p" +#include "winami.p" +#include "amidos.p" +#endif extern char Initialized; extern struct window_procs amii_procs; +struct ami_sysflags sysflags = {0}; #ifndef __SASC_60 int Enable_Abort = 0; /* for stdio package */ @@ -272,6 +279,7 @@ const char *from, *to; } #endif +#ifdef MFLOPPY /* this should be replaced */ saveDiskPrompt(start) { @@ -325,6 +333,7 @@ saveDiskPrompt(start) } return 1; } +#endif /* MFLOPPY */ /* Return 1 if the record file was found */ static boolean diff --git a/outdated/sys/amiga/amigst.c b/outdated/sys/amiga/amigst.c index 91f0d3430..64cdc2f0e 100644 --- a/outdated/sys/amiga/amigst.c +++ b/outdated/sys/amiga/amigst.c @@ -36,8 +36,14 @@ #include #endif +#ifndef AMIGA_CROSS #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 /* end amigst.c */ diff --git a/outdated/sys/amiga/amirip.c b/outdated/sys/amiga/amirip.c index eea00e2a0..ba17cbdf0 100644 --- a/outdated/sys/amiga/amirip.c +++ b/outdated/sys/amiga/amirip.c @@ -191,7 +191,7 @@ time_t when; tomb_text(buf); /* Put $ on stone */ - Sprintf(buf, "%ld Au", done_money); + Sprintf(buf, "%ld Au", g.done_money); buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */ tomb_text(buf); diff --git a/outdated/sys/amiga/amiwind.c b/outdated/sys/amiga/amiwind.c index a5c4f7d67..9654fb5d9 100644 --- a/outdated/sys/amiga/amiwind.c +++ b/outdated/sys/amiga/amiwind.c @@ -3,9 +3,15 @@ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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 @@ -20,10 +26,21 @@ static int BufferGetchar(void); static void ProcessMessage(register struct IntuiMessage *message); #define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch)) - +#ifndef AMIGA_CROSS struct Library *ConsoleDevice; +#else +struct Device * +# ifdef __CONSTLIBBASEDECL__ + __CONSTLIBBASEDECL__ +# endif /* __CONSTLIBBASEDECL__ */ + ConsoleDevice; +#endif +#ifndef AMIGA_CROSS #include "NH:sys/amiga/amimenu.c" +#else +#include "amimenu.c" +#endif /* Now our own variables */ diff --git a/outdated/sys/amiga/winmenu.c b/outdated/sys/amiga/winamenu.c similarity index 99% rename from outdated/sys/amiga/winmenu.c rename to outdated/sys/amiga/winamenu.c index 085294008..cf1d75376 100644 --- a/outdated/sys/amiga/winmenu.c +++ b/outdated/sys/amiga/winamenu.c @@ -1,11 +1,17 @@ -/* NetHack 3.6 winmenu.c $NHDT-Date: 1432512796 2015/05/25 00:13:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ +/* NetHack 3.6 winamenu.c $NHDT-Date: 1432512796 2015/05/25 00:13:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.7 $ */ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996. */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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/outdated/sys/amiga/winami.c b/outdated/sys/amiga/winami.c index 5045d1592..0a9bd2951 100644 --- a/outdated/sys/amiga/winami.c +++ b/outdated/sys/amiga/winami.c @@ -3,11 +3,22 @@ */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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" +#ifdef AMIGA_CROSS +#define strnicmp strncmpi +#endif + #ifdef AMIGA_INTUITION static int FDECL(put_ext_cmd, (char *, int, struct amii_WinDesc *, int)); @@ -29,8 +40,9 @@ long amii_scrnmode; */ struct window_procs amii_procs = { "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 */ - 0L, amii_init_nhwindows, + 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, @@ -63,8 +75,9 @@ struct window_procs amii_procs = { */ struct window_procs amiv_procs = { "amitile", 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 */ - 0L, amii_init_nhwindows, + 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, @@ -1134,7 +1147,7 @@ boolean complain; register int win; register dlb *fp; register char *t; - register char buf[200]; + char buf[200]; if (fn == NULL) panic("NULL file name in display_file()"); diff --git a/outdated/sys/amiga/winchar.c b/outdated/sys/amiga/winchar.c index b7960c01a..020b721ed 100644 --- a/outdated/sys/amiga/winchar.c +++ b/outdated/sys/amiga/winchar.c @@ -14,14 +14,24 @@ #ifdef TESTING #include "hack.h" #else +#ifndef AMIGA_CROSS #include "NH:src/tile.c" +#else +#include "../src/tile.c" +#endif #endif +#ifndef AMIGA_CROSS #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 #ifdef OPT_DISPMAP #define DISPMAP /* use display_map() from dispmap.s */ diff --git a/outdated/sys/amiga/winfuncs.c b/outdated/sys/amiga/winfuncs.c index 380954681..130d66cc9 100644 --- a/outdated/sys/amiga/winfuncs.c +++ b/outdated/sys/amiga/winfuncs.c @@ -3,14 +3,29 @@ */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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" #include "date.h" extern struct TagItem scrntags[]; - +#ifndef AMIGA_CROSS +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); @@ -776,8 +791,17 @@ amii_create_nhwindow(type) register int type; Abort(AG_OpenDev | AO_ConsoleDev); } - ConsoleDevice = (struct Library *) ConsoleIO.io_Device; - + ConsoleDevice = +#ifndef AMIGA_CROSS + (struct Library *) +#else + (struct Device * +# ifdef __CONSTLIBBASEDECL__ + __CONSTLIBBASEDECL__ +# endif /* __CONSTLIBBASEDECL__ */ + ) +#endif + ConsoleIO.io_Device; KbdBuffered = 0; #ifdef HACKFONT diff --git a/outdated/sys/amiga/winkey.c b/outdated/sys/amiga/winkey.c index c90e06fc8..0964f0574 100644 --- a/outdated/sys/amiga/winkey.c +++ b/outdated/sys/amiga/winkey.c @@ -2,9 +2,15 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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 amii_nh_poskey(x, y, mod) int *x, *y, *mod; { diff --git a/outdated/sys/amiga/winproto.h b/outdated/sys/amiga/winproto.h index dffa90f67..5fb1441c7 100644 --- a/outdated/sys/amiga/winproto.h +++ b/outdated/sys/amiga/winproto.h @@ -65,7 +65,7 @@ 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, int bkglyph); +void amiga_print_glyph(winid window, int color_index, int glyph); void start_glyphout(winid window); void amii_end_glyphout(winid window); struct NewWindow *DupNewWindow(struct NewWindow *win); diff --git a/outdated/sys/amiga/winreq.c b/outdated/sys/amiga/winreq.c index 3d59f5960..fecf2b4ce 100644 --- a/outdated/sys/amiga/winreq.c +++ b/outdated/sys/amiga/winreq.c @@ -2,9 +2,15 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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 @@ -39,7 +45,11 @@ struct NewWindow StrWindow = { &String, NULL, NULL, NULL, NULL, 5, 5, 0xffff, 0xffff, CUSTOMSCREEN }; +#ifndef AMIGA_CROSS #include "NH:sys/amiga/colorwin.c" +#else +#include "colorwin.c" +#endif #define XSIZE 2 #define YSIZE 3 @@ -48,7 +58,11 @@ struct NewWindow StrWindow = { #define GADOKAY 6 #define GADCANCEL 7 +#ifndef AMIGA_CROSS #include "NH:sys/amiga/clipwin.c" +#else +#include "clipwin.c" +#endif void ClearCol(struct Window *w); diff --git a/outdated/sys/amiga/winstr.c b/outdated/sys/amiga/winstr.c index 75d1d2509..d74e566a0 100644 --- a/outdated/sys/amiga/winstr.c +++ b/outdated/sys/amiga/winstr.c @@ -2,10 +2,15 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ +#ifndef AMIGA_CROSS #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 @@ -76,8 +81,8 @@ const char *str; while (isspace(*str)) str++; - strncpy(toplines, str, TBUFSZ); - toplines[TBUFSZ - 1] = 0; + strncpy(g.toplines, str, TBUFSZ); + g.toplines[TBUFSZ - 1] = 0; /* For initial message to be visible, we need to explicitly position * the @@ -96,15 +101,15 @@ const char *str; memcpy(cw->data, &cw->data[1], (iflags.msg_history - 1) * sizeof(char *)); cw->data[iflags.msg_history - 1] = - (char *) alloc(strlen(toplines) + 5); + (char *) alloc(strlen(g.toplines) + 5); strcpy(cw->data[i = iflags.msg_history - 1] + SOFF + (scrollmsg != 0), - toplines); + g.toplines); } else { /* Otherwise, allocate a new one and copy the line in */ - cw->data[cw->maxrow] = (char *) alloc(strlen(toplines) + 5); + cw->data[cw->maxrow] = (char *) alloc(strlen(g.toplines) + 5); strcpy(cw->data[i = cw->maxrow++] + SOFF + (scrollmsg != 0), - toplines); + g.toplines); } cw->data[i][SEL_ITEM] = 1; cw->data[i][VATTR] = attr + 1; @@ -177,7 +182,7 @@ const char *str; / w->RPort->TxHeight, totalvis, totalvis); } - i = strlen(toplines + SOFF); + i = strlen(g.toplines + SOFF); cw->maxcol = max(cw->maxcol, i); cw->vwy = cw->maxrow; break; diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 704da8d2c..633c1f13a 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -268,7 +268,7 @@ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);*/ if (argc == 0) chdirx(HACKDIR, 1); #endif - ami_wininit_data(); + ami_wininit_data(WININIT); #endif initoptions(); @@ -754,4 +754,40 @@ char *str; } #endif /* EXEPATH */ +#ifdef AMIGA_CROSS +void msmsg +VA_DECL(const char *, fmt) +{ + VA_START(fmt); + VA_INIT(fmt, const char *); + Vprintf(fmt, VA_ARGS); + flushout(); + VA_END(); + return; +} + +unsigned long +sys_random_seed() +{ + unsigned long seed = 0L; + unsigned long pid = (unsigned long) getpid(); + boolean no_seed = TRUE; + +#ifdef AMIGA_STRONG_RANDOM_SEED_HERE + /* hypothetical - strong seed code is required */ + /* then has_strong_seed could be set */ +#endif + if (no_seed) { + seed = (unsigned long) getnow(); /* time((TIME_type) 0) */ + /* Quick dirty band-aid to prevent PRNG prediction */ + if (pid) { + if (!(pid & 3L)) + pid -= 1L; + seed *= pid; + } + } + return seed; +} +#endif + /*pcmain.c*/ diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index 0282c7a49..c027827c4 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -12,10 +12,10 @@ #include #include -#if !defined(MSDOS) && !defined(WIN_CE) /* already done */ +#if !defined(MSDOS) && !defined(WIN_CE) && !defined(AMIGA_CROSS) #include #endif -#ifdef __GO32__ +#if defined(__GO32__) || defined(AMIGA_CROSS) #define P_WAIT 0 #define P_NOWAIT 1 #endif @@ -153,8 +153,12 @@ const char *str; { #ifdef TOS msmsg("Hit %s.", str); +#else +#ifdef AMIGA_CROSS + (void) printf("Hit %s.", str); #else msmsg("Hit %s.", str); +#endif #endif while (pgetchar() != '\n') ; diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 844fa3e2b..a89d6ca08 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -37,6 +37,81 @@ dospkg: $(GAMEBIN) $(TARGETDIR)/recover.exe ../dat/nhtiles.bmp @echo msdos package zip file $(TARGETDIR)/NH370DOS.ZIP endif # CROSS_TO_MSDOS +ifdef CROSS_TO_AMIGA +$(TARGETDIR)/amidos.o : ../outdated/sys/amiga/amidos.c $(HACK_H) +$(TARGETDIR)/amigst.o : ../outdated/sys/amiga/amigst.c $(HACK_H) +$(TARGETDIR)/amirip.o : ../outdated/sys/amiga/amirip.c $(HACK_H) +$(TARGETDIR)/amistack.o : ../outdated/sys/amiga/amistack.c $(HACK_H) +$(TARGETDIR)/amitty.o : ../outdated/sys/amiga/amitty.c $(HACK_H) +$(TARGETDIR)/amiwind.o : ../outdated/sys/amiga/amiwind.c \ + ../outdated/sys/amiga/amimenu.c $(HACK_H) +$(TARGETDIR)/winami.o : ../outdated/sys/amiga/winami.c $(HACK_H) +$(TARGETDIR)/winchar.o : ../outdated/sys/amiga/winchar.c tile.c $(HACK_H) +$(TARGETDIR)/winfuncs.o : ../outdated/sys/amiga/winfuncs.c $(HACK_H) +$(TARGETDIR)/winkey.o : ../outdated/sys/amiga/winkey.c $(HACK_H) +$(TARGETDIR)/winamenu.o : ../outdated/sys/amiga/winamenu.c $(HACK_H) +$(TARGETDIR)/winreq.o : ../outdated/sys/amiga/winreq.c \ + ../outdated/sys/amiga/colorwin.c \ + ../outdated/sys/amiga/clipwin.c $(HACK_H) +$(TARGETDIR)/winstr.o : ../outdated/sys/amiga/winstr.c $(HACK_H) +$(TARGETDIR)/tomb.iff : ../util/xpm2iff ../outdated/sys/amiga/gave16.xpm +../util/tiletext.o : ../win/share/tiletext.c + $(CC) $(CFLAGS) -c \ + -o $@ ../win/share/tiletext.c +../util/txt2iff : ../util/txt2iff.o ../util/tiletext.o \ + ../util/tiletxt.o + $(LINK) $(LFLAGS) -L../lib -o $@ ../util/txt2iff.o ../util/tiletext.o \ + ../util/tiletxt.o -lriffl +../util/txt2iff.o : ../outdated/sys/amiga/txt2iff.c $(HACK_H) + $(CC) $(CFLAGS) -c \ + -I../lib/riffl-0.2/include \ + -I/opt/amiga/m68k-amigaos/ndk13-include \ + -o $@ ../outdated/sys/amiga/txt2iff.c +../util/xpm2iff : ../util/xpm2iff.o + $(LINK) $(LFLAGS) -L../lib -o $@ ../util/txt2iff.o -lriffl +../util/xpm2iff.o : ../outdated/sys/amiga/xpm2iff.c $(HACK_H) + $(CC) $(CFLAGS) -o $@ ../outdated/sys/amiga/xpm2iff.c +$(TARGETDIR)/objects.iff: ../win/share/objects.txt ../util/txt2iff + ../util/txt2iff ../win/share/objects.txt $@ +$(TARGETDIR)/monsters.iff: ../win/share/monsters.txt ../util/txt2iff + ../util/txt2iff ../win/share/monsters.txt $@ +$(TARGETDIR)/other.iff: ../win/share/other.txt ../util/txt2iff + ../util/txt2iff ../win/share/other.txt $@ +# +#.PHONY: amigapkg +amigapkg: $(GAMEBIN) $(TARGETDIR)/recover.exe ../dat/nhtiles.bmp + mkdir -p $(TARGETDIR)/pkg + cp $(GAMEBIN) $(TARGETDIR)/pkg/nethack + cp ../dat/nhdat $(TARGETDIR)/pkg/nhdat + cp ../dat/license $(TARGETDIR)/pkg/license + cp ../dat/nhtiles.bmp $(TARGETDIR)/pkg/nhtiles.bmp + cp $(TARGETDIR)/tomb.iff $(TARGETDIR)/pkg/tomb.iff + cp $(TARGETDIR)/monsters.iff $(TARGETDIR)/pkg/monsters.iff + cp $(TARGETDIR)/objects.iff $(TARGETDIR)/pkg/objects.iff + cp $(TARGETDIR)/other.iff $(TARGETDIR)/pkg/other.iff + cp ../dat/symbols $(TARGETDIR)/pkg/symbols + cp ../sys/share/NetHack.cnf $(TARGETDIR)/pkg/nethack.cnf + cp ../sys/msdos/sysconf $(TARGETDIR)/pkg/sysconf + cp ../outdated/sys/amiga/amii.hlp $(TARGETDIR)/pkg/amii.hlp + cp ../sys/msdos/sysconf $(TARGETDIR)/pkg/sysconf + cp ../doc/nethack.txt $(TARGETDIR)/pkg/nethack.txt + ../util/uudecode ../outdated/sys/amiga/amifont8.uu + cp 8 $(TARGETDIR)/pkg/8 + ../util/uudecode ../outdated/sys/amiga/amifont.uu + cp hack.font $(TARGETDIR)/pkg/hack.font + ../util/uudecode ../outdated/sys/amiga/dflticon.uu + cp default.icon $(TARGETDIR)/pkg/default.icon + ../util/uudecode ../outdated/sys/amiga/NHinfo.uu + cp NetHack.info $(TARGETDIR)/pkg/NetHack.info + ../util/uudecode ../outdated/sys/amiga/NewGame.uu + cp NewGame.info $(TARGETDIR)/pkg/NewGame.info + ../util/uudecode ../outdated/sys/amiga/HackWB.uu + cp HackWB.info $(TARGETDIR)/pkg/HackWB.info + -touch $(TARGETDIR)/pkg/record + zip -9 $(TARGETDIR)/NH370AMI.ZIP $(TARGETDIR)/pkg/* + @echo amiga package zip file $(TARGETDIR)/NH370AMI.ZIP +endif # CROSS_TO_AMIGA + # # shared file dependencies # diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index b3da7e30b..846fed9c9 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -12,6 +12,14 @@ override TARGETDIR = ../targets/$(TARGET) override TARGET_LIBS= endif +ifdef CROSS_TO_AMIGA +BUILD_LUA=1 +BUILD_PDCURSES=1 +override TARGET = amiga +override TARGETDIR = ../targets/$(TARGET) +override TARGET_LIBS= +endif + ifdef BUILD_LUA #===============-================================================= # LUA library @@ -86,6 +94,10 @@ override TARGET_LIBS += $(PDCLIB) ifdef CROSS_TO_MSDOS PDCINCL += -I$(PDCTOP)/dos endif +ifdef CROSS_TO_AMIGA +PDCINCL += -I$(PDCTOP)/sdl1 -I/opt/amiga/m68k-amigaos/include/SDL +override TARGET_LIBS += -lSDL +endif BUILDMORE += $(PDCLIB) # Rules for PDCurses files $(TARGETDIR)/%.o : $(PDCTOP)/pdcurses/%.c @@ -167,6 +179,95 @@ $(TARGETDIR)/%.o : ../sys/msdos/%.c endif # CROSS_TO_MSDOS #================================================================= +ifdef CROSS_TO_AMIGA +#===============-================================================= +# AmigaOS m68k cross-compile recipe +#===============-================================================= +# Uses an Amiga M68K cross-compiler on linux or macOS. +# +# 1. You can obtain the cross-compiler for your system via: +# sys/amiga/fetch-cross.sh +# 2. Then +# make CROSS_TO_AMIGAOS=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 all +# +# Amiga m68k from https://github.com/bebbo/amiga-gcc +#================================================================= + +CFLAGS += -DCROSSCOMPILE -DCROSSCOMPILE_HOST + +# +# Override the build tools and some obj files to +# reflect the amiga-gccs cross-compiler. +# +TOOLTOP = /opt/amiga/bin +#TOOLARCH = -m68020 -mcrt=clib2 +#TOOLARCH = -m68020 #newlib +TOOLARCH = -m68020 -noixemul +override REGEXOBJ = $(TARGETDIR)/cppregex.o +override TARGET_CC = $(TOOLTOP)/m68k-amigaos-gcc +override TARGET_CXX = $(TOOLTOP)/m68k-amigaos-c++ +override TARGET_AR = $(TOOLTOP)/m68k-amigaos-ar +override TARGET_STUBEDIT= +#override TARGET_CFLAGS = -c -O $(TOOLARCH) -I../include -I../outdated/include +override TARGET_CFLAGS = -c -O $(TOOLARCH) \ + -I../include -I../outdated/include \ + -I../outdated/sys/amiga -I../win/share \ + $(LUAINCL) -DAMIGA -DAMIGA_CROSS $(PDCURSESDEF) \ + -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET \ + -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0 \(12.13.2020)\"" +override TARGET_CXXFLAGS = $(TARGET_CFLAGS) +ifeq "$(REGEXOBJ)" "$(TARGETDIR)/cppregex.o" +override TARGET_LINK = $(TARGET_CXX) +else +override TARGET_LINK = $(TARGET_CC) +endif +override TARGET_LFLAGS= $(TOOLARCH) +#override TARGET_LIBS += +VARDATND += nhtiles.bmp +override SYSSRC = ../outdated/sys/amiga/amidos.c ../outdated/sys/amiga/amigst.c \ + ../outdated/sys/amiga/amimenu.c ../outdated/sys/amiga/amirip.c \ + ../outdated/sys/amiga/amistack.c ../outdated/sys/amiga/amitty.c \ + ../outdated/sys/amiga/amiwind.c ../outdated/sys/amiga/clipwin.c \ + ../outdated/sys/amiga/colorwin.c \ + ../outdated/sys/amiga/winami.c ../outdated/sys/amiga/winchar.c \ + ../outdated/sys/amiga/winfuncs.c ../outdated/sys/amiga/winkey.c \ + ../outdated/sys/amiga/winamenu.c ../outdated/sys/amiga/winreq.c \ + ../outdated/sys/amiga/winstr.c ../sys/share/pcmain.c \ + ../win/share/bmptiles.c ../win/share/giftiles.c \ + ../win/share/tileset.c +# ../outdated/sys/amiga/xpm2iff.c +# ../outdated/sys/amiga/txt2iff.c +override SYSOBJ = $(TARGETDIR)/amidos.o $(TARGETDIR)/amigst.o \ + $(TARGETDIR)/amirip.o $(TARGETDIR)/amistack.o \ + $(TARGETDIR)/amitty.o $(TARGETDIR)/amiwind.o \ + $(TARGETDIR)/winami.o $(TARGETDIR)/winchar.o \ + $(TARGETDIR)/winfuncs.o $(TARGETDIR)/winkey.o \ + $(TARGETDIR)/winamenu.o $(TARGETDIR)/winreq.o \ + $(TARGETDIR)/winstr.o $(TARGETDIR)/pcmain.o \ + $(TARGETDIR)/bmptiles.o $(TARGETDIR)/giftiles.o \ + $(TARGETDIR)/tileset.o +# $(TARGETDIR)/xpm2iff.o +# ../util/txt2iff.o +override WINLIB= +override LUALIB= +override GAMEBIN = $(TARGETDIR)/nethack.exe +override PACKAGE= amigapkg +PREGAME = mkdir -p ../targets/amiga +CLEANMORE += rm -r ../targets/amiga +BUILDMORE += $(TARGETDIR)/recover.exe +# ../util/txt2iff +# +ifdef WANT_WIN_CURSES +# rules for pdcurses sdl1-specific files +$(TARGETDIR)/%.o : $(PDCTOP)/sdl1/%.c + $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< +endif # WANT_WIN_CURSES +# Rule for files in sys/amiga +$(TARGETDIR)/%.o : ../outdated/sys/amiga/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< +endif # CROSS_TO_AMIGA +#================================================================= + ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files $(TARGETDIR)/%.o : $(PDCTOP)/sdl1/%.c From 4b58cfd2018773a9a746201f44c2c4c167e95565 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 18:19:20 -0400 Subject: [PATCH 237/708] follow-up bit break into TARGETDIR and TARGETPFX --- sys/unix/hints/include/cross-post.2020 | 308 ++++++++++++------------- sys/unix/hints/include/cross-pre.2020 | 152 ++++++------ 2 files changed, 231 insertions(+), 229 deletions(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index a89d6ca08..45d0ce018 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -5,56 +5,56 @@ ifdef CROSS_TO_MSDOS # -$(TARGETDIR)/msdos.o : ../sys/msdos/msdos.c $(HACK_H) -$(TARGETDIR)/pckeys.o : ../sys/msdos/pckeys.c $(HACK_H) -$(TARGETDIR)/pctiles.o : ../sys/msdos/pctiles.c ../sys/msdos/portio.h $(HACK_H) -$(TARGETDIR)/video.o : ../sys/msdos/video.c ../sys/msdos/portio.h $(HACK_H) -$(TARGETDIR)/vidtxt.o : ../sys/msdos/vidtxt.c ../sys/msdos/portio.h \ +$(TARGETPFX)msdos.o : ../sys/msdos/msdos.c $(HACK_H) +$(TARGETPFX)pckeys.o : ../sys/msdos/pckeys.c $(HACK_H) +$(TARGETPFX)pctiles.o : ../sys/msdos/pctiles.c ../sys/msdos/portio.h $(HACK_H) +$(TARGETPFX)video.o : ../sys/msdos/video.c ../sys/msdos/portio.h $(HACK_H) +$(TARGETPFX)vidtxt.o : ../sys/msdos/vidtxt.c ../sys/msdos/portio.h \ ../win/share/tile.h ../include/tileset.h $(HACK_H) -$(TARGETDIR)/vidvga.o : ../sys/msdos/vidvga.c ../sys/msdos/portio.h \ +$(TARGETPFX)vidvga.o : ../sys/msdos/vidvga.c ../sys/msdos/portio.h \ ../win/share/tile.h ../include/tileset.h $(HACK_H) -$(TARGETDIR)/vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ +$(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ ../win/share/tile.h ../include/tileset.h $(HACK_H) -$(TARGETDIR)/vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ +$(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) -$(TARGETDIR)/tile.o : tile.c +$(TARGETPFX)tile.o : tile.c # #.PHONY: dospkg -dospkg: $(GAMEBIN) $(TARGETDIR)/recover.exe ../dat/nhtiles.bmp +dospkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp $(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K - mkdir -p $(TARGETDIR)/pkg - cp $(GAMEBIN) $(TARGETDIR)/pkg/NETHACK.EXE - cp ../dat/nhdat $(TARGETDIR)/pkg/NHDAT - cp ../dat/license $(TARGETDIR)/pkg/LICENSE - cp ../dat/nhtiles.bmp $(TARGETDIR)/pkg/NHTILES.BMP - cp ../dat/symbols $(TARGETDIR)/pkg/SYMBOLS - cp ../sys/share/NetHack.cnf $(TARGETDIR)/pkg/NETHACK.CNF - cp ../sys/msdos/sysconf $(TARGETDIR)/pkg/SYSCONF - cp ../doc/nethack.txt $(TARGETDIR)/pkg/NETHACK.TXT - cp ../lib/djgpp/cwsdpmi/bin/CWSDPMI.EXE $(TARGETDIR)/pkg/CWSDPMI.EXE - -touch $(TARGETDIR)/pkg/RECORD - zip -9 $(TARGETDIR)/NH370DOS.ZIP $(TARGETDIR)/pkg/* - @echo msdos package zip file $(TARGETDIR)/NH370DOS.ZIP + mkdir -p $(TARGETPFX)pkg + cp $(GAMEBIN) $(TARGETPFX)pkg/NETHACK.EXE + cp ../dat/nhdat $(TARGETPFX)pkg/NHDAT + cp ../dat/license $(TARGETPFX)pkg/LICENSE + 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 + cp ../doc/nethack.txt $(TARGETPFX)pkg/NETHACK.TXT + cp ../lib/djgpp/cwsdpmi/bin/CWSDPMI.EXE $(TARGETPFX)pkg/CWSDPMI.EXE + -touch $(TARGETPFX)pkg/RECORD + zip -9 $(TARGETPFX)NH370DOS.ZIP $(TARGETPFX)pkg/* + @echo msdos package zip file $(TARGETPFX)NH370DOS.ZIP endif # CROSS_TO_MSDOS ifdef CROSS_TO_AMIGA -$(TARGETDIR)/amidos.o : ../outdated/sys/amiga/amidos.c $(HACK_H) -$(TARGETDIR)/amigst.o : ../outdated/sys/amiga/amigst.c $(HACK_H) -$(TARGETDIR)/amirip.o : ../outdated/sys/amiga/amirip.c $(HACK_H) -$(TARGETDIR)/amistack.o : ../outdated/sys/amiga/amistack.c $(HACK_H) -$(TARGETDIR)/amitty.o : ../outdated/sys/amiga/amitty.c $(HACK_H) -$(TARGETDIR)/amiwind.o : ../outdated/sys/amiga/amiwind.c \ +$(TARGETPFX)amidos.o : ../outdated/sys/amiga/amidos.c $(HACK_H) +$(TARGETPFX)amigst.o : ../outdated/sys/amiga/amigst.c $(HACK_H) +$(TARGETPFX)amirip.o : ../outdated/sys/amiga/amirip.c $(HACK_H) +$(TARGETPFX)amistack.o : ../outdated/sys/amiga/amistack.c $(HACK_H) +$(TARGETPFX)amitty.o : ../outdated/sys/amiga/amitty.c $(HACK_H) +$(TARGETPFX)amiwind.o : ../outdated/sys/amiga/amiwind.c \ ../outdated/sys/amiga/amimenu.c $(HACK_H) -$(TARGETDIR)/winami.o : ../outdated/sys/amiga/winami.c $(HACK_H) -$(TARGETDIR)/winchar.o : ../outdated/sys/amiga/winchar.c tile.c $(HACK_H) -$(TARGETDIR)/winfuncs.o : ../outdated/sys/amiga/winfuncs.c $(HACK_H) -$(TARGETDIR)/winkey.o : ../outdated/sys/amiga/winkey.c $(HACK_H) -$(TARGETDIR)/winamenu.o : ../outdated/sys/amiga/winamenu.c $(HACK_H) -$(TARGETDIR)/winreq.o : ../outdated/sys/amiga/winreq.c \ +$(TARGETPFX)winami.o : ../outdated/sys/amiga/winami.c $(HACK_H) +$(TARGETPFX)winchar.o : ../outdated/sys/amiga/winchar.c tile.c $(HACK_H) +$(TARGETPFX)winfuncs.o : ../outdated/sys/amiga/winfuncs.c $(HACK_H) +$(TARGETPFX)winkey.o : ../outdated/sys/amiga/winkey.c $(HACK_H) +$(TARGETPFX)winamenu.o : ../outdated/sys/amiga/winamenu.c $(HACK_H) +$(TARGETPFX)winreq.o : ../outdated/sys/amiga/winreq.c \ ../outdated/sys/amiga/colorwin.c \ ../outdated/sys/amiga/clipwin.c $(HACK_H) -$(TARGETDIR)/winstr.o : ../outdated/sys/amiga/winstr.c $(HACK_H) -$(TARGETDIR)/tomb.iff : ../util/xpm2iff ../outdated/sys/amiga/gave16.xpm +$(TARGETPFX)winstr.o : ../outdated/sys/amiga/winstr.c $(HACK_H) +$(TARGETPFX)tomb.iff : ../util/xpm2iff ../outdated/sys/amiga/gave16.xpm ../util/tiletext.o : ../win/share/tiletext.c $(CC) $(CFLAGS) -c \ -o $@ ../win/share/tiletext.c @@ -71,58 +71,58 @@ $(TARGETDIR)/tomb.iff : ../util/xpm2iff ../outdated/sys/amiga/gave16.xpm $(LINK) $(LFLAGS) -L../lib -o $@ ../util/txt2iff.o -lriffl ../util/xpm2iff.o : ../outdated/sys/amiga/xpm2iff.c $(HACK_H) $(CC) $(CFLAGS) -o $@ ../outdated/sys/amiga/xpm2iff.c -$(TARGETDIR)/objects.iff: ../win/share/objects.txt ../util/txt2iff +$(TARGETPFX)objects.iff: ../win/share/objects.txt ../util/txt2iff ../util/txt2iff ../win/share/objects.txt $@ -$(TARGETDIR)/monsters.iff: ../win/share/monsters.txt ../util/txt2iff +$(TARGETPFX)monsters.iff: ../win/share/monsters.txt ../util/txt2iff ../util/txt2iff ../win/share/monsters.txt $@ -$(TARGETDIR)/other.iff: ../win/share/other.txt ../util/txt2iff +$(TARGETPFX)other.iff: ../win/share/other.txt ../util/txt2iff ../util/txt2iff ../win/share/other.txt $@ # #.PHONY: amigapkg -amigapkg: $(GAMEBIN) $(TARGETDIR)/recover.exe ../dat/nhtiles.bmp - mkdir -p $(TARGETDIR)/pkg - cp $(GAMEBIN) $(TARGETDIR)/pkg/nethack - cp ../dat/nhdat $(TARGETDIR)/pkg/nhdat - cp ../dat/license $(TARGETDIR)/pkg/license - cp ../dat/nhtiles.bmp $(TARGETDIR)/pkg/nhtiles.bmp - cp $(TARGETDIR)/tomb.iff $(TARGETDIR)/pkg/tomb.iff - cp $(TARGETDIR)/monsters.iff $(TARGETDIR)/pkg/monsters.iff - cp $(TARGETDIR)/objects.iff $(TARGETDIR)/pkg/objects.iff - cp $(TARGETDIR)/other.iff $(TARGETDIR)/pkg/other.iff - cp ../dat/symbols $(TARGETDIR)/pkg/symbols - cp ../sys/share/NetHack.cnf $(TARGETDIR)/pkg/nethack.cnf - cp ../sys/msdos/sysconf $(TARGETDIR)/pkg/sysconf - cp ../outdated/sys/amiga/amii.hlp $(TARGETDIR)/pkg/amii.hlp - cp ../sys/msdos/sysconf $(TARGETDIR)/pkg/sysconf - cp ../doc/nethack.txt $(TARGETDIR)/pkg/nethack.txt +amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp + mkdir -p $(TARGETPFX)pkg + cp $(GAMEBIN) $(TARGETPFX)pkg/nethack + cp ../dat/nhdat $(TARGETPFX)pkg/nhdat + cp ../dat/license $(TARGETPFX)pkg/license + cp ../dat/nhtiles.bmp $(TARGETPFX)pkg/nhtiles.bmp + cp $(TARGETPFX)tomb.iff $(TARGETPFX)pkg/tomb.iff + cp $(TARGETPFX)monsters.iff $(TARGETPFX)pkg/monsters.iff + cp $(TARGETPFX)objects.iff $(TARGETPFX)pkg/objects.iff + cp $(TARGETPFX)other.iff $(TARGETPFX)pkg/other.iff + cp ../dat/symbols $(TARGETPFX)pkg/symbols + cp ../sys/share/NetHack.cnf $(TARGETPFX)pkg/nethack.cnf + cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf + cp ../outdated/sys/amiga/amii.hlp $(TARGETPFX)pkg/amii.hlp + cp ../sys/msdos/sysconf $(TARGETPFX)pkg/sysconf + cp ../doc/nethack.txt $(TARGETPFX)pkg/nethack.txt ../util/uudecode ../outdated/sys/amiga/amifont8.uu - cp 8 $(TARGETDIR)/pkg/8 + cp 8 $(TARGETPFX)pkg/8 ../util/uudecode ../outdated/sys/amiga/amifont.uu - cp hack.font $(TARGETDIR)/pkg/hack.font + cp hack.font $(TARGETPFX)pkg/hack.font ../util/uudecode ../outdated/sys/amiga/dflticon.uu - cp default.icon $(TARGETDIR)/pkg/default.icon + cp default.icon $(TARGETPFX)pkg/default.icon ../util/uudecode ../outdated/sys/amiga/NHinfo.uu - cp NetHack.info $(TARGETDIR)/pkg/NetHack.info + cp NetHack.info $(TARGETPFX)pkg/NetHack.info ../util/uudecode ../outdated/sys/amiga/NewGame.uu - cp NewGame.info $(TARGETDIR)/pkg/NewGame.info + cp NewGame.info $(TARGETPFX)pkg/NewGame.info ../util/uudecode ../outdated/sys/amiga/HackWB.uu - cp HackWB.info $(TARGETDIR)/pkg/HackWB.info - -touch $(TARGETDIR)/pkg/record - zip -9 $(TARGETDIR)/NH370AMI.ZIP $(TARGETDIR)/pkg/* - @echo amiga package zip file $(TARGETDIR)/NH370AMI.ZIP + cp HackWB.info $(TARGETPFX)pkg/HackWB.info + -touch $(TARGETPFX)pkg/record + zip -9 $(TARGETPFX)NH370AMI.ZIP $(TARGETPFX)pkg/* + @echo amiga package zip file $(TARGETPFX)NH370AMI.ZIP endif # CROSS_TO_AMIGA # # shared file dependencies # -$(TARGETDIR)/pcmain.o : ../sys/share/pcmain.c $(HACK_H) -$(TARGETDIR)/pcsys.o : ../sys/share/pcsys.c $(HACK_H) -$(TARGETDIR)/pctty.o : ../sys/share/pctty.c $(HACK_H) -$(TARGETDIR)/pcunix.o : ../sys/share/pcunix.c $(HACK_H) -$(TARGETDIR)/tileset.o : ../win/share/tileset.c -$(TARGETDIR)/bmptiles.o : ../win/share/bmptiles.c -$(TARGETDIR)/giftiles.o : ../win/share/giftiles.c -$(TARGETDIR)/recover.exe : $(TARGETDIR)/recover.o +$(TARGETPFX)pcmain.o : ../sys/share/pcmain.c $(HACK_H) +$(TARGETPFX)pcsys.o : ../sys/share/pcsys.c $(HACK_H) +$(TARGETPFX)pctty.o : ../sys/share/pctty.c $(HACK_H) +$(TARGETPFX)pcunix.o : ../sys/share/pcunix.c $(HACK_H) +$(TARGETPFX)tileset.o : ../win/share/tileset.c +$(TARGETPFX)bmptiles.o : ../win/share/bmptiles.c +$(TARGETPFX)giftiles.o : ../win/share/giftiles.c +$(TARGETPFX)recover.exe : $(TARGETPFX)recover.o # # Lua lib @@ -133,95 +133,95 @@ $(LUACROSSLIB): $(LUALIBOBJS) $(TARGET_AR) rcS $@ $(LUAOBJFILES3) $(TARGET_AR) rcs $@ $(LUAOBJFILES4) ifdef WANT_WIN_CURSES -$(TARGETDIR)/pdclib.a : $(PDCLIBOBJS) $(PDCOBJS) +$(TARGETPFX)pdclib.a : $(PDCLIBOBJS) $(PDCOBJS) if [ -f $@ ]; then rm $@; fi; $(TARGET_AR) rcs $@ $(PDCLIBOBJS) $(PDCOBJS) endif # # Lua src -$(TARGETDIR)/lapi.o : $(LUATOP)/src/lapi.c -$(TARGETDIR)/lauxlib.o : $(LUATOP)/src/lauxlib.c -$(TARGETDIR)/lbaselib.o : $(LUATOP)/src/lbaselib.c -$(TARGETDIR)/lbitlib.o : $(LUATOP)/src/lbitlib.c -$(TARGETDIR)/lcode.o : $(LUATOP)/src/lcode.c -$(TARGETDIR)/lcorolib.o : $(LUATOP)/src/lcorolib.c -$(TARGETDIR)/lctype.o : $(LUATOP)/src/lctype.c -$(TARGETDIR)/ldblib.o : $(LUATOP)/src/ldblib.c -$(TARGETDIR)/ldebug.o : $(LUATOP)/src/ldebug.c -$(TARGETDIR)/ldo.o : $(LUATOP)/src/ldo.c -$(TARGETDIR)/ldump.o : $(LUATOP)/src/ldump.c -$(TARGETDIR)/lfunc.o : $(LUATOP)/src/lfunc.c -$(TARGETDIR)/lgc.o : $(LUATOP)/src/lgc.c -$(TARGETDIR)/linit.o : $(LUATOP)/src/linit.c -$(TARGETDIR)/liolib.o : $(LUATOP)/src/liolib.c -$(TARGETDIR)/llex.o : $(LUATOP)/src/llex.c -$(TARGETDIR)/lmathlib.o : $(LUATOP)/src/lmathlib.c -$(TARGETDIR)/lmem.o : $(LUATOP)/src/lmem.c -$(TARGETDIR)/loadlib.o : $(LUATOP)/src/loadlib.c -$(TARGETDIR)/lobject.o : $(LUATOP)/src/lobject.c -$(TARGETDIR)/lopcodes.o : $(LUATOP)/src/lopcodes.c -$(TARGETDIR)/loslib.o : $(LUATOP)/src/loslib.c -$(TARGETDIR)/lparser.o : $(LUATOP)/src/lparser.c -$(TARGETDIR)/lstate.o : $(LUATOP)/src/lstate.c -$(TARGETDIR)/lstring.o : $(LUATOP)/src/lstring.c -$(TARGETDIR)/lstrlib.o : $(LUATOP)/src/lstrlib.c -$(TARGETDIR)/ltable.o : $(LUATOP)/src/ltable.c -$(TARGETDIR)/ltablib.o : $(LUATOP)/src/ltablib.c -$(TARGETDIR)/ltm.o : $(LUATOP)/src/ltm.c -$(TARGETDIR)/lundump.o : $(LUATOP)/src/lundump.c -$(TARGETDIR)/lutf8lib.o : $(LUATOP)/src/lutf8lib.c -$(TARGETDIR)/lvm.o : $(LUATOP)/src/lvm.c -$(TARGETDIR)/lzio.o : $(LUATOP)/src/lzio.c +$(TARGETPFX)lapi.o : $(LUATOP)/src/lapi.c +$(TARGETPFX)lauxlib.o : $(LUATOP)/src/lauxlib.c +$(TARGETPFX)lbaselib.o : $(LUATOP)/src/lbaselib.c +$(TARGETPFX)lbitlib.o : $(LUATOP)/src/lbitlib.c +$(TARGETPFX)lcode.o : $(LUATOP)/src/lcode.c +$(TARGETPFX)lcorolib.o : $(LUATOP)/src/lcorolib.c +$(TARGETPFX)lctype.o : $(LUATOP)/src/lctype.c +$(TARGETPFX)ldblib.o : $(LUATOP)/src/ldblib.c +$(TARGETPFX)ldebug.o : $(LUATOP)/src/ldebug.c +$(TARGETPFX)ldo.o : $(LUATOP)/src/ldo.c +$(TARGETPFX)ldump.o : $(LUATOP)/src/ldump.c +$(TARGETPFX)lfunc.o : $(LUATOP)/src/lfunc.c +$(TARGETPFX)lgc.o : $(LUATOP)/src/lgc.c +$(TARGETPFX)linit.o : $(LUATOP)/src/linit.c +$(TARGETPFX)liolib.o : $(LUATOP)/src/liolib.c +$(TARGETPFX)llex.o : $(LUATOP)/src/llex.c +$(TARGETPFX)lmathlib.o : $(LUATOP)/src/lmathlib.c +$(TARGETPFX)lmem.o : $(LUATOP)/src/lmem.c +$(TARGETPFX)loadlib.o : $(LUATOP)/src/loadlib.c +$(TARGETPFX)lobject.o : $(LUATOP)/src/lobject.c +$(TARGETPFX)lopcodes.o : $(LUATOP)/src/lopcodes.c +$(TARGETPFX)loslib.o : $(LUATOP)/src/loslib.c +$(TARGETPFX)lparser.o : $(LUATOP)/src/lparser.c +$(TARGETPFX)lstate.o : $(LUATOP)/src/lstate.c +$(TARGETPFX)lstring.o : $(LUATOP)/src/lstring.c +$(TARGETPFX)lstrlib.o : $(LUATOP)/src/lstrlib.c +$(TARGETPFX)ltable.o : $(LUATOP)/src/ltable.c +$(TARGETPFX)ltablib.o : $(LUATOP)/src/ltablib.c +$(TARGETPFX)ltm.o : $(LUATOP)/src/ltm.c +$(TARGETPFX)lundump.o : $(LUATOP)/src/lundump.c +$(TARGETPFX)lutf8lib.o : $(LUATOP)/src/lutf8lib.c +$(TARGETPFX)lvm.o : $(LUATOP)/src/lvm.c +$(TARGETPFX)lzio.o : $(LUATOP)/src/lzio.c # # PDCurses src # -$(TARGETDIR)/addch.o : $(PDCTOP)/pdcurses/addch.c -$(TARGETDIR)/addchstr.o : $(PDCTOP)/pdcurses/addchstr.c -$(TARGETDIR)/addstr.o : $(PDCTOP)/pdcurses/addstr.c -$(TARGETDIR)/attr.o : $(PDCTOP)/pdcurses/attr.c -$(TARGETDIR)/beep.o : $(PDCTOP)/pdcurses/beep.c -$(TARGETDIR)/bkgd.o : $(PDCTOP)/pdcurses/bkgd.c -$(TARGETDIR)/border.o : $(PDCTOP)/pdcurses/border.c -$(TARGETDIR)/clear.o : $(PDCTOP)/pdcurses/clear.c -$(TARGETDIR)/color.o : $(PDCTOP)/pdcurses/color.c -$(TARGETDIR)/delch.o : $(PDCTOP)/pdcurses/delch.c -$(TARGETDIR)/deleteln.o : $(PDCTOP)/pdcurses/deleteln.c -$(TARGETDIR)/getch.o : $(PDCTOP)/pdcurses/getch.c -$(TARGETDIR)/getstr.o : $(PDCTOP)/pdcurses/getstr.c -$(TARGETDIR)/getyx.o : $(PDCTOP)/pdcurses/getyx.c -$(TARGETDIR)/inch.o : $(PDCTOP)/pdcurses/inch.c -$(TARGETDIR)/inchstr.o : $(PDCTOP)/pdcurses/inchstr.c -$(TARGETDIR)/initscr.o : $(PDCTOP)/pdcurses/initscr.c -$(TARGETDIR)/inopts.o : $(PDCTOP)/pdcurses/inopts.c -$(TARGETDIR)/insch.o : $(PDCTOP)/pdcurses/insch.c -$(TARGETDIR)/insstr.o : $(PDCTOP)/pdcurses/insstr.c -$(TARGETDIR)/instr.o : $(PDCTOP)/pdcurses/instr.c -$(TARGETDIR)/kernel.o : $(PDCTOP)/pdcurses/kernel.c -$(TARGETDIR)/keyname.o : $(PDCTOP)/pdcurses/keyname.c -$(TARGETDIR)/mouse.o : $(PDCTOP)/pdcurses/mouse.c -$(TARGETDIR)/move.o : $(PDCTOP)/pdcurses/move.c -$(TARGETDIR)/outopts.o : $(PDCTOP)/pdcurses/outopts.c -$(TARGETDIR)/overlay.o : $(PDCTOP)/pdcurses/overlay.c -$(TARGETDIR)/pad.o : $(PDCTOP)/pdcurses/pad.c -$(TARGETDIR)/panel.o : $(PDCTOP)/pdcurses/panel.c -$(TARGETDIR)/printw.o : $(PDCTOP)/pdcurses/printw.c -$(TARGETDIR)/refresh.o : $(PDCTOP)/pdcurses/refresh.c -$(TARGETDIR)/scanw.o : $(PDCTOP)/pdcurses/scanw.c -$(TARGETDIR)/scr_dump.o : $(PDCTOP)/pdcurses/scr_dump.c -$(TARGETDIR)/scroll.o : $(PDCTOP)/pdcurses/scroll.c -$(TARGETDIR)/slk.o : $(PDCTOP)/pdcurses/slk.c -$(TARGETDIR)/termattr.o : $(PDCTOP)/pdcurses/termattr.c -$(TARGETDIR)/touch.o : $(PDCTOP)/pdcurses/touch.c -$(TARGETDIR)/util.o : $(PDCTOP)/pdcurses/util.c -$(TARGETDIR)/window.o : $(PDCTOP)/pdcurses/window.c -$(TARGETDIR)/debug.o : $(PDCTOP)/pdcurses/debug.c -$(TARGETDIR)/pdcclip.o : $(PDCTOP)/dos/pdcclip.c -$(TARGETDIR)/pdcdisp.o : $(PDCTOP)/dos/pdcdisp.c -$(TARGETDIR)/pdcgetsc.o : $(PDCTOP)/dos/pdcgetsc.c -$(TARGETDIR)/pdckbd.o : $(PDCTOP)/dos/pdckbd.c -$(TARGETDIR)/pdcscrn.o : $(PDCTOP)/dos/pdcscrn.c -$(TARGETDIR)/pdcsetsc.o : $(PDCTOP)/dos/pdcsetsc.c -$(TARGETDIR)/pdcutil.o : $(PDCTOP)/dos/pdcutil.c +$(TARGETPFX)addch.o : $(PDCTOP)/pdcurses/addch.c +$(TARGETPFX)addchstr.o : $(PDCTOP)/pdcurses/addchstr.c +$(TARGETPFX)addstr.o : $(PDCTOP)/pdcurses/addstr.c +$(TARGETPFX)attr.o : $(PDCTOP)/pdcurses/attr.c +$(TARGETPFX)beep.o : $(PDCTOP)/pdcurses/beep.c +$(TARGETPFX)bkgd.o : $(PDCTOP)/pdcurses/bkgd.c +$(TARGETPFX)border.o : $(PDCTOP)/pdcurses/border.c +$(TARGETPFX)clear.o : $(PDCTOP)/pdcurses/clear.c +$(TARGETPFX)color.o : $(PDCTOP)/pdcurses/color.c +$(TARGETPFX)delch.o : $(PDCTOP)/pdcurses/delch.c +$(TARGETPFX)deleteln.o : $(PDCTOP)/pdcurses/deleteln.c +$(TARGETPFX)getch.o : $(PDCTOP)/pdcurses/getch.c +$(TARGETPFX)getstr.o : $(PDCTOP)/pdcurses/getstr.c +$(TARGETPFX)getyx.o : $(PDCTOP)/pdcurses/getyx.c +$(TARGETPFX)inch.o : $(PDCTOP)/pdcurses/inch.c +$(TARGETPFX)inchstr.o : $(PDCTOP)/pdcurses/inchstr.c +$(TARGETPFX)initscr.o : $(PDCTOP)/pdcurses/initscr.c +$(TARGETPFX)inopts.o : $(PDCTOP)/pdcurses/inopts.c +$(TARGETPFX)insch.o : $(PDCTOP)/pdcurses/insch.c +$(TARGETPFX)insstr.o : $(PDCTOP)/pdcurses/insstr.c +$(TARGETPFX)instr.o : $(PDCTOP)/pdcurses/instr.c +$(TARGETPFX)kernel.o : $(PDCTOP)/pdcurses/kernel.c +$(TARGETPFX)keyname.o : $(PDCTOP)/pdcurses/keyname.c +$(TARGETPFX)mouse.o : $(PDCTOP)/pdcurses/mouse.c +$(TARGETPFX)move.o : $(PDCTOP)/pdcurses/move.c +$(TARGETPFX)outopts.o : $(PDCTOP)/pdcurses/outopts.c +$(TARGETPFX)overlay.o : $(PDCTOP)/pdcurses/overlay.c +$(TARGETPFX)pad.o : $(PDCTOP)/pdcurses/pad.c +$(TARGETPFX)panel.o : $(PDCTOP)/pdcurses/panel.c +$(TARGETPFX)printw.o : $(PDCTOP)/pdcurses/printw.c +$(TARGETPFX)refresh.o : $(PDCTOP)/pdcurses/refresh.c +$(TARGETPFX)scanw.o : $(PDCTOP)/pdcurses/scanw.c +$(TARGETPFX)scr_dump.o : $(PDCTOP)/pdcurses/scr_dump.c +$(TARGETPFX)scroll.o : $(PDCTOP)/pdcurses/scroll.c +$(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 +$(TARGETPFX)window.o : $(PDCTOP)/pdcurses/window.c +$(TARGETPFX)debug.o : $(PDCTOP)/pdcurses/debug.c +$(TARGETPFX)pdcclip.o : $(PDCTOP)/dos/pdcclip.c +$(TARGETPFX)pdcdisp.o : $(PDCTOP)/dos/pdcdisp.c +$(TARGETPFX)pdcgetsc.o : $(PDCTOP)/dos/pdcgetsc.c +$(TARGETPFX)pdckbd.o : $(PDCTOP)/dos/pdckbd.c +$(TARGETPFX)pdcscrn.o : $(PDCTOP)/dos/pdcscrn.c +$(TARGETPFX)pdcsetsc.o : $(PDCTOP)/dos/pdcsetsc.c +$(TARGETPFX)pdcutil.o : $(PDCTOP)/dos/pdcutil.c # diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 846fed9c9..796703754 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -8,7 +8,8 @@ ifdef CROSS_TO_MSDOS BUILD_LUA=1 BUILD_PDCURSES=1 override TARGET = msdos -override TARGETDIR = ../targets/$(TARGET) +override TARGETDIR=../targets/$(TARGET) +override TARGETPFX = $(TARGETDIR)/ override TARGET_LIBS= endif @@ -16,7 +17,8 @@ ifdef CROSS_TO_AMIGA BUILD_LUA=1 BUILD_PDCURSES=1 override TARGET = amiga -override TARGETDIR = ../targets/$(TARGET) +override TARGETDIR=../targets/$(TARGET) +override TARGETPFX = $(TARGETDIR)/ override TARGET_LIBS= endif @@ -28,26 +30,26 @@ ifdef BUILD_LUA LUA_VERSION ?=5.4.0 LUATOP ?= ../lib/lua-$(LUA_VERSION) LUASRCDIR ?= $(LUATOP)/src -LUAOBJFILES1 = $(TARGETDIR)/lapi.o $(TARGETDIR)/lauxlib.o \ - $(TARGETDIR)/lbaselib.o $(TARGETDIR)/lcode.o \ - $(TARGETDIR)/lcorolib.o $(TARGETDIR)/lctype.o \ - $(TARGETDIR)/ldblib.o +LUAOBJFILES1 = $(TARGETPFX)lapi.o $(TARGETPFX)lauxlib.o \ + $(TARGETPFX)lbaselib.o $(TARGETPFX)lcode.o \ + $(TARGETPFX)lcorolib.o $(TARGETPFX)lctype.o \ + $(TARGETPFX)ldblib.o ifeq "$(LUA_VERSION)" "5.3.5" -LUAOBJFILES1 += $(TARGETDIR)/lbitlib.o +LUAOBJFILES1 += $(TARGETPFX)lbitlib.o endif -LUAOBJFILES2 = $(TARGETDIR)/ldebug.o $(TARGETDIR)/ldo.o $(TARGETDIR)/ldump.o \ - $(TARGETDIR)/lfunc.o $(TARGETDIR)/lgc.o $(TARGETDIR)/linit.o \ - $(TARGETDIR)/liolib.o $(TARGETDIR)/llex.o -LUAOBJFILES3 = $(TARGETDIR)/lmathlib.o $(TARGETDIR)/lmem.o \ - $(TARGETDIR)/loadlib.o $(TARGETDIR)/lobject.o \ - $(TARGETDIR)/lopcodes.o $(TARGETDIR)/loslib.o \ - $(TARGETDIR)/lparser.o $(TARGETDIR)/lstate.o -LUAOBJFILES4 = $(TARGETDIR)/lstring.o $(TARGETDIR)/lstrlib.o \ - $(TARGETDIR)/ltable.o $(TARGETDIR)/ltablib.o \ - $(TARGETDIR)/ltm.o $(TARGETDIR)/lundump.o \ - $(TARGETDIR)/lutf8lib.o $(TARGETDIR)/lvm.o $(TARGETDIR)/lzio.o +LUAOBJFILES2 = $(TARGETPFX)ldebug.o $(TARGETPFX)ldo.o $(TARGETPFX)ldump.o \ + $(TARGETPFX)lfunc.o $(TARGETPFX)lgc.o $(TARGETPFX)linit.o \ + $(TARGETPFX)liolib.o $(TARGETPFX)llex.o +LUAOBJFILES3 = $(TARGETPFX)lmathlib.o $(TARGETPFX)lmem.o \ + $(TARGETPFX)loadlib.o $(TARGETPFX)lobject.o \ + $(TARGETPFX)lopcodes.o $(TARGETPFX)loslib.o \ + $(TARGETPFX)lparser.o $(TARGETPFX)lstate.o +LUAOBJFILES4 = $(TARGETPFX)lstring.o $(TARGETPFX)lstrlib.o \ + $(TARGETPFX)ltable.o $(TARGETPFX)ltablib.o \ + $(TARGETPFX)ltm.o $(TARGETPFX)lundump.o \ + $(TARGETPFX)lutf8lib.o $(TARGETPFX)lvm.o $(TARGETPFX)lzio.o LUALIBOBJS = $(LUAOBJFILES1) $(LUAOBJFILES2) $(LUAOBJFILES3) $(LUAOBJFILES4) -LUACROSSLIB = $(TARGETDIR)/$(O)lua$(subst .,,$(LUA_VERSION)).a +LUACROSSLIB = $(TARGETPFX)$(O)lua$(subst .,,$(LUA_VERSION)).a LUAINCL = -I$(LUASRCDIR) BUILDMORE += $(LUACROSSLIB) override TARGET_LIBS += $(LUACROSSLIB) -lm @@ -63,33 +65,33 @@ ifdef WANT_WIN_CURSES PDCTOP = ../lib/pdcurses PDCURSESDEF= -I../lib/pdcurses -I../lib/pdcurses/dos \ -D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" -PDCLIBOBJ1= $(TARGETDIR)/addch.o $(TARGETDIR)/addchstr.o \ - $(TARGETDIR)/addstr.o $(TARGETDIR)/attr.o \ - $(TARGETDIR)/beep.o $(TARGETDIR)/bkgd.o \ - $(TARGETDIR)/border.o $(TARGETDIR)/clear.o \ - $(TARGETDIR)/color.o $(TARGETDIR)/delch.o \ - $(TARGETDIR)/deleteln.o $(TARGETDIR)/getch.o \ - $(TARGETDIR)/getstr.o $(TARGETDIR)/getyx.o \ - $(TARGETDIR)/inch.o -PDCLIBOBJ2= $(TARGETDIR)/inchstr.o $(TARGETDIR)/initscr.o \ - $(TARGETDIR)/inopts.o $(TARGETDIR)/insch.o \ - $(TARGETDIR)/insstr.o $(TARGETDIR)/instr.o \ - $(TARGETDIR)/kernel.o $(TARGETDIR)/keyname.o \ - $(TARGETDIR)/mouse.o $(TARGETDIR)/move.o \ - $(TARGETDIR)/outopts.o $(TARGETDIR)/overlay.o -PDCLIBOBJ3= $(TARGETDIR)/pad.o $(TARGETDIR)/panel.o $(TARGETDIR)/printw.o \ - $(TARGETDIR)/refresh.o $(TARGETDIR)/scanw.o \ - $(TARGETDIR)/scr_dump.o $(TARGETDIR)/scroll.o \ - $(TARGETDIR)/slk.o $(TARGETDIR)/termattr.o -PDCLIBOBJ4= $(TARGETDIR)/touch.o $(TARGETDIR)/util.o $(TARGETDIR)/window.o \ - $(TARGETDIR)/debug.o +PDCLIBOBJ1= $(TARGETPFX)addch.o $(TARGETPFX)addchstr.o \ + $(TARGETPFX)addstr.o $(TARGETPFX)attr.o \ + $(TARGETPFX)beep.o $(TARGETPFX)bkgd.o \ + $(TARGETPFX)border.o $(TARGETPFX)clear.o \ + $(TARGETPFX)color.o $(TARGETPFX)delch.o \ + $(TARGETPFX)deleteln.o $(TARGETPFX)getch.o \ + $(TARGETPFX)getstr.o $(TARGETPFX)getyx.o \ + $(TARGETPFX)inch.o +PDCLIBOBJ2= $(TARGETPFX)inchstr.o $(TARGETPFX)initscr.o \ + $(TARGETPFX)inopts.o $(TARGETPFX)insch.o \ + $(TARGETPFX)insstr.o $(TARGETPFX)instr.o \ + $(TARGETPFX)kernel.o $(TARGETPFX)keyname.o \ + $(TARGETPFX)mouse.o $(TARGETPFX)move.o \ + $(TARGETPFX)outopts.o $(TARGETPFX)overlay.o +PDCLIBOBJ3= $(TARGETPFX)pad.o $(TARGETPFX)panel.o $(TARGETPFX)printw.o \ + $(TARGETPFX)refresh.o $(TARGETPFX)scanw.o \ + $(TARGETPFX)scr_dump.o $(TARGETPFX)scroll.o \ + $(TARGETPFX)slk.o $(TARGETPFX)termattr.o +PDCLIBOBJ4= $(TARGETPFX)touch.o $(TARGETPFX)util.o $(TARGETPFX)window.o \ + $(TARGETPFX)debug.o PDCLIBOBJS = $(PDCLIBOBJ1) $(PDCLIBOBJ2) $(PDCLIBOBJ3) $(PDCLIBOBJ4) -PDCLIB = $(TARGETDIR)/pdclib.a +PDCLIB = $(TARGETPFX)pdclib.a PDCINCL = -I$(PDCTOP) -I$(PDCTOP)/pdcurses -PDCOBJS = $(TARGETDIR)/pdcclip.o $(TARGETDIR)/pdcdisp.o \ - $(TARGETDIR)/pdcgetsc.o $(TARGETDIR)/pdckbd.o \ - $(TARGETDIR)/pdcscrn.o $(TARGETDIR)/pdcsetsc.o \ - $(TARGETDIR)/pdcutil.o +PDCOBJS = $(TARGETPFX)pdcclip.o $(TARGETPFX)pdcdisp.o \ + $(TARGETPFX)pdcgetsc.o $(TARGETPFX)pdckbd.o \ + $(TARGETPFX)pdcscrn.o $(TARGETPFX)pdcsetsc.o \ + $(TARGETPFX)pdcutil.o override TARGET_LIBS += $(PDCLIB) ifdef CROSS_TO_MSDOS PDCINCL += -I$(PDCTOP)/dos @@ -100,7 +102,7 @@ override TARGET_LIBS += -lSDL endif BUILDMORE += $(PDCLIB) # Rules for PDCurses files -$(TARGETDIR)/%.o : $(PDCTOP)/pdcurses/%.c +$(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< else #WANT_WIN_CURSES PDCURSESDEF= @@ -151,30 +153,30 @@ override SYSSRC = ../sys/share/pcmain.c ../sys/msdos/msdos.c \ ../sys/msdos/vidvga.c ../sys/msdos/vidvesa.c \ ../win/share/bmptiles.c ../win/share/giftiles.c \ ../win/share/tileset.c -override SYSOBJ= $(TARGETDIR)/pcmain.o $(TARGETDIR)/msdos.o \ - $(TARGETDIR)/pcsys.o $(TARGETDIR)/pctty.o \ - $(TARGETDIR)/pcunix.o $(TARGETDIR)/video.o \ - $(TARGETDIR)/vidtxt.o $(TARGETDIR)/pckeys.o \ - $(TARGETDIR)/vidvga.o $(TARGETDIR)/vidvesa.o \ - $(TARGETDIR)/bmptiles.o $(TARGETDIR)/giftiles.o \ - $(TARGETDIR)/tileset.o $(TARGETDIR)/tile.o +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)bmptiles.o $(TARGETPFX)giftiles.o \ + $(TARGETPFX)tileset.o $(TARGETPFX)tile.o override WINLIB= override LUALIB= -override GAMEBIN = $(TARGETDIR)/nethack.exe +override GAMEBIN = $(TARGETPFX)nethack.exe override PACKAGE= dospkg VARDATND += nhtiles.bmp PREGAME = mkdir -p $(TARGETDIR) CLEANMORE += rm -r $(TARGETDIR) -BUILDMORE += $(TARGETDIR)/recover.exe +BUILDMORE += $(TARGETPFX)recover.exe # ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files -$(TARGETDIR)/%.o : $(PDCTOP)/dos/%.c +$(TARGETPFX)%.o : $(PDCTOP)/dos/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< endif # WANT_WIN_CURSES # # Rule for files in sys/msdos -$(TARGETDIR)/%.o : ../sys/msdos/%.c +$(TARGETPFX)%.o : ../sys/msdos/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< endif # CROSS_TO_MSDOS #================================================================= @@ -203,7 +205,7 @@ TOOLTOP = /opt/amiga/bin #TOOLARCH = -m68020 -mcrt=clib2 #TOOLARCH = -m68020 #newlib TOOLARCH = -m68020 -noixemul -override REGEXOBJ = $(TARGETDIR)/cppregex.o +override REGEXOBJ = $(TARGETPFX)cppregex.o override TARGET_CC = $(TOOLTOP)/m68k-amigaos-gcc override TARGET_CXX = $(TOOLTOP)/m68k-amigaos-c++ override TARGET_AR = $(TOOLTOP)/m68k-amigaos-ar @@ -216,7 +218,7 @@ override TARGET_CFLAGS = -c -O $(TOOLARCH) \ -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET \ -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0 \(12.13.2020)\"" override TARGET_CXXFLAGS = $(TARGET_CFLAGS) -ifeq "$(REGEXOBJ)" "$(TARGETDIR)/cppregex.o" +ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" override TARGET_LINK = $(TARGET_CXX) else override TARGET_LINK = $(TARGET_CC) @@ -237,48 +239,48 @@ override SYSSRC = ../outdated/sys/amiga/amidos.c ../outdated/sys/amiga/amigst.c ../win/share/tileset.c # ../outdated/sys/amiga/xpm2iff.c # ../outdated/sys/amiga/txt2iff.c -override SYSOBJ = $(TARGETDIR)/amidos.o $(TARGETDIR)/amigst.o \ - $(TARGETDIR)/amirip.o $(TARGETDIR)/amistack.o \ - $(TARGETDIR)/amitty.o $(TARGETDIR)/amiwind.o \ - $(TARGETDIR)/winami.o $(TARGETDIR)/winchar.o \ - $(TARGETDIR)/winfuncs.o $(TARGETDIR)/winkey.o \ - $(TARGETDIR)/winamenu.o $(TARGETDIR)/winreq.o \ - $(TARGETDIR)/winstr.o $(TARGETDIR)/pcmain.o \ - $(TARGETDIR)/bmptiles.o $(TARGETDIR)/giftiles.o \ - $(TARGETDIR)/tileset.o -# $(TARGETDIR)/xpm2iff.o +override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ + $(TARGETPFX)amirip.o $(TARGETPFX)amistack.o \ + $(TARGETPFX)amitty.o $(TARGETPFX)amiwind.o \ + $(TARGETPFX)winami.o $(TARGETPFX)winchar.o \ + $(TARGETPFX)winfuncs.o $(TARGETPFX)winkey.o \ + $(TARGETPFX)winamenu.o $(TARGETPFX)winreq.o \ + $(TARGETPFX)winstr.o $(TARGETPFX)pcmain.o \ + $(TARGETPFX)bmptiles.o $(TARGETPFX)giftiles.o \ + $(TARGETPFX)tileset.o +# $(TARGETPFX)xpm2iff.o # ../util/txt2iff.o override WINLIB= override LUALIB= -override GAMEBIN = $(TARGETDIR)/nethack.exe +override GAMEBIN = $(TARGETPFX)nethack.exe override PACKAGE= amigapkg PREGAME = mkdir -p ../targets/amiga CLEANMORE += rm -r ../targets/amiga -BUILDMORE += $(TARGETDIR)/recover.exe +BUILDMORE += $(TARGETPFX)recover.exe # ../util/txt2iff # ifdef WANT_WIN_CURSES # rules for pdcurses sdl1-specific files -$(TARGETDIR)/%.o : $(PDCTOP)/sdl1/%.c +$(TARGETPFX)%.o : $(PDCTOP)/sdl1/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< endif # WANT_WIN_CURSES # Rule for files in sys/amiga -$(TARGETDIR)/%.o : ../outdated/sys/amiga/%.c +$(TARGETPFX)%.o : ../outdated/sys/amiga/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< endif # CROSS_TO_AMIGA #================================================================= ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files -$(TARGETDIR)/%.o : $(PDCTOP)/sdl1/%.c +$(TARGETPFX)%.o : $(PDCTOP)/sdl1/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< endif # WANT_WIN_CURSES # Rule for LUA files -$(TARGETDIR)/%.o : $(LUATOP)/src/%.c +$(TARGETPFX)%.o : $(LUATOP)/src/%.c $(TARGET_CC) $(TARGET_CFLAGS) $(LUA_FLAGS) -o$@ $< ifdef WANT_WIN_CURSES # Rules for PDCurses files -$(TARGETDIR)/%.o : $(PDCTOP)/pdcurses/%.c +$(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< endif # WANT_WIN_CURSES From 24a554ecafc56276a317c00d633d5d3a4fd67e9f Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 18:33:46 -0400 Subject: [PATCH 238/708] cron-daily Files update --- Files | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/Files b/Files index 9ba9750a1..a4e23d56c 100644 --- a/Files +++ b/Files @@ -123,9 +123,9 @@ Build.ami Install.ami Makefile.agc Makefile.ami NetHack.cnf amidos.c amidos.p amifont.uu amifont8.uu amigst.c amii.hlp amimenu.c amirip.c amistack.c amitty.c amiwind.c amiwind.p clipwin.c colorwin.c grave16.xpm -ifchange mkdmake txt2iff.c winami.c winami.p -winchar.c windefs.h winext.h winfuncs.c winkey.c -winmenu.c winproto.h winreq.c winstr.c xpm2iff.c +ifchange mkdmake txt2iff.c winamenu.c winami.c +winami.p winchar.c windefs.h winext.h winfuncs.c +winkey.c winproto.h winreq.c winstr.c xpm2iff.c outdated/sys/atari: (files for Atari version - untested for 3.7) @@ -222,13 +222,14 @@ zap.c sys/msdos: (files for MSDOS version) -Install.dos Makefile.GCC Makefile1.cross -Makefile2.cross msdos-cross-compile.sh msdos.c -msdoshlp.txt nhlua.h pckeys.c -pctiles.c pctiles.h pcvideo.h -portio.h setup.bat sysconf -tile2bin.c vesa.h video.c -vidtxt.c vidvesa.c vidvga.c +Install.dos Makefile.GCC Makefile1.cross +Makefile2.cross fetch-cross-compiler.sh msdos-cross-compile.sh +msdos.c msdoshlp.txt nhlua.h +pckeys.c pctiles.c pctiles.h +pcvideo.h portio.h setup.bat +sysconf tile2bin.c vesa.h +video.c vidtxt.c vidvesa.c +vidvga.c (files for running MSDOS binary under Windows) nhico.uu nhpif.uu @@ -312,7 +313,7 @@ unix sys/unix/hints/include: (files for configuring UNIX NetHack versions) -multiw-1.2020 multiw-2.2020 +cross-post.2020 cross-pre.2020 multiw-1.2020 multiw-2.2020 sys/vms: (files for VMS version) @@ -343,16 +344,17 @@ dlb_main.c makedefs.c mdgrep.h mdgrep.pl panic.c recover.c win/Qt: (files for the Qt 4 or 5 widget library - X11, Windows, Mac OS X) -qt_bind.cpp qt_bind.h qt_click.cpp qt_click.h qt_clust.cpp -qt_clust.h qt_delay.cpp qt_delay.h qt_glyph.cpp qt_glyph.h -qt_icon.cpp qt_icon.h qt_inv.cpp qt_inv.h qt_kde0.h -qt_key.cpp qt_key.h qt_line.cpp qt_line.h qt_main.cpp -qt_main.h qt_map.cpp qt_map.h qt_menu.cpp qt_menu.h -qt_msg.cpp qt_msg.h qt_plsel.cpp qt_plsel.h qt_post.h -qt_pre.h qt_rip.cpp qt_rip.h qt_set.cpp qt_set.h -qt_stat.cpp qt_stat.h qt_str.cpp qt_str.h qt_streq.cpp -qt_streq.h qt_svsel.cpp qt_svsel.h qt_win.cpp qt_win.h -qt_xcmd.cpp qt_xcmd.h qt_xpms.h qt_yndlg.cpp qt_yndlg.h +Qt-issues.txt qt_bind.cpp qt_bind.h qt_click.cpp qt_click.h +qt_clust.cpp qt_clust.h qt_delay.cpp qt_delay.h qt_glyph.cpp +qt_glyph.h qt_icon.cpp qt_icon.h qt_inv.cpp qt_inv.h +qt_kde0.h qt_key.cpp qt_key.h qt_line.cpp qt_line.h +qt_main.cpp qt_main.h qt_map.cpp qt_map.h qt_menu.cpp +qt_menu.h qt_msg.cpp qt_msg.h qt_plsel.cpp qt_plsel.h +qt_post.h qt_pre.h qt_rip.cpp qt_rip.h qt_set.cpp +qt_set.h qt_stat.cpp qt_stat.h qt_str.cpp qt_str.h +qt_streq.cpp qt_streq.h qt_svsel.cpp qt_svsel.h qt_win.cpp +qt_win.h qt_xcmd.cpp qt_xcmd.h qt_xpms.h qt_yndlg.cpp +qt_yndlg.h win/X11: (files for X versions) From d33cc59c644fe9b17e2b678afed518f6f596f120 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 18:42:27 -0400 Subject: [PATCH 239/708] move some left-over outdated files from old Mac --- {include => outdated/include}/mac-carbon.h | 0 {include => outdated/include}/mac-qt.h | 0 {include => outdated/include}/mac-term.h | 0 {include => outdated/include}/macpopup.h | 0 {include => outdated/include}/mactty.h | 0 {include => outdated/include}/macwin.h | 0 {include => outdated/include}/mttypriv.h | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename {include => outdated/include}/mac-carbon.h (100%) rename {include => outdated/include}/mac-qt.h (100%) rename {include => outdated/include}/mac-term.h (100%) rename {include => outdated/include}/macpopup.h (100%) rename {include => outdated/include}/mactty.h (100%) rename {include => outdated/include}/macwin.h (100%) rename {include => outdated/include}/mttypriv.h (100%) diff --git a/include/mac-carbon.h b/outdated/include/mac-carbon.h similarity index 100% rename from include/mac-carbon.h rename to outdated/include/mac-carbon.h diff --git a/include/mac-qt.h b/outdated/include/mac-qt.h similarity index 100% rename from include/mac-qt.h rename to outdated/include/mac-qt.h diff --git a/include/mac-term.h b/outdated/include/mac-term.h similarity index 100% rename from include/mac-term.h rename to outdated/include/mac-term.h diff --git a/include/macpopup.h b/outdated/include/macpopup.h similarity index 100% rename from include/macpopup.h rename to outdated/include/macpopup.h diff --git a/include/mactty.h b/outdated/include/mactty.h similarity index 100% rename from include/mactty.h rename to outdated/include/mactty.h diff --git a/include/macwin.h b/outdated/include/macwin.h similarity index 100% rename from include/macwin.h rename to outdated/include/macwin.h diff --git a/include/mttypriv.h b/outdated/include/mttypriv.h similarity index 100% rename from include/mttypriv.h rename to outdated/include/mttypriv.h From 560ace217b1f99e913dc2a19cfe129d5fca429f7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Sep 2020 21:58:12 -0400 Subject: [PATCH 240/708] cron-daily Files update --- Files | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Files b/Files index a4e23d56c..3b86dc039 100644 --- a/Files +++ b/Files @@ -109,13 +109,11 @@ you.h youprop.h (file for tty versions) wintty.h -(files for various Macintosh versions) -mac-carbon.h mac-qt.h mac-term.h macpopup.h mactty.h -macwin.h mttypriv.h - outdated/include: (files that are no longer maintained for current game code) -amiconf.h beconf.h def_os2.h macconf.h os2conf.h tosconf.h wceconf.h +amiconf.h beconf.h def_os2.h mac-carbon.h mac-qt.h +mac-term.h macconf.h macpopup.h mactty.h macwin.h +mttypriv.h os2conf.h tosconf.h wceconf.h outdated/sys/amiga: (files for Amiga versions - untested for 3.7) From 5e9303f9dffa44a9f84b4e3aa0bd035184c9f3c1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 29 Sep 2020 09:41:31 -0400 Subject: [PATCH 241/708] msdos cross-compile follow-up bits add missing make rule for ../win/share files to cross-pre.2020 adjust .travis.yml to use the new approach for building msdos target --- .travis.yml | 7 ++++--- sys/unix/hints/include/cross-post.2020 | 1 + sys/unix/hints/include/cross-pre.2020 | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 21bd109d2..0b1e388a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -138,7 +138,7 @@ matrix: - mingw32-make LUA_VERSION=$LUA_VERSION install - name: msdos-linux-focal-djgpp-crosscompile os: linux - env: HINTS=linux LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.0 dist: focal compiler: gcc script: @@ -148,8 +148,9 @@ matrix: - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - make fetch-lua - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - cd lib/lua-$LUA_VERSION/src && make CC='gcc' a && cd ../../.. - - sh sys/msdos/msdos-cross-compile.sh + - sh sys/msdos/fetch-cross-compiler.sh + - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all + - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package exclude: # - os: osx # osx_image: xcode10.3 diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 45d0ce018..7bc1288a6 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -18,6 +18,7 @@ $(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) $(TARGETPFX)tile.o : tile.c +$(TARGETPFX)recover.o : ../util/recover.c # #.PHONY: dospkg dospkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 796703754..77ee5b3f7 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -283,7 +283,9 @@ ifdef WANT_WIN_CURSES $(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< endif # WANT_WIN_CURSES - +# Rules for win/share files +$(TARGETPFX)%.o : ../win/share/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< # # End of cross-compiling -PRE section #===============-================================================= From c5b5a869d74de7fc24a06d60cbf8842ab0d9c95a Mon Sep 17 00:00:00 2001 From: copperwater Date: Wed, 13 May 2020 00:15:10 -0400 Subject: [PATCH 242/708] Enable themed rooms to be constrained by level difficulty The system of themed rooms currently makes it so that any themed room can potentially generate anywhere a themed room can be placed. This is problematic in the long run, since it makes it difficult to design new rooms that are an appropriate amount of challenge at all levels of the dungeon. (A few themed rooms already have this problem: a hero starting out on level 1 probably won't live very long when the neighboring room is full of giant spiders, or an arch-lich has generated in a mausoleum nearby). This commit adds optional "mindiff" and "maxdiff" properties for themerooms defined as tables and exposes level_difficulty() to Lua. A themeroom whose mindiff exceeds the current level difficulty, or whose maxdiff is lower than the current level difficulty, is prevented from being selected. Because the set of rooms eligible to generate on a given level is no longer fixed, the total frequency of all the rooms can't be computed once per game when the file is first parsed, as it was before. In place of this, the themerooms_generate() function now uses a reservoir sampling algorithm to choose a room from among the eligible rooms, weighted by frequency. --- dat/themerms.lua | 58 +++++++++++++++++++++++++++++------------------- src/nhlua.c | 17 ++++++++++++++ 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/dat/themerms.lua b/dat/themerms.lua index 85c3e18f4..db831a496 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -1,7 +1,10 @@ -- themerooms is an array of tables and/or functions. --- the tables define "frequency" and "contents", --- a plain function has frequency of 1 +-- the tables define "frequency", "contents", "mindiff" and "maxdiff". +-- frequency is optional; if omitted, 1 is assumed. +-- mindiff and maxdiff are optional and independent; if omitted, the room is +-- not constrained by level difficulty. +-- a plain function has frequency of 1, and no difficulty constraints. -- des.room({ type = "ordinary", filled = 1 }) -- - ordinary rooms can be converted to shops or any other special rooms. -- - filled = 1 means the room gets random room contents, even if it @@ -538,36 +541,45 @@ end }); }; -local total_frequency = 0; -for i = 1, #themerooms do - local t = type(themerooms[i]); +function is_eligible(room) + local t = type(room); + local diff = nh.level_difficulty(); if (t == "table") then - total_frequency = total_frequency + themerooms[i].frequency; + if (room.mindiff ~= nil and diff < room.mindiff) then + return false + elseif (room.maxdiff ~= nil and diff > room.maxdiff) then + return false + end elseif (t == "function") then - total_frequency = total_frequency + 1; + -- functions currently have no constraints end -end - -if (total_frequency == 0) then - error("Theme rooms total_frequency == 0"); + return true end function themerooms_generate() - local pick = nh.rn2(total_frequency); + local pick = 1; + local total_frequency = 0; for i = 1, #themerooms do - local t = type(themerooms[i]); - if (t == "table") then - pick = pick - themerooms[i].frequency; - if (pick < 0) then - themerooms[i].contents(); - return; + -- Reservoir sampling: select one room from the set of eligible rooms, + -- which may change on different levels because of level difficulty. + if is_eligible(themerooms[i]) then + local this_frequency; + if (type(themerooms[i]) == "table" and themerooms[i].frequency ~= nil) then + this_frequency = themerooms[i].frequency; + else + this_frequency = 1; end - elseif (t == "function") then - pick = pick - 1; - if (pick < 0) then - themerooms[i](); - return; + total_frequency = total_frequency + this_frequency; + if (nh.rn2(total_frequency) < this_frequency) then + pick = i; end end end + + local t = type(themerooms[pick]); + if (t == "table") then + themerooms[pick].contents(); + elseif (t == "function") then + themerooms[pick](); + end end diff --git a/src/nhlua.c b/src/nhlua.c index 24bcc5d59..b3906592b 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -34,6 +34,7 @@ static int FDECL(nhl_ing_suffix, (lua_State *)); static int FDECL(nhl_an, (lua_State *)); static int FDECL(nhl_rn2, (lua_State *)); static int FDECL(nhl_random, (lua_State *)); +static int FDECL(nhl_level_difficulty, (lua_State *)); static void FDECL(init_nhc_data, (lua_State *)); static int FDECL(nhl_push_anything, (lua_State *, int, void *)); static int FDECL(nhl_meta_u_index, (lua_State *)); @@ -657,6 +658,21 @@ lua_State *L; return 1; } +/* level_difficulty() */ +static int +nhl_level_difficulty(L) +lua_State *L; +{ + int argc = lua_gettop(L); + if (argc == 0) { + lua_pushinteger(L, level_difficulty()); + } + else { + nhl_error(L, "level_difficulty should not have any args"); + } + return 1; +} + /* get mandatory integer value from table */ int get_table_int(L, name) @@ -831,6 +847,7 @@ static const struct luaL_Reg nhl_functions[] = { {"an", nhl_an}, {"rn2", nhl_rn2}, {"random", nhl_random}, + {"level_difficulty", nhl_level_difficulty}, {NULL, NULL} }; From 999222a8a4c8e432e2f83351d0af673e7aadc9e1 Mon Sep 17 00:00:00 2001 From: copperwater Date: Wed, 13 May 2020 20:52:33 -0400 Subject: [PATCH 243/708] Add minimum difficulty cutoffs to two themed rooms This sets the minimum level depth of "Spider nest" to 10, somewhat above the difficulty of an individual giant spider, because a whole room full of them is a tougher challenge. Note that this isn't the only possible fix to this problem; another solution would be to alter the special case in mktrap that hardcodes a giant spider to generate with each web to produce cave spiders if giant spiders would be too tough. Even then, a lower difficulty cutoff is probably still warranted for this room, since a large number of cave spiders might be too tough for level 1 or 2. This also sets the minimum level depth of "Boulder room" to 4, based on the fact that individual rolling boulder traps normally can't appear until level 2, and having a bunch of them in one place which may be required to reach the downstairs could be problematic. This doesn't do anything to address the "Mausoleum" room problem, in which a master or arch-lich can generate and immediately warp out and attack the player. Even with a high difficulty threshold, it won't fix the problem of these liches generating out of their normal difficulty and Gehennom constraints. Other potential candidates for difficulty thresholds: - "Trap room": This room might be perilous on the first few levels, especially if the level generates with it blocking the way to the downstairs. - "Massacre": Doesn't have any particular hazards, but might be interesting if it only generated at deeper levels. --- dat/themerms.lua | 68 ++++++++++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/dat/themerms.lua b/dat/themerms.lua index db831a496..73d6e8367 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -16,7 +16,7 @@ -- to generate a single themed room. themerooms = { - { + { -- the "default" room frequency = 1000, contents = function() @@ -79,38 +79,44 @@ themerooms = { end, -- Boulder room - function() - des.room({ type = "themed", - contents = function(rm) - for x = 0, rm.width - 1 do - for y = 0, rm.height - 1 do - if (percent(30)) then - if (percent(50)) then - des.object("boulder"); - else - des.trap("rolling boulder"); - end - end - end - end - end - }); - end, + { + mindiff = 4, + contents = function() + des.room({ type = "themed", + contents = function(rm) + for x = 0, rm.width - 1 do + for y = 0, rm.height - 1 do + if (percent(30)) then + if (percent(50)) then + des.object("boulder"); + else + des.trap("rolling boulder"); + end + end + end + end + end + }); + end + }, -- Spider nest - function() - des.room({ type = "themed", - contents = function(rm) - for x = 0, rm.width - 1 do - for y = 0, rm.height - 1 do - if (percent(30)) then - des.trap("web", x, y); - end - end - end - end - }); - end, + { + mindiff = 10, + contents = function() + des.room({ type = "themed", + contents = function(rm) + for x = 0, rm.width - 1 do + for y = 0, rm.height - 1 do + if (percent(30)) then + des.trap("web", x, y); + end + end + end + end + }); + end + }, -- Trap room function() From 3d4ba4d66640694d3f961a5c49dbd3f64a705a10 Mon Sep 17 00:00:00 2001 From: copperwater Date: Sat, 23 May 2020 17:11:36 -0400 Subject: [PATCH 244/708] Avoid calling rn2(0) when the first room(s) have frequency 0 This probably won't happen in practice, but it is a good safeguard if this ever does happen (it happened for me in debugging when I wished to have no "regular" rooms and only generate themed rooms). --- dat/themerms.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dat/themerms.lua b/dat/themerms.lua index 73d6e8367..4f4f59029 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -576,7 +576,8 @@ function themerooms_generate() this_frequency = 1; end total_frequency = total_frequency + this_frequency; - if (nh.rn2(total_frequency) < this_frequency) then + -- avoid rn2(0) if a room has freq 0 + if this_frequency > 0 and nh.rn2(total_frequency) < this_frequency then pick = i; end end From 476990b3031d71198758be5440d8d25e772229ff Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 29 Sep 2020 17:35:16 +0300 Subject: [PATCH 245/708] Fixes and lua doc --- doc/fixes37.0 | 1 + doc/lua.adoc | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 5465ae338..2adfa50f3 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -588,6 +588,7 @@ redo rndmonst() to operate in a single pass (github pull request #286) fix the "stuck pets" issue (github #329) allow themed room subrooms to be filled (github #347) allow rereading spellbooks to refresh memory at any time (github #261) +allow themed rooms constrained by level difficulty (github #344) Code Cleanup and Reorganization diff --git a/doc/lua.adoc b/doc/lua.adoc index cc4835d7b..b19186003 100644 --- a/doc/lua.adoc +++ b/doc/lua.adoc @@ -111,6 +111,15 @@ Example: local str = nh.ing_suffix("foo"); +=== level_difficulty + +Returns an integer value describing the level difficulty. +Normally this is the level's physical depth from the surface. + +Example: + + local diff = nh.level_difficulty(); + === makeplural Pluralize the given string. From 945d10cfbcf7c8af28a6a4c875f203a1ba25fbbf Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 29 Sep 2020 15:01:37 -0400 Subject: [PATCH 246/708] cross-compile update Update the cross-compiling doc at the top. Remove sys/msdos/Makefile1.cross, sys/msdos/Makefile2.cross, and sys/msdos/msdos-cross-compile.sh as they are no longer required. Remove occurrences of CROSSCOMPILE_HOST as the host-side of a cross-compile can be determined from: defined(CROSSCOMPILE) && !defined(CROSSCOMPILE_TARGET) without the additional macro. --- Cross-compiling | 247 ++++-- src/version.c | 8 +- sys/msdos/Makefile1.cross | 641 --------------- sys/msdos/Makefile2.cross | 1091 ------------------------- sys/msdos/msdos-cross-compile.sh | 129 --- sys/unix/hints/include/cross-pre.2020 | 4 +- sys/winnt/Makefile.msc | 44 +- util/makedefs.c | 14 +- 8 files changed, 206 insertions(+), 1972 deletions(-) delete mode 100644 sys/msdos/Makefile1.cross delete mode 100644 sys/msdos/Makefile2.cross delete mode 100644 sys/msdos/msdos-cross-compile.sh diff --git a/Cross-compiling b/Cross-compiling index b7fc4b58b..aa561df6c 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -1,4 +1,4 @@ -Cross-compiling NetHack 3.7 Last edit: May 31, 2020 +Cross-compiling NetHack 3.7 Last edit: September 29, 2020 The NetHack 3.7 build process differs from the build process of previous versions in some important ways that make it possible to use a cross-compiler @@ -17,6 +17,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) -------------------------------------------------------------------------------- Part A - Cross-compiling NetHack @@ -45,7 +46,7 @@ may include, but not necessarily be limited to, any of the following: o Compilers: Some of the native compilers on historical platforms may only support the particular dialect of C that was popular when the platform and - compiler were in their prime. + compiler were in their prime. Another useful potential result of cross-compiling, is that it paves the way for carrying out test and production builds of NetHack for multiple target @@ -65,27 +66,27 @@ steps to be carried out: (a) additional build steps to follow, including some header files: pm.h, onames.h, date.h. (b) creation of files, containing information required by, - or about the game during its execution, that are stored in a + or about the game during its execution, that are stored in a portable, platform-independent way, that need to be inserted into the game package. (c) creation of files containing information required by, or about the game during its execution, that are stored in an architecture and/or platform and/or operating system dependent way, that need - to be inserted into the game package (the quest text format is + to be inserted into the game package (the quest text format is one example). - 3. Compile and link the level compiler. This step needs to execute + 3. Compile and link the level compiler. This step needs to execute work-alike tools to lex and yacc, or needs to build pre-built lex and yacc output (.c, .h files) that are provided in the sys/share part of the NetHack source code tree. 4. Execute the level compiler to read dat/*.des files and create - a set of binary output files that are architecture and/or operating + a set of binary output files that are architecture and/or operating system dependent on the build platform, for use by the game during its execution. 5. Compile and link the dungeon compiler. Like the level compiler, this - step needs to execute work-alike tools to lex and yacc, or needs to + step needs to execute work-alike tools to lex and yacc, or needs to build pre-built lex and yacc output (.c, .h files) that are provided in the sys/share part of the NetHack source code tree. - 6. Execute the dungeon compiler to read dat/dungeon.def and create + 6. Execute the dungeon compiler to read dat/dungeon.def and create a set of binary output files that are architecture and/or operating system dependent on the build platform, for use by the game during its execution. @@ -126,7 +127,7 @@ steps to be carried out: (a) additional build steps to follow, including some header files: pm.h, onames.h, date.h. (b) creation of files, containing information required by, - or about the game during its execution, that are stored in a + or about the game during its execution, that are stored in a portable, platform-independent way, that need to be inserted into the game package. 3. Compile and link several less critical utilities such as uudecode, @@ -143,7 +144,7 @@ steps to be carried out: previous steps 2b, 3 and 4 above. Step 4 is now the only impediment to cross-compiling NetHack, and is resolved -by executing step 4 using a cross-compiler that runs on the build (host) +by executing step 4 using a cross-compiler that runs on the build (host) platform to produce a resulting binary for the target platform, instead of executing the native compiler. @@ -158,18 +159,15 @@ cross-compiling possible: o There is no creation of platform-dependent files, such as the quest text files, by makedefs during the build process. Instead, the quest text files have been converted to Lua and are inserted into the game - package for processing by the embedded Lua - during execution of NetHack. + package for processing by the embedded Lua during execution of NetHack. o There is no build-time level compiler involved. Instead, the level descriptions have been converted to Lua and are inserted into the game - package for processing by the embeded Lua - during execution of NetHack. + package for processing by the embeded Lua during execution of NetHack. o There is no build-time dungeon compiler involved. Instead, the dungeon description has been converted to Lua and is inserted into the game - package for processing by the embeded Lua - during execution of NetHack. + package for processing by the embeded Lua during execution of NetHack. o Some of the build and option information that was formerly produced during build time by makedefs, and contained information about the @@ -182,7 +180,7 @@ cross-compiling possible: +------------------------------------------------------------+ o If you have a favourite target platform (let's call it XX-Platform for - example purposes) that you'd like to see NetHack be able to run on, do + example purposes) that you'd like to see NetHack be able to run on, do some research to find out if a cross-compiler exists that: - produces output for XX-Platform. - executes on a platform that you use and love (Linux, Windows, @@ -191,9 +189,9 @@ cross-compiling possible: o Then, make the community, devteam, and others aware that you're starting a cross-compile of NetHack for XX-Platform. You might need to ask some - "starting out" questions initially, and as you get deeper into it, you + "starting out" questions initially, and as you get deeper into it, you might need to ask some tougher questions. - + o Perhaps consider forking from NetHack on GitHub, and do the cross-compiler work there in your fork. Strive to get it to a point where it's ready to play-test on XX-Platform, or perhaps even use an emulator @@ -205,9 +203,9 @@ cross-compiling possible: - It will make it possible and straightforward to merge upstream NetHack changes into your work for the XX-Platform cross-compile so that it stays current with the game as it evolves. - - You may get help from others in the form of suggestions, or + - You may get help from others in the form of suggestions, or pull-requests, or offers to join the development. Chances are, - you aren't the only person out there that would like to + you aren't the only person out there that would like to establish/resurrect/maintain NetHack on XX-Platform. Have fun! @@ -258,7 +256,7 @@ On the HOST, here are the mandatory things that have to be built. a) Using the HOST native compiler, build HOST native utility makedefs Compile and link the following with these compiler switches: - -DCROSSCOMPILE and -DCROSSCOMPILE_HOST + -DCROSSCOMPILE from sources: util/makedefs.c, src/mdlib.c, src/monst.c, src/objects.c b) Execute HOST native makedefs utility, util/makedefs, as follows: @@ -307,7 +305,7 @@ On the HOST, here are the mandatory things that have to be built. util/uudecode from sources: sys/share/uudecode.c - purpose: convert some binary files, that are + purpose: convert some binary files, that are distributed in the NetHack sources in uuencoded format, back into their original binary state @@ -452,67 +450,166 @@ Using the cross-compiler, build the following targets: Cross-compiler used: Andrew Wu's djgpp cross-compiler Cross-compiler url: https://github.com/andrewwutw/build-djgpp Cross-compiler pre-built binary downloads: - https://github.com/andrewwutw/build-djgpp/releases/download/v2.9/ - Mac OS X pre-built binary: djgpp-osx-gcc550.tar.bz2 (tested) - Linux pre-built binary : djgpp-linux64-gcc550.tar.bz2 (tested) - mingw pre-built binary : djgpp-mingw-gcc550-standalone.zip (untested) + https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/ + Cross-compiler bits tested: + https://github.com/andrewwutw/build-djgpp + and the pre-built binary for your platform from: + https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/ + and a DOS-extender (for including in msdos packaging) from + http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip + and pdcurses from: + https://github.com/wmcbrine/PDCurses.git -The msdos cross-compile for NetHack 3.7 uses two phases of compiles: -Phase1 is the host-side prerequisite stuff that needs to be done first. -Phase2 is the cross-compile pieces using the djgpp cross-compiler hosted on -Linux, Mac OS X, or Windows mingw. + - A shell script to download that djgpp cross-compiler and associated + pieces for either linux or macOS is available: -First, on the host platform, you need to set up for a native Unix NetHack -build in the usual way. For example, on linux: - cd sys/unix - sh setup.sh hints/linux - cd ../.. - make fetch-lua + sh sys/msdos/fetch-cross-compiler.sh -Now, you could proceed to go ahead and issue - make all -to build a native NetHack at that point if you wish, but it is not needed -for the msdos cross-compile. + That script won't install anything, it just does file fetches and stores + them in subfolders of lib. The linux.2020 and macOS.2020 hints files are + configured to find the cross-compiler there if you add + CROSS_TO_MSDOS=1 + on your make command line. -Instead, a test shell script has been put together that will next accomplish -each of the following tasks when it is executed. The shell script can be -invoked by: - sh sys/msdos/msdos-cross-compile.sh -but before you do that, please read the paragraphs below. + Note: Both the fetch-cross-compiler.sh script and and the msdos + cross-compile and package procedures require unzip and zip to be available + on your host build system. -The shell script is meant to accomplish the following things: + On your linux host: - Prep : the script downloads the djgpp cross-compiler for the host - platform into lib/djgpp (it doesn't install anything on the - system, nor does it need to, it just downloads them into the - identified directories), it downloads a copy of the msdos - dos-extender into lib/djgpp/cwsdpmi for later packaging up with - the msdos game, and it downloads pdcurses into lib/pdcurses - for cross-compiling during the TARGET build. + cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. + make fetch-lua - Be certain to ensure the right products are at the url's - identified above *before* you execute the Case sample msdos - cross-compile script. The correct products were at those url's - at the time this was written in Dec 2019, but we don't assume - any responsibility for what is at those url's now or in the - future. You need to check before executing the script. + On your macOS host: - Phase1 : the script uses the Makefile sys/msdos/Makefile1.cross - to complete the host-side build steps using the native gcc - compiler for the host platform. During phase1 the host obj - files are put in subfolder src/host_o to keep them separated - and distinguishable from the target obj files that will be - built in phase2. + cd sys/unix ; sh setup.sh hints/macOS.2020 ; cd ../.. + make fetch-lua - Phase2 : the script uses the Makefile sys/msdos/Makefile2.cross - to complete the target-side build steps using the - cross-compiler that was obtained during the prep step of the - script described above. During phase2 the target obj files - are put in src/msdos_o to keep them separated and - distinguishable from the host obj files + The MSDOS cross-compile can then be carried out by specifying + CROSS_TO_MSDOS=1 on the make command line: - Package: the script then packages up the results that reside in - msdos-binary into a zip file which it places in lib called - nh370dos.zip. + make CROSS_TO_MSDOS=1 all + make CROSS_TO_MSDOS=1 package + You can explicitly include tty and curses support if desired. The default + you'll end up with is a tty-only cross-compile build: + + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package + + 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 + + Also note that building the msdos targets using the make command + above, does not preclude you from building local linux or macOS + targets as well. Just drop the CROSS_TO_MSDOS=1 from the make + command line. That's because the cross-compiler hints additions are + enclosed inside ifdef sections and won't interfere with the + non-cross-compile build in that case. + + +-------------------------+ + | B5. Case sample: amiga | + +-------------------------+ + +Disclaimer: This is a minimal recipe, just to help someone else get + started if they have a desire to get a full cross-compile of + NetHack going for the Amiga. + See CAVEATS below. + +Cross-compiler used: bebbo's amiga-gcc +Cross-compiler url: https://github.com/bebbo/amiga-gcc + + 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 + build it on your system. + + The build prerequisite packages for building the compiler on Ubuntu can be + easily obtained: + + sudo apt install make wget git gcc g++ lhasa libgmp-dev \ + libmpfr-dev libmpc-dev flex bison gettext texinfo ncurses-dev \ + autoconf rsync + + The build prerequisite packages for macOS via homebrew are documented but + not tested by us any of us to date. + + brew install bash wget make lhasa gmp mpfr libmpc flex gettext \ + texinfo gcc make autoconf + + After installing the prerequite packages and the cross-compiler + it was a straightforward build: + + git clone https://github.com/bebbo/amiga-gcc.git + cd amiga-gcc + make update + + [Note that you may have to take ownership of the files in the bebbo + repo via chown before succesfully carrying out the next steps] + + make clean + make clean-prefix + date; make all -j3 >&b.log; date + + The compiler pieces are installed in /opt/amiga by default. If you prefer, + you can alter the prefix before you build if you want. The instructions + for doing so were spelled out at the time of this writing at: + + https://github.com/bebbo/amiga-gcc + + On your linux host: + + cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. + make fetch-lua + + On your macOS host: + + cd sys/unix ; sh setup.sh hints/macOS.2020 ; cd ../.. + make fetch-lua + + The Amiga cross-compile can then be carried out by specifying + CROSS_TO_AMIGA=1 on the make command line: + + make CROSS_TO_AMIGA=1 all + make CROSS_TO_AMIGA=1 package + + You can explicitly include tty and curses support if desired, otherwise + you'll end up with a tty-only cross-compile build. The SDL1 pdcurses + support has not been tested. + + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_AMIGA=1 all + + Result: The "make package" target will bundle the (hopefully) necessary + components to run NetHack on msdos into a folder: + targets/amiga/pkg + and then it zips the contents of that folder into: + targets/amiga/nh370ami.zip + + Also note that building the amiga targets using the make command + above, does not preclude you from building local linux or macOS + targets as well. Just drop the CROSS_TO_AMIGA=1 from the make + command line. + + The cross-compiler hints additions are enclosed inside ifdef sections + and won't interfere with the non-cross-compile build in that case. + + CAVEATS: The original NetHack Amiga build steps included the source for + some utilities that were built and executed on the amiga: + txt2iff and xpm2iff + as part of the NetHack build procedure on amiga. + Those did not compile out-of-the-box on the linux host. They + will either have to be: + - ported to build and run on the linux or macOS cross-compile + host + or + + - their functionality will have to be rolled into amiga NetHack + itself and executed on the target Amiga the first time the game + is run, perhaps. + + If you make headway, or are successful getting a working copy of + NetHack going on the amiga, drop us a note at devteam@nethack.org. +--- diff --git a/src/version.c b/src/version.c index 049b92137..d6b8ed724 100644 --- a/src/version.c +++ b/src/version.c @@ -29,7 +29,7 @@ struct cross_target_s cross_target = { #if defined(NETHACK_GIT_SHA) const char *NetHack_git_sha -#if !defined(CROSSCOMPILE) || (defined(CROSSCOMPILE) && defined(CROSSCOMPILE_HOST)) +#if !defined(CROSSCOMPILE) || !defined(CROSSCOMPILE_TARGET) = NETHACK_GIT_SHA #else #ifdef NETHACK_HOST_GIT_SHA @@ -41,7 +41,7 @@ const char *NetHack_git_sha #if defined(NETHACK_GIT_BRANCH) const char *NetHack_git_branch -#if !defined(CROSSCOMPILE) || (defined(CROSSCOMPILE) && defined(CROSSCOMPILE_HOST)) +#if !defined(CROSSCOMPILE) || !defined(CROSSCOMPILE_TARGET) = NETHACK_GIT_BRANCH #else #ifdef NETHACK_HOST_GIT_BRANCH @@ -429,7 +429,7 @@ void store_version(nhfp) NHFILE *nhfp; { -#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_HOST) +#if !defined(CROSSCOMPILE) || !defined(CROSSCOMPILE_TARGET) static const struct version_info version_data = { VERSION_NUMBER, VERSION_FEATURES, VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3 @@ -439,7 +439,7 @@ NHFILE *nhfp; #endif }; -#if defined(CROSSCOMPILE) && !defined(CROSSCOMPILE_HOST) +#if defined(CROSSCOMPILE) && defined(CROSSCOMPILE_TARGET) version_data.incarnation = VERSION_NUMBER; /* actual version number */ version_data.feature_set = VERSION_FEATURES; /* bitmask of config settings */ version_data.entity_count = VERSION_SANITY1; /* # of monsters and objects */ diff --git a/sys/msdos/Makefile1.cross b/sys/msdos/Makefile1.cross deleted file mode 100644 index eb62bd337..000000000 --- a/sys/msdos/Makefile1.cross +++ /dev/null @@ -1,641 +0,0 @@ -# NetHack 3.7 Makefile1.cross -# Cross-compile msdos version of NetHack using a -# linux-hosted djgpp cross-compiler. -# -# Makefile1.cross (this file) is for the host-side obj files and -# utilities that will run on the host platform only. -# -# Makefile2.cross is for the target platform obj files -# and utilities. -# -# Makefile2 utilizes the djgpp cross-compiler from Andrew Wu: -# https://github.com/andrewwutw/build-djgpp -# -# Currently, in NetHack 3.7, it is now feasible to cross-compile -# the game in a 2-stage process. Makefile1.cross (this file) carries -# out the 1st stage. -# -# The GNU Make has a problem if you include a drive spec below. -GAMEDIR =../msdos-binary - -# -#============================================================================== -# This marks the end of the BUILD DECISIONS section. -#============================================================================== -# -# Directories, gcc likes unix style directory specs -# - -OBJ = o -HOBJ = host_o -DAT = ../dat -DOC = ../doc -INCL = ../include -LIB = ../lib -MSYS = ../sys/msdos -SRC = ../src -SSHR = ../sys/share -UTIL = ../util -WIN = ../win/tty -WCURSES = ../win/curses -WSHR = ../win/share - -# -# Executables. -# -HOST_CC = gcc -HOST_LINK = gcc -MAKEBIN = make - -# -# Special libraries and how to link them in. -# -LIBS = -lpc -LIBRARIES = $(LIBS) - -# -# Yacc/Lex off -# -YACC_LEX = N - -# -# Uncomment the line below if you want to store all the level files, -# help files, etc. in a single library file. -# -USE_DLB = Y - -#=============================================== -#======= End of Modification Section =========== -#=============================================== -################################################ -# # -# Nothing below here should have to be changed.# -# # -################################################ - -# Changing this conditional block is not recommended -ifeq "$(USE_DLB)" "Y" -DLBFLG = -DDLB -else -DLBFLG = -endif - -TERMLIB = - -#========================================== -#================ MACROS ================== -#========================================== -# This section creates shorthand macros for many objects -# referenced later on in the Makefile. -# -# Have windows path styles available for use in commands -# -W_OBJ =$(subst /,\, $(OBJ)) -W_INCL =$(subst /,\, $(INCL)) -W_DAT =$(subst /,\, $(DAT)) -W_DOC =$(subst /,\, $(DOC)) -W_UTIL =$(subst /,\, $(UTIL)) -W_SRC =$(subst /,\, $(SRC)) -W_SSYS =$(subst /,\, $(SSYS)) -W_MSWSYS =$(subst /,\, $(MSWSYS)) -W_TTY =$(subst /,\, $(TTY)) -W_MSWIN =$(subst /,\, $(MSWIN)) -ifeq "$(ADD_CURSES)" "Y" -W_WCURSES =$(subst /,\, $(WCURSES)) -endif -W_WSHR =$(subst /,\, $(WSHR)) -W_GAMEDIR =$(subst /,\, $(GAMEDIR)) - -# -# Shorten up the location for some files -# - -O = $(OBJ)/ -HOST_O = $(HOBJ)/ -U = $(UTIL)/ - -#========================================== -# Utility Objects. -#========================================== - -MAKESRC = makedefs.c - -MAKEDEFSOBJS = $(HOST_O)makedefs.o $(HOST_O)monst.o $(HOST_O)objects.o - -LUA_QTEXT_FILE = "quest.lua" - -#========================================== -# Tile related object files. -#========================================== - -TILOBJ2 = $(HOST_O)tileset.o $(HOST_O)bmptiles.o $(HOST_O)giftiles.o - -TEXTIO = $(HOST_O)tiletext.o $(HOST_O)tiletxt.o $(HOST_O)drawing.o $(HOST_O)monst.o \ - $(HOST_O)objects.o - -TEXTIO2 = $(HOST_O)tiletex2.o $(HOST_O)tiletxt2.o $(HOST_O)drawing.o $(HOST_O)monst.o \ - $(HOST_O)objects.o - -TILE_BMP = $(DAT)/NHTILES.BMP - -TILEUTIL = $(TILE_BMP) - -TILEFILES = $(WSHR)/monsters.txt $(WSHR)/objects.txt $(WSHR)/other.txt - -TILEFILES2 = $(WSHR)/monthin.txt $(WSHR)/objthin.txt $(WSHR)/oththin.txt - -GIFREADERS = $(HOST_O)gifread.o $(HOST_O)alloc.o $(HOST_O)panic.o - -GIFREAD2 = $(HOST_O)gifread2.o $(HOST_O)alloc.o $(HOST_O)panic.o - -PPMWRITERS = $(HOST_O)ppmwrite.o $(HOST_O)alloc.o $(HOST_O)panic.o - -PPMWRIT2 = $(HOST_O)ppmwrit2.o $(HOST_O)alloc.o $(HOST_O)panic.o - -#========================================== -# Object files. -#========================================== - -DLBOBJ = $(HOST_O)dlb.o - -ALLOBJ = $(MAKEDEFSOBJS) $(TILOBJ) $(TILOBJ2) $(TEXTIO) $(TEXTIO2) - -#========================================== -# Header file macros -#========================================== - -PATCHLEV_H = $(INCL)/patchlev.h -DGN_FILE_H = $(INCL)/align.h $(INCL)/dgn_file.h -DUNGEON_H = $(INCL)/align.h $(INCL)/dungeon.h -MONDATA_H = $(INCL)/align.h $(INCL)/mondata.h -MONST_H = $(INCL)/align.h $(INCL)/monst.h $(INCL)/mextra.h -PERMONST_H = $(INCL)/monattk.h $(INCL)/monflag.h $(INCL)/align.h \ - $(INCL)/permonst.h -REGION_H = $(INCL)/region.h -RM_H = $(INCL)/align.h $(INCL)/rm.h -SKILLS_H = $(INCL)/skills.h -SP_LEV_H = $(INCL)/align.h $(INCL)/sp_lev.h -YOUPROP_H = $(PERMONST_H) $(MONDATA_H) $(INCL)/prop.h \ - $(INCL)/pm.h $(INCL)/youprop.h -YOU_H = $(MONST_H) $(YOUPROP_H) $(INCL)/align.h \ - $(INCL)/attrib.h $(INCL)/you.h -DISPLAY_H = $(MONDATA_H) $(INCL)/vision.h $(INCL)/display.h -PCCONF_H = $(INCL)/micro.h $(INCL)/system.h $(INCL)/pcconf.h \ - $(MSYS)/pcvideo.h -DECL_H = $(YOU_H) $(INCL)/spell.h $(INCL)/color.h \ - $(INCL)/obj.h $(INCL)/onames.h $(INCL)/pm.h \ - $(INCL)/decl.h -GLOBAL_H = $(PCCONF_H) $(INCL)/coord.h $(INCL)/global.h - -CONFIG_H = $(INCL)/config.h $(INCL)/config1.h $(INCL)/tradstdc.h \ - $(INCL)/global.h $(INCL)/coord.h $(INCL)/vmsconf.h \ - $(INCL)/system.h $(INCL)/nhlua.h $(INCL)/unixconf.h \ - $(INCL)/micro.h $(INCL)/pcconf.h $(INCL)/ntconf.h - -HACK_H = $(INCL)/hack.h $(CONFIG_H) $(INCL)/lint.h $(INCL)/align.h \ - $(INCL)/dungeon.h $(INCL)/monsym.h $(INCL)/mkroom.h \ - $(INCL)/objclass.h $(INCL)/youprop.h $(INCL)/prop.h \ - $(INCL)/permonst.h $(INCL)/monattk.h \ - $(INCL)/monflag.h $(INCL)/mondata.h $(INCL)/pm.h \ - $(INCL)/wintype.h $(INCL)/context.h $(INCL)/rm.h \ - $(INCL)/botl.h $(INCL)/rect.h \ - $(INCL)/region.h $(INCL)/decl.h $(INCL)/quest.h \ - $(INCL)/spell.h $(INCL)/color.h $(INCL)/obj.h \ - $(INCL)/you.h $(INCL)/attrib.h $(INCL)/monst.h \ - $(INCL)/mextra.h $(INCL)/skills.h $(INCL)/onames.h \ - $(INCL)/timeout.h $(INCL)/trap.h $(INCL)/flag.h \ - $(INCL)/vision.h $(INCL)/display.h $(INCL)/engrave.h \ - $(INCL)/winprocs.h $(INCL)/sys.h $(INCL)/wintty.h \ - $(INCL)/trampoli.h - -DLB_H = $(INCL)/dlb.h - -ifeq ($(SUPPRESS_GRAPHICS),Y) -TILE_H = -else -TILE_H = $(WSHR)/tile.h $(INCL)/tileset.h -endif - -ifeq ($(USE_DLB),Y) -DLB = dlb -DLBOBJS = $(HOST_O)dlb_main.o $(HOST_O)dlb.o $(HOST_O)alloc.o $(HOST_O)panic.o -else -DLB = -DLBOBJS = -endif - -#========================================== -# More compiler setup macros -#========================================== -# -CURSESDEF= -CURSESLIB= -INCLDIR=-I../include -I../sys/msdos -# Debugging -#cflags = -pg -c $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DSUPPRESS_GRAPHICS -DCROSSCOMPILE -CROSSCOMPILE_HOST -#LFLAGS = -pg -# -#cflags = -c -O $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DSUPPRESS_GRAPHICS -DCROSSCOMPILE -DCROSSCOMPILE_HOST -#LFLAGS = -# -# Debugging -#cflags = -g -c $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_HOST -#LFLAGS = -g -# -# Normal -cflags = -c -O $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_HOST -LFLAGS = - -#========================================== -#================ RULES ================== -#========================================== - -.SUFFIXES: .o .til .uu .c .y .l - -#========================================== -# Rules for host files in src -#========================================== - -$(HOST_O)%.o : $(SRC)/%.c - $(HOST_CC) $(cflags) -o$@ $< - -#========================================== -# Rules for host files in sys/msdos -#========================================== - -$(HOST_O)%.o : $(MSYS)/%.c - $(HOST_CC) $(cflags) -I../sys/msdos -o$@ $< - -#========================================== -# Rules for host files in util -#========================================== - -$(HOST_O)%.o : $(SRC)/%.c - $(HOST_CC) $(cflags) -o$@ $< - -$(HOST_O)%.o : $(UTIL)/%.c - $(HOST_CC) $(cflags) -o$@ $< - -$(HOST_O)%.o : %.c - $(HOST_CC) $(cflags) -o$@ $< - -#========================================== -# Rules for host files in win/share -#========================================== - -$(HOST_O)%.o : $(WSHR)/%.c - $(HOST_CC) $(cflags) -I../win/share -o$@ $< - -#========================================== -# Primary Targets. -#========================================== - -# The default target. - -all : prereq - -prereq: $(HOST_O)prereq.tag - @echo Done. - -default: prereq - -util: $(HOST_O)utility.tag - -$(HOST_O)utility.tag: $(INCL)/date.h $(INCL)/trap.h $(INCL)/onames.h \ - $(INCL)/pm.h vis_tab.c $(TILEUTIL) $(SRC)/tile.c - echo host utilities made > $@ - -tileutil: $(U)gif2txt $(U)txt2ppm - @echo Optional tile development utilities are up to date. - -$(HOST_O)prereq.tag: $(INCL)/nhlua.h hobj.tag $(U)makedefs \ - $(HOST_O)utility.tag $(DAT)/nhdat - echo prereq done >$@ - -ifeq "$(LUA_VERSION)" "5.3.5" -LUAVER=5.3.5 -else -LUAVER=5.4.0 -endif - -$(INCL)/nhlua.h: - cd $(INCL); \ - echo '/* nhlua.h - generated by Makefile1.cross */' > $@; \ - echo '#include "../lib/lua-$(LUAVER)/src/lua.h"' >> $@; \ - sed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' < $(LIB)/lua-$(LUAVER)/src/lua.h >> $@; \ - echo '#include "../lib/lua-$(LUAVER)/src/lualib.h"' >> $@; \ - echo '#include "../lib/lua-$(LUAVER)/src/lauxlib.h"' >> $@; \ - echo '/*nhlua.h*/' >> $@; \ - cd $(SRC) - -#========================================== -# Other host targets. -#========================================== - -#note that dir below assumes bin/dir from djgpp distribution -# -$(DAT)/nhdat: $(U)dlb_main $(DAT)/data $(DAT)/rumors \ - $(DAT)/oracles \ - $(DAT)/bogusmon $(DAT)/engrave $(DAT)/epitaph $(DAT)/tribute - cd $(DAT); \ - pwd; \ - cp $(MSYS)/msdoshlp.txt .; \ - ls -1 data oracles options rumors help hh >dlb.lst; \ - ls -1 cmdhelp history opthelp wizhelp license >>dlb.lst; \ - ls -1 bogusmon engrave epitaph tribute msdoshlp.txt >>dlb.lst; \ - ls -1 *.lua >>dlb.lst; \ - $(U)dlb_main cvIf dlb.lst nhdat; \ - cd $(SRC) - -$(U)dlb_main: $(DLBOBJS) - $(HOST_LINK) $(LFLAGS) -o$@ $(DLBOBJS) - -$(HOST_O)dlb_main.o: $(U)dlb_main.c $(INCL)/config.h $(DLB_H) - $(HOST_CC) $(cflags) -o$@ $(U)dlb_main.c - - -$(INCL)/date.h : $(U)makedefs - -$(U)makedefs -v - -$(INCL)/onames.h: $(U)makedefs - -$(U)makedefs -o - -$(INCL)/pm.h: $(U)makedefs - -$(U)makedefs -p - -#monstr.c: $(U)makedefs -# -$(U)makedefs -m - -$(INCL)/vis_tab.h: $(U)makedefs - -$(U)makedefs -z - -vis_tab.c: $(U)makedefs - -$(U)makedefs -z - -# make data.base an 8.3 filename to prevent an make warning -DATABASE = $(DAT)/data.bas - -$(DAT)/data: $(HOST_O)utility.tag $(DATABASE) - $(U)makedefs -d - -$(DAT)/rumors: $(HOST_O)utility.tag $(DAT)/rumors.tru $(DAT)/rumors.fal - $(U)makedefs -r - -$(DAT)/oracles: $(HOST_O)utility.tag $(DAT)/oracles.txt - $(U)makedefs -h - -$(DAT)/bogusmon: $(HOST_O)utility.tag $(DAT)/bogusmon.txt - $(U)makedefs -s - -$(DAT)/engrave: $(HOST_O)utility.tag $(DAT)/engrave.txt - $(U)makedefs -s - -$(DAT)/epitaph: $(HOST_O)utility.tag $(DAT)/epitaph.txt - $(U)makedefs -s - -#=============================================== -# Create directory for holding host object files -#=============================================== - -hobj.tag: - mkdir -p ./$(HOBJ) - echo directory ready ./$(HOBJ) - -#========================================== -# Makedefs Stuff -#========================================== - -$(U)makedefs: $(MAKEDEFSOBJS) - $(HOST_LINK) $(LFLAGS) -o$@ $(MAKEDEFSOBJS) - -$(HOST_O)makedefs.o: $(U)makedefs.c $(SRC)/mdlib.c $(CONFIG_H) $(INCL)/permonst.h \ - $(INCL)/objclass.h $(INCL)/monsym.h \ - $(INCL)/artilist.h $(INCL)/dungeon.h $(INCL)/obj.h \ - $(INCL)/monst.h $(INCL)/you.h $(INCL)/flag.h \ - $(INCL)/dlb.h $(INCL)/patchlevel.h - -#============================================= -# Header file moves required for tile support -#============================================= - -ifeq ($(SUPPRESS_GRAPHICS),Y) - -else -# -# Tile Mapping -# - -$(SRC)/tile.c: $(U)tilemap - @$(U)tilemap - @echo A new $@ has been created - -$(U)tilemap: $(HOST_O)tilemap.o - $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)tilemap.o - -$(HOST_O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H) $(TILE_H) - $(HOST_CC) $(cflags) -I$(WSHR) -I$(MSYS) -DSTATUES_LOOK_LIKE_MONSTERS -o$@ $(WSHR)/tilemap.c - - -#========================================== -# Tile Utilities -# Required for tile support -#========================================== - -#$(DAT)/NetHack1.tib: $(TILEFILES) $(U)tile2bin -# @echo Creating binary tile files -# cd $(DAT) -# $(U)tile2bin -# cd $(SRC) - -#$(DAT)/NetHacko.tib: $(HOST_O)thintile.tag $(TILEFILES2) $(U)til2bin2 -# @echo Creating overview binary tile files -# cd $(DAT) -# $(U)til2bin2 -# cd $(SRC) - -$(DAT)/NHTILES.BMP: $(TILEFILES) $(U)tile2bmp - @echo Creating binary tile files which may take some time - @cd $(DAT) - @$(U)tile2bmp $@ - @cd $(SRC) - -$(U)tile2bmp: $(HOST_O)tile2bmp.o $(TEXTIO) - -rm -f temp.a - ar r temp.a $(TEXTIO) - $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)tile2bmp.o temp.a - -#$(U)tile2bin: $(HOST_O)tile2bin.o $(TEXTIO) -# -rm -f temp.a -# ar r temp.a $(TEXTIO) -# $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)tile2bin.o temp.a - -#$(U)til2bin2: $(HOST_O)til2bin2.o $(TEXTIO2) -# -rm -f temp.a -# ar r temp.a $(TEXTIO2) -# $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)til2bin2.o temp.a - -#$(U)thintile: $(HOST_O)thintile.o -# $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)thintile.o - -#$(HOST_O)thintile.o: $(HACK_H) $(WSHR)/tile.h $(WSHR)/thintile.c -# -rm -f temp.a -# ar r temp.a $(TEXTIO) -# $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)tile2bmp.o temp.a - -#$(HOST_O)thintile.o: $(HACK_H) $(WSHR)/tile.h $(WSHR)/thintile.c -# $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -DTILE -DOVERVIEW_FILE -o$@ $(WSHR)/thintile.c - -#$(HOST_O)thintile.tag: $(U)thintile $(TILEFILES) -# $(U)thintile -# echo thintiles created >$@ - -$(HOST_O)tile2bmp.o: $(HACK_H) $(TILE_H) $(WSHR)/tile2bmp.c - $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(WSHR)/tile2bmp.c - -#$(HOST_O)tile2bin.o: $(HACK_H) $(TILE_H) $(MSYS)/pctiles.h $(MSYS)/pcvideo.h $(MSYS)/tile2bin.c -# $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/tile2bin.c - -#$(HOST_O)til2bin2.o: $(HACK_H) $(TILE_H) $(MSYS)/pctiles.h $(MSYS)/pcvideo.h $(MSYS)/tile2bin.c -# $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -DTILE_X=8 -DOVERVIEW_FILE -o$@ $(MSYS)/tile2bin.c - -$(HOST_O)tiletext.o: $(CONFIG_H) $(TILE_H) $(WSHR)/tiletext.c - $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(WSHR)/tiletext.c - -$(HOST_O)tiletex2.o: $(CONFIG_H) $(TILE_H) $(WSHR)/tiletext.c - $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -DTILE_X=8 -o$@ $(WSHR)/tiletext.c - -$(HOST_O)tiletxt.o: $(CONFIG_H) $(TILE_H) $(WSHR)/tilemap.c - $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -DTILETEXT -o$@ $(WSHR)/tilemap.c - -$(HOST_O)tiletxt2.o: $(CONFIG_H) $(TILE_H) $(WSHR)/tilemap.c - $(HOST_CC) $(cflags) -I$(MSYS) -I$(WSHR) -DTILETEXT -DTILE_X=8 -o$@ $(WSHR)/tilemap.c -# -# Optional GIF Utilities (for development) -# - -$(U)gif2txt: $(GIFREADERS) $(TEXTIO) - $(HOST_LINK) $(LFLAGS) -o$@ $(GIFREADERS) $(TEXTIO) - -$(U)gif2txt2: $(GIFREAD2) $(TEXTIO2) - $(HOST_LINK) $(LFLAGS) -o$@ $(GIFREAD2) $(TEXTIO2) - -$(U)txt2ppm: $(PPMWRITERS) $(TEXTIO) - $(HOST_LINK) $(LFLAGS) -o$@ $(PPMWRITERS) $(TEXTIO) - -$(U)txt2ppm2: $(PPMWRIT2) $(TEXTIO2) - $(HOST_LINK) $(LFLAGS) -o$@ $(PPMWRIT2) $(TEXTIO2) - -$(HOST_O)gifread.o: $(CONFIG_H) $(WSHR)/tile.h $(WSHR)/gifread.c - -$(HOST_O)gifread2.o: $(CONFIG_H) $(WSHR)/tile.h $(WSHR)/gifread.c - $(HOST_CC) $(cflags) -DTILE_X=8 -o$@ $(WSHR)/gifread.c - -ppmwrite.c: $(WSHR)/ppmwrite.c - cp $(WSHR)/ppmwrite.c . - -$(HOST_O)ppmwrite.o: $(CONFIG_H) $(WSHR)/tile.h - -$(HOST_O)ppmwrit2.o: $(CONFIG_H) $(WSHR)/tile.h ppmwrite.c - $(HOST_CC) $(cflags) -DTILE_X=8 -o$@ ppmwrite.c - -# -# Optional tile viewer (development sources only) -# - -$(U)viewtib: $(HOST_O)viewtib.o - $(HOST_LINK) $(LFLAGS) -o$@ $(HOST_O)viewtib.o $(LIBRARIES) - -$(HOST_O)viewtib.o: $(MSYS)/viewtib.c - -endif - -#========================================== -# Other host Util Dependencies. -#========================================== - -$(HOST_O)monst.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/monsym.h \ - $(INCL)/color.h monst.c - $(HOST_CC) $(cflags) -o$@ monst.c - -$(HOST_O)objects.o: $(CONFIG_H) $(INCL)/obj.h $(INCL)/objclass.h \ - $(INCL)/prop.h $(INCL)/color.h objects.c - $(HOST_CC) $(cflags) -o$@ objects.c - -$(HOST_O)panic.o: $(CONFIG_H) $(U)panic.c - $(HOST_CC) $(cflags) -o$@ $(U)panic.c - -#========================================== -# Housekeeping for host side. -#========================================== - -clean: - -rm $(HOBJ)/*.o - -rm ./msdos_o/*.o - if [ -f $(HOST_O)prereq.tag ]; then rm $(HOST_O)prereq.tag; fi; - if [ -f hobj.tag ]; then rm hobj.tag; fi; - if [ -f $(HOST_O)utility.tag ]; then rm $(HOST_O)utility.tag; fi; - if [ -f temp.a ]; then rm temp.a; fi; - -spotless: clean - - if [ -f $(INCL)/pm.h ]; then rm $(INCL)/pm.h; fi; -## if [ -f $(U)dgn_flex.c ]; then rm $(U)dgn_flex.c; fi; -## if [ -f $(U)dgn_lex.c ]; then rm $(U)dgn_lex.c; fi; -# if [ -f $(U)makedefs ]; then rm $(U)makedefs; fi; -## if [ -f $(U)dgn_comp ]; then rm $(U)dgn_comp; fi; -# if [ -f $(U)recover.exe ]; then rm $(U)recover.exe; fi; -# if [ -f $(U)tilemap ]; then rm $(U)tilemap; fi; -# if [ -f $(U)tile2bmp ]; then rm $(U)tile2bmp; fi; -## if [ -f $(U)tile2bin ]; then rm $(U)tile2bin; fi; -## if [ -f $(U)til2bin2 ]; then rm $(U)til2bin2; fi; -## if [ -f $(U)thintile ]; then rm $(U)thintile; fi; -# if [ -f $(U)dlb_main ]; then rm $(U)dlb_main; fi; -# if [ -f $(INCL)/vis_tab.h ]; then rm $(INCL)/vis_tab.h; fi; -# if [ -f $(INCL)/onames.h ]; then rm $(INCL)/onames.h; fi; -# if [ -f $(INCL)/pm.h ]; then rm $(INCL)/pm.h; fi; -# if [ -f $(INCL)/date.h ]; then rm $(INCL)/date.h; fi; -## if [ -f $(INCL)/dgn_comp.h ]; then rm $(INCL)/dgn_comp.h; fi; -## if [ -f $(INCL)/lev_comp.h ]; then rm $(INCL)/lev_comp.h; fi; -# if [ -f $(SRC)/vis_tab.c ]; then rm $(SRC)/vis_tab.c; fi; -# if [ -f $(SRC)/tile.c ]; then rm $(SRC)/tile.c; fi; -# if [ -f $(DAT)/options ]; then rm $(DAT)/options; fi; -# if [ -f $(DAT)/data ]; then rm $(DAT)/data; fi; -# if [ -f $(DAT)/rumors ]; then rm $(DAT)/rumors; fi; -## if [ -f $(DAT)/dungeon.pdf ]; then rm $(DAT)/dungeon.pdf; fi; -## if [ -f $(DAT)/dungeon ]; then rm $(DAT)/dungeon; fi; -# if [ -f $(DAT)/oracles ]; then rm $(DAT)/oracles; fi; -## if [ -f $(DAT)/quest.dat ]; then rm $(DAT)/quest.dat; fi; -# if [ -f $(DAT)/bogusmon ]; then rm $(DAT)/bogusmon; fi; -# if [ -f $(DAT)/engrave ]; then rm $(DAT)/engrave; fi; -# if [ -f $(DAT)/epitaph ]; then rm $(DAT)/epitaph; fi; -# if [ -f $(DAT)/dlb.lst ]; then rm $(DAT)/dlb.lst; fi; -# if [ -f $(DAT)/nhdat ]; then rm $(DAT)/nhdat; fi; -# if [ -f $(DAT)/*.lev ]; then rm $(DAT)/*.lev; fi; -# if [ -f $(TILE_BMP) ]; then rm $(TILE_BMP); fi; -# if [ -f $(WSHR)/monthin.txt ]; then rm $(WSHR)/monthin.txt; fi; -# if [ -f $(WSHR)/objthin.txt ]; then rm $(WSHR)/objthin.txt; fi; -# if [ -f $(WSHR)/oththin.txt ]; then rm $(WSHR)/oththin.txt; fi; - -#========================================== -# Host Utility Dependencies -#========================================== - -# src dependencies - -$(HOST_O)drawing.o: $(CONFIG_H) $(INCL)/color.h $(INCL)/rm.h \ - $(INCL)/objclass.h $(INCL)/monsym.h -$(HOST_O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h -$(HOST_O)alloc.o: alloc.c $(CONFIG_H) -$(HOST_O)dlb.o: dlb.c $(CONFIG_H) $(INCL)/dlb.h - $(HOST_CC) $(cflags) -I../sys/msdos -o$@ dlb.c -$(HOST_O)monst.o: monst.c $(CONFIG_H) $(INCL)/permonst.h $(INCL)/align.h \ - $(INCL)/monattk.h $(INCL)/monflag.h $(INCL)/monsym.h \ - $(INCL)/color.h -$(HOST_O)objects.o: objects.c $(CONFIG_H) $(INCL)/obj.h $(INCL)/objclass.h \ - $(INCL)/prop.h $(INCL)/skills.h $(INCL)/color.h -$(HOST_O)tileset.o: $(WSHR)/tileset.c $(HACK_H) -$(HOST_O)bmptiles.o: $(WSHR)/bmptiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h -$(HOST_O)giftiles.o: $(WSHR)/giftiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h - -# end of file - diff --git a/sys/msdos/Makefile2.cross b/sys/msdos/Makefile2.cross deleted file mode 100644 index 76c33e890..000000000 --- a/sys/msdos/Makefile2.cross +++ /dev/null @@ -1,1091 +0,0 @@ -# NetHack 3.7 Makefile2.cross -# Cross-compile msdos version of NetHack using a -# linux-hosted djgpp cross-compiler. -# -# Makefile1.cross is for the host-side obj files and utilities that -# will run on the host platform only. -# -# Makefile2.cross (this file) is for the target platform obj files -# and utilities. -# -# Makefile2 utilizes the djgpp cross-compiler from Andrew Wu: -# https://github.com/andrewwutw/build-djgpp -# -# Currently, in NetHack 3.7, it is now feasible to cross-compile -# the game in a 2-stage process. Makefile2.cross (this file) carries -# out the 2nd stage. -# -# A proof-of-concept to cross-compile NetHack 3.7 was achieved on -# November 22, 2019 using the msdos set of Makefiles. -# -# - -# Game Installation Variables -# NOTE: Make sure GAMEDIR exists before make is started. - -GAME = NETHACK -# The GNU Make has a problem if you include a drive spec below (unfortunately). -GAMEDIR =../msdos-binary - -# Optional PDCurses support -# Uncomment these and set them appropriately if you want to -# include curses port support alongside TTY support in your -# NetHack.exe binary. -# -# You'll have to set PDCURSES_H to the correct location of the -# PDCurses header (.h) files and PDCURSES_C to the location -# of your PDCurses C files which must already be resident on -# your machine. -# -ADD_CURSES=Y -PDCURSES_TOP=../lib/pdcurses - -# Set top of djgpp if not specified through ENV variables prior to make: -#DJGPP_TOP = $(HOME)/lib/djgpp - -#--------------------------------------------------------------- -ifeq "$(LUA_VERSION)" "5.3.5" -LUAVER=5.3.5 -else -LUAVER=5.4.0 -endif -#--------------------------------------------------------------- -# Location of LUA -# -# Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.0.tar.gz -# -# 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. -# -ADD_LUA=Y -LUATOP=../lib/lua-$(LUAVER) -# -# -#============================================================================== -# This marks the end of the BUILD DECISIONS section. -#============================================================================== -# -# Directories, gcc likes unix style directory specs -# - -TARGET = msdos -OBJ = $(TARGET)_o -HOBJ = host_o -DAT = ../dat -DOC = ../doc -INCL = ../include -LIB = ../lib -MSYS = ../sys/msdos -SRC = ../src -SSHR = ../sys/share -UTIL = ../util -WIN = ../win/tty -WCURSES = ../win/curses -WSHR = ../win/share - -# -# Executables. -ifndef DJGPP_TOP -ifdef TRAVIS_BUILD_DIR -DJGPP_TOP = TRAVIS_BUILD_DIR/lib/djgpp -else -DJGPP_TOP = $(HOME)/lib/djgpp -endif -endif - -TARGET_CC = $(DJGPP_TOP)/i586-pc-msdosdjgpp/bin/gcc -TARGET_LINK = $(DJGPP_TOP)/i586-pc-msdosdjgpp/bin/gcc -TARGET_STUBEDIT = $(DJGPP_TOP)/i586-pc-msdosdjgpp/bin/stubedit -TARGET_AR = $(DJGPP_TOP)/i586-pc-msdosdjgpp/bin/ar -MAKEBIN = make - -# -# Special libraries and how to link them in. - -LIBS = -lpc - -# If TERMLIB is defined in pcconf.h, comment out the upper line and -# uncomment the lower. Note that you must build the termc library -# and place it in djgpp's lib directory. See termcap.zip for details - -TERMLIB = -#TERMLIB = -ltermc - -LIBRARIES = $(LIBS) $(TERMLIB) - -# -# Yacc/Lex ... if you got 'em. -# -# If you have yacc/lex or a work-alike set YACC_LEX to Y -# -YACC_LEX = N - -ifeq "$(YACC_LEX)" "Y" -DO_YACC = YACC_ACT -DO_LEX = LEX_ACT -endif - -# If YACC_LEX is Y above, set the following to values appropriate for -# your tools. -# -YACC = bison -y -LEX = lex -# -# If your flex and bison port mess with the output names directly -# you must set the file names to the appropriate output file names -# here -#YTABC = y_tab.c -#YTABH = y_tab.h -#LEXYYC = lexyy.c -# -# If your flex and bison are able to produce files named -# y.tab.c, y.tab.h or lex.yy.c you might have to set these -# to the short file name equivalent (DIR /X to reveal them): -YTABC = ytab~1.c -YTABH = ytab~1.h -LEXYYC = lexyy~1.c - -# -# Uncomment the line below if you want to store all the level files, -# help files, etc. in a single library file. - -USE_DLB = Y - -# djgpp includes ls.exe and touch.exe in fil41b.zip from the v2gnu -# folder so be sure to include that when downloading djgpp. Doing -# so will make changing this unnecessary. - -LS = ls -1 # ls.exe from djgpp distribution -#LS = dir /l/b # DOS command - -# To build a binary without any graphics -# suitable for blind players, -# set SUPPRESS_GRAPHICS to Y -# (Note: binary will require ANSI.SYS driver or equivalent loaded) -# SUPPRESS_GRAPHICS = Y -SUPPRESS_GRAPHICS = - -# ZLIB Support -# To support zlib compression in bones and save files, you must -# define ZLIB_COMP in include/config.h. -# You must also have a zlib library to link NetHack with, and -# for the djgpp build, you need one compatible with djgpp. -# At the time that this was written (post-NetHack 3.4.3) the -# following URL was a valid place to get a pre-built djgpp library -# to add to your djgpp tools directory tree. -# http://www.delorie.com/pub/djgpp/current/v2tk/zlib114b.zip -# -# If you defined ZLIB_COMP in include/config.h to build in support -# for ZLIB compression, you need to uncomment the line below. -#ZLIB= -lz - -#=============================================== -#======= End of Modification Section =========== -#=============================================== -################################################ -# # -# Nothing below here should have to be changed.# -# # -################################################ - -GAMEFILE = $(GAMEDIR)/$(GAME).EXE - -# Changing this conditional block is not recommended -ifeq "$(USE_DLB)" "Y" -DLBFLG = -DDLB -else -DLBFLG = -endif - -TERMLIB = -# Build NetHack suitable for blind players - -#========================================== -#================ MACROS ================== -#========================================== -# This section creates shorthand macros for many objects -# referenced later on in the Makefile. -# -# Have windows path styles available for use in commands -# -W_OBJ =$(subst /,\, $(OBJ)) -W_INCL =$(subst /,\, $(INCL)) -W_DAT =$(subst /,\, $(DAT)) -W_DOC =$(subst /,\, $(DOC)) -W_UTIL =$(subst /,\, $(UTIL)) -W_SRC =$(subst /,\, $(SRC)) -W_SSYS =$(subst /,\, $(SSYS)) -W_MSWSYS =$(subst /,\, $(MSWSYS)) -W_TTY =$(subst /,\, $(TTY)) -W_MSWIN =$(subst /,\, $(MSWIN)) -ifeq "$(ADD_CURSES)" "Y" -W_WCURSES =$(subst /,\, $(WCURSES)) -endif -W_WSHR =$(subst /,\, $(WSHR)) -W_GAMEDIR =$(subst /,\, $(GAMEDIR)) - -# -# Shorten up the location for some files -# - -O = $(OBJ)/ -HOST_O = $(HOBJ)/ -U = $(UTIL)/ - -#========================================== -# Tile related object files. -#========================================== - -PLANAR_TIB = $(DAT)/NETHACK1.tib -OVERVIEW_TIB = $(DAT)/NETHACKO.tib -TILE_BMP = $(DAT)/NHTILES.BMP - -##REGEX = $(O)pmatchregex.o -##REGEX = $(O)cppregex.o -REGEX = $(O)posixreg.o -DLBOBJ = $(O)dlb.o -VIDEO_OBJ = $(O)vidvga.o $(O)vidvesa.o $(O)tile.o $(O)tileset.o $(O)bmptiles.o $(O)giftiles.o -RECOVOBJS = $(O)recover.o - -# Object files for the game itself. - -VOBJ01 = $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o -VOBJ02 = $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o -VOBJ03 = $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o -VOBJ04 = $(O)display.o $(O)dlb.o $(O)dig.o $(O)do.o -VOBJ05 = $(O)do_name.o $(O)do_wear.o $(O)dog.o $(O)dogmove.o -VOBJ06 = $(O)dokick.o $(O)dothrow.o $(O)drawing.o $(O)dungeon.o -VOBJ07 = $(O)eat.o $(O)end.o $(O)engrave.o $(O)exper.o -VOBJ08 = $(O)explode.o $(O)extralev.o $(O)files.o $(O)fountain.o -VOBJ09 = $(O)getline.o $(O)hack.o $(O)hacklib.o $(O)insight.o -VOBJ10 = $(O)invent.o $(O)isaac64.o $(O)light.o $(O)lock.o -VOBJ11 = $(O)mail.o $(O)main.o $(O)makemon.o $(O)mapglyph.o -VOBJ12 = $(O)mcastu.o $(O)mhitm.o $(O)mhitu.o $(O)minion.o -VOBJ13 = $(O)mkmap.o $(O)mklev.o $(O)mkmaze.o $(O)mkobj.o -VOBJ14 = $(O)mkroom.o $(O)mon.o $(O)mondata.o $(O)monmove.o -VOBJ15 = $(O)monst.o $(O)mplayer.o $(O)mthrowu.o $(O)muse.o -VOBJ16 = $(O)music.o $(O)o_init.o $(O)objects.o $(O)objnam.o -VOBJ17 = $(O)options.o $(O)pickup.o $(O)pline.o $(O)polyself.o -VOBJ18 = $(O)potion.o $(O)quest.o $(O)questpgr.o $(O)pager.o -VOBJ19 = $(O)pray.o $(O)priest.o $(O)read.o $(O)rect.o -VOBJ20 = $(O)region.o $(O)restore.o $(O)rip.o $(O)rnd.o -VOBJ21 = $(O)role.o $(O)rumors.o $(O)save.o $(O)sfstruct.o -VOBJ22 = $(O)shk.o $(O)shknam.o $(O)sit.o $(O)sounds.o -VOBJ23 = $(O)sp_lev.o $(O)spell.o $(O)steal.o $(O)steed.o -VOBJ24 = $(O)symbols.o $(O)sys.o $(O)teleport.o $(O)termcap.o -VOBJ25 = $(O)timeout.o $(O)topl.o $(O)topten.o $(O)track.o -VOBJ26 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)vault.o -VOBJ27 = $(O)vision.o $(O)vis_tab.o $(O)weapon.o $(O)were.o -VOBJ28 = $(O)wield.o $(O)windows.o $(O)wintty.o $(O)wizard.o -VOBJ29 = $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o -VOBJ30 = $(REGEX) $(VIDEO_OBJ) - -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 - -MDLIB = $(O)mdlib.o - -ifeq "$(ADD_LUA)" "Y" -LUAOBJ = $(O)nhlua.o $(O)nhlsel.o $(O)nhlobj.o -endif - -ifeq "$(ADD_CURSES)" "Y" -CURSESOBJ= $(O)cursdial.o $(O)cursinit.o $(O)cursinvt.o $(O)cursmain.o \ - $(O)cursmesg.o $(O)cursmisc.o $(O)cursstat.o $(O)curswins.o -else -CURSESOBJ= -endif - -VOBJ = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \ - $(VOBJ06) $(VOBJ07) $(VOBJ08) $(VOBJ09) $(VOBJ10) \ - $(VOBJ11) $(VOBJ12) $(VOBJ13) $(VOBJ14) $(VOBJ15) \ - $(VOBJ16) $(VOBJ17) $(VOBJ18) $(VOBJ19) $(VOBJ20) \ - $(VOBJ21) $(VOBJ22) $(VOBJ23) $(VOBJ24) $(VOBJ25) \ - $(VOBJ26) $(VOBJ27) $(VOBJ28) $(VOBJ29) $(VOBJ30) \ - $(LUAOBJ) $(CURSESOBJ) $(MDLIB) - -ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ) - -ifeq "$(ADD_LUA)" "Y" -#===============-================================================= -# LUA library -# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz -#================================================================= - -LUASRC = $(LUATOP)/src -LUALIB = $(O)lua$(subst .,, $(LUAVER))s.a -#LUADLL = $(O)lua$(subst .,, $(LUAVER)).a -LUAINCL = -I$(LUASRC) -#LUAFLAGS = unix added -lm here? -LUATARGETS = lua.exe luac.exe $(LUALIB) -#LUATARGETS = $(LUADLL) $(LUALIB) - -LUASRCFILES = lapi.c lauxlib.c lbaselib.c lcode.c \ - lcorolib.c lctype.c ldblib.c ldebug.c ldo.c \ - ldump.c lfunc.c lgc.c linit.c liolib.c llex.c \ - lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c \ - loslib.c lparser.c lstate.c lstring.c lstrlib.c \ - ltable.c ltablib.c ltm.c lundump.c lutf8lib.c \ - lvm.c lzio.c - -LUAOBJFILES1 = $(O)lapi.o $(O)lauxlib.o $(O)lbaselib.o \ - $(O)lcode.o $(O)lcorolib.o $(O)lctype.o $(O)ldblib.o -LUAOBJFILES2 = $(O)ldebug.o $(O)ldo.o $(O)ldump.o $(O)lfunc.o \ - $(O)lgc.o $(O)linit.o $(O)liolib.o $(O)llex.o -LUAOBJFILES3 = $(O)lmathlib.o $(O)lmem.o $(O)loadlib.o $(O)lobject.o \ - $(O)lopcodes.o $(O)loslib.o $(O)lparser.o $(O)lstate.o -LUAOBJFILES4 = $(O)lstring.o $(O)lstrlib.o $(O)ltable.o $(O)ltablib.o \ - $(O)ltm.o $(O)lundump.o $(O)lutf8lib.o $(O)lvm.o $(O)lzio.o - -#LUAOBJFILES = $(O)lapi.o $(O)lauxlib.o $(O)lbaselib.o \ -# $(O)lcode.o $(O)lcorolib.o $(O)lctype.o $(O)ldblib.o \ -# $(O)ldebug.o $(O)ldo.o $(O)ldump.o $(O)lfunc.o \ -# $(O)lgc.o $(O)linit.o $(O)liolib.o $(O)llex.o \ -# $(O)lmathlib.o $(O)lmem.o $(O)loadlib.o $(O)lobject.o \ -# $(O)lopcodes.o $(O)loslib.o $(O)lparser.o $(O)lstate.o \ -# $(O)lstring.o $(O)lstrlib.o $(O)ltable.o $(O)ltablib.o \ -# $(O)ltm.o $(O)lundump.o $(O)lutf8lib.o $(O)lvm.o $(O)lzio.o - -ifeq "$(LUAVER)" "5.3.5" -LUASRCFILES = $(LUASRCFILES) lbitlib.c -LUAOBJFILES1 = $(LUAOBJFILES1) $(O)lbitlib.o -endif -LUALIBOBJS = $(LUAOBJFILES1) $(LUAOBJFILES2) $(LUAOBJFILES3) $(LUAOBJFILES4) - -endif -ifeq "$(ADD_CURSES)" "Y" -#========================================== -# PDCurses build macros -#========================================== -PDCURSES_CURSES_H = $(PDCURSES_TOP)/curses.h -PDCURSES_CURSPRIV_H = $(PDCURSES_TOP)/curspriv.h -PDCURSES_HEADERS = $(PDCURSES_CURSES_H) $(PDCURSES_CURSPRIV_H) -PDCSRC = $(PDCURSES_TOP)/pdcurses -PDCDOS = $(PDCURSES_TOP)/dos -PDCLIBOBJS1 = $(O)addch.o $(O)addchstr.o $(O)addstr.o $(O)attr.o $(O)beep.o \ - $(O)bkgd.o $(O)border.o $(O)clear.o $(O)color.o $(O)delch.o $(O)deleteln.o \ - $(O)getch.o -PDCLIBOBJS2 = $(O)getstr.o $(O)getyx.o $(O)inch.o $(O)inchstr.o $(O)initscr.o \ - $(O)inopts.o $(O)insch.o $(O)insstr.o $(O)instr.o $(O)kernel.o \ - $(O)keyname.o $(O)mouse.o -PDCLIBOBJS3 = $(O)move.o $(O)outopts.o $(O)overlay.o $(O)pad.o $(O)panel.o \ - $(O)printw.o $(O)refresh.o $(O)scanw.o $(O)scr_dump.o $(O)scroll.o \ - $(O)slk.o $(O)termattr.o -PDCLIBOBJS4 = $(O)touch.o $(O)util.o $(O)window.o $(O)debug.o -PDCLIBOBJS = $(PDCLIBOBJS1) $(PDCLIBOBJS2) $(PDCLIBOBJS3) $(PDCLIBOBJS4) - -PDCOBJS = $(O)pdcclip.o $(O)pdcdisp.o $(O)pdcgetsc.o $(O)pdckbd.o \ - $(O)pdcscrn.o $(O)pdcsetsc.o $(O)pdcutil.o - -#PDCOBJS = $(O)pdcclip.o $(O)pdcdisp.o $(O)pdcgetsc.o $(O)pdckbd.o $(O)pdcscrn.o \ -# $(O)pdcsetsc.o $(O)pdcutil.o - -PDCLIB = $(O)pdcurses.a - -#PDCINCL = -I$(PDCURSES_TOP) -I$(PDCSRC) -I$(PDCDOS) -PDCINCL = -I$(PDCURSES_TOP) -I$(PDCDOS) -else -PDCLIB = -endif - -#========================================== -# Header file macros -#========================================== - -PATCHLEV_H = $(INCL)/patchlev.h -DGN_FILE_H = $(INCL)/align.h $(INCL)/dgn_file.h -DUNGEON_H = $(INCL)/align.h $(INCL)/dungeon.h -MONDATA_H = $(INCL)/align.h $(INCL)/mondata.h -MONST_H = $(INCL)/align.h $(INCL)/monst.h $(INCL)/mextra.h -PERMONST_H = $(INCL)/monattk.h $(INCL)/monflag.h $(INCL)/align.h \ - $(INCL)/permonst.h -REGION_H = $(INCL)/region.h -RM_H = $(INCL)/align.h $(INCL)/rm.h -SKILLS_H = $(INCL)/skills.h -SP_LEV_H = $(INCL)/align.h $(INCL)/sp_lev.h -YOUPROP_H = $(PERMONST_H) $(MONDATA_H) $(INCL)/prop.h \ - $(INCL)/pm.h $(INCL)/youprop.h -YOU_H = $(MONST_H) $(YOUPROP_H) $(INCL)/align.h \ - $(INCL)/attrib.h $(INCL)/you.h -DISPLAY_H = $(MONDATA_H) $(INCL)/vision.h $(INCL)/display.h -PCCONF_H = $(INCL)/micro.h $(INCL)/system.h $(INCL)/pcconf.h \ - $(MSYS)/pcvideo.h -DECL_H = $(YOU_H) $(INCL)/spell.h $(INCL)/color.h \ - $(INCL)/obj.h $(INCL)/onames.h $(INCL)/pm.h \ - $(INCL)/decl.h -GLOBAL_H = $(PCCONF_H) $(INCL)/coord.h $(INCL)/global.h - -CONFIG_H = $(INCL)/config.h $(INCL)/config1.h $(INCL)/tradstdc.h \ - $(INCL)/global.h $(INCL)/coord.h $(INCL)/vmsconf.h \ - $(INCL)/system.h $(INCL)/nhlua.h $(INCL)/unixconf.h \ - $(INCL)/micro.h $(INCL)/pcconf.h $(INCL)/ntconf.h - -HACK_H = $(INCL)/hack.h $(CONFIG_H) $(INCL)/lint.h $(INCL)/align.h \ - $(INCL)/dungeon.h $(INCL)/monsym.h $(INCL)/mkroom.h \ - $(INCL)/objclass.h $(INCL)/youprop.h $(INCL)/prop.h \ - $(INCL)/permonst.h $(INCL)/monattk.h \ - $(INCL)/monflag.h $(INCL)/mondata.h $(INCL)/pm.h \ - $(INCL)/wintype.h $(INCL)/context.h $(INCL)/rm.h \ - $(INCL)/botl.h $(INCL)/rect.h \ - $(INCL)/region.h $(INCL)/decl.h $(INCL)/quest.h \ - $(INCL)/spell.h $(INCL)/color.h $(INCL)/obj.h \ - $(INCL)/you.h $(INCL)/attrib.h $(INCL)/monst.h \ - $(INCL)/mextra.h $(INCL)/skills.h $(INCL)/onames.h \ - $(INCL)/timeout.h $(INCL)/trap.h $(INCL)/flag.h \ - $(INCL)/vision.h $(INCL)/display.h $(INCL)/engrave.h \ - $(INCL)/winprocs.h $(INCL)/sys.h $(INCL)/wintty.h \ - $(INCL)/trampoli.h - -DLB_H = $(INCL)/dlb.h - -ifeq ($(SUPPRESS_GRAPHICS),Y) -TILE_H = -else -TILE_H = $(WSHR)/tile.h $(INCL)/tileset.h -endif - -ifeq ($(USE_DLB),Y) -DLB = dlb -DLBOBJS = $(O)dlb_main.o $(O)dlb.o $(O)alloc.o $(O)panic.o -else -DLB = -DLBOBJS = -endif - -#========================================== -# More compiler setup macros -#========================================== -# -ifeq "$(ADD_CURSES)" "Y" -CURSESDEF=-D"CURSES_GRAPHICS" -D"CURSES_BRIEF_INCLUDE" -else -CURSESDEF= -CURSESLIB= -endif - -INCLDIR=-I../include -I../sys/msdos $(LUAINCL) - -# Debugging -#cflags = -pg -c $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DSUPPRESS_GRAPHICS -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -#LFLAGS = -pg - -#cflags = -c -O $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DSUPPRESS_GRAPHICS -DCROSSCOMPILE-DCROSSCOMPILE_TARGET -#LFLAGS = - -# Debugging -#cflags = -g -c $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -#LFLAGS = -g - -# Normal -cflags = -c -O $(INCLDIR) $(DLBFLG) $(CURSESDEF) -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -LFLAGS = - -#========================================== -#================ RULES ================== -#========================================== - -.SUFFIXES: .o .til .uu .c .y .l - -#========================================== -# Rules for files in src -#========================================== - -$(OBJ)/%.o : %.c - $(TARGET_CC) $(cflags) -o$@ $< - -$(OBJ)/%.o : $(SRC)/%.c - $(TARGET_CC) $(cflags) -o$@ $< - -#========================================== -# Rules for files in sys/share -#========================================== - -$(OBJ)/%.o : $(SSHR)/%.c - $(TARGET_CC) $(cflags) -o$@ $< - -#========================================== -# Rules for files in sys/msdos -#========================================== - -$(OBJ)/%.o : $(MSYS)/%.c - $(TARGET_CC) $(cflags) -I../sys/msdos -o$@ $< - -#========================================== -# Rules for files in util -#========================================== - -$(OBJ)/%.o : $(UTIL)/%.c - $(TARGET_CC) $(cflags) -o$@ $< - -#========================================== -# Rules for files in win/share -#========================================== - -$(OBJ)/%.o : $(WSHR)/%.c - $(TARGET_CC) $(cflags) -I../win/share -o$@ $< - -#========================================== -# Rules for files in win/tty -#========================================== - -$(OBJ)/%.o : $(TTY)/%.c - $(TARGET_CC) $(cflags) -o$@ $< - -#========================================== -# Rules for files in win/curses -#========================================== - -$(OBJ)/%.o : $(WCURSES)/%.c - $(TARGET_CC) -DPDC_NCMOUSE $(PDCINCL) $(cflags) -o$@ $< - -#========================================== -# Rules for files in PDCurses -#========================================== - -$(OBJ)/%.o : $(PDCURSES_TOP)/%.c - $(TARGET_CC) $(PDCINCL) $(cflags) -o$@ $< - -$(OBJ)/%.o : $(PDCSRC)/%.c - $(TARGET_CC) $(PDCINCL) $(cflags) -o$@ $< - -$(OBJ)/%.o : $(PDCDOS)/%.c - $(TARGET_CC) $(PDCINCL) $(cflags) -o$@ $< - -ifeq "$(ADD_LUA)" "Y" -#========================================== -# Rules for LUA files -#========================================== - -$(OBJ)/%.o : $(LUASRC)/%.c - $(TARGET_CC) $(cflags) -o$@ $< -endif - -#========================================== -# Primary Targets. -#========================================== - -# The default target. - -all : install - -install: $(GAMEFILE) $(O)install.tag - @echo Done. - -default: $(GAMEFILE) - -tileutil: $(U)gif2txt $(U)txt2ppm - @echo Optional tile development utilities are up to date. - -recover.exe: $(U)recover -# @$(subst /,\,if exist $(U)recover copy $(U)recover $(GAMEDIR)) -# @$(subst /,\,if exist $(DOC)/recover.txt copy $(DOC)/recover.txt $(GAMEDIR)) - -$(O)install.tag: $(DAT)/nhdat $(GAMEFILE) -ifeq ($(USE_DLB),Y) - cp $(DAT)/nhdat $(GAMEDIR)/NHDAT - cp $(DAT)/license $(GAMEDIR)/LICENSE -else - cp $(DAT)/*. $(GAMEDIR) - cp $(DAT)/*.dat $(GAMEDIR) - cp $(MSYS)/msdoshlp.txt $(GAMEDIR)) -ifeq "$(ADD_LUA)" "Y" - cp $(DAT)/*.lua $(GAMEDIR) -endif -endif -ifdef TERMLIB - cp $(SSHR)/termcap $(GAMEDIR)/TERMCAP) -endif -# if [ -f $(TILE_BMP) ]; then rm $(TILE_BMP); fi; - if [ -f $(TILE_BMP) ]; then cp $(TILE_BMP) $(GAMEDIR)/NHTILES.BMP; fi; - if [ -f $(DAT)/symbols ]; then cp $(DAT)/symbols $(GAMEDIR)/SYMBOLS; fi; - if [ -f $(SSHR)/NetHack.cnf ]; then cp $(SSHR)/NetHack.cnf $(GAMEDIR)/NETHACK.CNF; fi; - -touch $(GAMEDIR)/RECORD - if [ -f ../sys/msdos/sysconf ]; then cp ../sys/msdos/sysconf $(GAMEDIR)/SYSCONF; fi; - if [ -f $(DOC)/nethack.txt ]; then cp $(DOC)/nethack.txt $(GAMEDIR)/NETHACK.TXT; fi; - @echo install done > $@ - -#========================================== -# The main target. -#========================================== - -$(GAMEFILE): $(O)obj.tag $(PDCLIB) $(LUALIB) \ - $(ALLOBJ) $(O)$(GAME).lnk - if [ -f temp.a ]; then rm temp.a; fi; - @$(TARGET_AR) r temp.a $(VOBJ01) - @$(TARGET_AR) r temp.a $(VOBJ02) - @$(TARGET_AR) r temp.a $(VOBJ03) - @$(TARGET_AR) r temp.a $(VOBJ04) - @$(TARGET_AR) r temp.a $(VOBJ05) - @$(TARGET_AR) r temp.a $(VOBJ06) - @$(TARGET_AR) r temp.a $(VOBJ07) - @$(TARGET_AR) r temp.a $(VOBJ08) - @$(TARGET_AR) r temp.a $(VOBJ09) - @$(TARGET_AR) r temp.a $(VOBJ10) - @$(TARGET_AR) r temp.a $(VOBJ11) - @$(TARGET_AR) r temp.a $(VOBJ12) - @$(TARGET_AR) r temp.a $(VOBJ13) - @$(TARGET_AR) r temp.a $(VOBJ14) - @$(TARGET_AR) r temp.a $(VOBJ15) - @$(TARGET_AR) r temp.a $(VOBJ16) - @$(TARGET_AR) r temp.a $(VOBJ17) - @$(TARGET_AR) r temp.a $(VOBJ18) - @$(TARGET_AR) r temp.a $(VOBJ19) - @$(TARGET_AR) r temp.a $(VOBJ20) - @$(TARGET_AR) r temp.a $(VOBJ21) - @$(TARGET_AR) r temp.a $(VOBJ22) - @$(TARGET_AR) r temp.a $(VOBJ23) - @$(TARGET_AR) r temp.a $(VOBJ24) - @$(TARGET_AR) r temp.a $(VOBJ25) - @$(TARGET_AR) r temp.a $(VOBJ26) - @$(TARGET_AR) r temp.a $(VOBJ27) - @$(TARGET_AR) r temp.a $(VOBJ28) - @$(TARGET_AR) r temp.a $(VOBJ29) - @$(TARGET_AR) r temp.a $(VOBJ30) - @$(TARGET_AR) r temp.a $(VIDEO_OBJ) - @$(TARGET_AR) r temp.a $(SOBJ) - @$(TARGET_AR) r temp.a $(TILOBJ) - @$(TARGET_AR) r temp.a $(TILOBJ2) -ifeq "$(ADD_LUA)" "Y" - @$(TARGET_AR) r temp.a $(LUAOBJ) -endif - @$(TARGET_AR) r temp.a $(VVOBJ) -ifeq "$(ADD_CURSES)" "Y" - @$(TARGET_AR) r temp.a $(CURSESOBJ) -endif - @$(TARGET_AR) r temp.a $(MDLIB) - $(TARGET_LINK) $(LFLAGS) -o$(GAME).exe temp.a $(PDCLIB) $(LUALIB) $(LIBRARIES) $(ZLIB) - $(TARGET_STUBEDIT) $(GAME).exe minstack=2048K - cp $(GAME).exe $(GAMEFILE) - rm $(GAME).exe - -$(O)$(GAME).lnk: $(ALLOBJ) - echo $(VOBJ01) > $@ - echo $(VOBJ02) >> $@ - echo $(VOBJ03) >> $@ - echo $(VOBJ04) >> $@ - echo $(VOBJ05) >> $@ - echo $(VOBJ06) >> $@ - echo $(VOBJ07) >> $@ - echo $(VOBJ08) >> $@ - echo $(VOBJ09) >> $@ - echo $(VOBJ10) >> $@ - echo $(VOBJ11) >> $@ - echo $(VOBJ12) >> $@ - echo $(VOBJ13) >> $@ - echo $(VOBJ14) >> $@ - echo $(VOBJ15) >> $@ - echo $(VOBJ16) >> $@ - echo $(VOBJ17) >> $@ - echo $(VOBJ18) >> $@ - echo $(VOBJ19) >> $@ - echo $(VOBJ20) >> $@ - echo $(VOBJ21) >> $@ - echo $(VOBJ22) >> $@ - echo $(VOBJ23) >> $@ - echo $(VOBJ24) >> $@ - echo $(VOBJ25) >> $@ - echo $(VOBJ26) >> $@ - echo $(VOBJ27) >> $@ - echo $(VOBJ28) >> $@ - echo $(VOBJ29) >> $@ - echo $(VOBJ30) >> $@ - echo $(SOBJ) >> $@ - echo $(TILOBJ) >> $@ - echo $(TILOBJ2) >> $@ -ifeq "$(ADD_LUA)" "Y" - echo $(LUAOBJ) >> $@ -endif - echo $(VVOBJ) >> $@ -ifeq "$(ADD_CURSES)" "Y" - echo $(CURSESOBJ) >> $@ -endif - -#========================================== -#=========== SECONDARY TARGETS ============ -#========================================== -# -#========================================== -# Recover Utility -#========================================== - -$(U)recover.exe: $(RECOVOBJS) - $(TARGET_LINK) $(LFLAGS) -o$@ $(O)recover.o - -$(O)recover.o: $(CONFIG_H) $(U)recover.c - $(TARGET_CC) $(cflags) -o$@ $(U)recover.c - -#========================================== -# Header file moves required for tile support -#========================================== - -ifeq ($(SUPPRESS_GRAPHICS),Y) - -else -# -# Tile Mapping -# - -#$(SRC)/tile.c: $(U)tilemap -# @$(U)tilemap -# @echo A new $@ has been created - -endif - -#========================================== -# PDCurses Library -#========================================== - -$(O)pdcurses.a : $(PDCLIBOBJS) $(PDCOBJS) - if [ -f $@ ]; then rm $@; fi; - $(TARGET_AR) rcS $@ $(PDCLIBOBJS1) - $(TARGET_AR) rcS $@ $(PDCLIBOBJS2) - $(TARGET_AR) rcS $@ $(PDCLIBOBJS3) - $(TARGET_AR) rcS $@ $(PDCLIBOBJS4) - $(TARGET_AR) rcs $@ $(PDCOBJS) - -#========================================== -# Other Util Dependencies. -#========================================== - -$(O)alloc.o: $(CONFIG_H) alloc.c - $(TARGET_CC) $(cflags) -o$@ alloc.c - -$(O)drawing.o: drawing.c $(CONFIG_H) $(INCL)/color.h $(INCL)/rm.h \ - $(INCL)/objclass.h $(INCL)/monsym.h $(MSYS)/pcvideo.h - $(TARGET_CC) $(cflags) -I$(MSYS) -o$@ drawing.c - -$(O)decl.o: $(CONFIG_H) decl.c - $(TARGET_CC) $(cflags) -o$@ decl.c - -$(O)monst.o: $(CONFIG_H) $(PERMONST_H) $(INCL)/monsym.h \ - $(INCL)/color.h monst.c - $(TARGET_CC) $(cflags) -o$@ monst.c - -$(O)objects.o: $(CONFIG_H) $(INCL)/obj.h $(INCL)/objclass.h \ - $(INCL)/prop.h $(INCL)/color.h objects.c - $(TARGET_CC) $(cflags) -o$@ objects.c - -$(O)dat.tag: $(DAT)/nhdat - @echo dat done >$@ - -#============================================================= -# Lua -#============================================================= - -lua.exe: $(O)lua.o $(LUALIB) - $(TARGET_LINK) $(LFLAGS) -o$@ $(O)lua.o $(LUALIB) - -luac.exe: $(O)luac.o $(LUALIB) - $(TARGET_LINK) $(LFLAGSU) -o$@ $(O)luac.o $(LUALIB) - -$(O)lua.o: $(LUASRC)/lua.c -$(O)luac.o: $(LUASRC)/luac.c - -#========================================== -# Lua lib -#========================================== - -$(LUALIB): $(LUALIBOBJS) - if [ -f $@ ]; then rm $@; fi; - $(TARGET_AR) rcS $@ $(LUAOBJFILES1) - $(TARGET_AR) rcS $@ $(LUAOBJFILES2) - $(TARGET_AR) rcS $@ $(LUAOBJFILES3) - $(TARGET_AR) rcs $@ $(LUAOBJFILES4) - -#$(LUADLL): $(LUALIBOBJS) -# $(TARGET_CC) -shared -Wl,--export-all-symbols \ -# -Wl,--add-stdcall-alias -o $@ $< - -#========================================== -# Housekeeping. -#========================================== - -clean: - rm ./o/*.o - if [ -f $(O)install.tag ]; then rm $(O)install.tag; fi; - if [ -f $(O)obj.tag ]; then rm $(O)obj.tag; fi; - if [ -f $(O)$(GAME).lnk ]; then rm temp.a; fi; - if [ -f temp.a ]; then rm temp.a; fi; - -spotless: clean - - if [ -f $(U)recover.exe ]; then rm $(U)recover.exe; fi; - if [ -f $(INCL)/vis_tab.h ]; then rm $(INCL)/vis_tab.h; fi; - if [ -f $(INCL)/onames.h ]; then rm $(INCL)/onames.h; fi; - if [ -f $(INCL)/pm.h ]; then rm $(INCL)/pm.h; fi; - if [ -f $(INCL)/date.h ]; then rm $(INCL)/date.h; fi; -# if [ -f $(SRC)/monstr.c ]; then rm $(SRC)/monstr.c; fi; - if [ -f $(SRC)/vis_tab.c ]; then rm $(SRC)/vis_tab.c; fi; - if [ -f $(SRC)/tile.c ]; then rm $(SRC)/tile.c; fi; - if [ -f $(DAT)/options ]; then rm $(DAT)/options; fi; - if [ -f $(DAT)/data ]; then rm $(DAT)/data; fi; - if [ -f $(DAT)/rumors ]; then rm $(DAT)/rumors; fi; - if [ -f $(DAT)/oracles ]; then rm $(DAT)/oracles; fi; - if [ -f $(DAT)/bogusmon ]; then rm $(DAT)/bogusmon; fi; - if [ -f $(DAT)/engrave ]; then rm $(DAT)/engrave; fi; - if [ -f $(DAT)/epitaph ]; then rm $(DAT)/epitaph; fi; - if [ -f $(DAT)/dlb.lst ]; then rm $(DAT)/dlb.lst; fi; - if [ -f $(TILE_BMP) ]; then rm $(TILE_BMP); fi; - if [ -f $(PLANAR_TIB) ]; then rm $(PLANAR_TIB); fi; - if [ -f $(OVERVIEW_TIB) ]; then rm $(OVERVIEW_TIB); fi; - if [ -f $(WSHR)/monthin.txt ]; then rm $(WSHR)/monthin.txt; fi; - if [ -f $(WSHR)/objthin.txt ]; then rm $(WSHR)/objthin.txt; fi; - if [ -f $(WSHR)/oththin.txt ]; then rm $(WSHR)/oththin.txt; fi; - -#========================================== -# Create directory for holding object files -#========================================== - -$(O)obj.tag: - -mkdir -p $(OBJ) - @echo directory ready $(OBJ) - -#========================================== -# Game Dependencies -#========================================== - -# sys/share -$(O)main.o: $(HACK_H) $(DLB_H) $(SSHR)/pcmain.c - $(TARGET_CC) $(cflags) -o$@ $(SSHR)/pcmain.c - -$(O)tty.o: $(HACK_H) $(INCL)/wintty.h $(SSHR)/pctty.c - $(TARGET_CC) $(cflags) -o$@ $(SSHR)/pctty.c - -$(O)unix.o: $(HACK_H) $(SSHR)/pcunix.c - $(TARGET_CC) $(cflags) -o$@ $(SSHR)/pcunix.c - -$(O)pcsys.o : $(HACK_H) $(SSHR)/pcsys.c - $(TARGET_CC) $(cflags) -o$@ $(SSHR)/pcsys.c - -$(O)posixreg.o : $(HACK_H) $(SSHR)/posixreg.c - $(TARGET_CC) $(cflags) -o$@ $(SSHR)/posixreg.c - -$(O)cppregex.o : $(HACK_H) $(SSHR)/cppregex.cpp - gpp $(cflags) -std=c++11 -o$@ $(SSHR)/cppregex.cpp - -$(O)pmatchre.o : $(HACK_H) $(SSHR)/pmatchre.c - $(TARGET_CC) $(cflags) -o$@ $(SSHR)/pmatchre.c - -# sys/msdos -$(O)tile.o : $(HACK_H) $(SRC)/tile.c -$(O)msdos.o : $(HACK_H) $(MSYS)/msdos.c -$(O)pckeys.o : $(HACK_H) $(MSYS)/pckeys.c -$(O)pctiles.o : $(HACK_H) $(MSYS)/pctiles.c $(MSYS)/portio.h - $(TARGET_CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/pctiles.c -$(O)sound.o : $(HACK_H) $(MSYS)/sound.c $(MSYS)/portio.h -$(O)video.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(MSYS)/video.c -$(O)vidvga.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidvga.c - $(TARGET_CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/vidvga.c -$(O)vidvesa.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidvesa.c - $(TARGET_CC) $(cflags) -I$(MSYS) -I$(WSHR) -o$@ $(MSYS)/vidvesa.c -$(O)vidtxt.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/portio.h $(TILE_H) $(MSYS)/vidtxt.c -$(O)stubvid.o : $(HACK_H) $(MSYS)/pcvideo.h $(MSYS)/video.c - $(TARGET_CC) $(cflags) -I$(MSYS) -DSTUBVIDEO -o$@ $(MSYS)/video.c -# -# The rest are stolen from sys/unix/Makefile.src, -# with the following changes: -# o -c (which is included in cflags) substituted with -o$@ , -# o an explicit build instruction for dlb.o because it requires -# a .h file in ../sys/msdos. -# o $(CFLAGS) changed to $(cflags) -# Other than that, these dependencies are untouched. -# That means that there is some irrelevant stuff -# in here, but maintenance should be easier. -# -# -# src dependencies -$(O)pcmain.o: ../sys/share/pcmain.c $(HACK_H) $(INCL)/dlb.h \ - #$(INCL)/win32api.h - $(TARGET_CC) $(cflags) -o$@ ../sys/share/pcmain.c -$(O)pctty.o: ../sys/share/pctty.c $(HACK_H) - $(TARGET_CC) $(cflags) -o$@ ../sys/share/pctty.c -$(O)pcunix.o: ../sys/share/pcunix.c $(HACK_H) - $(TARGET_CC) $(cflags) -o$@ ../sys/share/pcunix.c -$(O)random.o: ../sys/share/random.c $(HACK_H) - $(TARGET_CC) $(cflags) -o$@ ../sys/share/random.c -$(O)ioctl.o: ../sys/share/ioctl.c $(HACK_H) $(INCL)/tcap.h - $(TARGET_CC) $(cflags) -o$@ ../sys/share/ioctl.c -$(O)unixtty.o: ../sys/share/unixtty.c $(HACK_H) - $(TARGET_CC) $(cflags) -o$@ ../sys/share/unixtty.c -$(O)unixmain.o: ../sys/unix/unixmain.c $(HACK_H) $(INCL)/dlb.h - $(TARGET_CC) $(cflags) -o$@ ../sys/unix/unixmain.c -$(O)unixunix.o: ../sys/unix/unixunix.c $(HACK_H) - $(TARGET_CC) $(cflags) -o$@ ../sys/unix/unixunix.c -$(O)unixres.o: ../sys/unix/unixres.c $(CONFIG_H) - $(TARGET_CC) $(cflags) -o$@ ../sys/unix/unixres.c -$(O)bemain.o: ../sys/be/bemain.c $(HACK_H) $(INCL)/dlb.h - $(TARGET_CC) $(cflags) -o$@ ../sys/be/bemain.c -$(O)getline.o: ../win/tty/getline.c $(HACK_H) $(INCL)/func_tab.h - $(TARGET_CC) $(cflags) -o$@ ../win/tty/getline.c -$(O)termcap.o: ../win/tty/termcap.c $(HACK_H) $(INCL)/tcap.h - $(TARGET_CC) $(cflags) -o$@ ../win/tty/termcap.c -$(O)topl.o: ../win/tty/topl.c $(HACK_H) $(INCL)/tcap.h - $(TARGET_CC) $(cflags) -o$@ ../win/tty/topl.c -$(O)wintty.o: ../win/tty/wintty.c $(HACK_H) $(INCL)/dlb.h \ - $(INCL)/date.h $(INCL)/tcap.h - $(TARGET_CC) $(cflags) -o$@ ../win/tty/wintty.c -$(O)Window.o: ../win/X11/Window.c $(INCL)/xwindowp.h $(INCL)/xwindow.h \ - $(CONFIG_H) - $(TARGET_CC) $(cflags) -o$@ ../win/X11/Window.c -$(O)dialogs.o: ../win/X11/dialogs.c $(CONFIG_H) - $(TARGET_CC) $(cflags) -o$@ ../win/X11/dialogs.c -$(O)winX.o: ../win/X11/winX.c $(HACK_H) $(INCL)/winX.h $(INCL)/dlb.h \ - ../win/X11/nh72icon \ - ../win/X11/nh56icon ../win/X11/nh32icon - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winX.c -$(O)winmap.o: ../win/X11/winmap.c $(INCL)/xwindow.h $(HACK_H) $(INCL)/dlb.h \ - $(INCL)/winX.h $(INCL)/tile2x11.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winmap.c -$(O)winmenu.o: ../win/X11/winmenu.c $(HACK_H) $(INCL)/winX.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winmenu.c -$(O)winmesg.o: ../win/X11/winmesg.c $(INCL)/xwindow.h $(HACK_H) $(INCL)/winX.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winmesg.c -$(O)winmisc.o: ../win/X11/winmisc.c $(HACK_H) $(INCL)/func_tab.h \ - $(INCL)/winX.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winmisc.c -$(O)winstat.o: ../win/X11/winstat.c $(HACK_H) $(INCL)/winX.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winstat.c -$(O)wintext.o: ../win/X11/wintext.c $(HACK_H) $(INCL)/winX.h $(INCL)/xwindow.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/wintext.c -$(O)winval.o: ../win/X11/winval.c $(HACK_H) $(INCL)/winX.h - $(TARGET_CC) $(cflags) -o$@ ../win/X11/winval.c -#$(O)tile.o: tile.c $(HACK_H) -#$(HOST_O)tile.o: tile.c $(HACK_H) -$(O)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) $(INCL)/func_tab.h \ - $(INCL)/dlb.h $(INCL)/tile2x11.h \ - $(INCL)/qt_win.h $(INCL)/qt_clust.h $(INCL)/qt_kde0.h \ - $(INCL)/qt_xpms.h qt_win.moc qt_kde0.moc qttableview.moc - $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_win.cpp -$(O)qt_clust.o: ../win/Qt/qt_clust.cpp $(INCL)/qt_clust.h - $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_clust.cpp -$(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h - $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qttableview.cpp -$(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h -$(O)allmain.o: allmain.c $(HACK_H) -$(O)alloc.o: alloc.c $(CONFIG_H) -$(O)apply.o: apply.c $(HACK_H) -$(O)artifact.o: artifact.c $(HACK_H) $(INCL)/artifact.h $(INCL)/artilist.h -$(O)attrib.o: attrib.c $(HACK_H) -$(O)ball.o: ball.c $(HACK_H) -$(O)bones.o: bones.c $(HACK_H) -$(O)botl.o: botl.c $(HACK_H) -$(O)cmd.o: cmd.c $(HACK_H) $(INCL)/func_tab.h -$(O)dbridge.o: dbridge.c $(HACK_H) -$(O)decl.o: decl.c $(HACK_H) -$(O)detect.o: detect.c $(HACK_H) $(INCL)/artifact.h -$(O)dig.o: dig.c $(HACK_H) -$(O)display.o: display.c $(HACK_H) -$(O)dlb.o: dlb.c $(CONFIG_H) $(INCL)/dlb.h - $(TARGET_CC) $(cflags) -I../sys/msdos -o$@ dlb.c -$(O)do.o: do.c $(HACK_H) -$(O)do_name.o: do_name.c $(HACK_H) -$(O)do_wear.o: do_wear.c $(HACK_H) -$(O)dog.o: dog.c $(HACK_H) -$(O)dogmove.o: dogmove.c $(HACK_H) $(INCL)/mfndpos.h -$(O)dokick.o: dokick.c $(HACK_H) -$(O)dothrow.o: dothrow.c $(HACK_H) -$(O)dungeon.o: dungeon.c $(HACK_H) $(INCL)/dgn_file.h $(INCL)/dlb.h -$(O)eat.o: eat.c $(HACK_H) -$(O)end.o: end.c $(HACK_H) $(INCL)/dlb.h -$(O)engrave.o: engrave.c $(HACK_H) -$(O)exper.o: exper.c $(HACK_H) -$(O)explode.o: explode.c $(HACK_H) -$(O)extralev.o: extralev.c $(HACK_H) -$(O)files.o: files.c $(HACK_H) $(INCL)/dlb.h -$(O)fountain.o: fountain.c $(HACK_H) -$(O)hack.o: hack.c $(HACK_H) -$(O)hacklib.o: hacklib.c $(HACK_H) -$(O)insight.o: insight.c $(HACK_H) -$(O)invent.o: invent.c $(HACK_H) -$(O)light.o: light.c $(HACK_H) -$(O)lock.o: lock.c $(HACK_H) -$(O)mail.o: mail.c $(HACK_H) $(INCL)/mail.h -$(O)makemon.o: makemon.c $(HACK_H) -$(O)mapglyph.o: mapglyph.c $(HACK_H) -$(O)mcastu.o: mcastu.c $(HACK_H) -$(O)mhitm.o: mhitm.c $(HACK_H) $(INCL)/artifact.h -$(O)mhitu.o: mhitu.c $(HACK_H) $(INCL)/artifact.h -$(O)minion.o: minion.c $(HACK_H) -$(O)mklev.o: mklev.c $(HACK_H) -$(O)mkmap.o: mkmap.c $(HACK_H) $(INCL)/sp_lev.h -$(O)mkmaze.o: mkmaze.c $(HACK_H) $(INCL)/sp_lev.h -$(O)mkobj.o: mkobj.c $(HACK_H) -$(O)mkroom.o: mkroom.c $(HACK_H) -$(O)mon.o: mon.c $(HACK_H) $(INCL)/mfndpos.h -$(O)mondata.o: mondata.c $(HACK_H) -$(O)monmove.o: monmove.c $(HACK_H) $(INCL)/mfndpos.h $(INCL)/artifact.h -$(O)monst.o: monst.c $(CONFIG_H) $(INCL)/permonst.h $(INCL)/align.h \ - $(INCL)/monattk.h $(INCL)/monflag.h $(INCL)/monsym.h \ - $(INCL)/color.h -$(O)mplayer.o: mplayer.c $(HACK_H) -$(O)mthrowu.o: mthrowu.c $(HACK_H) -$(O)muse.o: muse.c $(HACK_H) -$(O)music.o: music.c $(HACK_H) #interp.c -$(O)nhlua.o: nhlua.c $(HACK_H) -$(O)nhlsel.o: nhlsel.c $(HACK_H) -$(O)nhlobj.o: nhlobj.c $(HACK_H) -$(O)o_init.o: o_init.c $(HACK_H) -$(O)objects.o: objects.c $(CONFIG_H) $(INCL)/obj.h $(INCL)/objclass.h \ - $(INCL)/prop.h $(INCL)/skills.h $(INCL)/color.h -$(O)objnam.o: objnam.c $(HACK_H) -$(O)options.o: options.c $(CONFIG_H) $(INCL)/objclass.h $(INCL)/flag.h \ - $(HACK_H) $(INCL)/tcap.h -$(O)pager.o: pager.c $(HACK_H) $(INCL)/dlb.h -$(O)pickup.o: pickup.c $(HACK_H) -$(O)pline.o: pline.c $(HACK_H) -$(O)polyself.o: polyself.c $(HACK_H) -$(O)potion.o: potion.c $(HACK_H) -$(O)pray.o: pray.c $(HACK_H) -$(O)priest.o: priest.c $(HACK_H) $(INCL)/mfndpos.h -$(O)quest.o: quest.c $(HACK_H) -$(O)questpgr.o: questpgr.c $(HACK_H) $(INCL)/dlb.h -$(O)read.o: read.c $(HACK_H) -$(O)rect.o: rect.c $(HACK_H) -$(O)region.o: region.c $(HACK_H) -$(O)restore.o: restore.c $(HACK_H) $(INCL)/tcap.h -$(O)rip.o: rip.c $(HACK_H) -$(O)rnd.o: rnd.c $(HACK_H) -$(O)role.o: role.c $(HACK_H) -$(O)rumors.o: rumors.c $(HACK_H) $(INCL)/dlb.h -$(O)save.o: save.c $(HACK_H) -$(O)shk.o: shk.c $(HACK_H) -$(O)shknam.o: shknam.c $(HACK_H) -$(O)sit.o: sit.c $(HACK_H) $(INCL)/artifact.h -$(O)sounds.o: sounds.c $(HACK_H) -$(O)sp_lev.o: sp_lev.c $(HACK_H) $(INCL)/dlb.h $(INCL)/sp_lev.h -$(O)spell.o: spell.c $(HACK_H) -$(O)steal.o: steal.c $(HACK_H) -$(O)steed.o: steed.c $(HACK_H) -$(O)symbols.o: symbols.c $(HACK_H) $(INCL)/tcap.h -$(O)sys.o: sys.c $(HACK_H) -$(O)teleport.o: teleport.c $(HACK_H) -$(O)timeout.o: timeout.c $(HACK_H) -$(O)topten.o: topten.c $(HACK_H) $(INCL)/dlb.h -$(O)track.o: track.c $(HACK_H) -$(O)trap.o: trap.c $(HACK_H) -$(O)u_init.o: u_init.c $(HACK_H) -$(O)uhitm.o: uhitm.c $(HACK_H) -$(O)vault.o: vault.c $(HACK_H) -$(O)version.o: version.c $(HACK_H) $(INCL)/date.h -$(O)vision.o: vision.c $(HACK_H) $(INCL)/vis_tab.h -$(O)weapon.o: weapon.c $(HACK_H) -$(O)were.o: were.c $(HACK_H) -$(O)wield.o: wield.c $(HACK_H) -$(O)windows.o: windows.c $(HACK_H) $(INCL)/wingem.h $(INCL)/winGnome.h -$(O)wizard.o: wizard.c $(HACK_H) -$(O)worm.o: worm.c $(HACK_H) -$(O)worn.o: worn.c $(HACK_H) -$(O)write.o: write.c $(HACK_H) -$(O)zap.o: zap.c $(HACK_H) -$(O)pmatchre.o: $(SSHR)/pmatchre.c $(HACK_H) -$(O)tileset.o: $(WSHR)/tileset.c $(HACK_H) -$(O)bmptiles.o: $(WSHR)/bmptiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h -$(O)giftiles.o: $(WSHR)/giftiles.c $(INCL)/config.h $(INCL)/tileset.h $(INCL)/integer.h - -#end of file - diff --git a/sys/msdos/msdos-cross-compile.sh b/sys/msdos/msdos-cross-compile.sh deleted file mode 100644 index fc3fc31db..000000000 --- a/sys/msdos/msdos-cross-compile.sh +++ /dev/null @@ -1,129 +0,0 @@ -#!/bin/sh -#set -x - -if [ -z "$TRAVIS_BUILD_DIR" ]; then - export DJGPP_TOP=$(pwd)/lib/djgpp -else - export DJGPP_TOP="$TRAVIS_BUILD_DIR/lib/djgpp" -fi - -if [ -z "$GCCVER" ]; then - export GCCVER=gcc1010 -fi - -if [ -z "$LUA_VERSION" ]; then - export LUA_VERSION=5.4.0 -fi - -if [ ! -d "$(pwd)/lib" ]; then - echo "Set up for Unix build and 'make fetch-lua' first." - exit 1 -fi - -#DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v2.9/" -DJGPP_URL="https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/" -if [ "$(uname)" = "Darwin" ]; then - #Mac - DJGPP_FILE="djgpp-osx-$GCCVER.tar.bz2" - if [ -z "HINTS" ]; then - export HINTS=macOS.2020 - 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.2020 - fi -elif [ "$(expr substr $(uname -s) 1 10)" = "MINGW32_NT" ]; then - #mingw - DJGPP_FILE="djgpp-mingw-$GCCVER-standalone.zip" -else - echo "No DJGPP release for you, sorry." - exit 1 -fi - -DJGPP_URL="$DJGPP_URL$DJGPP_FILE" - -# export - -if [ ! -d lib ]; then -mkdir -p lib -fi - -cd lib -if [ ! -f "$DJGPP_FILE" ]; then - if [ "$(uname)" = "Darwin" ]; then - #Mac - curl -L $DJGPP_URL -o $DJGPP_FILE - else - wget --no-hsts "$DJGPP_URL" - fi -fi - -if [ ! -d djgpp/i586-pc-msdosdjgpp ]; then - tar xjf "$DJGPP_FILE" - rm -f $DJGPP_FILE -fi - -# DOS-extender for use with djgpp -if [ ! -d djgpp/cwsdpmi ]; then - if [ "$(uname)" = "Darwin" ]; then - #Mac - curl http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip -o csdpmi7b.zip - else - wget --no-hsts http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip - fi - cd djgpp - mkdir -p cwsdpmi - cd cwsdpmi - unzip ../../csdpmi7b.zip - cd ../../ - rm csdpmi7b.zip -fi - -# PDCurses -if [ ! -d "pdcurses" ]; then - echo "Getting ../pdcurses from https://github.com/wmcbrine/PDCurses.git" ; \ - git clone --depth 1 https://github.com/wmcbrine/PDCurses.git pdcurses -fi - -cd ../ - -# Don't fail the build if lua fetch failed because we cannot do anything about it -# but don't bother proceeding forward either -if [ ! -d "lib/lua-$LUA_VERSION/src" ]; then - exit 0 -fi - -#echo after dos extender - -cd src - -mkdir -p ../msdos-binary -cp ../dat/data.base ../dat/data.bas -cp ../include/patchlevel.h ../include/patchlev.h -cp ../doc/Guidebook.txt ../doc/guidebk.txt -cp ../sys/share/posixregex.c ../sys/share/posixreg.c -#cp ../sys/msdos/Makefile1.cross ../src/Makefile1 -#cp ../sys/msdos/Makefile2.cross ../src/Makefile2 -make -f ../sys/msdos/Makefile1.cross -#cat ../include/date.h -export GCC_EXEC_PREFIX=$DJGPP_TOP/lib/gcc/ -# export - -#pwd - -make -f ../sys/msdos/Makefile2.cross -unset GCC_EXEC_PREFIX -#pwd - -if [ -f ../lib/djgpp/cwsdpmi/bin/CWSDPMI.EXE ]; then - cp ../lib/djgpp/cwsdpmi/bin/CWSDPMI.EXE ../msdos-binary/CWSDPMI.EXE; -fi - -# ls -l ../msdos-binary -cd ../msdos-binary -zip -9 ../lib/NH370DOS.ZIP * -cd ../ -ls -l lib/NH370DOS.ZIP - diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 77ee5b3f7..258051f7d 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -127,7 +127,7 @@ ifdef CROSS_TO_MSDOS # Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz #================================================================= -CFLAGS += -DCROSSCOMPILE -DCROSSCOMPILE_HOST +CFLAGS += -DCROSSCOMPILE # # Override the build tools and some obj files to @@ -195,7 +195,7 @@ ifdef CROSS_TO_AMIGA # Amiga m68k from https://github.com/bebbo/amiga-gcc #================================================================= -CFLAGS += -DCROSSCOMPILE -DCROSSCOMPILE_HOST +CFLAGS += -DCROSSCOMPILE # # Override the build tools and some obj files to diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index be7fdcce2..8cfa61740 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -253,12 +253,10 @@ U = $(UTIL)^\ !IFDEF TEST_CROSSCOMPILE HOST=_host CROSSCOMPILE_TARGET= -DCROSSCOMPILE_TARGET -CROSSCOMPILE_HOST= -DCROSSCOMPILE_HOST CROSSCOMPILE= -DCROSSCOMPILE !ELSE HOST= CROSSCOMPILE_TARGET= -CROSSCOMPILE_HOST= CROSSCOMPILE= !ENDIF @@ -1064,7 +1062,7 @@ $(U)nhsizes3.exe: $(O)nhsizes3.o $(link) $(lflagsBuild) -out:$@ $(O)nhsizes.o $(O)panic$(HOST).o $(O)alloc$(HOST).o $(O)nhsizes3.o: $(CONFIG_H) nhsizes3.c - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ nhsizes3.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -Fo$@ nhsizes3.c $(U)makedefs.exe: $(MAKEDEFSOBJS) @echo Linking $(@:\=/) @@ -1077,8 +1075,8 @@ $(O)makedefs.o: $(U)makedefs.c $(SRC)\mdlib.c $(CONFIG_H) $(INCL)\permonst.h \ $(INCL)\dlb.h @if not exist $(OBJ)\*.* echo creating directory $(OBJ:\=/) @if not exist $(OBJ)\*.* mkdir $(OBJ) - @$(cc) -DENUM_PM $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ $(U)makedefs.c -# @$(cc) -DENUM_PM $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) /EP -Fo$@ $(U)makedefs.c >makedefs.c.preprocessed + @$(cc) -DENUM_PM $(cflagsBuild) $(CROSSCOMPILE) -Fo$@ $(U)makedefs.c +# @$(cc) -DENUM_PM $(cflagsBuild) $(CROSSCOMPILE) /EP -Fo$@ $(U)makedefs.c >makedefs.c.preprocessed # # date.h should be remade every time any of the source or include @@ -1109,7 +1107,7 @@ $(U)uudecode.exe: $(O)uudecode.o @$(link) $(lflagsBuild) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ $(O)uudecode.o $(O)uudecode.o: $(SSYS)\uudecode.c - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) /D_CRT_SECURE_NO_DEPRECATE -Fo$@ $(SSYS)\uudecode.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /D_CRT_SECURE_NO_DEPRECATE -Fo$@ $(SSYS)\uudecode.c $(MSWSYS)\NetHack.ico : $(U)uudecode.exe $(MSWSYS)\nhico.uu chdir $(MSWSYS) @@ -1208,7 +1206,7 @@ $(U)dlb.exe: $(DLBOBJ_HOST) $(O)dlb$(HOST).o !IFDEF TEST_CROSSCOMPILE $(O)dlb$(HOST).o: $(O)dlb_main$(HOST).o $(O)alloc$(HOST).o $(O)panic$(HOST).o $(INCL)\dlb.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) /Fo$@ $(SRC)\dlb.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /Fo$@ $(SRC)\dlb.c !ENDIF $(O)dlb.o: $(O)dlb_main.o $(O)alloc.o $(O)panic.o $(INCL)\dlb.h @@ -1216,11 +1214,11 @@ $(O)dlb.o: $(O)dlb_main.o $(O)alloc.o $(O)panic.o $(INCL)\dlb.h !IFDEF TEST_CROSSCOMPILE $(O)dlb_main$(HOST).o: $(UTIL)\dlb_main.c $(INCL)\config.h $(INCL)\dlb.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) /Fo$@ $(UTIL)\dlb_main.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /Fo$@ $(UTIL)\dlb_main.c !ENDIF $(O)dlb_main.o: $(UTIL)\dlb_main.c $(INCL)\config.h $(INCL)\dlb.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) /Fo$@ $(UTIL)\dlb_main.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /Fo$@ $(UTIL)\dlb_main.c $(DAT)\porthelp: $(MSWSYS)\porthelp @copy $(MSWSYS)\porthelp $@ >nul @@ -1277,28 +1275,28 @@ $(U)tilemap.exe: $(O)tilemap.o @$(link) $(lflagsBuild) /PDB:"$(O)$(@B).PDB" /MAP:"$(O)$(@B).MAP" -out:$@ $(O)tilemap.o $(O)tilemap.o: $(WSHR)\tilemap.c $(HACK_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ $(WSHR)\tilemap.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -Fo$@ $(WSHR)\tilemap.c $(O)tiletx32.o: $(WSHR)\tilemap.c $(HACK_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) /DTILETEXT /DTILE_X=32 /DTILE_Y=32 -Fo$@ $(WSHR)\tilemap.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /DTILETEXT /DTILE_X=32 /DTILE_Y=32 -Fo$@ $(WSHR)\tilemap.c $(O)tiletxt.o: $(WSHR)\tilemap.c $(HACK_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) /DTILETEXT -Fo$@ $(WSHR)\tilemap.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /DTILETEXT -Fo$@ $(WSHR)\tilemap.c $(O)gifread.o: $(WSHR)\gifread.c $(CONFIG_H) $(TILE_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) -Fo$@ $(WSHR)\gifread.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) -Fo$@ $(WSHR)\gifread.c $(O)gifrd32.o: $(WSHR)\gifread.c $(CONFIG_H) $(TILE_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DTILE_X=32 /DTILE_Y=32 -Fo$@ $(WSHR)\gifread.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) /DTILE_X=32 /DTILE_Y=32 -Fo$@ $(WSHR)\gifread.c $(O)ppmwrite.o: $(WSHR)\ppmwrite.c $(CONFIG_H) $(TILE_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) -Fo$@ $(WSHR)\ppmwrite.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) -Fo$@ $(WSHR)\ppmwrite.c $(O)tiletext.o: $(WSHR)\tiletext.c $(CONFIG_H) $(TILE_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) -Fo$@ $(WSHR)\tiletext.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) -Fo$@ $(WSHR)\tiletext.c $(O)tilete32.o: $(WSHR)\tiletext.c $(CONFIG_H) $(TILE_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DTILE_X=32 /DTILE_Y=32 -Fo$@ $(WSHR)\tiletext.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) /DTILE_X=32 /DTILE_Y=32 -Fo$@ $(WSHR)\tiletext.c #========================================== # Optional Tile Utilities @@ -1357,10 +1355,10 @@ $(U)til2bm32.exe: $(O)til2bm32.o $(TEXT_IO32) << $(O)tile2bmp.o: $(WSHR)\tile2bmp.c $(HACK_H) $(TILE_H) $(MSWSYS)\win32api.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DPACKED_FILE /Fo$@ $(WSHR)\tile2bmp.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) /DPACKED_FILE /Fo$@ $(WSHR)\tile2bmp.c $(O)til2bm32.o: $(WSHR)\tile2bmp.c $(HACK_H) $(TILE_H) $(MSWSYS)\win32api.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DPACKED_FILE /DTILE_X=32 /DTILE_Y=32 /Fo$@ $(WSHR)\tile2bmp.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) /DPACKED_FILE /DTILE_X=32 /DTILE_Y=32 /Fo$@ $(WSHR)\tile2bmp.c $(U)tile2x11.exe: $(O)tile2x11.o $(O)tiletext.o $(O)tiletxt.o $(O)alloc.o \ $(O)panic.o $(O)monst.o $(O)objects.o @@ -1377,7 +1375,7 @@ $(U)tile2x11.exe: $(O)tile2x11.o $(O)tiletext.o $(O)tiletxt.o $(O)alloc.o \ << $(O)tile2x11.o: $(X11)\tile2x11.c $(HACK_H) $(TILE_H) $(INCL)\tile2x11.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -I$(WSHR) /DPACKED_FILE /Fo$@ $(X11)\tile2x11.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -I$(WSHR) /DPACKED_FILE /Fo$@ $(X11)\tile2x11.c $(SRC)\x11tiles: $(U)tile2x11.exe $(WSHR)\monsters.txt $(WSHR)\objects.txt \ $(WSHR)\other.txt \ @@ -1509,7 +1507,7 @@ $(O)sfstruct.o: $(HACK_H) $(SRC)\sfstruct.c !IFDEF TEST_CROSSCOMPILE $(O)mdlib$(HOST).o: $(SRC)\mdlib.c - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ $(SRC)\mdlib.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -Fo$@ $(SRC)\mdlib.c !ENDIF $(O)mdlib.o: $(SRC)\mdlib.c @@ -1523,13 +1521,13 @@ $(O)mdlib.o: $(SRC)\mdlib.c # These have dual-roles and need to be build for host and target platforms. # $(O)panic_host.o: $(U)panic.c $(CONFIG_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ $(U)panic.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -Fo$@ $(U)panic.c $(O)panic.o: $(U)panic.c $(CONFIG_H) @$(cc) $(cflagsBuild) -Fo$@ $(U)panic.c $(O)drawing_host.o: drawing.c $(CONFIG_H) - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_HOST) -Fo$@ drawing.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) -Fo$@ drawing.c $(O)drawing.o: drawing.c $(CONFIG_H) $(INCL)\color.h $(INCL)\rm.h \ $(INCL)\objclass.h $(INCL)\monsym.h diff --git a/util/makedefs.c b/util/makedefs.c index 96e13afaa..0d4b61cfd 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1135,13 +1135,13 @@ do_date() char githash[BUFSZ], gitbranch[BUFSZ]; char *c, cbuf[60], buf[BUFSZ]; const char *ul_sfx; -#if defined(CROSSCOMPILE) && defined(CROSSCOMPILE_HOST) +#if defined(CROSSCOMPILE) && !defined(CROSSCOMPILE_TARGET) int steps = 0; const char ind[] = " "; const char *xpref = "HOST_"; #else const char *xpref = (const char *) 0; -#endif /* CROSSCOMPILE && CROSSCOMPILE_HOST */ +#endif /* CROSSCOMPILE && !CROSSCOMPILE_TARGET */ /* before creating date.h, make sure that xxx_GRAPHICS and DEFAULT_WINDOW_SYS have been set up in a viable fashion */ @@ -1243,10 +1243,10 @@ do_date() ul_sfx = "L"; #endif -#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_HOST) +#if !defined(CROSSCOMPILE) || !defined(CROSSCOMPILE_TARGET) Fprintf(ofp, - "\n#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_HOST)\n"); -#endif /* CROSSCOMPILE || CROSSCOMPILE_HOST */ + "\n#if !defined(CROSSCOMPILE) || !defined(CROSSCOMPILE_TARGET)\n"); +#endif /* CROSSCOMPILE || !CROSSCOMPILE_TARGET */ if (date_via_env) Fprintf(ofp, "#define SOURCE_DATE_EPOCH (%lu%s) /* via getenv() */\n", (unsigned long) clocktim, ul_sfx); @@ -1282,13 +1282,13 @@ do_date() Fprintf(ofp, "#define NETHACK_GIT_BRANCH \"%s\"\n", gitbranch); } if (xpref && get_gitinfo(githash, gitbranch)) { - Fprintf(ofp, "#else /* !CROSSCOMPILE || CROSSCOMPILE_HOST */\n"); + Fprintf(ofp, "#else /* !CROSSCOMPILE || !CROSSCOMPILE_TARGET */\n"); Fprintf(ofp, "#define NETHACK_%sGIT_SHA \"%s\"\n", xpref, githash); Fprintf(ofp, "#define NETHACK_%sGIT_BRANCH \"%s\"\n", xpref, gitbranch); } - Fprintf(ofp, "#endif /* !CROSSCOMPILE || CROSSCOMPILE_HOST */\n"); + Fprintf(ofp, "#endif /* !CROSSCOMPILE || !CROSSCOMPILE_TARGET */\n"); Fprintf(ofp, "\n"); #ifdef AMIGA { From 1ff5b519c8757ce4a75b1305b1d6603c85d99a57 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 29 Sep 2020 15:13:52 -0400 Subject: [PATCH 247/708] reinstate one $(CROSSCOMPILE_TARGET) in sys/winnt/Makefile.msc It was removed but shouldn't have been. --- sys/winnt/Makefile.msc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 8cfa61740..546d346e4 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1218,7 +1218,7 @@ $(O)dlb_main$(HOST).o: $(UTIL)\dlb_main.c $(INCL)\config.h $(INCL)\dlb.h !ENDIF $(O)dlb_main.o: $(UTIL)\dlb_main.c $(INCL)\config.h $(INCL)\dlb.h - @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /Fo$@ $(UTIL)\dlb_main.c + @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) /Fo$@ $(UTIL)\dlb_main.c $(DAT)\porthelp: $(MSWSYS)\porthelp @copy $(MSWSYS)\porthelp $@ >nul From a47e742892aac0970f35a4b4252891fe191b7dc3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 29 Sep 2020 19:44:13 -0400 Subject: [PATCH 248/708] cron daily Files update --- Files | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Files b/Files index 3b86dc039..db689a079 100644 --- a/Files +++ b/Files @@ -220,8 +220,7 @@ zap.c sys/msdos: (files for MSDOS version) -Install.dos Makefile.GCC Makefile1.cross -Makefile2.cross fetch-cross-compiler.sh msdos-cross-compile.sh +Install.dos Makefile.GCC fetch-cross-compiler.sh msdos.c msdoshlp.txt nhlua.h pckeys.c pctiles.c pctiles.h pcvideo.h portio.h setup.bat From fb7b578af19f50629087457b89b1f522a432ea42 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 30 Sep 2020 18:59:09 +0300 Subject: [PATCH 249/708] Make piranhas faster and more bitey Piranhas are pretty bland, so make them faster and give them an extra bite attack. (via xNetHack) --- doc/fixes37.0 | 1 + src/monst.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 2adfa50f3..8897d086f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -262,6 +262,7 @@ when make was invoked with -j makedefs instances could end up running in mkstemp() to define HAS_NO_MKSTEMP to revert to the old behaviour; provide a work-alike mkstemp() implementation for windows visual studio in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there +make piranhas faster and give them extra bite attack Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/monst.c b/src/monst.c index 8173aea04..9bbce0a27 100644 --- a/src/monst.c +++ b/src/monst.c @@ -2636,9 +2636,9 @@ struct permonst _mons2[] = { M1_SWIM | M1_AMPHIBIOUS | M1_SLITHY | M1_NOLIMBS | M1_NOHEAD | M1_NOTAKE | M1_POIS, M2_HOSTILE, 0, 5, CLR_BLUE), - MON("piranha", S_EEL, LVL(5, 12, 4, 0, 0), (G_GENO | G_NOGEN | G_SGROUP), - A(ATTK(AT_BITE, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, - NO_ATTK), + MON("piranha", S_EEL, LVL(5, 18, 4, 0, 0), (G_GENO | G_NOGEN | G_SGROUP), + A(ATTK(AT_BITE, AD_PHYS, 2, 6), ATTK(AT_BITE, AD_PHYS, 2, 6), + NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(60, 30, MS_SILENT, MZ_SMALL), 0, 0, M1_SWIM | M1_AMPHIBIOUS | M1_ANIMAL | M1_SLITHY | M1_NOLIMBS | M1_CARNIVORE | M1_OVIPAROUS | M1_NOTAKE, From 6a35a84c56844e6c4bc6d2105c2368f9cd8f650e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 30 Sep 2020 19:43:12 +0300 Subject: [PATCH 250/708] Fire sources can ignite candles, lamps, and potions of oil ... on the floor, in monster inventory, and in hero's inventory. Items in your inventory being ignited produce a message even if you're blind - you can see the lit-state by viewing inventory anyway, so just give player the message. (via xNetHack) --- doc/fixes37.0 | 1 + include/extern.h | 1 + src/artifact.c | 2 ++ src/explode.c | 7 ++++++- src/mcastu.c | 1 + src/mhitm.c | 1 + src/mhitu.c | 4 ++++ src/muse.c | 1 + src/polyself.c | 2 ++ src/trap.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/uhitm.c | 1 + src/zap.c | 8 ++++++++ 12 files changed, 72 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 8897d086f..9355123bd 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -263,6 +263,7 @@ when make was invoked with -j makedefs instances could end up running in provide a work-alike mkstemp() implementation for windows visual studio in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there make piranhas faster and give them extra bite attack +fire sources can ignite candles, lamps, and potions of oil Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 374598ae4..7e4af0781 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2715,6 +2715,7 @@ E boolean NDECL(lava_effects); E void NDECL(sink_into_lava); E void NDECL(sokoban_guilt); E const char * FDECL(trapname, (int, BOOLEAN_P)); +E void FDECL(ignite_items, (struct obj *)); /* ### u_init.c ### */ diff --git a/src/artifact.c b/src/artifact.c index 990be7b43..c71c0e87c 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1192,6 +1192,8 @@ int dieroll; /* needed for Magicbane and vorpal blades */ (void) destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); if (!rn2(7)) (void) destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); + if (!rn2(4)) + ignite_items(mdef->minvent); if (youdefend && Slimed) burn_away_slime(); return realizes_damage; diff --git a/src/explode.c b/src/explode.c index 469eaeff2..8abe642fd 100644 --- a/src/explode.c +++ b/src/explode.c @@ -412,6 +412,9 @@ int expltype; idamnonres += destroy_mitem(mtmp, WAND_CLASS, (int) adtyp); idamnonres += destroy_mitem(mtmp, RING_CLASS, (int) adtyp); + if (adtyp == AD_FIRE) + ignite_items(mtmp->minvent); + if (explmask[i][j] == 1) { golemeffects(mtmp, (int) adtyp, dam + idamres); mtmp->mhp -= idamnonres; @@ -500,8 +503,10 @@ int expltype; You("are unharmed!"); } else if (adtyp == AD_PHYS || physical_dmg) damu = Maybe_Half_Phys(damu); - if (adtyp == AD_FIRE) + if (adtyp == AD_FIRE) { (void) burnarmor(&g.youmonst); + ignite_items(g.invent); + } destroy_item(SCROLL_CLASS, (int) adtyp); destroy_item(SPBOOK_CLASS, (int) adtyp); destroy_item(POTION_CLASS, (int) adtyp); diff --git a/src/mcastu.c b/src/mcastu.c index e53195f72..f6b23986e 100644 --- a/src/mcastu.c +++ b/src/mcastu.c @@ -553,6 +553,7 @@ int spellnum; destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE); + ignite_items(g.invent); (void) burn_floor_objects(u.ux, u.uy, TRUE, FALSE); break; case CLC_LIGHTNING: { diff --git a/src/mhitm.c b/src/mhitm.c index e848c1d99..e08ce35ba 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1042,6 +1042,7 @@ int dieroll; } /* only potions damage resistant players in destroy_item */ tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); + ignite_items(mdef->minvent); break; case AD_COLD: if (cancelled) { diff --git a/src/mhitu.c b/src/mhitu.c index ddfc45453..f28f0c6b7 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1115,6 +1115,8 @@ register struct attack *mattk; destroy_item(POTION_CLASS, AD_FIRE); if ((int) mtmp->m_lev > rn2(25)) destroy_item(SPBOOK_CLASS, AD_FIRE); + if ((int) mtmp->m_lev > rn2(20)) + ignite_items(g.invent); burn_away_slime(); } else dmg = 0; @@ -2362,6 +2364,8 @@ struct attack *mattk; destroy_item(POTION_CLASS, AD_FIRE); if (lev > rn2(25)) destroy_item(SPBOOK_CLASS, AD_FIRE); + if (lev > rn2(20)) + ignite_items(g.invent); if (dmg) mdamageu(mtmp, dmg); } diff --git a/src/muse.c b/src/muse.c index 424a444c5..f14f979ff 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1594,6 +1594,7 @@ struct monst *mtmp; (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); + ignite_items(mtmp->minvent); num = (2 * (rn1(3, 3) + 2 * bcsign(otmp)) + 1) / 3; if (Fire_resistance) You("are not harmed."); diff --git a/src/polyself.c b/src/polyself.c index fbfe59fd1..5beef979f 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1447,6 +1447,8 @@ dogaze() (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); if (lev > rn2(25)) (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); + if (lev > rn2(20)) + ignite_items(mtmp->minvent); if (dmg) mtmp->mhp -= dmg; if (DEADMONSTER(mtmp)) diff --git a/src/trap.c b/src/trap.c index c2e30afd5..7aa3f3e71 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2434,6 +2434,7 @@ register struct monst *mtmp; (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); + ignite_items(mtmp->minvent); } if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE) && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3) @@ -3196,6 +3197,7 @@ struct obj *box; /* null for floor trap */ destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE); + ignite_items(g.invent); } if (!box && burn_floor_objects(u.ux, u.uy, see_it, TRUE) && !see_it) You("smell paper burning."); @@ -5400,6 +5402,7 @@ lava_effects() destroy_item(SCROLL_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(POTION_CLASS, AD_FIRE); + ignite_items(g.invent); return FALSE; } @@ -5560,4 +5563,45 @@ boolean override; return defsyms[trap_to_defsym(ttyp)].explanation; } +/* Ignite ignitable items in the given object chain, due to some external source + * of fire. The object chain should be somewhere exposed, like someone's open + * inventory or the floor. + * This is modeled after destroy_item() somewhat and hopefully will be able to + * merge into it in the future. + */ +void +ignite_items(objchn) +struct obj *objchn; +{ + struct obj *obj; + boolean vis = FALSE; + if (!objchn) + return; + + if (objchn->where == OBJ_INVENT) + vis = TRUE; /* even when blind; lit-state can be seen in inventory */ + else if (objchn->where == OBJ_MINVENT) + vis = canseemon(objchn->ocarry); + else if (objchn->where == OBJ_FLOOR) + vis = cansee(objchn->ox, objchn->oy); + else { + impossible("igniting item in a weird location %d", objchn->where); + return; + } + + for (obj = objchn; obj; obj = obj->nobj) { + if (!(ignitable(obj) || obj->otyp == MAGIC_LAMP) + /* The Candelabrum requires intention to be lit */ + || obj->otyp == CANDELABRUM_OF_INVOCATION + || obj->otyp == BRASS_LANTERN /* doesn't ignite via fire */ + || obj->in_use /* not available */ + || obj->lamplit) { /* already burning */ + continue; + } + begin_burn(obj, FALSE); + if (vis) + pline("%s on fire!", Yobjnam2(obj, "catch")); + } +} + /*trap.c*/ diff --git a/src/uhitm.c b/src/uhitm.c index 4a0b6f7e7..53a82d7d3 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1790,6 +1790,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } /* only potions damage resistant players in destroy_item */ tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); + ignite_items(mdef->minvent); break; case AD_COLD: if (negated) { diff --git a/src/zap.c b/src/zap.c index 049090edc..3910b909a 100644 --- a/src/zap.c +++ b/src/zap.c @@ -2428,6 +2428,7 @@ boolean ordinary; destroy_item(POTION_CLASS, AD_FIRE); destroy_item(SPBOOK_CLASS, AD_FIRE); destroy_item(FOOD_CLASS, AD_FIRE); /* only slime for now */ + ignite_items(g.invent); break; case WAN_COLD: @@ -3717,6 +3718,8 @@ struct obj **ootmp; /* to return worn armor for caller to disintegrate */ (void) destroy_mitem(mon, SCROLL_CLASS, AD_FIRE); if (!rn2(5)) (void) destroy_mitem(mon, SPBOOK_CLASS, AD_FIRE); + if (!rn2(3)) + ignite_items(mon->minvent); destroy_mitem(mon, FOOD_CLASS, AD_FIRE); /* carried slime */ } break; @@ -3874,6 +3877,8 @@ xchar sx, sy; destroy_item(SCROLL_CLASS, AD_FIRE); if (!rn2(5)) destroy_item(SPBOOK_CLASS, AD_FIRE); + if (!rn2(3)) + ignite_items(g.invent); destroy_item(FOOD_CLASS, AD_FIRE); } break; @@ -4035,6 +4040,9 @@ boolean u_caused; } } } + /* This also ignites floor items, but does not change cnt + because they weren't consumed. */ + ignite_items(g.level.objects[x][y]); return cnt; } From 92902fd1281adeb6342c75bb5f08527515002cfe Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 30 Sep 2020 21:45:45 -0400 Subject: [PATCH 251/708] make sure recover utily is built for the CROSSCOMPILE target --- sys/unix/hints/include/cross-post.2020 | 4 ++-- sys/unix/hints/include/cross-pre.2020 | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 7bc1288a6..1b4a984bb 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -18,7 +18,6 @@ $(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) $(TARGETPFX)tile.o : tile.c -$(TARGETPFX)recover.o : ../util/recover.c # #.PHONY: dospkg dospkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp @@ -123,8 +122,9 @@ $(TARGETPFX)pcunix.o : ../sys/share/pcunix.c $(HACK_H) $(TARGETPFX)tileset.o : ../win/share/tileset.c $(TARGETPFX)bmptiles.o : ../win/share/bmptiles.c $(TARGETPFX)giftiles.o : ../win/share/giftiles.c +$(TARGETPFX)recover.o : ../util/recover.c $(TARGETPFX)recover.exe : $(TARGETPFX)recover.o - + $(TARGET_LINK) $(TARGET_LFLAGS) -o $@ $(TARGETPFX)recover.o $(TARGET_LIBS) # # Lua lib $(LUACROSSLIB): $(LUALIBOBJS) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 258051f7d..e66275ea3 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -286,7 +286,9 @@ endif # WANT_WIN_CURSES # Rules for win/share files $(TARGETPFX)%.o : ../win/share/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< -# +# Rules for util files heading for target +$(TARGETPFX)%.o : ../util/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< # End of cross-compiling -PRE section #===============-================================================= From 2e90c1ebd44c0b64adbf24ec107acccd61cb6918 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 1 Oct 2020 03:16:14 -0700 Subject: [PATCH 252/708] implement "--More--" for Qt Support MSGTYPE=stop by having qt_display_nhwindow(WIN_MESSAGE,TRUE) issue a tty-style --More-- prompt. For popup_dialog Off, the prompt gets appended to the most recent message; for popup_dialog On, it is issued via a popup and not displayed in the message window. It accepts , ^J, ^M, and ^[ (ESC) to dismiss. There's no way to dismiss it with the mouse (for !popup_dialog) which might need some fix.... Several adventures along the way. The '^C-in-parent-terminal triggers infinite loop repeatedly complaining about "event loop already running"' is now a one-shot complaint. It isn't fixed but the severity of having it happen is greatly reduced. --- doc/fixes37.0 | 3 +- win/Qt/Qt-issues.txt | 14 +++-- win/Qt/qt_bind.cpp | 143 +++++++++++++++++++++++++++++++++++++------ win/Qt/qt_bind.h | 1 + win/Qt/qt_key.cpp | 2 +- win/Qt/qt_main.cpp | 8 +-- win/Qt/qt_msg.cpp | 77 +++++++++++++++-------- 7 files changed, 193 insertions(+), 55 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9355123bd..41ec6dcb5 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.309 $ $NHDT-Date: 1600933440 2020/09/24 07:44:00 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ $NHDT-Date: 1601547360 2020/10/01 10:16:00 $ General Fixes and Modified Features ----------------------------------- @@ -424,6 +424,7 @@ Qt: enable the popup_dialog WC option (result is a bit flakey but usable) Qt: 3.6 catchup - show unexplored locations as unexplored rather than as stone Qt: tried to honor 'showexp' but the value was unintentionally supressed by [lack of] obsolete conditional EXP_ON_BOTL +Qt: implement --More-- prompt to support MSGTYPE=stop Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index 612180399..ba7ad5c95 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -6,11 +6,15 @@ whether to [ignore], [report], or [restart] will eventually appear (it's slow). That should be repressed even if the report choice could be directed at nethack.org. -Urgent: launching Qt nethack as a synchronous subprocess (ie, no -trailing '&') from a Terminal window, changing focus back to that -terminal after NetHack has started, and typing ^C sends the program -into an endless loop with repeated messages to stderr (the terminal) -complaining that the event loop is already running. +Launching Qt nethack as a synchronous subprocess (ie, no trailing '&') +from a Terminal window, changing focus back to that terminal after +NetHack has started, and typing ^C was sending the program into an +endless loop in qt_nhgetch() with repeated messages to stderr +(the terminal) complaining that the event loop is already running. +Triggered by yn_function("Really quit?") in the core. That situation +has been reduced to a single event loop complaint, do downgraded from +"Urgent", but the prompt is auto-answered with ESC instead of letting +the user respond. On OSX, if the program is run from nethackdir/nethack rather than from NetHack.app/Contents/MacOS/nethack (plus having NetHack.app/Contents/ diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index defc0e0ad..821772eef 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -313,22 +313,26 @@ winid NetHackQtBind::qt_create_nhwindow(int type) void NetHackQtBind::qt_clear_nhwindow(winid wid) { NetHackQtWindow* window=id_to_window[(int)wid]; - window->Clear(); + if (window) + window->Clear(); } void NetHackQtBind::qt_display_nhwindow(winid wid, BOOLEAN_P block) { NetHackQtWindow* window=id_to_window[(int)wid]; - window->Display(block); + if (window) + window->Display(block); } void NetHackQtBind::qt_destroy_nhwindow(winid wid) { NetHackQtWindow* window=id_to_window[(int)wid]; - main->RemoveWindow(window); - if (window->Destroy()) - delete window; - id_to_window[(int)wid] = 0; + if (window) { + main->RemoveWindow(window); + if (window->Destroy()) + delete window; + id_to_window[(int) wid] = 0; + } } void NetHackQtBind::qt_curs(winid wid, int x, int y) @@ -476,7 +480,22 @@ int NetHackQtBind::qt_nhgetch() // Process events until a key arrives. // while (keybuffer.Empty()) { - qApp->exec(); + int exc = qApp->exec(); + /* + * On OSX (possibly elsewhere), this prevents an infinite + * loop repeatedly issuing the complaint: +QCoreApplication::exec: The event loop is already running + * to stderr if you syncronously start nethack from a terminal + * then switch focus back to that terminal and type ^C. + * SIGINT -> done1() -> done2() -> yn_function("Really quit?") + * in the core asks for another keystroke. + * + * However, it still issues one such complaint, and whatever + * prompt wanted a response ("Really quit?") is shown in the + * message window but is auto-answered with ESC. + */ + if (exc == -1) + keybuffer.Put('\033'); } // after getting a key rather than before @@ -494,7 +513,10 @@ int NetHackQtBind::qt_nh_poskey(int *x, int *y, int *mod) // Process events until a key or map-click arrives. // while (keybuffer.Empty() && clickbuffer.Empty()) { - qApp->exec(); + int exc = qApp->exec(); + // [see comment above in qt_nhgetch()] + if (exc == -1) + keybuffer.Put('\033'); } // after getting a key or click rather than before @@ -524,6 +546,70 @@ int NetHackQtBind::qt_doprev_message() return 0; } +// display "--More--" as a prompt and wait for a response from the user +// +// Used by qt_display_nhwindow(WIN_MESSAGE, TRUE) where second argument +// True requests blocking. We need it to support MSGTYPE=stop but the +// core also uses that in various other situations. +char NetHackQtBind::qt_more() +{ + char ch = '\033'; + + // without this gameover hack, quitting via menu or window close + // button ends up provoking a complaint from qt_nhgetch() [see the + // ^C comment in that routine] when the core triggers --More-- via + // done2() -> really_done() -> display_nhwindow(WIN_MESSAGE, TRUE) + // (get rid of this if the exec() loop issue gets properly fixed) + if (::g.program_state.gameover) + return ch; // bypass --More-- and just continue with program exit + + NetHackQtMessageWindow *mesgwin = main ? main->GetMessageWindow() : NULL; + + // kill any typeahead; for '!popup_dialog' this forces qt_nhgetch() + keybuffer.Drain(); + + if (mesgwin && !::iflags.wc_popup_dialog && WIN_MESSAGE != WIN_ERR) { + + mesgwin->AddToStr("--More--"); + bool retry = false; + int complain = 0; + do { + ch = NetHackQtBind::qt_nhgetch(); + switch (ch) { + case '\0': // hypothetical + ch = '\033'; + /*FALLTHRU*/ + case ' ': + case '\n': + case '\r': + case '\033': + retry = false; + break; + default: + if (++complain > 1) + NetHackQtBind::qt_nhbell(); + retry = true; + break; + } + } while (retry); + // unhighlight the line with the prompt; does not erase the window + NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); + + } else { + // use a popup dialog box; unlike yn_function(), we don't show + // the prompt+response in the message window + NetHackQtYnDialog dialog(main, "--More--", " \033\n\r", ' '); + ch = dialog.Exec(); + if (ch == '\0') { + ch = '\033'; + } + // discard any input that YnDialog() might have left pending + keybuffer.Drain(); + } + + return ch; +} + char NetHackQtBind::qt_yn_function(const char *question_, const char *choices, CHAR_P def) { @@ -533,10 +619,13 @@ char NetHackQtBind::qt_yn_function(const char *question_, int result = -1; if (choices) { - // anything beyond is hidden> - QString choicebuf = choices; - size_t cb = choicebuf.indexOf('\033'); - choicebuf = choicebuf.mid(0U, cb); + QString choicebuf((int) strlen(choices) + 1, QChar('\0')); + for (const char *p = choices; *p; ++p) { + if (*p == '\033') // and anything beyond is hidden + break; + choicebuf += visctrl(*p); + } + choicebuf.truncate(QBUFSZ - 1); // no effect if already shorter message = QString("%1 [%2] ").arg(question, choicebuf); if (def) message += QString("(%1) ").arg(QChar(def)); @@ -617,14 +706,16 @@ char NetHackQtBind::qt_yn_function(const char *question_, Sprintf(eos(cbuf), " %ld", ::yn_number); message += QString(" %1").arg(cbuf); - // add the prompt with appended response to the messsage window - NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); + // add the prompt with appended response to the message window + if (WIN_MESSAGE != WIN_ERR) + NetHackQtBind::qt_putstr(WIN_MESSAGE, ATR_BOLD, message); result = ret; } // unhighlight the prompt; does not erase the multi-line message window - NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); + if (WIN_MESSAGE != WIN_ERR) + NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); return (char) result; } @@ -747,6 +838,7 @@ void NetHackQtBind::qt_putmsghistory(const char *msg, BOOLEAN_P is_restoring) } } +// event loop callback bool NetHackQtBind::notify(QObject *receiver, QEvent *event) { // Ignore Alt-key navigation to menubar, it's annoying when you @@ -756,7 +848,9 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) return true; bool result = QApplication::notify(receiver, event); - if (event->type() == QEvent::KeyPress) { + int evtyp = event->type(); + + if (evtyp == QEvent::KeyPress) { QKeyEvent *key_event = (QKeyEvent *) event; if (!key_event->isAccepted()) { @@ -778,10 +872,11 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) if (ch > 128) ch = 0; // on OSX, ascii control codes are not sent, force them - if ((mod & Qt::ControlModifier) != 0) { - if (ch == 0 && k >= Qt::Key_A && k <= Qt::Key_Underscore) + if (ch == 0 && (mod & Qt::ControlModifier) != 0) { + if (k >= Qt::Key_A && k <= Qt::Key_Underscore) ch = (QChar) (k - (Qt::Key_A - 1)); } + //raw_printf("notify()=%d \"%s\"", k, visctrl(ch.cell())); // if we have a valid character, queue it up if (ch != 0) { bool alt = ((mod & Qt::AltModifier) != 0 @@ -792,6 +887,18 @@ bool NetHackQtBind::notify(QObject *receiver, QEvent *event) qApp->exit(); result = true; } + +#if 0 /* this was a failed attempt to prevent qt_more() from looping + * after command+q (on OSX) is used to bring up the quit dialog; + * now qt_more() uses an early return if program_state.gameover + * is set */ + } else if (evtyp == QEvent::FocusOut + || evtyp == QEvent::ShortcutOverride + || evtyp == QEvent::PlatformSurface) { + // leave qt_nhgetch()'s event loop if focus switches somewhere else + qApp->exit(); + result = false; +#endif } } return result; diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index e020a83d4..295fafc57 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -71,6 +71,7 @@ public: static int qt_nh_poskey(int *x, int *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_P def); static void qt_getlin(const char *prompt, char *line); diff --git a/win/Qt/qt_key.cpp b/win/Qt/qt_key.cpp index 81acb1786..060fc1eed 100644 --- a/win/Qt/qt_key.cpp +++ b/win/Qt/qt_key.cpp @@ -25,7 +25,7 @@ bool NetHackQtKeyBuffer::Full() const { return (in+1)%maxkey==out; } void NetHackQtKeyBuffer::Put(int k, int a, uint kbstate) { - //raw_printf("k:%3d a:%3d s:0x%08x", k, a, kbstate); + //raw_printf("k:%3d a:'%s' s:0x%08x", k, visctrl((char) a), kbstate); if ( Full() ) return; // Safety key[in] = k; ascii[in] = a; diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index e57a1a8e1..dffaf8614 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1225,10 +1225,10 @@ void NetHackQtMainWindow::keyPressEvent(QKeyEvent* event) if (message) message->Scroll(0,+1); break; case Qt::Key_Space: - if ( flags.rest_on_space ) { - event->ignore(); - return; - } + //if (flags.rest_on_space) { + event->ignore(); // punt to NetHackQtBind::notify() + return; + //} case Qt::Key_Enter: if ( map ) map->clickCursor(); diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index abde5c179..bdd8f535c 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -75,15 +75,16 @@ void NetHackQtMessageWindow::ClearMessages() list->clear(); } -void NetHackQtMessageWindow::Display(bool block UNUSED) +void NetHackQtMessageWindow::Display(bool block) { - // - // FIXME: support for 'block' is necessary for MSGTYPE=stop - // if (changed) { list->repaint(); changed=false; } + if (block) { + // we don't care what the response is here + (void) NetHackQtBind::qt_more(); + } } const char * NetHackQtMessageWindow::GetStr(bool init) @@ -113,49 +114,73 @@ void NetHackQtMessageWindow::PutStr(int attr, const QString& text) } else { text2 = text; } + #if 0 - QListWidgetItem *item = new QListWidgetItem(text2); - - QFont font = item->font(); - font.setUnderline(attr == ATR_ULINE); - font.setWeight((attr == ATR_BOLD) ? QFont::Bold : QFont::Normal); - item->setFont(font); - - if (attr == ATR_DIM || attr == ATR_INVERSE) { - QColor fg = item->foreground().color(); - QColor bg = item->background().color(); - if (attr == ATR_DIM) { - fg.setAlpha(fg.alpha() / 2); - new_fgbg = true; + if (attr != ATR_NONE) { + QListWidgetItem *item = new QListWidgetItem(text2); + if (attr != ATR_DIM && attr != ATR_INVERSE) { + QFont font = item->font(); + font.setUnderline(attr == ATR_ULINE); + font.setWeight((attr == ATR_BOLD) ? QFont::Bold : QFont::Normal); + item->setFont(font); + // ATR_BLINK not supported + } else { + // ATR_DIM or ATR_INVERSE + QBrush fg = item->foreground(); + QBrush bg = item->background(); + if (fg.color() == bg.color()) { // from menu coloring [AddRow()] + // default foreground and background come up the same for + // some unknown reason + //[pr: both are set to 'Qt::color1' which has same RGB + // value as 'Qt::black'; X11 on OSX behaves similarly] + if (fg.color() == Qt::color1) { + fg = Qt::black; + bg = Qt::white; + } else { + fg = (bg.color() == Qt::white) ? Qt::black : Qt::white; + } + } + if (attr == ATR_DIM) { + QColor fg_clr = fg.color(); + fg_clr.setAlpha(fg_clr.alpha() / 2); + item->setFlags(Qt::NoItemFlags); + } else if (attr == ATR_INVERSE) { + QBrush swapfb; + swapfb = fg; fg = bg; bg = swapfb; + } + item->setForeground(fg); + item->setBackground(bg); } - if (attr == ATR_INVERSE) { - QColor swap; - swap = fg; fg = bg; bg = swap; - } - item->setForeground(fg); - item->setBackground(bg); } - // ATR_BLINK not supported #endif if (list->count() >= (int) ::iflags.msg_history) delete list->item(0); list->addItem(text2); + /* assert( list->count() > 0 ); */ - // Force scrollbar to bottom + // force scrollbar to bottom; + // selects most recent message, which causes it to be highlighted list->setCurrentRow(list->count() - 1); if (map) map->putMessage(attr, text2); } -// append the user's answer to a prompt message +// append to the last message; usually the user's answer to a prompt void NetHackQtMessageWindow::AddToStr(const char *answer) { if (list) { QListWidgetItem *item = list->currentItem(); + int ct = 0; + if (!item && (ct = list->count()) > 0) { + list->setCurrentRow(ct - 1); + item = list->currentItem(); + } if (item) item->setText(item->text() + QString(" %1").arg(answer)); + else // just in case... + NetHackQtMessageWindow::PutStr(ATR_NONE, answer); } } From 1261aedd457f88796e8db0d5ae7dabe01cca2b7e Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 1 Oct 2020 10:04:05 -0400 Subject: [PATCH 253/708] more recover and cross-compiling --- sys/unix/hints/include/cross-post.2020 | 26 +++++++++++++++++--------- sys/unix/hints/include/cross-pre.2020 | 12 +++++++----- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 1b4a984bb..2c34d2189 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -18,12 +18,16 @@ $(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) $(TARGETPFX)tile.o : tile.c +$(GAMEBIN) : $(HOBJ) + $(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ + $(HOBJ) $(WINLIB) $(TARGET_LIBS) $(LUALIB) # -#.PHONY: dospkg +.PHONY: dospkg dospkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp $(TARGET_STUBEDIT) $(GAMEBIN) minstack=2048K mkdir -p $(TARGETPFX)pkg cp $(GAMEBIN) $(TARGETPFX)pkg/NETHACK.EXE + cp $(TARGETPFX)recover.exe $(TARGETPFX)pkg/RECOVER.EXE cp ../dat/nhdat $(TARGETPFX)pkg/NHDAT cp ../dat/license $(TARGETPFX)pkg/LICENSE cp ../dat/nhtiles.bmp $(TARGETPFX)pkg/NHTILES.BMP @@ -77,8 +81,11 @@ $(TARGETPFX)monsters.iff: ../win/share/monsters.txt ../util/txt2iff ../util/txt2iff ../win/share/monsters.txt $@ $(TARGETPFX)other.iff: ../win/share/other.txt ../util/txt2iff ../util/txt2iff ../win/share/other.txt $@ +$(GAMEBIN) : $(HOBJ) + $(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ + $(HOBJ) $(WINLIB) $(TARGET_LIBS) $(LUALIB) # -#.PHONY: amigapkg +.PHONY: amigapkg amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp mkdir -p $(TARGETPFX)pkg cp $(GAMEBIN) $(TARGETPFX)pkg/nethack @@ -112,9 +119,8 @@ amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp @echo amiga package zip file $(TARGETPFX)NH370AMI.ZIP endif # CROSS_TO_AMIGA -# +ifdef CROSS_SHARED # shared file dependencies -# $(TARGETPFX)pcmain.o : ../sys/share/pcmain.c $(HACK_H) $(TARGETPFX)pcsys.o : ../sys/share/pcsys.c $(HACK_H) $(TARGETPFX)pctty.o : ../sys/share/pctty.c $(HACK_H) @@ -124,8 +130,10 @@ $(TARGETPFX)bmptiles.o : ../win/share/bmptiles.c $(TARGETPFX)giftiles.o : ../win/share/giftiles.c $(TARGETPFX)recover.o : ../util/recover.c $(TARGETPFX)recover.exe : $(TARGETPFX)recover.o - $(TARGET_LINK) $(TARGET_LFLAGS) -o $@ $(TARGETPFX)recover.o $(TARGET_LIBS) + $(TARGET_LINK) $(TARGET_LFLAGS) $(TARGETPFX)recover.o -o $@ +endif # CROSS_SHARED # +ifdef BUILD_LUA # Lua lib $(LUACROSSLIB): $(LUALIBOBJS) if [ -f $@ ]; then rm $@; fi; @@ -173,9 +181,10 @@ $(TARGETPFX)lundump.o : $(LUATOP)/src/lundump.c $(TARGETPFX)lutf8lib.o : $(LUATOP)/src/lutf8lib.c $(TARGETPFX)lvm.o : $(LUATOP)/src/lvm.c $(TARGETPFX)lzio.o : $(LUATOP)/src/lzio.c -# +endif # BUILD_LUA + +ifdef BUILD_PDCURSES # PDCurses src -# $(TARGETPFX)addch.o : $(PDCTOP)/pdcurses/addch.c $(TARGETPFX)addchstr.o : $(PDCTOP)/pdcurses/addchstr.c $(TARGETPFX)addstr.o : $(PDCTOP)/pdcurses/addstr.c @@ -223,8 +232,7 @@ $(TARGETPFX)pdckbd.o : $(PDCTOP)/dos/pdckbd.c $(TARGETPFX)pdcscrn.o : $(PDCTOP)/dos/pdcscrn.c $(TARGETPFX)pdcsetsc.o : $(PDCTOP)/dos/pdcsetsc.c $(TARGETPFX)pdcutil.o : $(PDCTOP)/dos/pdcutil.c - - +endif # BUILD_PDCURSES # # End of cross-compiling -POST section #===============-================================================= diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index e66275ea3..174ad81e2 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -7,6 +7,7 @@ ifdef CROSS_TO_MSDOS BUILD_LUA=1 BUILD_PDCURSES=1 +CROSS_SHARED=1 override TARGET = msdos override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ @@ -16,6 +17,7 @@ endif ifdef CROSS_TO_AMIGA BUILD_LUA=1 BUILD_PDCURSES=1 +CROSS_SHARED=1 override TARGET = amiga override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ @@ -166,8 +168,7 @@ override GAMEBIN = $(TARGETPFX)nethack.exe override PACKAGE= dospkg VARDATND += nhtiles.bmp PREGAME = mkdir -p $(TARGETDIR) -CLEANMORE += rm -r $(TARGETDIR) -BUILDMORE += $(TARGETPFX)recover.exe +CLEANMORE += rm -f -r $(TARGETDIR) # ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files @@ -252,11 +253,10 @@ override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ # ../util/txt2iff.o override WINLIB= override LUALIB= -override GAMEBIN = $(TARGETPFX)nethack.exe +override GAMEBIN = $(TARGETPFX)nethack override PACKAGE= amigapkg PREGAME = mkdir -p ../targets/amiga CLEANMORE += rm -r ../targets/amiga -BUILDMORE += $(TARGETPFX)recover.exe # ../util/txt2iff # ifdef WANT_WIN_CURSES @@ -269,7 +269,7 @@ $(TARGETPFX)%.o : ../outdated/sys/amiga/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< endif # CROSS_TO_AMIGA #================================================================= - +ifdef CROSS_SHARED ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files $(TARGETPFX)%.o : $(PDCTOP)/sdl1/%.c @@ -289,6 +289,8 @@ $(TARGETPFX)%.o : ../win/share/%.c # Rules for util files heading for target $(TARGETPFX)%.o : ../util/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< +endif # CROSS_SHARED +# # End of cross-compiling -PRE section #===============-================================================= From ada5ffd627ff5834029f51c6c4c22e7706e541a7 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 1 Oct 2020 16:16:26 -0700 Subject: [PATCH 254/708] ggetobj bug when dropping just gold Noticed when testing something unrelated: for menustyle=traditional and =combination, when using 'D' to drop multiple items, if the player only supplied '$' for the list of object classes of interest then that list remained empty and all classes were processed. Caused by retaining an old special case for gold which isn't needed any more. I think that it only mattered for 'D'. Other callers of ggetobj() don't include gold as applicable so player can't pick gold hence can't pick just gold to trigger this. --- doc/fixes37.0 | 4 +++- src/invent.c | 14 +++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 41ec6dcb5..4f70d8dfa 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.315 $ $NHDT-Date: 1601547360 2020/10/01 10:16:00 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.316 $ $NHDT-Date: 1601594180 2020/10/01 23:16:20 $ General Fixes and Modified Features ----------------------------------- @@ -264,6 +264,8 @@ when make was invoked with -j makedefs instances could end up running in in mdlib.c so there is no requirement to define HAS_NO_MKSTEMP there make piranhas faster and give them extra bite attack fire sources can ignite candles, lamps, and potions of oil +for multiple drop ('D') with menustyle traditional or combination, if the only + object class player picked was '$' then it operated on all classes Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/invent.c b/src/invent.c index e33740ace..126947f99 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1596226443 2020/07/31 20:14:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.300 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1601594180 2020/10/01 23:16:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2102,9 +2102,7 @@ unsigned *resultflags; } } - if (oc_of_sym == COIN_CLASS && !combo) { - g.context.botl = 1; - } else if (sym == 'a') { + if (sym == 'a') { allflag = TRUE; } else if (sym == 'A') { ; /* same as the default */ @@ -2133,11 +2131,6 @@ unsigned *resultflags; ? -2 : -3; } else if (flags.menu_style != MENU_TRADITIONAL && combo && !allflag) { return 0; -#if 0 - /* !!!! test gold dropping */ - } else if (allowgold == 2 && !oletct) { - return 1; /* you dropped gold (or at least tried to) */ -#endif } else { int cnt = askchain(&g.invent, olets, allflag, fn, ckfn, mx, word); /* @@ -3232,8 +3225,7 @@ dotypeinv() } } if (traditional) { - /* collect a list of classes of objects carried, for use as a prompt - */ + /* collect list of classes of objects carried, for use as a prompt */ types[0] = 0; class_count = collect_obj_classes(types, g.invent, FALSE, (boolean FDECL((*), (OBJ_P))) 0, From 9045ccb63d23e0e575fbf5fff706e0d6d74abb39 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 1 Oct 2020 16:41:56 -0700 Subject: [PATCH 255/708] venom fixes Noticed when fixing 'D$'. Some commands, including D, which should have been handling venom weren't doing so. I'm not sure whether I got all the applicable cases. --- doc/fixes37.0 | 5 ++++- include/hack.h | 42 ++++++++++++++++++++++-------------------- src/do.c | 10 ++++++---- src/invent.c | 11 ++++++----- src/pickup.c | 20 +++++++++++++------- 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4f70d8dfa..325db0d6b 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.316 $ $NHDT-Date: 1601594180 2020/10/01 23:16:20 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.317 $ $NHDT-Date: 1601595709 2020/10/01 23:41:49 $ General Fixes and Modified Features ----------------------------------- @@ -227,6 +227,9 @@ hero poly'd into a mind flayer who used #monster to emit a psychic blast was able to harm mindless monsters with it some hero attacks that should have gotten a skill bonus or penalty didn't change internal name of " venom" to "splash of venom" +some operations that made sense to handle venom ('D', scroll of identify, no + doubt others) ignored it because venom is suppressed from packorder; + matters for wizard mode or for normal play that loads wizard bones singularize "splashes" to "splash" instead of "splashe" treat slinging gems and tossing or slinging stones at unicorns as attacks give rot-away timer instead of revive timer to corpses of cancelled trolls diff --git a/include/hack.h b/include/hack.h index ae66209e6..9900d5426 100644 --- a/include/hack.h +++ b/include/hack.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.h $NHDT-Date: 1596498538 2020/08/03 23:48:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 3.7 hack.h $NHDT-Date: 1601595709 2020/10/01 23:41:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -346,27 +346,29 @@ typedef struct sortloot_item Loot; #define ALL_FINISHED 0x01 /* called routine already finished the job */ /* flags to control query_objlist() */ -#define BY_NEXTHERE 0x01 /* follow objlist by nexthere field */ -#define AUTOSELECT_SINGLE 0x02 /* if only 1 object, don't ask */ -#define USE_INVLET 0x04 /* use object's invlet */ -#define INVORDER_SORT 0x08 /* sort objects by packorder */ -#define SIGNAL_NOMENU 0x10 /* return -1 rather than 0 if none allowed */ -#define SIGNAL_ESCAPE 0x20 /* return -2 rather than 0 for ESC */ -#define FEEL_COCKATRICE 0x40 /* engage cockatrice checks and react */ -#define INCLUDE_HERO 0x80 /* show hero among engulfer's inventory */ +#define BY_NEXTHERE 0x0001 /* follow objlist by nexthere field */ +#define INCLUDE_VENOM 0x0002 /* include venom objects if present */ +#define AUTOSELECT_SINGLE 0x0004 /* if only 1 object, don't ask */ +#define USE_INVLET 0x0008 /* use object's invlet */ +#define INVORDER_SORT 0x0010 /* sort objects by packorder */ +#define SIGNAL_NOMENU 0x0020 /* return -1 rather than 0 if none allowed */ +#define SIGNAL_ESCAPE 0x0040 /* return -2 rather than 0 for ESC */ +#define FEEL_COCKATRICE 0x0080 /* engage cockatrice checks and react */ +#define INCLUDE_HERO 0x0100 /* show hero among engulfer's inventory */ /* Flags to control query_category() */ -/* BY_NEXTHERE used by query_category() too, so skip 0x01 */ -#define UNPAID_TYPES 0x002 -#define GOLD_TYPES 0x004 -#define WORN_TYPES 0x008 -#define ALL_TYPES 0x010 -#define BILLED_TYPES 0x020 -#define CHOOSE_ALL 0x040 -#define BUC_BLESSED 0x080 -#define BUC_CURSED 0x100 -#define BUC_UNCURSED 0x200 -#define BUC_UNKNOWN 0x400 +/* BY_NEXTHERE and INCLUDE_VENOM are used by query_category() too, so + skip 0x0001 and 0x0002 */ +#define UNPAID_TYPES 0x0004 +#define GOLD_TYPES 0x0008 +#define WORN_TYPES 0x0010 +#define ALL_TYPES 0x0020 +#define BILLED_TYPES 0x0040 +#define CHOOSE_ALL 0x0080 +#define BUC_BLESSED 0x0100 +#define BUC_CURSED 0x0200 +#define BUC_UNCURSED 0x0400 +#define BUC_UNKNOWN 0x0800 #define BUC_ALLBKNOWN (BUC_BLESSED | BUC_CURSED | BUC_UNCURSED) #define BUCX_TYPES (BUC_ALLBKNOWN | BUC_UNKNOWN) #define ALL_TYPES_SELECTED -2 diff --git a/src/do.c b/src/do.c index 580c701c0..6aaee1407 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do.c $NHDT-Date: 1598575088 2020/08/28 00:38:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ */ +/* NetHack 3.7 do.c $NHDT-Date: 1601595709 2020/10/01 23:41:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -845,8 +845,9 @@ int retry; } else if (flags.menu_style == MENU_FULL) { all_categories = FALSE; n = query_category("Drop what type of items?", g.invent, - UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL | BUC_BLESSED - | BUC_CURSED | BUC_UNCURSED | BUC_UNKNOWN, + (UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL + | BUC_BLESSED | BUC_CURSED | BUC_UNCURSED + | BUC_UNKNOWN | INCLUDE_VENOM), &pick_list, PICK_ANY); if (!n) goto drop_done; @@ -897,7 +898,8 @@ int retry; } else { /* should coordinate with perm invent, maybe not show worn items */ n = query_objlist("What would you like to drop?", &g.invent, - (USE_INVLET | INVORDER_SORT), &pick_list, PICK_ANY, + (USE_INVLET | INVORDER_SORT | INCLUDE_VENOM), + &pick_list, PICK_ANY, all_categories ? allow_all : allow_category); if (n > 0) { /* diff --git a/src/invent.c b/src/invent.c index 126947f99..eeb540449 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1601594180 2020/10/01 23:16:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.301 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1601595710 2020/10/01 23:41:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.302 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2116,11 +2116,11 @@ unsigned *resultflags; m_seen = TRUE; } else if (oc_of_sym == MAXOCLASSES) { You("don't have any %c's.", sym); - } else if (oc_of_sym != VENOM_CLASS) { /* suppress venom */ + } else { if (!index(olets, oc_of_sym)) { add_valid_menu_class(oc_of_sym); olets[oletct++] = oc_of_sym; - olets[oletct] = 0; + olets[oletct] = '\0'; } } } @@ -2360,7 +2360,7 @@ int id_limit; Sprintf(buf, "What would you like to identify %s?", first ? "first" : "next"); n = query_objlist(buf, &g.invent, (SIGNAL_NOMENU | SIGNAL_ESCAPE - | USE_INVLET | INVORDER_SORT), + | USE_INVLET | INVORDER_SORT), &pick_list, PICK_ANY, not_fully_identified); if (n > 0) { @@ -3217,6 +3217,7 @@ dotypeinv() i |= BUC_CURSED; if (xcnt) i |= BUC_UNKNOWN; + i |= INCLUDE_VENOM; n = query_category(prompt, g.invent, i, &pick_list, PICK_ONE); if (!n) return 0; @@ -3341,7 +3342,7 @@ dotypeinv() } if (query_objlist((char *) 0, &g.invent, ((flags.invlet_constant ? USE_INVLET : 0) - | INVORDER_SORT), + | INVORDER_SORT | INCLUDE_VENOM), &pick_list, PICK_NONE, this_type_only) > 0) free((genericptr_t) pick_list); return 0; diff --git a/src/pickup.c b/src/pickup.c index ad6644dfb..ddabf097c 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pickup.c $NHDT-Date: 1596498195 2020/08/03 23:43:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.271 $ */ +/* NetHack 3.7 pickup.c $NHDT-Date: 1601595711 2020/10/01 23:41:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.272 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -910,7 +910,7 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ int i, n; winid win; struct obj *curr, *last, fake_hero_object, *olist = *olist_p; - char *pack; + char *pack, packbuf[MAXOCLASSES + 1]; anything any; boolean printed_type_name, first, sorted = (qflags & INVORDER_SORT) != 0, @@ -970,7 +970,9 @@ boolean FDECL((*allow), (OBJ_P)); /* allow function */ * each type so we can group them. The allow function was * called by sortloot() and will be called once per item here. */ - pack = flags.inv_order; + pack = strcpy(packbuf, flags.inv_order); + if (qflags & INCLUDE_VENOM) + (void) strkitten(pack, VENOM_CLASS); /* venom is not in inv_order */ first = TRUE; do { printed_type_name = FALSE; @@ -1095,7 +1097,7 @@ int how; /* type of query */ int n; winid win; struct obj *curr; - char *pack; + char *pack, packbuf[MAXOCLASSES + 1]; anything any; boolean collected_type_name; char invlet; @@ -1154,7 +1156,10 @@ int how; /* type of query */ win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); - pack = flags.inv_order; + + pack = strcpy(packbuf, flags.inv_order); + if (qflags & INCLUDE_VENOM) + (void) strkitten(pack, VENOM_CLASS); /* venom is not in inv_order */ if (qflags & CHOOSE_ALL) { invlet = 'A'; @@ -2990,13 +2995,14 @@ boolean put_in; } } } else { - mflags = INVORDER_SORT; + mflags = INVORDER_SORT | INCLUDE_VENOM; if (put_in && flags.invlet_constant) mflags |= USE_INVLET; if (!put_in) g.current_container->cknown = 1; Sprintf(buf, "%s what?", action); - n = query_objlist(buf, put_in ? &g.invent : &(g.current_container->cobj), + n = query_objlist(buf, + put_in ? &g.invent : &(g.current_container->cobj), mflags, &pick_list, PICK_ANY, all_categories ? allow_all : allow_category); if (n) { From d1e1b0cdc9c88997e6cd2517e78d99e55160faa0 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 1 Oct 2020 17:59:58 -0700 Subject: [PATCH 256/708] Qt popup_dialog's count entry For Qt with 'popup_dialog' On, fix number entry when user types a digit (or '#') directly onto the dialog instead of clicking inside the Count box and then typing. Before, that first typed digit was starting out as selected, so typing the next digit replaced the selection instead of getting appended to the string of digits being constructed. Fixed by moving the relevant code to the KeyPress handler instead of re-executing the dialog. Also, if a keypress is just a modifier, ignore it. The next event should be the actual character. Prevents treating (and !) as useless dialog responses. Before this, attempting to type '#' to initiate a count wouldn't work because the part of shift+3 ended the dialog. Now '#' works (and is still optional; starting with a digit suffices). --- doc/fixes37.0 | 7 ++- win/Qt/qt_main.cpp | 4 +- win/Qt/qt_yndlg.cpp | 118 ++++++++++++++++++-------------------------- win/Qt/qt_yndlg.h | 2 + 4 files changed, 54 insertions(+), 77 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 325db0d6b..d5b868888 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.317 $ $NHDT-Date: 1601595709 2020/10/01 23:41:49 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.318 $ $NHDT-Date: 1601600393 2020/10/02 00:59:53 $ General Fixes and Modified Features ----------------------------------- @@ -389,7 +389,6 @@ Qt: when selecting an extended command by typing its name, support Qt: switch to fixed-width font for menus Qt: don't disable [cancel] button when viewing inventory or other pick-none menus; ESC works to dismiss those and [cancel] should be the same -Qt: bring status conditions up to 3.6 levels but new ones lack pictures Qt: clicking on the window's Close button brought up a dialog offering choices of "Save" and "Cancel"; picking Cancel sent nethack into an infinite loop with complaints about Qt's event loop already being @@ -427,8 +426,8 @@ Qt: update message window's last message with player's response if it's a Qt: for line input, display the prompt+response in the message window Qt: enable the popup_dialog WC option (result is a bit flakey but usable) Qt: 3.6 catchup - show unexplored locations as unexplored rather than as stone -Qt: tried to honor 'showexp' but the value was unintentionally supressed by - [lack of] obsolete conditional EXP_ON_BOTL +Qt: tried to honor 'showexp' but the value was unintentionally suppressed by + [lack of definition for] obsolete conditional EXP_ON_BOTL Qt: implement --More-- prompt to support MSGTYPE=stop Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index dffaf8614..de4dff75c 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -956,7 +956,7 @@ void NetHackQtMainWindow::doQuit(bool) case 0: // quit -- bypass the prompting preformed by done2() g.program_state.stopprint++; - done(QUIT); + ::done(QUIT); /*NOTREACHED*/ break; case 1: @@ -1260,7 +1260,7 @@ void NetHackQtMainWindow::closeEvent(QCloseEvent *e UNUSED) // quit -- bypass the prompting preformed by done2() ok = 1; g.program_state.stopprint++; - done(QUIT); + ::done(QUIT); /*NOTREACHED*/ break; } diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 110f2b784..a696fdb92 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -35,7 +35,9 @@ NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent, const QString &q, const char *ch, char df) : QDialog(parent), question(q), choices(ch), def(df), - keypress('\033') + keypress('\033'), + allow_count(false), + le((QLineEdit *) NULL) { setWindowTitle("NetHack: Question"); @@ -49,6 +51,7 @@ NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent, const QString &q, if (choices) { // special handling for wearing rings; prompt asks "right or left?" // but side-by-side buttons look better with [left][right] instead + // (assumes that we're using left to right layout) if (!strcmp(choices, "rl")) { choices = lrq; if (!def) @@ -57,6 +60,7 @@ NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent, const QString &q, // if count is allowed, explicitly add the digits as valid } else if (!strncmp(choices, "yn#", (size_t) 3)) { ::yn_number = 0L; + allow_count = true; if (!strchr(choices, '9')) { copynchars(altchoices, choices, BUFSZ - 1); @@ -148,8 +152,7 @@ char NetHackQtYnDialog::Exec() QButtonGroup *bgroup = new QButtonGroup(group); int nchoices=ch.length(); - bool allow_count = (ch.left(3) == QString("yn#")), - is_ynq = (ch == QString("ynq")), // [ Yes ][ No ][Cancel] + bool is_ynq = (ch == QString("ynq")), // [ Yes ][ No ][Cancel] is_yn = (ch == QString("yn")), // [Yes ][ No ] is_lr = (ch == QString(lrq)); // [ Left ][Right ] @@ -160,7 +163,7 @@ char NetHackQtYnDialog::Exec() int butheight = fontMetrics().height() * 2 + 5, butwidth = (butheight - 5) * ((is_ynq || is_lr) ? 3 : is_yn ? 2 : 1) + 5; - if (butwidth == butheight) { // square, room for one character or ^c + if (butwidth == butheight) { // square, enough room for C or ^C // some characters will be labelled by name rather than by // keystroke so will need wider buttons for (int i = 0; i < nchoices; ++i) { @@ -248,7 +251,6 @@ char NetHackQtYnDialog::Exec() connect(bgroup, SIGNAL(buttonClicked(int)), this, SLOT(doneItem(int))); QLabel *lb = 0; - QLineEdit *le = 0; if (allow_count) { // put the Count widget in between [y] and [n][a][q] lb = new QLabel("Count:"); @@ -278,63 +280,24 @@ char NetHackQtYnDialog::Exec() // typing in digits followed by is 'normal' operation. // However, typing a digit without clicking first will set focus // to the count widget with that typed digit preloaded. - // FIXME: Unfortunately, it will also be selected, so typing - // another digit replaces it instead of being the next digit in - // a multiple-digit number. // - // Theoretically typing '#' does this to, with a 0 preloaded - // and intentionally selected, but the KeyPress bug (below) of - // treating as a complete response prevents use of - // shift+3 from being used to generate '#'. - // - bool retry; // for digit + re-activate widget + rest of number - do { - retry = false; // might have a second pass (but not a third) - exec(); - int res = result(); - if (res == 0) { - choice = is_lr ? '\033' : ch_esc ? ch_esc : def ? def : ' '; - } else if (res == 1) { - choice = def ? def : ch_esc ? ch_esc : ' '; - } else if (res >= 1000) { - choice = (char) ch[res - 1000].cell(); - - if (allow_count && strchr("#0123456789", choice)) { - if (choice == '#') { - // 0 will be preselected; typing anything replaces it - le->insert(QString("0")); - } else { -#if 1 - le->insert(QString(choice)); - // - // FIXME: despite the documentation claiming that - // 'false' cancels any selection, the digit always - // starts out selected (from running exec() again?) - // so typing the next digit replaces it instead of - // being appended to it unless the player uses - // right-arrow to move the cursor. - // - le->end(false); -#else - // this also claims to cancel any selection and - // position the cursor after the text but actually - // leaves the digit selected, ready to be overwritten - le->setText(QString(choice)); - le->setModified(true); -#endif - } - // (don't know whether this actually does anything useful) - le->setAttribute(Qt::WA_KeyboardFocusChange, true); - le->setFocus(Qt::ActiveWindowFocusReason); - retry = true; - } - } - } while (retry); + exec(); + int res = result(); + if (res == 0) { + choice = is_lr ? '\033' : ch_esc ? ch_esc : def ? def : ' '; + } else if (res == 1) { + choice = def ? def : ch_esc ? ch_esc : ' '; + } else if (res >= 1000) { + choice = (char) ch[res - 1000].cell(); + } // non-Null 'le' implies 'allow_count'; having a grayed-out '#' // present in the QLineEdit widget doesn't affect its isEmpty() test if (le && !le->text().isEmpty()) { - ::yn_number = le->text().toLong(); + QString text(le->text()); + if (text[0] == "#") + text = text.mid(1); + ::yn_number = text.toLong(); choice = '#'; } keypress = choice; @@ -358,24 +321,37 @@ char NetHackQtYnDialog::Exec() void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) { - // - // FIXME: on OSX (possibly elsewhere), this accepts - // (and even ) as the entire response before the user - // has a chance to type any character to be shifted. - // - - // Don't want QDialog's Return/Esc behaviour - //RLC ...or do we? QString text(event->text()); - if (choices == NULL || choices[0] == 0) { - if (text != "") { + if (text.isEmpty() && event->modifiers()) + return; + + if (!choices || !*choices) { + if (!text.isEmpty()) { keypress = text.toUcs4()[0]; - done(1); + this->done(1); } + } else { int where = QString::fromLatin1(choices).indexOf(text); - if (where != -1 && text != "#") { - done(where+1000); + + if (where != -1 && allow_count + && strchr("#0123456789", text[0].cell())) { + if (text == "#") { + // 0 will be preselected; typing anything replaces it + le->setText(QString("0")); + le->home(true); + } else { + // digit will not be preselected; typing another appends + le->setText(text); + le->end(false); + } + // (don't know whether this actually does anything useful) + le->setAttribute(Qt::WA_KeyboardFocusChange, true); + le->setFocus(Qt::ActiveWindowFocusReason); + + } else if (where != -1) { + this->done(where + 1000); + } else { QDialog::keyPressEvent(event); } @@ -384,7 +360,7 @@ void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) void NetHackQtYnDialog::doneItem(int i) { - done(i+1000); + this->done(i + 1000); } } // namespace nethack_qt_ diff --git a/win/Qt/qt_yndlg.h b/win/Qt/qt_yndlg.h index 079d7119f..049886355 100644 --- a/win/Qt/qt_yndlg.h +++ b/win/Qt/qt_yndlg.h @@ -16,6 +16,8 @@ private: const char* choices; char def; char keypress; + bool allow_count; + QLineEdit *le; protected: virtual void keyPressEvent(QKeyEvent*); From aaf88f9662278e805e66b6f3f94d866500b5a69a Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 2 Oct 2020 04:51:15 -0700 Subject: [PATCH 257/708] Qt build fix The failing Travis build issued about 500 lines of diagnostics when complaining about one line of the source. It compiled ok for me but I use older versions of Qt library and C++ compiler. --- win/Qt/qt_yndlg.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index a696fdb92..7ae167da2 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -295,8 +295,8 @@ char NetHackQtYnDialog::Exec() // present in the QLineEdit widget doesn't affect its isEmpty() test if (le && !le->text().isEmpty()) { QString text(le->text()); - if (text[0] == "#") - text = text.mid(1); + if (text.at(0) == QChar('#')) + text = text.mid(1); // rest of string past [0] ::yn_number = text.toLong(); choice = '#'; } From 396b819988c1bf2af9be8a16596c0d28f6f98eb4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Oct 2020 18:50:19 +0300 Subject: [PATCH 258/708] Add safe_wait to toggle search and wait prevention --- doc/Guidebook.mn | 11 +++++++++-- doc/Guidebook.tex | 10 ++++++++-- doc/fixes37.0 | 3 ++- include/extern.h | 1 + include/flag.h | 1 + include/optlist.h | 2 ++ src/detect.c | 13 +++---------- src/do.c | 34 ++++++++++++++++++++++++---------- 8 files changed, 50 insertions(+), 25 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index a73b5dc8e..5dc432bd2 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -675,7 +675,9 @@ support, the command is also invoked when a mouse-click takes place on a location other than the current position. .lp . Wait or rest, do nothing for one turn. Precede with the \(oqm\(cq prefix -to wait for a turn even next to a hostile monster. +to wait for a turn even next to a hostile monster, if +.op safe_wait +is on. .lp a Apply (use) a tool (pick-axe, key, lamp...). .lp "" @@ -884,7 +886,9 @@ Redraw the screen. Search for secret doors and traps around you. It usually takes several tries to find something. Precede with the \(oqm\(cq prefix to search for a turn -even next to a hostile monster. +even next to a hostile monster, if +.op safe_wait +is on. .lp "" Can also be used to figure out whether there is still a monster at an adjacent \(lqremembered, unseen monster\(rq marker. @@ -3987,6 +3991,9 @@ Persistent. .lp safe_pet Prevent you from (knowingly) attacking your pets (default on). Persistent. +.lp safe_wait +Prevents you from waiting or searching when next to a hostile monster +(default on). Persistent. .lp sanity_check Evaluate monsters, objects, and map prior to each turn (default off). Debug mode only. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 16b662884..689266954 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -769,7 +769,8 @@ location other than the current position. %.lp \item[\tb{.}] Wait or rest, do nothing for one turn. Precede with the `{\tt m}' prefix -to wait for a turn even next to a hostile monster. +to wait for a turn even next to a hostile monster, if {\it safe\verb+_+wait\/} +is on. %.lp \item[\tb{a}] Apply (use) a tool (pick-axe, key, lamp \ldots).\\ @@ -968,7 +969,8 @@ Redraw the screen. Search for secret doors and traps around you. It usually takes several tries to find something. Precede with the `{\tt m}' prefix to wait for a turn -even next to a hostile monster.\\ +even next to a hostile monster, if {\it safe\verb+_+wait\/} +is on.\\ %.lp "" Can also be used to figure out whether there is still a monster at an adjacent ``remembered, unseen monster'' marker. @@ -4307,6 +4309,10 @@ depend upon the window port used or on the type of terminal. Persistent. %.lp \item[\ib{safe\verb+_+pet}] Prevent you from (knowingly) attacking your pets (default on). Persistent. +%.lp +\item[\ib{safe\verb+_+wait}] +Prevents you from waiting or searching when next to a hostile monster +(default on). Persistent. %+.lp \item[\ib{sanity\verb+_+check}] Evaluate monsters, objects, and map prior to each turn (default off). diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d5b868888..b5dae5e94 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -126,7 +126,8 @@ it's possible to wish for tins of the Riders in wizard mode; eating one is fatal but if you're life-saved or decline to die, the game crashed revival via undead turning of corpse carried by hero said "your corpse comes alive" even when revived monster was undead -prevent searching or waiting next to a hostile monster - override with 'm' +prevent searching or waiting next to a hostile monster if boolean option + safe_wait is on - override with 'm' allow random mimics to show up mimicing more furniture than just stairs scatter exploding bag of holding contents instead of outright deleting them male hero poly'd into nymph chooses charm vs seduce message based on being diff --git a/include/extern.h b/include/extern.h index 7e4af0781..101293ab7 100644 --- a/include/extern.h +++ b/include/extern.h @@ -424,6 +424,7 @@ E void FDECL(schedule_goto, (d_level *, BOOLEAN_P, BOOLEAN_P, int, E void NDECL(deferred_goto); E boolean FDECL(revive_corpse, (struct obj *)); E void FDECL(revive_mon, (ANY_P *, long)); +E boolean FDECL(cmd_safety_prevention, (char *, char *, int *)); E int NDECL(donull); E int NDECL(dowipe); E void FDECL(legs_in_no_shape, (const char *, BOOLEAN_P)); diff --git a/include/flag.h b/include/flag.h index ddb86720d..5a0f0213e 100644 --- a/include/flag.h +++ b/include/flag.h @@ -52,6 +52,7 @@ struct flag { * clairvoyance */ boolean rest_on_space; /* space means rest */ boolean safe_dog; /* give complete protection to the dog */ + boolean safe_wait; /* prevent wait or search next to hostile */ boolean showexp; /* show experience points */ boolean showscore; /* show score */ boolean silent; /* whether the bell rings or not */ diff --git a/include/optlist.h b/include/optlist.h index 085b527b1..c8d4f28e8 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -379,6 +379,8 @@ pfx_##a, NoAlias, "display frequency when `running' or `travelling'") NHOPTB(safe_pet, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.safe_dog) + NHOPTB(safe_wait, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, + &flags.safe_wait) NHOPTB(sanity_check, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.sanity_check) NHOPTC(scores, 32, opt_in, set_in_game, No, Yes, No, No, NoAlias, diff --git a/src/detect.c b/src/detect.c index 3fa2ae9ca..29acd7a18 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1868,17 +1868,10 @@ register int aflag; /* intrinsic autosearch vs explicit searching */ int dosearch() { - if (!iflags.menu_requested && !g.multi && monster_nearby()) { - char buf[QBUFSZ]; - - buf[0] = '\0'; - if (iflags.cmdassist || !g.already_found_flag++) - Sprintf(buf, " Use '%s' prefix to force another search.", - visctrl(g.Cmd.spkeys[NHKF_REQMENU])); /* default is "m" */ - Norep("You already found a monster.%s", buf); + if (cmd_safety_prevention("another search", + "You already found a monster.", + &g.already_found_flag)) return 0; - } - g.already_found_flag = 0; /* start over */ return dosearch0(0); } diff --git a/src/do.c b/src/do.c index 6aaee1407..3156e5132 100644 --- a/src/do.c +++ b/src/do.c @@ -1982,22 +1982,36 @@ long timeout UNUSED; } } +boolean +cmd_safety_prevention(cmddesc, act, flagcounter) +char *cmddesc; +char *act; +int *flagcounter; +{ + if (flags.safe_wait && !iflags.menu_requested + && !g.multi && monster_nearby()) { + char buf[QBUFSZ]; + + buf[0] = '\0'; + if (iflags.cmdassist || !*flagcounter++) + Sprintf(buf, " Use '%s' prefix to force %s.", + visctrl(g.Cmd.spkeys[NHKF_REQMENU]), cmddesc); + Norep("%s%s", act, buf); + return TRUE; + } + *flagcounter = 0; + return FALSE; +} + /* '.' command: do nothing == rest; also the ' ' command iff 'rest_on_space' option is On */ int donull() { - if (!iflags.menu_requested && !g.multi && monster_nearby()) { - char buf[QBUFSZ]; - - buf[0] = '\0'; - if (iflags.cmdassist || !g.did_nothing_flag++) - Sprintf(buf, " Use '%s' prefix to force a no-op (to rest).", - visctrl(g.Cmd.spkeys[NHKF_REQMENU])); /* default is "m" */ - Norep("Are you waiting to get hit?%s", buf); + if (cmd_safety_prevention("a no-op (to rest)", + "Are you waiting to get hit?", + &g.did_nothing_flag)) return 0; - } - g.did_nothing_flag = 0; /* reset */ return 1; /* Do nothing, but let other things happen */ } From fac154d364fa9cba3e9ec8c692181780bc5cee95 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Oct 2020 19:00:16 +0300 Subject: [PATCH 259/708] Fix some Guidebook.tex errors --- doc/Guidebook.tex | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 689266954..da8f7696d 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -2840,7 +2840,7 @@ That's done implicitly to avoid unnecessary tedium. %.pg The commands to use rings are `{\tt P}' (put on) and `{\tt R}' (remove). -`{\tt A|', `{\tt W}', and `{\tt T}' can also be used; see {\it Amulets\/}. +`{\tt A}', `{\tt W}', and `{\tt T}' can also be used; see {\it Amulets\/}. %.hn 2 \subsection*{Spellbooks (`{\tt +}')} @@ -3173,7 +3173,7 @@ 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 +The {\tt \#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, providing you with a way to discover which actions incur bad luck so that you can be better informed about whether @@ -3290,7 +3290,7 @@ Losing enough levels to revert to lower rank(s) does not discard the corresponding achievement(s). %.pg -The ``special items'' hidden in {\it Mines'~End\/} and (\it Sokoban\/} +The ``special items'' hidden in {\it Mines'~End\/} and {\it 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. @@ -3363,7 +3363,7 @@ Empty lines are ignored. Any line beginning with `{\tt [}' and ending in `{\tt ]}' is a section marker (the closing `{\tt ]}' can be followed -by whitespace and then an arbitrary comment beginning with `{\tt #}'). +by whitespace and then an arbitrary comment beginning with `{\tt \#}'). 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. From 40648503b21758a64bdb50ae90c24e8a6051e8cb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 2 Oct 2020 19:11:15 +0300 Subject: [PATCH 260/708] Increment EDITLEVEL due to safe_wait --- include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/patchlevel.h b/include/patchlevel.h index b5cda35a8..29450b3cf 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 22 +#define EDITLEVEL 23 /* * Development status possibilities. From af739196cf732f746c62517b0e409d93feb8ee1a Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 2 Oct 2020 12:29:26 -0400 Subject: [PATCH 261/708] bump Guidebook date to reflect most recent changes --- 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 5dc432bd2..49eea8730 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "August 5, 2020 +.ds f2 "October 2, 2020 . .\" A note on some special characters: .\" \(lq = left double quote diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index da8f7696d..00154f042 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{August 5, 2020} +\date{October 2, 2020} \maketitle From ee08122771d97a094b3988ae406ec0536e855527 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 2 Oct 2020 12:32:11 -0400 Subject: [PATCH 262/708] Guidebook.txt update --- doc/Guidebook.txt | 1526 ++++++++++++++++++++++----------------------- 1 file changed, 763 insertions(+), 763 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 2691c508c..e4873f630 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - August 5, 2020 + October 2, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -740,23 +740,24 @@ tion. . Wait or rest, do nothing for one turn. Precede with the `m' - prefix to wait for a turn even next to a hostile monster. + prefix 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 + 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 + Use `T' (take off) to take off only one piece of armor or `R' (remove) to take off only one accessory. ^A Redo the previous command. c Close a door. - C Call (name) a monster, an individual object, or a type of + C Call (name) a monster, an individual object, or a type of object. Same as extended command "#name". @@ -773,9 +774,9 @@ "What kinds of things do you want to drop? [!%= BUCXaium]" - you should type zero or more object symbols possibly fol- + you should type zero or more object symbols possibly fol- lowed by `a' and/or `i' and/or `u' and/or `m'. In addition, - one or more of the blessed/uncursed/cursed groups may be + one or more of the blessed/uncursed/cursed groups may be typed. DB - drop all objects known to be blessed. @@ -783,10 +784,9 @@ DC - drop all objects known to be cursed. DX - drop all objects of unknown B/U/C status. Da - drop all objects, without asking for confirmation. - Di - examine your inventory before dropping anything. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -796,38 +796,39 @@ + Di - examine your inventory before dropping anything. Du - drop only unpaid objects (when in a shop). 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 three cate- - gories of object filtering: class (`!' for potions, `?' for - scrolls, and so on), shop status (`u' for unpaid, in other - words, owned by the shop), and bless/curse state (`B', `U', - `C', and `X' as shown above). If you specify more than one + gories of object filtering: class (`!' for potions, `?' for + scrolls, and so on), shop status (`u' for unpaid, in other + words, owned by the shop), and bless/curse state (`B', `U', + `C', and `X' as shown above). 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 + "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 category - criteria (so "%u" means class `%' and unpaid `u'). Lastly, - you may specify multiple values within multiple categories: - "!?BU" will select all potions and scrolls which are known - to be blessed or uncursed. (In versions prior to 3.6, fil- + criteria (so "%u" means class `%' and unpaid `u'). Lastly, + you may specify multiple values within multiple categories: + "!?BU" will select all potions and scrolls which are known + to be blessed or uncursed. (In versions prior to 3.6, fil- ter combinations behaved differently.) ^D Kick something (usually a door). e Eat food. - Normally checks for edible item(s) on the floor, then if + Normally checks for edible item(s) on the floor, then if none are found or none are chosen, checks for edible item(s) in inventory. Precede `e' with the `m' prefix to bypass at- tempting to eat anything off the floor. - If you attempt to eat while already satiated, you might - choke to death. If you risk it, you will be asked whether - to "continue eating?" if you survive the first bite. You + If you attempt to eat while already satiated, you might + choke to death. If you risk it, you will be asked whether + to "continue eating?" if you survive the first bite. You can set the paranoid_confirmation:eating option to require a response of yes instead of just y. @@ -835,14 +836,14 @@ E- - write in the dust with your fingers. - Engraving the word "Elbereth" will cause most monsters to + Engraving the word "Elbereth" will cause most monsters to not 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 + 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 + may select ammunition with a previous `Q' command, or let + the computer pick something appropriate if autoquiver is true. See also `t' (throw) for more general throwing and shooting. @@ -851,8 +852,7 @@ - - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -863,7 +863,7 @@ I List selected parts of your inventory, usually be specifying - the character for a particular set of objects, like `[' for + the character for a particular set of objects, like `[' for armor or `!' for potions. I* - list all gems in inventory; @@ -879,22 +879,22 @@ O Set options. - A menu showing the current option values will be displayed. - You can change most values simply by selecting the menu en- + A menu showing the current option values will be displayed. + You can change most values simply by selecting the menu en- try for the given option (ie, by typing its letter or click- - ing 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 + ing 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 be- fore the game rather than with the `O' command; see the sec- tion on options below. ^O Show overview. - Shortcut for "#overview": list interesting dungeon levels + Shortcut for "#overview": list interesting dungeon levels visited. - (Prior to 3.6.0, `^O' was a debug mode command which listed + (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.) @@ -903,22 +903,22 @@ 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 - choosing an unlisted item of armor will attempt to wear it. + 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.) ^P Repeat previous message. - Subsequent `^P's repeat earlier messages. For some inter- + Subsequent `^P's repeat earlier messages. For some inter- faces, the behavior can be varied via the msg_window option. q Quaff (drink) something (potion, water, etc). - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -928,34 +928,35 @@ - Q Select an object for your quiver, quiver sack, or just gen- - erally at the ready (only one of these is available at a - time). You can then throw this (or one of these) using the + Q Select an object for your quiver, quiver sack, or just gen- + erally 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. - (In versions prior to 3.3 this was the command to quit the + (In versions prior to 3.3 this was the command to quit the game, which has been moved to "#quit".) r Read a scroll or spellbook. R Remove a worn accessory (ring, amulet, or blindfold). - If you're wearing more than one, you'll be prompted for - which one to remove. When you're only wearing one, then by - default it will be removed without asking, but you can set + If you're wearing more than one, you'll be prompted for + which one to remove. When you're only wearing one, then by + default it will be removed without asking, but you can set the paranoid_confirmation 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 acces- - sories, but an item of worn armor can be chosen. (See the - `T' command below. It lists armor as the inventory choices + for which inventory item to remove only lists worn acces- + sories, 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 accessory and attempt to remove it.) ^R Redraw the screen. - s Search for secret doors and traps around you. It usually + 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. + prefix to search for a turn even next to a hostile monster, + if safe_wait is on. Can also be used to figure out whether there is still a mon- ster at an adjacent "remembered, unseen monster" marker. @@ -981,10 +982,9 @@ 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 generally be less effective than when shot. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -994,6 +994,8 @@ + hand and it will generally be less effective than when shot. + See also `f' (fire) for throwing or shooting an item pre-se- lected via the `Q' (quiver) command. @@ -1046,11 +1048,9 @@ 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 was the command to switch - from normal play to "explore mode", also known as "discovery - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1060,6 +1060,8 @@ + (In versions prior to 3.6 this was the command to switch + from normal play to "explore mode", also known as "discovery mode", which has now been moved to "#exploremode".) ^X Display basic information about your character. @@ -1108,15 +1110,13 @@ ( Tell what tools you are using. - * Tell what equipment you are using. - __________ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1126,6 +1126,8 @@ + * Tell what equipment you are using. + Combines the preceding five type-specific commands into one. $ Count your gold pieces. @@ -1178,11 +1180,9 @@ 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 - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1192,14 +1192,16 @@ - eligible. In either case, otherwise compatible stacks with - a different name will not be merged. This contrasts with - using "#adjust" to move from one slot to a different slot. - In that situation, moving (no count given) a compatible - 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 de- - ciding whether to merge with the destination stack. + provided that all their other attributes match. If it does + not have a name, only other stacks with no name are eligi- + ble. In either case, otherwise compatible stacks with a + different name will not be merged. This contrasts with us- + ing "#adjust" to move from one slot to a different slot. In + that situation, moving (no count given) a compatible 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 @@ -1244,11 +1246,9 @@ See the section below entitled "Conduct" for details. - #dip - Dip an object into something. Autocompletes. Default key - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1258,6 +1258,8 @@ + #dip + Dip an object into something. Autocompletes. Default key is `M-d'. #down @@ -1312,9 +1314,7 @@ Show your inventory. Default key is `i'. - - - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1380,7 +1380,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1446,7 +1446,7 @@ it. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1512,7 +1512,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1578,7 +1578,7 @@ Show bare map without displaying monsters, objects, or - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1644,7 +1644,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1710,7 +1710,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1776,7 +1776,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1842,7 +1842,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1908,7 +1908,7 @@ attempt is made to open (when unlocked) or unlock (when locked) - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -1974,7 +1974,7 @@ send you to a different level but behave differently. Some - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2040,7 +2040,7 @@ scribed below). Monsters are only active on the current level; - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2106,7 +2106,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2172,7 +2172,7 @@ on the map. Setting this option to true will describe such - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2238,7 +2238,7 @@ when angered. Remember: discretion is the better part of valor. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2304,7 +2304,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2370,7 +2370,7 @@ pends on your strength and your constitution. The stronger and - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2436,7 +2436,7 @@ as uncursed. They could just as easily have been described as - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2502,7 +2502,7 @@ encumbrance, and proficiency (see below). The monster's armor - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2568,7 +2568,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2634,7 +2634,7 @@ boost your training towards the next skill level (unless you've - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2700,7 +2700,7 @@ protection in NetHack. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2766,7 +2766,7 @@ protected. Food stored in ice boxes or tins ("cans") will - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2832,7 +2832,7 @@ is the bane of the undead, so potions of holy water are good - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2898,7 +2898,7 @@ ing a ring and then re-wear them after. That's done implicitly - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -2964,7 +2964,7 @@ mand casts a spell. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3030,7 +3030,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3096,7 +3096,7 @@ map. That remains the case even if it is not actually there any - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3162,7 +3162,7 @@ and candy bars), and lumps of royal jelly. Monks are expected to - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3228,7 +3228,7 @@ The identity of scrolls and spellbooks (and knowledge of spells) - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3294,7 +3294,7 @@ - Attained rank title . - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3360,7 +3360,7 @@ abled by setting the correspondingly named option in - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3426,7 +3426,7 @@ a CHOOSE directive has selected that section. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3492,7 +3492,7 @@ extended command. Prefix the command with "!" to disable the - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3558,7 +3558,7 @@ Define a sound mapping. See the "Configuring User Sounds" - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3624,7 +3624,7 @@ option to the list, and turn it off by typing a `!' or "no" - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3690,7 +3690,7 @@ command. Persistent. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3756,7 +3756,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3822,7 +3822,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3888,7 +3888,7 @@ Your starting gender (gender:male or gender:female). You may - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -3954,7 +3954,7 @@ Name your starting horse (for example "horsename:Trigger"). - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4020,7 +4020,7 @@ consists of a prompt for object class characters, followed by - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4086,7 +4086,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4152,7 +4152,7 @@ can also set your character's role by appending a dash and one - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4218,7 +4218,7 @@ the game or switching into non-scoring explore - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4284,7 +4284,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4350,7 +4350,7 @@ Using the `w' (wield) command when already wielding something - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4416,7 +4416,7 @@ This option only affects the game's screen display, not the - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4435,13 +4435,17 @@ Prevent you from (knowingly) attacking your pets (default on). Persistent. + safe_wait + Prevents you from waiting or searching when next to a hostile + monster (default on). Persistent. + sanity_check 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 + 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. @@ -4450,9 +4454,9 @@ off). Persistent. showrace - Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4464,25 +4468,21 @@ sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + 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, + 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. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. - sparkle - Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- - sistent. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4492,37 +4492,42 @@ + sparkle + Display a sparkly effect when a monster (including yourself) is + hit by an attack to which it is resistant (default on). Per- + sistent. + standout Boldface monsters and "--More--" (default off). Persistent. statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. See "Configuring 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 + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (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 "symset:default" to explicitly select the default + 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 "symset:default" to explicitly select the default symbols. time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface only; "X11" interface always uses a timer based delay. The de- fault is on if configured into the program.) Persistent. @@ -4532,23 +4537,18 @@ toptenwin Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map win- - dow. Does not affect traveling via the `_' ("#travel") com- - mand. Persistent. - - verbose - Provide more commentary during the game (default on). + ed moves if you make inadvertent mouse clicks on the map - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4558,12 +4558,17 @@ - Persistent. + window. Does not affect traveling via the `_' ("#travel") com- + mand. Persistent. + + verbose + Provide more commentary during the game (default on). Persis- + tent. whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -4580,41 +4585,36 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possi- + through next and previous targets, allows filtering the possi- ble 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 + 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 + Filtering can also be changed when getting a location with the "getpos.filter" key. whatis_menu - When getting a location on the map, and using a key to cycle + 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. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement + 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 de- - pends 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 + select which one to use, such as "tty" or "X11" (default - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4624,45 +4624,50 @@ - 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 option in the list. + depends on build-time settings; use "#version" to check). Can- + not 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 op- + tions. 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 option in the list. wizweight 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 + 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 + 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 adjust- - ing 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 + 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 adjust- + ing 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. Some options - are dynamic and can be specified during the game with the `O' + 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, + 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, + Where to align or place the status window (top, bottom, left, or right). ascii_map - If NetHack can, it should display an ascii character map if it + If NetHack can, it should display an ascii character map if it can. color @@ -4670,17 +4675,12 @@ monsters, objects, and dungeon features. eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to your terminal (default off). - font_map - if NetHack can, it should use a font by the chosen name for the - map window. - - - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4690,8 +4690,12 @@ + font_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 + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -4703,50 +4707,46 @@ status window. font_text - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for text windows. font_size_map - If NetHack can, it should use this size font for the map win- + If NetHack can, it should use this size font for the map win- dow. 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 + 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 + 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. fullscreen - If NetHack can, it should try and display on the entire screen + If NetHack can, it should try and display on the entire screen rather than in a window. guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- terface only; default is on. large_font If NetHack can, it should use a large font. map_mode - If NetHack can, it should display the map in the manner speci- + If NetHack can, it should display the map in the manner speci- fied. - player_selection - If NetHack can, it should pop up dialog boxes, or use prompts - for character selection. - - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4756,32 +4756,36 @@ + player_selection + 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 exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount - If NetHack can, it should scroll the display by this number of + If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- dow. selectsaved - If NetHack can, it should display a menu of existing saved + If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to + Display an onscreen keyboard. Handhelds are most likely to support this option. splash_screen @@ -4789,30 +4793,26 @@ 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). Curses and tty + Number of lines for traditional below-the-map status display. + Acceptable values are 2 and 3 (default is 2). Curses and tty interfaces only. term_cols and term_rows - Curses interface only. Number of columns and rows to use for + Curses interface only. Number of columns and rows to use for the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. + ified but will settle for smaller sizes if they are too big. Default is the current window size. tiled_map If NetHack can, it should display a tiled map if it can. tile_file - Specify the name of an alternative tile file to override the - default. - - tile_height - Specify the preferred height of each tile in a tile capable + Specify the name of an alternative tile file to override the - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4822,6 +4822,10 @@ + default. + + tile_height + Specify the preferred height of each tile in a tile capable port. tile_width @@ -4831,42 +4835,42 @@ Use bold black instead of blue for black glyphs (TTY only). use_inverse - If NetHack can, it should display inverse when the game speci- + If NetHack can, it should display inverse when the game speci- fies it. vary_msgcount - If NetHack can, it should display this number of messages at a + 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 in- + Whether to draw boxes around the map, status area, message + area, and persistent inventory window if enabled. Curses in- terface only. Acceptable values are 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) (default) - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns + (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 for align_status set to left or right.) windowcolors - If NetHack can, it should display windows with the specified + If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- text). wraptext @@ -4874,11 +4878,7 @@ fit in the visible area of the window. - - - - - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4890,12 +4890,12 @@ 9.6. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be set with the `O' command. @@ -4905,23 +4905,23 @@ altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). flush @@ -4934,17 +4934,17 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of + (Win32 tty NetHack only). May be used to alter the value of - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -4955,53 +4955,53 @@ keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assign- - ments in the configuration file if needed. Cannot be set with + ments in the configuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause + tect", "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA - hardware. Setting "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 of those modes works. Cannot be set + hardware. Setting "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 of those modes works. Cannot be set with the `O' command. video_height - Set the VGA mode resolution height (MS-DOS only, with + Set the VGA mode resolution height (MS-DOS only, with video:vesa) video_width - Set the VGA mode resolution width (MS-DOS only, with + 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 bright.cyan. Cannot be set with the `O' + 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 (de- fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the `O' command. 9.7. Regular Expressions - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -5010,7 +5010,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5025,29 +5025,29 @@ 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 + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as 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 oc- + In addition, some characters are treated specially if they oc- cur 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 + 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 save and then restore your game. autopickup_ex- + 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 save and then restore your game. autopickup_ex- ception rules and not saved with the game. Here are some examples: @@ -5056,17 +5056,17 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - 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 ex- + 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 ex- clusion of items known to be cursed from autopickup. 9.9. 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 + 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"), or a three-digit decimal ASCII code. @@ -5076,7 +5076,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5091,25 +5091,25 @@ BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a key by using "nothing" as the extended command to bind - to. You can also bind the "", "", and "" + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- + The menu control or accelerator keys can also be rebound via + OPTIONS lines in the configuration file. You cannot bind ob- ject symbols into menu accelerators. 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 "context", and if bound to same keys, only one of those - commands will be available. Special command can only be bound + 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 "context", 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 + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. doinv @@ -5119,19 +5119,19 @@ Prefix key to force fight a direction. Default is `F'. fight.numpad - Prefix key to force fight a direction. With number_pad only. + Prefix key to force fight a direction. With number_pad only. Default is `-'. getdir.help - When asked for a direction, the key to show the help. Default + When asked for a direction, the key to show the help. Default is `?'. getdir.self - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `.'. getdir.self2 - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `s'. getpos.autodescribe @@ -5139,10 +5139,10 @@ fault is `#'. getpos.all.next - When asked for a location, the key to go to next closest + When asked for a location, the key to go to next closest - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5155,60 +5155,60 @@ interesting thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest interesting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door + When asked for a location, the key to go to next closest door or doorway. Default is `d'. getpos.door.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest door or doorway. Default is `D'. getpos.help - When asked for a location, the key to show help. Default is + 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 mon- + When asked for a location, the key to go to next closest mon- ster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest monster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest ob- + When asked for a location, the key to go to next closest ob- ject. Default is `o'. getpos.obj.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest object. Default is `O'. getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- stead. 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 + 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 + 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 + When asked for a location, the key to choose the location, and possibly ask for more info. Default is `.'. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5219,16 +5219,16 @@ getpos.pick.once - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. getpos.pick.quick When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- + asking for more info, and exit the location asking loop. De- fault is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self @@ -5236,23 +5236,23 @@ fault is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unex- + When asked for a location, the key to go to next closest unex- plored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest unexplored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target + When asked for a location, the key to go to show valid target locations. Default is `$'. getpos.valid.next - When asked for a location, the key to go to next closest valid + When asked for a location, the key to go to next closest valid location. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest valid location. Default is `Z'. nopickup @@ -5262,7 +5262,7 @@ Key to redraw the screen. Default is `^R'. redraw.numpad - Key to redraw the screen. With number_pad only. Default is + Key to redraw the screen. With number_pad only. Default is `^L'. repeat @@ -5274,7 +5274,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5288,11 +5288,11 @@ Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad - Prefix key to run towards a direction. With number_pad only. + Prefix key to run towards a direction. With number_pad only. Default is `5'. rush @@ -5303,7 +5303,7 @@ 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 + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5316,31 +5316,31 @@ 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 mes- + norep - show the message once, but not again if no other mes- sage is shown in between. - Here's an example of message types using NetHack's internal + 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 + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when the line matches a user-defined pattern. At this time the tty, curses, win32tty and win32gui interfaces support this. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5350,63 +5350,63 @@ - In general, the configuration file entries to describe the + 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 pat- + color - the color to use for lines matching the pat- tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- - genta, light-cyan, and white. And no-color, the default fore- - ground color, which isn't necessarily the same as any of the + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- + 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 line will be shown in red color and under- lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu + uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5416,24 +5416,24 @@ - The following configuration file entries are relevant to + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + 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 3.6); pattern - the pattern to match; sound file - the sound file to play; - volume - the volume to be set while playing the sound + volume - the volume to be set while playing the sound file; - sound index - optional; the index corresponding to a sound + sound index - optional; the index corresponding to a sound file. The pattern should be a POSIX extended regular expression. @@ -5441,7 +5441,7 @@ 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5449,8 +5449,8 @@ 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 + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -5458,21 +5458,21 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground color on the display, which is not necessarily the same as black or white or any of the other colors. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5482,26 +5482,26 @@ - Allowed attributes are none, bold, dim, underline, blink, - and inverse. "Normal" is a synonym for "none"; they should not + Allowed attributes are none, bold, dim, underline, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5512,16 +5512,16 @@ 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 condition- + 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 condition- ally displayed depending upon your other option settings. - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. @@ -5530,15 +5530,15 @@ * "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 + * "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 val- - ue changes. This attribute times out after statushilites + ue changes. This attribute times out after statushilites - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5548,51 +5548,51 @@ - turns. (If a field has both a "changed" rule and an "up" - or "down" rule which matches a change in the field's val- + turns. (If a field has both a "changed" rule and an "up" + or "down" rule which matches a change in the field's val- ue, 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 be- - tween 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 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 corresponding maxi- - mum field. Percentage highlight rules are also allowed + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- perience level to the start of the next level. So if lev- - el 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 + el 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 + a rule for =100% is allowed and matches the special case of being exactly 1 experience point short of the next lev- el. - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only match when strictly above or below. * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". For title, only the role's rank title is tested; + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- + The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: @@ -5604,7 +5604,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5629,23 +5629,23 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols @@ -5670,7 +5670,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5736,7 +5736,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5802,7 +5802,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5868,7 +5868,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5884,57 +5884,57 @@ Notes: * 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 en- + space character, except for S_pet_override and S_hero_override + which don't have any default value and can only be used if en- abled 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 de- - pict. So S_rock is only used for boulders and not used at all + * 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 de- + pict. So S_rock is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. 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 charac- + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- ter 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 + 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 location of items on the screen. - 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 message handler", your NetHack has been compiled + 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 message 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 environment variable NETHACK_MSGHANDLER + and other POSIX systems, define MSGHANDLER to enable it. To use + the capability, set the environment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task somewhat daunting. Included within the "symbols" file of all of- ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -5945,19 +5945,19 @@ configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- abled in the sysconf file. - The most crucial settings to make the game more accessible + The most crucial settings to make the game more accessible are: symset:NHAccess Load a symbol set appropriate for use by blind players. roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional @@ -5967,40 +5967,40 @@ 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 + 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. autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip - When targeting with cursor and using fast-move, skip the same + When targeting with cursor and using fast-move, skip the same glyphs 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 in- + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6012,16 +6012,16 @@ 9.16. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed + 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. @@ -6029,44 +6029,44 @@ SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS = A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- + SUPPORT = A string explaining how to get local support (no de- fault value). - RECOVER = A string explaining how to recover a game on this + 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, WIZ- + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6077,8 +6077,8 @@ 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6087,26 +6087,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6122,17 +6122,17 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on + 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 + 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. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6142,55 +6142,55 @@ - Your score is chiefly based upon how much experience you + 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 + 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 all your gold, but if + 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 + 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 + 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 paltry cost of not getting on the high score + "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 game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - other benefits of explore mode are left for the trepid reader to + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 + vide god-like powers 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 par- - ticular 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 + For some systems, the player must be logged in under a par- + ticular 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. @@ -6198,7 +6198,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6210,61 +6210,61 @@ 12. Credits - 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 + 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 Dungeons of Doom, by Ken Arromdee. NetHack is the product of literally scores of people's work. - Main events in the course of the game development are described + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting + Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming Hack into a very different game. He published the Hack - source code for use on UNIX systems by posting that to Usenet + forming 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 ver- sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 1.0.3 in July of 1985. Usenet newsgroup net.games.hack - (later renamed rec.games.hack, eventually replaced by + nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6274,63 +6274,63 @@ - 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 + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 + Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor and so forth, not separate images for beetles and ants or for cloaks and boots). - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6340,63 +6340,63 @@ - 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 ob- + 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6406,63 +6406,63 @@ - (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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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 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 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 plat- + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows CE port for 3.4.1. - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6473,12 +6473,12 @@ 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 + 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 + 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 af- @@ -6487,48 +6487,48 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 + velopment 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 Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6540,49 +6540,49 @@ restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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 en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6594,7 +6594,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6607,19 +6607,19 @@ 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6660,7 +6660,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 @@ -6677,7 +6677,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6726,7 +6726,7 @@ - NetHack 3.7 August 5, 2020 + NetHack 3.7 October 2, 2020 From ef6978ec51b3e6854199d7176cfbb4ee1e1aa619 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 2 Oct 2020 16:01:04 -0400 Subject: [PATCH 263/708] update sys/winnt/console.rc --- sys/winnt/console.rc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sys/winnt/console.rc b/sys/winnt/console.rc index c2019cd7c..110e94553 100644 --- a/sys/winnt/console.rc +++ b/sys/winnt/console.rc @@ -12,8 +12,8 @@ // VS_VERSION_INFO VERSIONINFO - FILEVERSION 3,6,3,0 - PRODUCTVERSION 3,6,3,0 + FILEVERSION 3,7,0,0 + PRODUCTVERSION 3,7,0,0 FILEFLAGSMASK 0x1fL #ifdef _DEBUG FILEFLAGS 0x9L @@ -29,13 +29,13 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "NetHack for Windows - TTY Interface\0" - VALUE "FileVersion", "3.6.3\0" + VALUE "FileVersion", "3.7.0\0" VALUE "InternalName", "NetHack\0" - VALUE "LegalCopyright", "Copyright (C) 1985 - 2019. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" + VALUE "LegalCopyright", "Copyright (C) 1985 - 2020. By Stichting Mathematisch Centrum and M. Stephenson. See license for details.\0" VALUE "OriginalFilename", "NetHack.exe\0" VALUE "PrivateBuild", "050102\0" VALUE "ProductName", "NetHack\0" - VALUE "ProductVersion", "3.6.3\0" + VALUE "ProductVersion", "3.7.0\0" END END BLOCK "VarFileInfo" From 9bad6840f467c3b20757b313249b24ae924d6338 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 4 Oct 2020 07:36:12 -0700 Subject: [PATCH 264/708] Qt ynaq/yn#aq dialogs When 'popup_dialog' is set, the Qt interface uses a popup window for yn_function() calls and the dialog has a list of buttons, one per potential choice. It has been handling "yn?" and "ynq?" questions differently from general request-one-char prompts, using buttons "Yes", "No, and "Cancel" instead of showing individual letters. This extends that to "ynaq" and "yn#aq" questions and labels 'q' reply as "Stop" instead of "Cancel" for those. Also, when player uses keyboard instead of mouse to answer, allow 'c' as well as 'q' for cancel ones, 's' as well as 'q' for stop ones. Prompt Buttons yn [Yes ][ No ] ynq [ Yes ][ No ][Cancel] ynaq [Yes ][ No ][All ][Stop] yn#aq [Yes ]Count:______[ No ][All ][Stop] rl [ Left ][Right ] //unchanged; included for completeness (For contrast, when something specifies "ny" as the acceptable choices, the buttons will just be [n][y]. Prompts for choosing from a list of inventory letters can't accidentally match these special cases as long as they're specified in alphabetical order.) --- win/Qt/qt_yndlg.cpp | 85 ++++++++++++++++++++++++++++++++++----------- win/Qt/qt_yndlg.h | 4 +++ 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 7ae167da2..d7b370a32 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -69,6 +69,7 @@ NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent, const QString &q, } } } + alt_answer[0] = alt_result[0] = '\0'; } char NetHackQtYnDialog::Exec() @@ -152,7 +153,10 @@ char NetHackQtYnDialog::Exec() QButtonGroup *bgroup = new QButtonGroup(group); int nchoices=ch.length(); - bool is_ynq = (ch == QString("ynq")), // [ Yes ][ No ][Cancel] + bool is_ynaq = (ch == QString("ynaq") // [Yes ][ No ][All ][Stop] + || ch == QString("yn#aq") + || ch == altchoices), // alternate "yn#aq" + is_ynq = (ch == QString("ynq")), // [ Yes ][ No ][Cancel] is_yn = (ch == QString("yn")), // [Yes ][ No ] is_lr = (ch == QString(lrq)); // [ Left ][Right ] @@ -161,8 +165,8 @@ char NetHackQtYnDialog::Exec() const int extra=fontMetrics().height(); // Extra for group int x=margin, y=extra+margin; int butheight = fontMetrics().height() * 2 + 5, - butwidth = (butheight - 5) - * ((is_ynq || is_lr) ? 3 : is_yn ? 2 : 1) + 5; + butwidth = (butheight - 5) * ((is_ynq || is_lr) ? 3 + : (is_ynaq || is_yn) ? 2 : 1) + 5; if (butwidth == butheight) { // square, enough room for C or ^C // some characters will be labelled by name rather than by // keystroke so will need wider buttons @@ -183,7 +187,9 @@ char NetHackQtYnDialog::Exec() if (ch[i] == '#' && allow_count) continue; // don't show a button for '#'; has Count box instead QString button_name = QString(visctrl((char) ch[i].cell())); - if (is_yn || is_ynq || is_lr) { + if (is_yn || is_ynq || is_ynaq || is_lr) { + // FIXME: a better way to recognize which labels should + // use alterate text is needed switch (ch[i].cell()) { case 'y': button_name = "Yes"; @@ -191,13 +197,28 @@ char NetHackQtYnDialog::Exec() case 'n': button_name = "No"; break; - case 'q': - // FIXME: sometimes the 'q' choice is ''cancel current - // action'' but other times it is actually 'quit'. - if (question.left(10) == QString("Dump core?")) - button_name = "Quit"; + case 'a': + // the display of vanquished monsters uses "ynaq" for + // convenience, where 'a' requests a sort-by menu; + // show "sort" instead of "all" and allow player to + // type either 'a' or 's' when not clicking on button + if (question.contains(QString("vanquished?"))) + button_name = "Sort", AltChoice('s', 'a'); else - button_name = "Cancel"; + button_name = "All"; + break; + case 'q': + // most 'q' replies are actually for "cancel" but + // for "ynaq" (where "all" is a choice) it's "stop" + // and for end of game disclosure it really is "quit" + if (question.left(10) == QString("Dump core?") + || (::g.program_state.gameover + && question.left(11) == QString("Do you want"))) + button_name = "Quit"; + else if (is_ynaq) + button_name = "Stop", AltChoice('s', 'q'); + else + button_name = "Cancel", AltChoice('c', 'q'); break; case 'l': button_name = "Left"; @@ -286,7 +307,10 @@ char NetHackQtYnDialog::Exec() if (res == 0) { choice = is_lr ? '\033' : ch_esc ? ch_esc : def ? def : ' '; } else if (res == 1) { - choice = def ? def : ch_esc ? ch_esc : ' '; + if (keypress) + choice = keypress; + else + choice = def ? def : ch_esc ? ch_esc : ' '; } else if (res >= 1000) { choice = (char) ch[res - 1000].cell(); } @@ -319,23 +343,33 @@ char NetHackQtYnDialog::Exec() return keypress; } +void NetHackQtYnDialog::AltChoice(char ans, char res) +{ + if (ans && !strchr(alt_answer, ans)) { + (void) strkitten(alt_answer, ans); + (void) strkitten(alt_result, res); + } +} + void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) { + keypress = '\0'; QString text(event->text()); - if (text.isEmpty() && event->modifiers()) + if (text.isEmpty()) /* && event->modifiers()) */ return; - if (!choices || !*choices) { - if (!text.isEmpty()) { - keypress = text.toUcs4()[0]; - this->done(1); - } + keypress = text.at(0).cell(); + char *p = NULL; + if (*alt_answer && (p = strchr(alt_answer, keypress)) != 0) + keypress = alt_result[p - alt_answer]; + + if (!choices || !*choices || !keypress) { + this->done(1); } else { - int where = QString::fromLatin1(choices).indexOf(text); + int where = QString::fromLatin1(choices).indexOf(QChar(keypress)); - if (where != -1 && allow_count - && strchr("#0123456789", text[0].cell())) { + if (allow_count && strchr("#0123456789", keypress)) { if (text == "#") { // 0 will be preselected; typing anything replaces it le->setText(QString("0")); @@ -347,7 +381,18 @@ void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) } // (don't know whether this actually does anything useful) le->setAttribute(Qt::WA_KeyboardFocusChange, true); + // this is definitely useful... le->setFocus(Qt::ActiveWindowFocusReason); + // + // TODO: 'No' is highlighted as default for result if player + // types , but once count entry starts that should + // be changed because this LineEdit dialog has now become + // the defacto default. We can't just turn off the default + // setting for the 'No' button because only works + // if there is a default explicitly set. Unfortunately the + // LineEdit widget isn't a viable candidate for that because + // it isn't a button. [Maybe just highlight 'Yes' instead?] + // } else if (where != -1) { this->done(where + 1000); diff --git a/win/Qt/qt_yndlg.h b/win/Qt/qt_yndlg.h index 049886355..cdbdc0710 100644 --- a/win/Qt/qt_yndlg.h +++ b/win/Qt/qt_yndlg.h @@ -19,8 +19,12 @@ private: bool allow_count; QLineEdit *le; + // abritrary size; might need to be more sophisicated someday + char alt_answer[26 + 1], alt_result[26 + 1]; + protected: virtual void keyPressEvent(QKeyEvent*); + void AltChoice(char answer, char result); private slots: void doneItem(int); From 741e6fd5b7d57ccd9db12c2cd4d64fcaaf7d7385 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 26 Aug 2020 19:17:40 -0700 Subject: [PATCH 265/708] initial shim graphics --- include/config.h | 8 ++- src/mdlib.c | 3 + src/rip.c | 38 +++++------ src/windows.c | 6 ++ win/shim/winshim.c | 161 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 196 insertions(+), 20 deletions(-) create mode 100644 win/shim/winshim.c diff --git a/include/config.h b/include/config.h index bbcd4b112..a94b38267 100644 --- a/include/config.h +++ b/include/config.h @@ -64,7 +64,7 @@ * Define the default window system. This should be one that is compiled * into your system (see defines above). Known window systems are: * - * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome + * tty, X11, mac, amii, BeOS, Qt, Gem, Gnome, shim */ /* MAC also means MAC windows */ @@ -144,6 +144,12 @@ #endif #endif +#ifdef SHIM_GRAPHICS +#ifndef DEFAULT_WINDOW_SYS +#define DEFAULT_WINDOW_SYS "shim" +#endif +#endif + #ifdef X11_GRAPHICS /* * There are two ways that X11 tiles may be defined. (1) using a custom diff --git a/src/mdlib.c b/src/mdlib.c index 79a748710..f2abba620 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -130,6 +130,9 @@ static struct win_info window_opts[] = { #ifdef MSWIN_GRAPHICS /* win32 */ { "mswin", "Windows GUI", TRUE }, #endif +#ifdef SHIM_GRAPHICS + { "shim", "Nethack Library Windowing Shim", TRUE }, +#endif #if 0 /* remainder have been retired */ #ifdef GNOME_GRAPHICS /* unmaintained/defunct */ diff --git a/src/rip.c b/src/rip.c index dca074720..b61a76254 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 3.7 rip.c $NHDT-Date: 1596498204 2020/08/03 23:43:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,7 +6,7 @@ #include "hack.h" #if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) \ - || defined(MSWIN_GRAPHICS) || defined(DUMPLOG) || defined(CURSES_GRAPHICS) + || defined(MSWIN_GRAPHICS) || defined(DUMPLOG) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) #define TEXT_TOMBSTONE #endif #if defined(mac) || defined(__BEOS__) || defined(WIN32_GRAPHICS) @@ -60,10 +60,12 @@ static const char *rip_txt[] = { }; #define STONE_LINE_CENT 19 /* char[] element of center of stone face */ #endif /* NH320_DEDICATION */ -#define STONE_LINE_LEN 16 /* # chars that fit on one line - * (note 1 ' ' border) */ -#define NAME_LINE 6 /* *char[] line # for player name */ -#define GOLD_LINE 7 /* *char[] line # for amount of gold */ +#define STONE_LINE_LEN \ + 16 /* # chars that fit on one line \ + * (note 1 ' ' border) \ + */ +#define NAME_LINE 6 /* *char[] line # for player name */ +#define GOLD_LINE 7 /* *char[] line # for amount of gold */ #define DEATH_LINE 8 /* *char[] line # for death description */ #define YEAR_LINE 12 /* *char[] line # for year */ @@ -88,9 +90,9 @@ time_t when; register char **dp; register char *dpx; char buf[BUFSZ]; + long year; register int x; - int line, year; - long cash; + int line; g.rip = dp = (char **) alloc(sizeof(rip_txt)); for (x = 0; rip_txt[x]; ++x) @@ -98,15 +100,13 @@ time_t when; dp[x] = (char *) 0; /* Put name on stone */ - Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, g.plname); + Sprintf(buf, "%s", g.plname); + buf[STONE_LINE_LEN] = 0; center(NAME_LINE, buf); /* Put $ on stone */ - cash = max(g.done_money, 0L); - /* arbitrary upper limit; practical upper limit is quite a bit less */ - if (cash > 999999999L) - cash = 999999999L; - Sprintf(buf, "%ld Au", cash); + Sprintf(buf, "%ld Au", g.done_money); + buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */ center(GOLD_LINE, buf); /* Put together death description */ @@ -114,11 +114,11 @@ time_t when; /* Put death type on stone */ for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) { + register int i, i0; char tmpchar; - int i, i0 = (int) strlen(dpx); - if (i0 > STONE_LINE_LEN) { - for (i = STONE_LINE_LEN; (i > 0) && (i0 > STONE_LINE_LEN); --i) + if ((i0 = strlen(dpx)) > STONE_LINE_LEN) { + for (i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--) if (dpx[i] == ' ') i0 = i; if (!i) @@ -135,8 +135,8 @@ time_t when; } /* Put year on stone */ - year = (int) ((yyyymmdd(when) / 10000L) % 10000L); - Sprintf(buf, "%4d", year); + year = yyyymmdd(when) / 10000L; + Sprintf(buf, "%4ld", year); center(YEAR_LINE, buf); #ifdef DUMPLOG diff --git a/src/windows.c b/src/windows.c index 03bc1e592..f3af21f49 100644 --- a/src/windows.c +++ b/src/windows.c @@ -44,6 +44,9 @@ extern struct window_procs Gnome_procs; #ifdef MSWIN_GRAPHICS extern struct window_procs mswin_procs; #endif +#ifdef SHIM_GRAPHICS +extern struct window_procs shim_procs; +#endif #ifdef WINCHAIN extern struct window_procs chainin_procs; extern void FDECL(chainin_procs_init, (int)); @@ -128,6 +131,9 @@ static struct win_choices { #ifdef MSWIN_GRAPHICS { &mswin_procs, 0 CHAINR(0) }, #endif +#ifdef SHIM_GRAPHICS + { &shim_procs, 0 CHAINR(0) }, +#endif #ifdef WINCHAIN { &chainin_procs, chainin_procs_init, chainin_procs_chain }, { (struct window_procs *) &chainout_procs, chainout_procs_init, diff --git a/win/shim/winshim.c b/win/shim/winshim.c new file mode 100644 index 000000000..d82d21334 --- /dev/null +++ b/win/shim/winshim.c @@ -0,0 +1,161 @@ +/* NetHack 3.7 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. */ + +/* not an actual windowing port, but a fake win port for libnethack */ + +#include "hack.h" + +#ifdef SHIM_GRAPHICS + +enum win_types { + WINSTUB_MESSAGE = 1, + WINSTUB_MAP, + WINSTUB_MENU, + WINSTUB_EXT +}; + +#define VSTUB(name, args) \ +void name args { \ + printf ("Running " #name "...\n"); \ +} + +#define STUB(name, retval, args) \ +name args { \ + printf ("Running " #name "...\n"); \ + return retval; \ +} + +#define DECL(name, args) \ +void name args; + +VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) +VSTUB(shim_player_selection,(void)) +VSTUB(shim_askname,(void)) +VSTUB(shim_get_nh_event,(void)) +VSTUB(shim_exit_nhwindows,(const char *a)) +VSTUB(shim_suspend_nhwindows,(const char *a)) +VSTUB(shim_resume_nhwindows,(void)) +winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) +VSTUB(shim_clear_nhwindow,(winid a)) +VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) +VSTUB(shim_destroy_nhwindow,(winid a)) +VSTUB(shim_curs,(winid a, int x, int y)) +DECL(shim_putstr,(winid w, int attr, const char *str)) +VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) +VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) +VSTUB(shim_add_menu,(winid a, int b, const ANY_P *c, CHAR_P d, CHAR_P e, int f, const char *h, unsigned int k)) +VSTUB(shim_end_menu,(winid a, const char *b)) +int STUB(shim_select_menu,0,(winid a, int b, MENU_ITEM_P **c)) +char STUB(shim_message_menu,'y',(CHAR_P a, int b, const char *c)) +VSTUB(shim_update_inventory,(void)) +VSTUB(shim_mark_synch,(void)) +VSTUB(shim_wait_synch,(void)) +VSTUB(shim_cliparound,(int a, int b)) +VSTUB(shim_update_positionbar,(char *a)) +DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) +DECL(shim_raw_print,(const char *str)) +VSTUB(shim_raw_print_bold,(const char *a)) +int STUB(shim_nhgetch,0,(void)) +int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) +VSTUB(shim_nhbell,(void)) +int STUB(shim_doprev_message,0,(void)) +char STUB(shim_yn_function,'y',(const char *a, const char *b, CHAR_P c)) +VSTUB(shim_getlin,(const char *a, char *b)) +int STUB(shim_get_ext_cmd,0,(void)) +VSTUB(shim_number_pad,(int a)) +VSTUB(shim_delay_output,(void)) +VSTUB(shim_change_color,(int a, long b, int c)) +VSTUB(shim_change_background,(int a)) +short STUB(set_shim_font_name,0,(winid a, char *b)) +VSTUB(shim_get_color_string,(void)) + +/* other defs that really should go away (they're tty specific) */ +VSTUB(shim_start_screen, (void)) +VSTUB(shim_end_screen, (void)) +VSTUB(shim_preference_update, (const char *a)) +char *STUB(shim_getmsghistory, (char *)"", (BOOLEAN_P a)) +VSTUB(shim_putmsghistory, (const char *a, BOOLEAN_P b)) +VSTUB(shim_status_init, (void)) +VSTUB(shim_status_enablefield, (int a, const char *b, const char *c, BOOLEAN_P d)) +VSTUB(shim_status_update, (int a, genericptr_t b, int c, int d, int e, unsigned long *f)) + + +/* old: | WC_TILED_MAP */ +/* Interface definition, for windows.c */ +struct window_procs shim_procs = { + "shim", + (0 + | WC_ASCII_MAP + | WC_COLOR | WC_HILITE_PET | WC_INVERSE | WC_EIGHT_BIT_IN), + (0 +#if defined(SELECTSAVED) + | WC2_SELECTSAVED +#endif +#if defined(STATUS_HILITES) + | WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS + | WC2_RESET_STATUS +#endif + | WC2_DARKGRAY | WC2_SUPPRESS_HIST | WC2_STATUSLINES), +#ifdef TEXTCOLOR + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ +#else + {1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1}, +#endif + shim_init_nhwindows, shim_player_selection, shim_askname, shim_get_nh_event, + shim_exit_nhwindows, shim_suspend_nhwindows, shim_resume_nhwindows, + shim_create_nhwindow, shim_clear_nhwindow, shim_display_nhwindow, + shim_destroy_nhwindow, shim_curs, shim_putstr, genl_putmixed, + shim_display_file, shim_start_menu, shim_add_menu, shim_end_menu, + shim_select_menu, shim_message_menu, shim_update_inventory, shim_mark_synch, + shim_wait_synch, +#ifdef CLIPPING + shim_cliparound, +#endif +#ifdef POSITIONBAR + shim_update_positionbar, +#endif + shim_print_glyph, shim_raw_print, shim_raw_print_bold, shim_nhgetch, + shim_nh_poskey, shim_nhbell, shim_doprev_message, shim_yn_function, + shim_getlin, shim_get_ext_cmd, shim_number_pad, shim_delay_output, +#ifdef CHANGE_COLOR /* the Mac uses a palette device */ + shim_change_color, +#ifdef MAC + shim_change_background, set_shim_font_name, +#endif + shim_get_color_string, +#endif + + /* other defs that really should go away (they're tty specific) */ + shim_start_screen, shim_end_screen, genl_outrip, + shim_preference_update, + shim_getmsghistory, shim_putmsghistory, + shim_status_init, + genl_status_finish, genl_status_enablefield, +#ifdef STATUS_HILITES + shim_status_update, +#else + genl_status_update, +#endif + genl_can_suspend_yes, +}; + +void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { + /* map glyph to character and color */ + // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); + + fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); + fflush(stdout); +} + +void shim_raw_print(const char *str) { + fprintf(stdout, "shim_raw_print: %s\n", str); + fflush(stdout); +} + +void shim_putstr(winid w, int attr, const char *str) { + fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); + fflush(stdout); +} + +#endif /* SHIM_GRAPHICS */ \ No newline at end of file From dc2d75739973188758ab4c586e4ffaf76ebfd6ad Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Wed, 26 Aug 2020 19:22:00 -0700 Subject: [PATCH 266/708] libnethack pr385 roll parts of pr385 into source tree This does not take the PR as is. Unlike the PR, this streamlines and minimizes the integration somewhat: - use hints/include mechanism instead of creating alternative Makefile.dat, Makefile.src, Makefile.top, Makefile.utl in sys/lib; those would have been a maintenance nightmare. - don't have alternative mkmkfile.sh and setup.sh in sys/lib. - sys/lib/libnethackmain.c differed from sys/unix/unixmain.c by very little, so just place a small bit of conditional code at the top of sys/unix/unixmain.c instead. - changed the conditional code bits from __EMSCRIPTEN__ to CROSS_TO_WASM. - You should be able to build the wasm result by: cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. make fetch-lua (<-one time) make WANT_LIBNH all - You should be able to build LIBNBH by: cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. make fetch-lua (<-one time) make CROSS_TO_WASM=1 all As it is currently coded, winshim.c requires C99. --- .gitignore | 8 +- doc/fixes37.0 | 2 + include/global.h | 11 +- include/unixconf.h | 2 +- src/mdlib.c | 2 +- src/rip.c | 39 +-- src/version.c | 2 +- sys/lib/README.md | 95 +++++++ sys/lib/hints/macOS.2020 | 360 +++++++++++++++++++++++++ sys/lib/hints/wasm | 77 ++++++ sys/lib/npm-package/LICENSE.md | 95 +++++++ sys/lib/npm-package/README.md | 47 ++++ sys/lib/npm-package/package.json | 20 ++ sys/lib/npm-package/src/nethackShim.js | 49 ++++ sys/lib/sysconf | 150 +++++++++++ sys/lib/test/README.md | 8 + sys/lib/test/libtest.c | 115 ++++++++ sys/lib/test/run.sh | 41 +++ sys/unix/Makefile.src | 8 +- sys/unix/Makefile.top | 2 +- sys/unix/hints/include/cross-post.2020 | 50 +++- sys/unix/hints/include/cross-pre.2020 | 116 +++++++- sys/unix/hints/include/multiw-2.2020 | 4 + sys/unix/hints/linux.2020 | 10 + sys/unix/hints/macOS.2020 | 13 + sys/unix/unixmain.c | 12 +- util/makedefs.c | 8 + win/shim/winshim.c | 329 +++++++++++++++++----- 28 files changed, 1555 insertions(+), 120 deletions(-) create mode 100644 sys/lib/README.md create mode 100755 sys/lib/hints/macOS.2020 create mode 100644 sys/lib/hints/wasm create mode 100644 sys/lib/npm-package/LICENSE.md create mode 100644 sys/lib/npm-package/README.md create mode 100644 sys/lib/npm-package/package.json create mode 100644 sys/lib/npm-package/src/nethackShim.js create mode 100644 sys/lib/sysconf create mode 100644 sys/lib/test/README.md create mode 100644 sys/lib/test/libtest.c create mode 100755 sys/lib/test/run.sh diff --git a/.gitignore b/.gitignore index 5c64716a3..366cf938f 100644 --- a/.gitignore +++ b/.gitignore @@ -37,7 +37,7 @@ Release/ binary/ build/ ipch/ -lib/ +lib/* Nethack.sln Nethack.sdf Nethack.opensdf @@ -81,3 +81,9 @@ win/share/monthin.txt win/share/objthin.txt win/share/oththin.txt # end of ms-dos + +#libnethack +targets/* +#test.js +#sys/lib/npm-package/build/nethack.js +#sys/lib/npm-package/build/nethack.wasm diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b5dae5e94..04e64186e 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -597,6 +597,8 @@ fix the "stuck pets" issue (github #329) allow themed room subrooms to be filled (github #347) allow rereading spellbooks to refresh memory at any time (github #261) allow themed rooms constrained by level difficulty (github #344) +add a varied form of LIBNH nethack library contribution (github #385) +add cross-compile to WASM (github #385) Code Cleanup and Reorganization diff --git a/include/global.h b/include/global.h index fbffef7a1..caa32847b 100644 --- a/include/global.h +++ b/include/global.h @@ -399,11 +399,14 @@ struct savefile_info { #ifdef UNIX #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) /* see end.c */ +#if !defined(CROSS_TO_WASM) #ifndef PANICTRACE #define PANICTRACE -#endif -#endif -#endif +#endif /* PANICTRACE */ +#endif /* CROSS_TO_WASM */ +#endif /* NH_DEVEL_STATUS != NH_STATUS_RELEASED */ +#endif /* UNIX */ + /* The following are meaningless if PANICTRACE is not defined: */ #if defined(__linux__) && defined(__GLIBC__) && (__GLIBC__ >= 2) #define PANICTRACE_LIBC @@ -412,8 +415,10 @@ struct savefile_info { #define PANICTRACE_LIBC #endif #ifdef UNIX +#if !defined(CROSS_TO_WASM) /* no popen in WASM */ #define PANICTRACE_GDB #endif +#endif /* Supply nethack_enter macro if not supplied by port */ #ifndef nethack_enter diff --git a/include/unixconf.h b/include/unixconf.h index abc69ee84..e97481d7d 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -389,7 +389,7 @@ #endif /* LINUX */ #endif /* GNOME_GRAPHICS */ -#ifdef MACOSX +#if defined(MACOSX) && !defined(LIBNH) # define RUNTIME_PASTEBUF_SUPPORT #endif diff --git a/src/mdlib.c b/src/mdlib.c index f2abba620..e0fef5a64 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -131,7 +131,7 @@ static struct win_info window_opts[] = { { "mswin", "Windows GUI", TRUE }, #endif #ifdef SHIM_GRAPHICS - { "shim", "Nethack Library Windowing Shim", TRUE }, + { "shim", "NetHack Library Windowing Shim", TRUE }, #endif #if 0 /* remainder have been retired */ diff --git a/src/rip.c b/src/rip.c index b61a76254..634d816d2 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rip.c $NHDT-Date: 1596498204 2020/08/03 23:43:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.7 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. */ @@ -6,7 +6,8 @@ #include "hack.h" #if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) \ - || defined(MSWIN_GRAPHICS) || defined(DUMPLOG) || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) + || defined(MSWIN_GRAPHICS) || defined(DUMPLOG) \ + || defined(CURSES_GRAPHICS) || defined(SHIM_GRAPHICS) #define TEXT_TOMBSTONE #endif #if defined(mac) || defined(__BEOS__) || defined(WIN32_GRAPHICS) @@ -60,12 +61,10 @@ static const char *rip_txt[] = { }; #define STONE_LINE_CENT 19 /* char[] element of center of stone face */ #endif /* NH320_DEDICATION */ -#define STONE_LINE_LEN \ - 16 /* # chars that fit on one line \ - * (note 1 ' ' border) \ - */ -#define NAME_LINE 6 /* *char[] line # for player name */ -#define GOLD_LINE 7 /* *char[] line # for amount of gold */ +#define STONE_LINE_LEN 16 /* # chars that fit on one line + * (note 1 ' ' border) */ +#define NAME_LINE 6 /* *char[] line # for player name */ +#define GOLD_LINE 7 /* *char[] line # for amount of gold */ #define DEATH_LINE 8 /* *char[] line # for death description */ #define YEAR_LINE 12 /* *char[] line # for year */ @@ -90,9 +89,9 @@ time_t when; register char **dp; register char *dpx; char buf[BUFSZ]; - long year; register int x; - int line; + int line, year; + long cash; g.rip = dp = (char **) alloc(sizeof(rip_txt)); for (x = 0; rip_txt[x]; ++x) @@ -100,13 +99,15 @@ time_t when; dp[x] = (char *) 0; /* Put name on stone */ - Sprintf(buf, "%s", g.plname); - buf[STONE_LINE_LEN] = 0; + Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, g.plname); center(NAME_LINE, buf); /* Put $ on stone */ - Sprintf(buf, "%ld Au", g.done_money); - buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */ + cash = max(g.done_money, 0L); + /* arbitrary upper limit; practical upper limit is quite a bit less */ + if (cash > 999999999L) + cash = 999999999L; + Sprintf(buf, "%ld Au", cash); center(GOLD_LINE, buf); /* Put together death description */ @@ -114,11 +115,11 @@ time_t when; /* Put death type on stone */ for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) { - register int i, i0; char tmpchar; + int i, i0 = (int) strlen(dpx); - if ((i0 = strlen(dpx)) > STONE_LINE_LEN) { - for (i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--) + if (i0 > STONE_LINE_LEN) { + for (i = STONE_LINE_LEN; (i > 0) && (i0 > STONE_LINE_LEN); --i) if (dpx[i] == ' ') i0 = i; if (!i) @@ -135,8 +136,8 @@ time_t when; } /* Put year on stone */ - year = yyyymmdd(when) / 10000L; - Sprintf(buf, "%4ld", year); + year = (int) ((yyyymmdd(when) / 10000L) % 10000L); + Sprintf(buf, "%4d", year); center(YEAR_LINE, buf); #ifdef DUMPLOG diff --git a/src/version.c b/src/version.c index d6b8ed724..a499c3a51 100644 --- a/src/version.c +++ b/src/version.c @@ -265,7 +265,7 @@ boolean pastebuf; raw_printf("%s", buf2); if (pastebuf) { -#ifdef RUNTIME_PASTEBUF_SUPPORT +#if defined(RUNTIME_PASTEBUF_SUPPORT) && !defined(LIBNH) /* * Call a platform/port-specific routine to insert the * version information into a paste buffer. Useful for diff --git a/sys/lib/README.md b/sys/lib/README.md new file mode 100644 index 000000000..3bc7c283a --- /dev/null +++ b/sys/lib/README.md @@ -0,0 +1,95 @@ +# About +This creates a library for NetHack that can be incorporated into other programs. There are two different libraries that are currently available: +* libnethack.a - a binary Unix library +* nethack.js / nethack.wasm - a [WebAssembly / WASM](https://webassembly.org/) library for use in JavaScript programs (both nodejs and browser) + +## Build +This library has only been built on MacOS, but should work on Linux and other unix-ish platforms. If you have problems, start by stealing hints files from the `sys/unix/hints` for your platform. Contributions for other platforms are happily accepted. + +Building the WASM module requires that you have the [emscripten toolchain / sdk installed](https://emscripten.org/docs/getting_started/downloads.html). + +Generally the build is the same as the unix build: +1. `cd sys/lib` +2. For `libnethack.a`: `./setup.sh hints/macOS.2020`; for `nethack.js`: `./setup.sh hints/wasm` +3. `cd ../..` +4. `make` + +Resulting libaries will be in the `src` directory. + +WASM also has a npm module that can be published out of `sys/lib/npm-library`. After building the `nethack.js` it can be published by: +1. `cd sys/lib/npm-library` +2. `npm publish` + +## API: libnethack.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 scrren. 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.doc) 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.doc](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc). + +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 sumbit a PR to fix it. :) + +## API: nethack.js +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.doc) 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.doc](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) + * The function must return the value expected for the specified `name` + + +## API Stability +The "shim graphics" API should generally be stable. I aspire to replace the command line arguments (argc / argv) with a structure of options, so the `nhmain()` and `main()` functions may change at some point. + +## libnethack.a example +``` c +#include + +int nhmain(int argc, char *argv[]); +typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +void shim_graphics_set_callback(shim_callback_t cb); + +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { + /* TODO */ +} + +int main(int argc, char *argv[]) { + shim_graphics_set_callback(window_cb); + nhmain(argc, argv); +} +``` + +## nethack.js example +``` js +const path = require("path"); + +// starts nethack +function nethackStart(cb, inputModule = {}) { + // set callback + let cbName = cb.name; + if (cbName === "") cbName = "__anonymousNetHackCallback"; + let userCallback = globalThis[cbName] = cb; + + // Emscripten Module config + let Module = inputModule; + savedOnRuntimeInitialized = Module.onRuntimeInitialized; + Module.onRuntimeInitialized = function (... args) { + // after the WASM is loaded, add the shim graphics callback function + Module.ccall( + "shim_graphics_set_callback", // C function name + null, // return type + ["string"], // arg types + [cbName], // arg values + {async: true} // options + ); + }; + + // load and run the module + var factory = require(path.join(__dirname, "../build/nethack.js")); + factory(Module); +} + +nethackStart(yourCallbackFunction); +``` \ No newline at end of file diff --git a/sys/lib/hints/macOS.2020 b/sys/lib/hints/macOS.2020 new file mode 100755 index 000000000..3edd3b768 --- /dev/null +++ b/sys/lib/hints/macOS.2020 @@ -0,0 +1,360 @@ +# NetHack 3.7 macOS.2020 $NHDT-Date: 1597704793 2020/08/17 22:53:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ +# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. +# NetHack may be freely redistributed. See license for details. +# +#--------------------------------------------------------------------- +# MacOS hints file with support for multiple window ports (interfaces) +# Tested on: +# - MacOS Catalina 10.15 +# +# If this doesn't work for some other version of Mac OS X, 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 + +#-PRE xxxx +# macOS X hints file +# + +# 5. Other + +#----------------------------------------------------------------------------- +# You shouldn't need to change anything below here (in the hints file; if +# you're reading this in Makefile augmented by hints, that may not be true). +# + +AR=ar rcu +RANLIB=ranlib + +# XXX -g vs -O should go here, -I../include goes in the makefile +CFLAGS+=-g -I../include -DNOTPARMDECL +CFLAGS+=-Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wformat -Wswitch -Wshadow -Wwrite-strings +CFLAGS+=-DGCC_WARN + +# NetHack sources control +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDLB +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE +#CFLAGS+=-DTIMED_DELAY +#CFLAGS+=-DDUMPLOG +#CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE +CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +#CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" +# older binaries use NOCLIPPING, but that disables SIGWINCH +#CFLAGS+=-DNOCLIPPING +CFLAGS+=-DNOMAIL +#CFLAGS+=-DEXTRA_SANITY_CHECKS +#CFLAGS+=-DEDIT_GETLIN +#CFLAGS+=-DSCORE_ON_BOTL +#CFLAGS+=-DMSGHANDLER +#CFLAGS+=-DTTY_TILES_ESCCODES +#CFLAGS+=-DTTY_SOUND_ESCCODES + +CFLAGS+=-DDEFAULT_WINDOW_SYS=\"shim\" -DNOTTYGRAPHICS -DLIBNH + +CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 + +VARDATND = +VARDATND0 = +CURSESLIB = + +ifdef WANT_WIN_CHAIN +HINTSRC=$(CHAINSRC) +HINTOBJ=$(CHAINOBJ) +endif # WANT_WIN_CHAIN + +LINK=$(CC) + +# prevent duplicate tile.o in WINOBJ +WINOBJ = $(sort $(WINOBJ0)) +# prevent duplicates in VARDATND if both X11 and Qt are being supported +VARDATND += $(sort $(VARDATND0)) + +WANT_BUNDLE=1 +ifdef WANT_SHARE_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 +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 +PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ + . sys/unix/hints/macosx.sh group2 $(GAMEGRP); \ + mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; + +else ifdef WANT_SOURCE_INSTALL + +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: +MOREALL=$(MAKE) install +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE + +else # !WANT_SOURCE_INSTALL + +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 +endif # WANT_DEFAULT X11 + +POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ + $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ + $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ + chmod $(VARFILEPERM) $(HACKDIR)/sysconf; +ifdef WANT_BUNDLE +# +# Bundle +# +# $(HACKDIR)/$(GAME).app/ +# Contents/ +# Frameworks/ +# Info.plist +# MacOS/ +# $(GAME) +# PkgInfo/ +# PlugIns/ +# Resources/ +# SharedFrameWorks/ +# +BUNDLE = mkdir -p $(HACKDIR)/nethack.app/Contents/MacOS; \ + sys/unix/hints/macosx.sh infoplist > $(HACKDIR)/nethack.app/Contents/Info.plist; \ + mv $(HACKDIR)/nethack $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +ifdef WANT_SHARE_INSTALL +BUNDLE+= chmod $(GAMEPERM) $(HACKDIR)/nethack.app/Contents/MacOS/nethack; +endif + +POSTINSTALL+= $(BUNDLE) +POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ + sed -i '' 's;HACKDIR/$(GAME);HACKDIR/$(GAME).app/Contents/MacOS/$(GAME);' $(SHELLDIR)/$(GAME) ; fi; +endif # WANT_BUNDLE +endif # !WANT_SHARE_INSTALL + +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) + +# ~/Library/Preferences/NetHack Defaults +# OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp +# OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt +# +# Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary +# package under the docs directory). + +#-POST +ifdef MAKEFILE_TOP +### +### Packaging +### +# Notes: +# 1) The Apple developer utilities must be installed in the default location. +# 2) Do a normal build before trying to package the game. +# 3) This matches the 3.4.3 Term package, but there are some things that +# should be changed. +# +# Packages that are being distributed must be signed by a Developer ID +# Installer certificate. Set DEVELOPER_CERT to the name of the certificate +# if you wish for your package to be signed for distribution. +# +# If building a package for signing, you must use sudo approriately. +# the binaries and package using sudo but you DO NOT use sudo to sign the +# package. If you use sudo to sign the package, it will fail. +# +# sudo make all +# sudo make build_tty_pkg +# make sign_tty_pkg +# + +ifdef WANT_WIN_TTY +DEVUTIL=/Developer/Applications/Utilities +SVS=$(shell $(NHSROOT)/util/makedefs --svs) +SVSDOT=$(shell $(NHSROOT)/util/makedefs --svs .) + +PKGROOT_UG = PKGROOT/$(PREFIX) +PKGROOT_UGLN = PKGROOT/$(HACKDIR) +PKGROOT_BIN = PKGROOT/$(SHELLDIR) + +#DEVELOPER_CERT = Developer ID Installer: Bart House +DEVELOPER_CERT = NONE + +spotless:: + rm -rf RESOURCES + rm -rf PKG + rm -rf PKGSCRIPTS + rm -rf PKGROOT + rm -f Info.plist + rm -f Distribution.xml + rm -f NetHack-*-mac-Term* + +build_tty_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_QT)) + -echo build_tty_pkg only works for a tty-only build + exit 1 +else + rm -rf NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + $(MAKE) build_package_root + rm -rf RESOURCES + mkdir RESOURCES + #enscript --language=rtf -o - < dat/license >RESOURCES/License.rtf + sys/unix/hints/macosx.sh descplist > RESOURCES/Description.plist + sys/unix/hints/macosx.sh infoplist > Info.plist + + mkdir PKGROOT/Applications + #osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + # win/macosx/NetHackRecover.applescript + #cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + osacompile -o PKGROOT/Applications/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl $(PKGROOT_UGLN) + + osacompile -o PKGROOT/Applications/NetHackTerm.app \ + win/macosx/NetHackTerm.applescript + + # XXX integrate into Makefile.doc + (cd doc; cat Guidebook.mn | ../util/makedefs --grep --input - --output - \ + | tbl tmac.n - | groff | pstopdf -i -o Guidebook.pdf) + cp doc/Guidebook.pdf $(PKGROOT_UG)/doc/NetHackGuidebook.pdf + + osacompile -o PKGROOT/Applications/NetHackGuidebook.app \ + win/macosx/NetHackGuidebook.applescript + + mkdir -p PKG + pkgbuild --root PKGROOT --identifier org.nethack.term --scripts PKGSCRIPTS PKG/NH-Term.pkg + productbuild --synthesize --product Info.plist --package PKG/NH-Term.pkg Distribution.xml + productbuild --distribution Distribution.xml --resources RESOURCES --package-path PKG NetHack-$(SVS)-mac-Term-unsigned.pkg +ifeq ($(DEVELOPER_CERT),NONE) + cp NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term-unsigned.dmg + @echo ------------------------------------------- + @echo PACKAGE IS NOT SIGNED FOR DISTRIBUTION!!!!! + @echo =========================================== +else + @echo "run 'make sign_tty_pkg' to complete package" +endif + +sign_tty_pkg: + productsign --timestamp=none --sign "$(DEVELOPER_CERT)" NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg || (echo "Package signing failed"; exit 1) + spctl -a -v --type install NetHack-$(SVS)-mac-Term.pkg || (echo "Package not signed properly"; exit 1) + hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg + +build_package_root: + cd src/.. # make sure we are at TOP + rm -rf PKGROOT + mkdir -p $(PKGROOT_UG)/lib $(PKGROOT_BIN) $(PKGROOT_UG)/man/man6 $(PKGROOT_UG)/doc $(PKGROOT_UGLN) + install -p src/nethack $(PKGROOT_BIN) + # XXX should this be called nethackrecover? + install -p util/recover $(PKGROOT_BIN) + install -p doc/nethack.6 $(PKGROOT_UG)/man/man6 + install -p doc/recover.6 $(PKGROOT_UG)/man/man6 + install -p doc/Guidebook $(PKGROOT_UG)/doc + install -p dat/nhdat $(PKGROOT_UGLN) + sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(PKGROOT_UGLN)/sysconf + cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN) +# XXX these files should be somewhere else for good Mac form + touch $(PKGROOT_UGLN)/perm $(PKGROOT_UGLN)/record $(PKGROOT_UGLN)/logfile $(PKGROOT_UGLN)/xlogfile + mkdir $(PKGROOT_UGLN)/save +# XXX what about a news file? + + mkdir -p PKGSCRIPTS + echo '#!/bin/sh' > PKGSCRIPTS/postinstall + echo dseditgroup -o create -r '"Games Group"' -s 3600 $(GAMEGRP) >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(HACKDIR)/* >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(HACKDIR)/* >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + echo chmod $(VARDIRPERM) $(HACKDIR) >> PKGSCRIPTS/postinstall + echo chmod $(VARDIRPERM) $(HACKDIR)/save >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/license >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/nhdat >> PKGSCRIPTS/postinstall + echo chmod $(FILEPERM) $(HACKDIR)/symbols >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/perm >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/record >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/logfile >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/xlogfile >> PKGSCRIPTS/postinstall + echo chmod $(VARFILEPERM) $(HACKDIR)/sysconf >> PKGSCRIPTS/postinstall + echo chmod $(GAMEPERM) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall + echo chmod $(EXEPERM) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall + chmod 0775 PKGSCRIPTS/postinstall + +endif # end of build_tty_pkg +endif # WANT_WIN_TTY for packaging + +ifdef WANT_WIN_QT +# XXX untested and incomplete (see below) +build_qt_pkg: +ifneq (,$(WANT_WIN_X11)$(WANT_WIN_TTY)) + -echo build_qt_pkg only works for a qt-only build + exit 1 +else + $(MAKE) build_package_root + rm -rf NetHackQt + mkdir -p NetHackQt/NetHackQt.app/nethackdir/save + mkdir NetHackQt/Documentation + cp doc/Guidebook.txt doc/nethack.txt doc/recover.txt NetHackQt/Documentation + + osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ + win/macosx/NetHackRecover.applescript + cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir + + mkdir -p NetHackQt/NetHackQt.app/Contents/Frameworks + cp $(QTDIR)/libqt-mt.3.dylib NetHackQt/NetHackQt.app/Contents/Frameworks + + mkdir NetHackQt/NetHackQt.app/Contents/MacOS + mv PKGROOT/nethack NetHackQt/NetHackQt.app/Contents/MacOS + + mv PKGROOT/lib/nethackdir NetHackQt/NetHackQt.app/nethackdir + +# XXX still missing: +#NetHackQt/NetHackQt.app +# /Contents +# Info.plist +# Resources/nethack.icns +#NetHackQt/Documentation +#NetHackQtRecover.txt +#NetHack Defaults.txt +#changes.patch XXX is this still needed? why isn't it part of the tree? +# doesn't go here + hdiutil create -verbose -srcfolder NetHackQt NetHack-$(SVS)-macosx-qt.dmg +endif # end of build_qt_pkg +endif # WANT_WIN_QT for packaging +endif # MAKEFILE_TOP diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm new file mode 100644 index 000000000..7f85090af --- /dev/null +++ b/sys/lib/hints/wasm @@ -0,0 +1,77 @@ + +#-PRE xxxx +# enscripten WebAssembly config + +WANT_WASM=1 +WASM_DEBUG=1 +WASM_DATA_DIR=$(NHSROOT)/src/wasm-data + +# toolchain +EMCC=emcc +EMAR=emar rcu +EMRANLIB=emranlib + +# link flags +EMCC_LFLAGS=-s SINGLE_FILE=1 +EMCC_LFLAGS=-s WASM=1 +EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH +EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' +EMCC_LFLAGS+=-O3 +EMCC_LFLAGS+=-s MODULARIZE +EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' +EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue", "setValue"]' +EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 +EMCC_LFLAGS+=--embed-file wasm-data@/ + +# For a list of EMCC settings: +# https://github.com/emscripten-core/emscripten/blob/master/src/settings.js + +# WASM C flags +EMCC_CFLAGS= +EMCC_CFLAGS+=-Wall +EMCC_CFLAGS+=-Werror +#EMCC_CFLAGS+=-s DISABLE_EXCEPTION_CATCHING=0 +EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 +#EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=2 +EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 +EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 +EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED=1 +#EMCC_DEBUG_CFLAGS+=-s EXCEPTION_DEBUG=1 +#EMCC_DEBUG_CFLAGS+=-fsanitize=undefined -fsanitize=address -fsanitize=leak +#EMCC_DEBUG_CFLAGS+=-s EXIT_RUNTIME +EMCC_PROD_CFLAGS+=-O3 + +# Nethack C flags +CFLAGS+=-DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE +CFLAGS+=-g -I../include -DNOTPARMDECL +CFLAGS+=-Wall +CFLAGS+=-Werror +CFLAGS+=-DGCC_WARN + +# NetHack sources control +CFLAGS+=-DDLB +CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" +CFLAGS+=-DDLB +#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" +CFLAGS+=-DNOMAIL + +ifdef WASM_DEBUG +EMCC_CFLAGS+=$(EMCC_DEBUG_CFLAGS) +else +EMCC_CFLAGS+=$(EMCC_PROD_CFLAGS) +endif + +# installation config +# hackdir is the wasm / emscripten embed data root directory +HACKDIR=/ +CHOWN=/usr/bin/true +CHGRP=/usr/bin/true +GAMEPERM = 0700 +VARFILEPERM = 0600 +VARDIRPERM = 0700 + +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) + +#-POST +# no post \ No newline at end of file diff --git a/sys/lib/npm-package/LICENSE.md b/sys/lib/npm-package/LICENSE.md new file mode 100644 index 000000000..5ad7e3417 --- /dev/null +++ b/sys/lib/npm-package/LICENSE.md @@ -0,0 +1,95 @@ + NETHACK GENERAL PUBLIC LICENSE + (Copyright 1989 M. Stephenson) + + (Based on the BISON general public license, + copyright 1988 Richard M. Stallman) + + Everyone is permitted to copy and distribute verbatim copies of this + license, but changing it is not allowed. You can also use this wording to + make the terms for other programs. + + The license agreements of most software companies keep you at the mercy of +those companies. By contrast, our general public license is intended to give +everyone the right to share NetHack. To make sure that you get the rights we +want you to have, we need to make restrictions that forbid anyone to deny you +these rights or to ask you to surrender the rights. Hence this license +agreement. + + Specifically, we want to make sure that you have the right to give away +copies of NetHack, that you receive source code or else can get it if you +want it, that you can change NetHack or use pieces of it in new free +programs, and that you know you can do these things. + + To make sure that everyone has such rights, we have to forbid you to +deprive anyone else of these rights. For example, if you distribute copies +of NetHack, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must tell them their rights. + + Also, for our own protection, we must make certain that everyone finds out +that there is no warranty for NetHack. If NetHack is modified by someone +else and passed on, we want its recipients to know that what they have is +not what we distributed. + + Therefore we (Mike Stephenson and other holders of NetHack copyrights) make +the following terms which say what you must do to be allowed to distribute or +change NetHack. + + + COPYING POLICIES + + 1. You may copy and distribute verbatim copies of NetHack source code as +you receive it, in any medium, provided that you keep intact the notices on +all files that refer to copyrights, to this License Agreement, and to the +absence of any warranty; and give any other recipients of the NetHack +program a copy of this License Agreement along with the program. + + 2. You may modify your copy or copies of NetHack or any portion of it, and +copy and distribute such modifications under the terms of Paragraph 1 above +(including distributing this License Agreement), provided that you also do the +following: + + a) cause the modified files to carry prominent notices stating that you + changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, that in + whole or in part contains or is a derivative of NetHack or any part + thereof, to be licensed at no charge to all third parties on terms + identical to those contained in this License Agreement (except that you + may choose to grant more extensive warranty protection to some or all + third parties, at your option) + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty protection + in exchange for a fee. + + 3. You may copy and distribute NetHack (or a portion or derivative of it, +under Paragraph 2) in object code or executable form under the terms of +Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete machine-readable source code, which + must be distributed under the terms of Paragraphs 1 and 2 above; or, + + b) accompany it with full information as to how to obtain the complete + machine-readable source code from an appropriate archive site. (This + alternative is allowed only for noncommercial distribution.) + +For these purposes, complete source code means either the full source +distribution as originally released over Usenet or updated copies of the +files in this distribution used to create the object code or executable. + + 4. You may not copy, sublicense, distribute or transfer NetHack except as +expressly provided under this License Agreement. Any attempt otherwise to +copy, sublicense, distribute or transfer NetHack is void and your rights to +use the program under this License agreement shall be automatically +terminated. However, parties who have received computer software programs +from you with this License Agreement will not have their licenses terminated +so long as such parties remain in full compliance. + + +Stated plainly: You are permitted to modify NetHack, or otherwise use parts +of NetHack, provided that you comply with the conditions specified above; +in particular, your modified NetHack or program containing parts of NetHack +must remain freely available as provided in this License Agreement. In +other words, go ahead and share NetHack, but don't try to stop anyone else +from sharing it farther. diff --git a/sys/lib/npm-package/README.md b/sys/lib/npm-package/README.md new file mode 100644 index 000000000..e39db8292 --- /dev/null +++ b/sys/lib/npm-package/README.md @@ -0,0 +1,47 @@ +# NetHack +This is the ACTUAL NetHack game, originally written in 1982 and one of the longest-standing open source collaborations. This isn't a wrapper around the binary NetHack, but the game itself compiled into [WebAssembly](https://webassembly.org/) (WASM) using [emscripten](https://emscripten.org/). This module should run [anywhere WebAssembly is supported](https://developer.mozilla.org/en-US/docs/WebAssembly#Browser_compatibility) including node.js and modern browsers. + +Since NetHack typically uses the [TTY](https://en.wikipedia.org/wiki/Computer_terminal#Text_terminals) to show depictions of the game and that won't work for WebAssembly, you are required to implement the graphics portion of NetHack to make this work. This allows a wide variety of UIs to be created, both text and graphics based as well as using keyboard and mouse to control the game. The API for implementing graphics is described below. + +## Install + +``` sh +npm install nethack +``` + +## API +The main module returns a setup function: `startNethack(uiCallback, moduleOptions)`. +* `uiCallback(name, ... args)` - Your callback function that will handle rendering NetHack on the screen of your choice. The `name` argument is one of the UI functions of the [NetHack Window Interface](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) and the `args` are corresponding to the window interface function that is being called. You are required to return the correct type of data for the function that is implemented. The `uiCallback` may be an `async` function. +* `moduleOptions` - An optional [emscripten Module object](https://emscripten.org/docs/api_reference/module.html) for configuring the WASM that will be run. + * `Module.arguments` - Of note is the [arguments property](https://emscripten.org/docs/api_reference/module.html#Module.arguments) which gets passed to NetHack as its [command line parameters](https://nethackwiki.com/wiki/Options). + +## Example +``` js +let nethackStart = require("nethack"); + +nethackStart(doGraphics); + +let winCount = 0; +async function doGraphics(name, ... args) { + console.log(`shim graphics: ${name} [${args}]`); + + switch(name) { + case "shim_create_nhwindow": + winCount++; + console.log("creating window", args, "returning", winCount); + return winCount; + case "shim_yn_function": + case "shim_message_menu": + return 121; // return 'y' to all questions + case "shim_nhgetch": + case "shim_nh_poskey": + return 0; // simulates a mouse click on "exit up the stairs" + default: + return 0; + } +} +``` + +## Other Notes +* This module isn't small -- the WASM code is about 10MB. It may be slow to load over non-broadband connections. There are some emscripten build optimizations that may help with browser builds (such as dynamic loading), but those aren't currently part of this package. Pull requests are always welcome. :) +* This hasn't been tested on browsers. If you get this to work on a browser, please let me know and I will add notes. Or if anyone wants to help setup automated browser testing, that would be supremely appreciated. \ No newline at end of file diff --git a/sys/lib/npm-package/package.json b/sys/lib/npm-package/package.json new file mode 100644 index 000000000..b4e931559 --- /dev/null +++ b/sys/lib/npm-package/package.json @@ -0,0 +1,20 @@ +{ + "name": "@neth4ck/neth4ck", + "version": "1.0.0", + "description": "The original NetHack rogue-like game built as a WebAssembly module", + "main": "src/nethackShim.js", + "scripts": { + "test": "node test/test.js", + "clean": "rm ./build/nethack.js; rm ./build/nethack.wasm; true", + "build": "cp ../../../src/nethack.js ../../../src/nethack.wasm ./build", + "prepack": "npm run build" + }, + "keywords": [ + "nethack", + "rogue", + "rogue-like", + "game" + ], + "author": "Adam Powers ", + "license": "SEE LICENSE IN LICENSE.md" +} diff --git a/sys/lib/npm-package/src/nethackShim.js b/sys/lib/npm-package/src/nethackShim.js new file mode 100644 index 000000000..e7a802c30 --- /dev/null +++ b/sys/lib/npm-package/src/nethackShim.js @@ -0,0 +1,49 @@ +const path = require("path"); + +let Module; +let userCallback; +let savedOnRuntimeInitialized; + +// starts nethack +function nethackStart(cb, inputModule = {}) { + if(typeof cb !== "string" && typeof cb !== "function") throw new TypeError("expected first argument to be 'Function' or 'String' representing global callback function name"); + if(typeof inputModule !== "object") throw new TypeError("expected second argument to be object"); + + let cbName; + if(typeof cb === "function") { + cbName = cb.name; + if (cbName === "") cbName = "__anonymousNetHackCallback"; + if (globalThis[cbName] === undefined) globalThis[cbName] = cb; + else if (globalThis[cbName] !== cb) throw new Error (`'globalThis["${cbName}"]' is not the same as specified callback`); + } + + /* global globalThis */ + userCallback = globalThis[cbName]; + if(typeof userCallback !== "function") throw new TypeError(`expected 'globalThis["${cbName}"]' to be a function`); + // if(userCallback.constructor.name !== "AsyncFunction") throw new TypeError(`expected 'globalThis["${cbName}"]' to be an async function`); + + // Emscripten Module config + Module = inputModule; + savedOnRuntimeInitialized = Module.onRuntimeInitialized; + Module.onRuntimeInitialized = function (... args) { + // after the WASM is loaded, add the shim graphics callback function + Module.ccall( + "shim_graphics_set_callback", // C function name + null, // return type + ["string"], // arg types + [cbName], // arg values + {async: true} // options + ); + + // if the user had their own onRuntimeInitialized(), call it now + if (savedOnRuntimeInitialized) savedOnRuntimeInitialized(... args); + }; + + // load and run the module + var factory = require(path.join(__dirname, "../build/nethack.js")); + factory(Module); +} + +// TODO: ES6 'import' style module +module.exports = nethackStart; + diff --git a/sys/lib/sysconf b/sys/lib/sysconf new file mode 100644 index 000000000..77b4c383f --- /dev/null +++ b/sys/lib/sysconf @@ -0,0 +1,150 @@ +# NetHack 3.7 sysconf $NHDT-Date: 1596498296 2020/08/03 23:44:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.39 $ +# Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland +# NetHack may be freely redistributed. See license for details. +# +# Sample sysconf file. +# The sysconf file is only used if NetHack is compiled with SYSCF defined. +# It can be used to augment or override certain settings compiled into the +# program. +# +# This file can also be used to set local system defaults for run-time +# options, using the same syntax as an individual user's ./nethackrc file. + +# Which users can use debug mode (aka wizard mode; accessed via '-D' command +# line flag or OPTIONS=playmode:debug in the runtime options config file). +# A value of * allows anyone to enter debugging mode. +WIZARDS=root games + +# Which users can use explore mode (aka discover mode; accessed via '-X' +# command line flag or OPTIONS=playmode:explore in runtime options file or +# via '#exploremode' command during normal play). Same syntax as WIZARDS. +EXPLORERS=* + +# Users allowed to use the '!' (shell escape) and '^Z' (suspend process) +# commands to temporarily leave the game and enter a shell process. +# (To resume play, use the shell command 'exit' (for most shells) to +# return from '!' or the shell command 'fg' to return from '^Z'. +# For the typical multi-user system where players have access to a shell +# prompt when logged in and run the game from their own username, a value +# of 'SHELLERS=*' is appropriate. However, some inexperienced players +# occasionally get stuck outside the game by accidentally typing '!' or +# '^Z' during play and not knowing how to go back.) +# Uses the same syntax as the WIZARDS and EXPLORERS options above. +#SHELLERS= + +# If the user name is found in this list, prompt for username instead. +# Uses the same syntax as the WIZARDS option above. +# A public server should probably disable this. +# ["ec2-user" is the default user name on Amazon Linux] +GENERICUSERS=play player game games nethack nethacker ec2-user + +# Use the player name for matching WIZARDS, EXPLORERS and SHELLERS, +# instead of the user's login name. +#CHECK_PLNAME=1 + +# Limit the number of simultaneous games (see also nethack.sh). +# Valid values are 0-25. +# Commenting this out or setting the value to 0 constructs lock files +# with UID and playername, so each user may have one game at a time, +# but number of different players is not limited. +# Setting this to any other value constructs the lock files with +# letter and "lock" (eg. alock, block, ...) +MAXPLAYERS=10 + +# If not null, added to string "To get local support, " in the support +# information help. +#SUPPORT=call Izchak at extension 42. + +# If not null, displayed at the end of a panic-save sequence. +#RECOVER=Run the recover program. + +# Uncomment the next line to disable the SEDUCE option, causing succubi and +# incubi to use nymphs' charm behavior rather than their own seduce behavior. +#SEDUCE=0 + +# Uncomment the next line to enable some accessibility features such +# as S_hero_override and S_pet_override symbols for screen readers +# in the user config file. +#ACCESSIBILITY=1 + +# Uncomment to disable savefile UID checking. +#CHECK_SAVE_UID=0 + +# Record (high score) file options. +# CAUTION: changing these after people have started playing games can +# lead to lost high scores! +# Maximum entries for one person. +#PERSMAX=10 +# Maximum entries in the record file. +#ENTRYMAX=100 +# Minimum points to get an entry. +#POINTSMIN=1 +# Determine identity of "person" in the score file with name (0) or +# numeric (1) user id. +#PERS_IS_UID=1 + +# Maximum number of score file entries to use for random statue names +#MAX_STATUENAME_RANK=10 + +# Show debugging information originating from these source files. +# Use '*' for all, or list source files separated by spaces. +# Only available if game has been compiled with DEBUG, and can be +# overridden via DEBUGFILES environment variable. +#DEBUGFILES=* + +# Save end of game dump log to this file. +# Only available if NetHack was compiled with DUMPLOG +# Allows following placeholders: +# %% literal '%' +# %v version (eg. "3.7.0-0") +# %u game UID +# %t game start time, UNIX timestamp format +# %T current time, UNIX timestamp format +# %d game start time, YYYYMMDDhhmmss format +# %D current time, YYYYMMDDhhmmss format +# %n player name +# %N first character of player name +#DUMPLOGFILE=/tmp/nethack.%n.%d.log + +# Number of bones file pools. +# The pool you belong to is determined at game start. You will +# load and save bones only from that pool. Generally useful +# for public servers only. +# Changing this might make existing bones inaccessible. +# Disabled by setting to 0, or commenting out. +#BONES_POOLS=10 + +# Try to get more info in case of a program bug or crash. Only used +# if the program is built with the PANICTRACE compile-time option enabled. +# By default PANICTRACE is enabled if (NH_DEVEL_STATUS != NH_STATUS_RELEASED), +# otherwise disabled. +# Using GDB can get more information and works on more systems but requires +# 'gdb' be available; using LIBC only works if NetHack is linked with a +# libc that supports the backtrace(3) API. Both require certain compilation +# options. See src/end.c and sys/unix/hints/* for more information. +#GDBPATH=/usr/bin/gdb +#GREPPATH=/bin/grep +# Values are priorities: 0 - do not use this method, 1 - low priority, +# 2 - high priority. Non-zero priority methods are tried in order. +PANICTRACE_GDB=0 +PANICTRACE_LIBC=0 + +# 'portable_device_paths' is only supported for Windows. Starting with +# 3.6.3, nethack on Windows treats the folder containing nethack.exe and +# nethackW.exe as read-only and puts data files which are generated or +# modified during play or by the user in assorted folders derived from +# user name. 3.6.4 added PORTABLE_DEVICE_PATHS to allow reverting to +# the old behavior of having the run-time configuration file and other +# data in the same directory as the executable so that the whole thing +# can be moved from one machine to another (flash drive or perhaps cloud) +# without updating folder paths. +#PORTABLE_DEVICE_PATHS=0 + +# Ordinary run-time options can be set here to override the builtin-in +# default values. Unlike all the SYSCF values above, individual users +# can override the overridden options set here by choosing their own +# option settings via NETHACKOPTIONS in their environment or via +# ~/.nethackrc run-time configuration file. +#OPTIONS=!autopickup,fruit:tomato,symset:DECgraphics + +#eof diff --git a/sys/lib/test/README.md b/sys/lib/test/README.md new file mode 100644 index 000000000..c9cfed377 --- /dev/null +++ b/sys/lib/test/README.md @@ -0,0 +1,8 @@ +Development helpers and tests for libnethack.a and nethack.js. + +Copy these files to the NetHack root directory. Commands include: +* run.sh wasm - rebuild makefiles and build nethack.js +* run.sh runwasm - simple testing of nethack.js +* run.sh lib - rebuild makefiles and build libnethack.a +* run.sh runlib - simple testing of libnethack.a +* run.sh bin - build the MacOS binary \ No newline at end of file diff --git a/sys/lib/test/libtest.c b/sys/lib/test/libtest.c new file mode 100644 index 000000000..31ca10e71 --- /dev/null +++ b/sys/lib/test/libtest.c @@ -0,0 +1,115 @@ +#include +#include + +/* external functions */ +int nhmain(int argc, char *argv[]); +typedef void(*stub_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +void shim_graphics_set_callback(stub_callback_t cb); + +/* forward declarations */ +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...); +void *yourFunctionToRenderGraphics(const char *name, va_list args); + +int main(int argc, char *argv[]) { + shim_graphics_set_callback(window_cb); + nhmain(argc, argv); +} + +void *yourFunctionToRenderGraphics(const char *name, va_list args) { + printf("yourFunctionToRenderGraphics name %s\n", name); + /* DO SOMETHING HERE */ + return NULL; +} + +void window_cb(const char *name, void *ret_ptr, const char *fmt, ...) { + void *ret; + va_list args; + /* TODO -- see windowCallback below for hints */ + va_start(args, fmt); + + ret = yourFunctionToRenderGraphics(name, args); + // *((int *)ret_ptr = *((int *)ret); // e.g. yourFunctionToRenderGraphics returns an int + + va_end(args); +} + +#if 0 +function variadicCallback(name, retPtr, fmt, args) { + // console.log ("variadicCallback called..."); + // console.log("typeof name", typeof name); + // console.log("typeof fmt", typeof fmt); + // console.log("typeof args", typeof args); + name = Module.UTF8ToString(name); + fmt = Module.UTF8ToString(fmt); + // console.log ("name:", name); + // console.log ("fmt:", fmt); + let argTypes = fmt.split(""); + let retType = argTypes.shift(); + // console.log ("arg count:", argTypes.length); + // console.log ("arg types:", argTypes); + // console.log ("ret type:", retType); + + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } + console.log(`graphics callback: ${name} [${jsArgs}]`); + setReturn(retPtr, retType); +} + +function setReturn(ptr, type, value = 0) { + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + Module.setValue(ptr, value, "i32"); + break; + case "c": + Module.setValue(ptr, value, "i8"); // 'Z' + break; + case "f": + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } +} + +function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + return Module.getValue(Module.getValue(ptr, "*"), "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } +} +#endif /* 0 */ \ No newline at end of file diff --git a/sys/lib/test/run.sh b/sys/lib/test/run.sh new file mode 100755 index 000000000..b89ab55d9 --- /dev/null +++ b/sys/lib/test/run.sh @@ -0,0 +1,41 @@ +#!/bin/bash -x + +if [ x$1 == "xlib" ]; then + echo Doing lib... + make spotless + cd sys/lib + ./setup.sh hints/macOS.2020 + cd ../.. + make +fi + +if [ x$1 == "xrunlib" ]; then + LIBS="-Lsrc -lnethack -Llib/lua -llua -lm" + BADLIBS="-lncurses" + rm nhlibtest + gcc -o nhlibtest libtest.c $LIBS $BADLIBS + ./nhlibtest +fi + +if [ x$1 == "xwasm" ]; then + echo Doing wasm... + make spotless + cd sys/lib + ./setup.sh hints/wasm + cd ../.. + make +fi + +if [ x$1 == "xrunwasm" ]; then + cd sys/lib/npm-package && node test/test.js +fi + +if [ x$1 == "xbin" ]; then + echo Doing bin... + make spotless + cd sys/unix + ./setup.sh hints/macOS.2020 + cd ../.. + make +fi + diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index cc69e6f5f..8977c5127 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -300,6 +300,12 @@ WINGNOMEOBJ = WINGEMSRC = WINGEMOBJ = +# Files for Shim windowing interface for libnethack -- doesn't do anything, +# just passes along the API calls to the library +# +WINSHIMSRC = ../win/shim/winshim.c +WINSHIMOBJ = winshim.o + # # Files for a BeOS InterfaceKit port -- not ready for prime time WINBESRC = @@ -524,7 +530,7 @@ SYSCXXSRC = ../sys/share/cppregex.cpp GENCSRC = vis_tab.c #tile.c # all windowing-system-dependent .c (for dependencies and such) -WINCSRC = $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINGNOMESRC) $(WINGEMSRC) +WINCSRC = $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINGNOMESRC) $(WINGEMSRC) $(WINSHIMSRC) # all windowing-system-dependent .cpp (for dependencies and such) WINCXXSRC = $(WINQTSRC) $(WINQT3SRC) $(WINBESRC) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 5d72e4221..89a273221 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -318,7 +318,7 @@ clean: # 'make spotless' returns the source tree to near-distribution condition. # it removes .o files, executables, and compiled data files -spotless:: +spotless:: clean ( cd src ; $(MAKE) spotless ) ( cd util ; $(MAKE) spotless ) ( cd dat ; $(MAKE) spotless ) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 2c34d2189..74228ce6c 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -18,9 +18,9 @@ $(TARGETPFX)vidvesa.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(TARGETPFX)vidstub.o : ../sys/msdos/vidvesa.c ../sys/msdos/portio.h \ $(HACK_H) $(TARGETPFX)tile.o : tile.c -$(GAMEBIN) : $(HOBJ) +$(GAMEBIN) : $(HOBJ) $(LUACROSSLIB) $(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(WINLIB) $(TARGET_LIBS) $(LUALIB) + $(HOBJ) $(WINLIB) $(TARGET_LIBS) # .PHONY: dospkg dospkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp @@ -81,9 +81,9 @@ $(TARGETPFX)monsters.iff: ../win/share/monsters.txt ../util/txt2iff ../util/txt2iff ../win/share/monsters.txt $@ $(TARGETPFX)other.iff: ../win/share/other.txt ../util/txt2iff ../util/txt2iff ../win/share/other.txt $@ -$(GAMEBIN) : $(HOBJ) +$(GAMEBIN) : $(HOBJ) $(LUACROSSLIB) $(TARGET_LINK) $(TARGET_LFLAGS) -o $(GAMEBIN) \ - $(HOBJ) $(WINLIB) $(TARGET_LIBS) $(LUALIB) + $(HOBJ) $(WINLIB) $(TARGET_LIBS) # .PHONY: amigapkg amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp @@ -119,6 +119,34 @@ amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp @echo amiga package zip file $(TARGETPFX)NH370AMI.ZIP endif # CROSS_TO_AMIGA +ifdef CROSS_TO_WASM +$(WASM_TARGET): $(HOBJ) $(LUACROSSLIB) Makefile $(WASM_DATA_DIR) + -rm $@ + $(TARGET_CC) $(EMCC_LFLAGS) $(EMCC_CFLAGS) -o $@ \ + $(HOBJ) $(TARGET_LIBS) + +$(WASM_DATA_DIR): + -mkdir -p $(WASM_DATA_DIR) + touch $(WASM_DATA_DIR)/perm + touch $(WASM_DATA_DIR)/record + touch $(WASM_DATA_DIR)/logfile + touch $(WASM_DATA_DIR)/xlogfile + ( cd ..; $(MAKE) dlb ) + ( cd ..; $(MAKE) dofiles-dlb ) + cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf +# +.PHONY: wasmpkg +wasmpkg: + @echo "$(WASM_TARGET) done." +$(TARGETPFX)unixmain.o : ../sys/unix/unixmain.c $(HACK_H) +$(TARGETPFX)unixres.o : ../sys/unix/unixres.c $(HACK_H) +$(TARGETPFX)unixunix.o : ../sys/unix/unixunix.c $(HACK_H) +$(TARGETPFX)ioctl.o : ../sys/share/ioctl.c $(HACK_H) +$(TARGETPFX)unixtty.o : ../sys/share/unixtty.c $(HACK_H) +$(TARGETPFX)winshim.o : ../win/shim/winshim.c $(HACK_H) +endif # CROSS_TO_WASM +# + ifdef CROSS_SHARED # shared file dependencies $(TARGETPFX)pcmain.o : ../sys/share/pcmain.c $(HACK_H) @@ -141,12 +169,9 @@ $(LUACROSSLIB): $(LUALIBOBJS) $(TARGET_AR) rcS $@ $(LUAOBJFILES2) $(TARGET_AR) rcS $@ $(LUAOBJFILES3) $(TARGET_AR) rcs $@ $(LUAOBJFILES4) -ifdef WANT_WIN_CURSES -$(TARGETPFX)pdclib.a : $(PDCLIBOBJS) $(PDCOBJS) - if [ -f $@ ]; then rm $@; fi; - $(TARGET_AR) rcs $@ $(PDCLIBOBJS) $(PDCOBJS) -endif -# + +# $(TARGET_AR) rcs $@ $(LUALIBOBJS) + # Lua src $(TARGETPFX)lapi.o : $(LUATOP)/src/lapi.c $(TARGETPFX)lauxlib.o : $(LUATOP)/src/lauxlib.c @@ -184,6 +209,11 @@ $(TARGETPFX)lzio.o : $(LUATOP)/src/lzio.c endif # BUILD_LUA ifdef BUILD_PDCURSES +ifdef WANT_WIN_CURSES +$(TARGETPFX)pdclib.a : $(PDCLIBOBJS) $(PDCOBJS) + if [ -f $@ ]; then rm $@; fi; + $(TARGET_AR) rcs $@ $(PDCLIBOBJS) $(PDCOBJS) +endif # PDCurses src $(TARGETPFX)addch.o : $(PDCTOP)/pdcurses/addch.c $(TARGETPFX)addchstr.o : $(PDCTOP)/pdcurses/addchstr.c diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 174ad81e2..8118c0610 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -24,6 +24,14 @@ override TARGETPFX = $(TARGETDIR)/ override TARGET_LIBS= endif +ifdef CROSS_TO_WASM +BUILD_LUA=1 +override TARGET = wasm +override TARGETDIR=../targets/$(TARGET) +override TARGETPFX = $(TARGETDIR)/ +override TARGET_LIBS= +endif + ifdef BUILD_LUA #===============-================================================= # LUA library @@ -51,7 +59,7 @@ LUAOBJFILES4 = $(TARGETPFX)lstring.o $(TARGETPFX)lstrlib.o \ $(TARGETPFX)ltm.o $(TARGETPFX)lundump.o \ $(TARGETPFX)lutf8lib.o $(TARGETPFX)lvm.o $(TARGETPFX)lzio.o LUALIBOBJS = $(LUAOBJFILES1) $(LUAOBJFILES2) $(LUAOBJFILES3) $(LUAOBJFILES4) -LUACROSSLIB = $(TARGETPFX)$(O)lua$(subst .,,$(LUA_VERSION)).a +LUACROSSLIB = $(TARGETPFX)lua$(subst .,,$(LUA_VERSION)).a LUAINCL = -I$(LUASRCDIR) BUILDMORE += $(LUACROSSLIB) override TARGET_LIBS += $(LUACROSSLIB) -lm @@ -255,8 +263,8 @@ override WINLIB= override LUALIB= override GAMEBIN = $(TARGETPFX)nethack override PACKAGE= amigapkg -PREGAME = mkdir -p ../targets/amiga -CLEANMORE += rm -r ../targets/amiga +PREGAME = mkdir -p $(TARGETDIR) +CLEANMORE += rm -r $(TARGETDIR) # ../util/txt2iff # ifdef WANT_WIN_CURSES @@ -269,20 +277,98 @@ $(TARGETPFX)%.o : ../outdated/sys/amiga/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< endif # CROSS_TO_AMIGA #================================================================= -ifdef CROSS_SHARED -ifdef WANT_WIN_CURSES -# rules for pdcurses dos-specific files -$(TARGETPFX)%.o : $(PDCTOP)/sdl1/%.c - $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< -endif # WANT_WIN_CURSES -# Rule for LUA files -$(TARGETPFX)%.o : $(LUATOP)/src/%.c - $(TARGET_CC) $(TARGET_CFLAGS) $(LUA_FLAGS) -o$@ $< + +ifdef CROSS_TO_WASM +#===============-================================================= +# WASM +# originally from https://github.com/NetHack/NetHack/pull/385 +#===============-================================================= +# +WASM_DATA_DIR = $(TARGETPFX)wasm-data/ +WASM_TARGET = $(TARGETPFX)nethack.js +EMCC_LFLAGS = -s SINGLE_FILE=1 +EMCC_LFLAGS += -s WASM=1 +EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH +EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' +EMCC_LFLAGS += -O3 +EMCC_LFLAGS += -s MODULARIZE +EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' +EMCC_LFLAGS += -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", \ + "removeFunction", "UTF8ToString", "getValue", "setValue"]' +EMCC_LFLAGS += -s ERROR_ON_UNDEFINED_SYMBOLS=0 +EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR) +# For a list of EMCC settings: +# https://github.com/emscripten-core/emscripten/blob/master/src/settings.js +# +# WASM C flags +EMCC_CFLAGS= +EMCC_CFLAGS += -Wall +EMCC_CFLAGS += -Werror +#EMCC_CFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 +EMCC_DEBUG_CFLAGS += -s ASSERTIONS=1 +#EMCC_DEBUG_CFLAGS += -s ASSERTIONS=2 +EMCC_DEBUG_CFLAGS += -s STACK_OVERFLOW_CHECK=2 +EMCC_DEBUG_CFLAGS += -s SAFE_HEAP=1 +EMCC_DEBUG_CFLAGS += -s LLD_REPORT_UNDEFINED=1 +#EMCC_DEBUG_CFLAGS += -s EXCEPTION_DEBUG=1 +#EMCC_DEBUG_CFLAGS += -fsanitize=undefined -fsanitize=address -fsanitize=leak +#EMCC_DEBUG_CFLAGS += -s EXIT_RUNTIME +EMCC_PROD_CFLAGS += -O3 +ifdef WASM_DEBUG +EMCC_CFLAGS += $(EMCC_DEBUG_CFLAGS) +else +EMCC_CFLAGS += $(EMCC_PROD_CFLAGS) +endif +# +# Override the build tools and some obj files to +# reflect emscripten +override TARGET_CC = emcc +override TARGET_CXX = emcc +override TARGET_AR = emar +override TARGET_CFLAGS = $(EMCC_CFLAGS) -c \ + -I../include \ + $(LUAINCL) -DDLB $(PDCURSESDEF) \ + -DNOTTYGRAPHICS -DSHIM_GRAPHICS -DDEFAULT_WINDOW_SYS=\"shim\" \ + -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_WASM -DLIBNH +override TARGET_CXXFLAGS = $(TARGET_CFLAGS) +override TARGET_LINK = $(TARGET_CC) +override TARGET_LFLAGS= $(EMCC_LFLAGS) +override SYSSRC = ../sys/unix/unixmain.c \ + ../sys/share/ioctl.c ../sys/share/unixtty.c \ + ../sys/unix/unixunix.c ../sys/unix/unixres.c \ + ../win/shim/winshim.c +override SYSOBJ= $(TARGETPFX)unixmain.o \ + $(TARGETPFX)ioctl.o $(TARGETPFX)unixtty.o \ + $(TARGETPFX)unixunix.o $(TARGETPFX)unixres.o \ + $(TARGETPFX)winshim.o +override WINLIB = emranlib +override LUALIB= +override PACKAGE= wasmpkg +override REGEXOBJ = $(TARGETPFX)posixregex.o +RANLIB=$(EMRANLIB) +#VARDATND += nhtiles.bmp +override GAME= +MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) $(WASM_TARGET) ) +PREGAME = mkdir -p $(TARGETDIR) +CLEANMORE += rm -f -r $(TARGETDIR) +# Rule for file in sys/unix +$(TARGETPFX)%.o : ../sys/unix/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< +# Rule for files in win/shim +$(TARGETPFX)%.o : ../win/shim/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< +endif # CROSS_TO_WASM +#================================================================= + ifdef WANT_WIN_CURSES +ifdef BUILD_PDCURSES # Rules for PDCurses files $(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< +endif # BUILD_PDCURSES endif # WANT_WIN_CURSES + +ifdef CROSS_SHARED # Rules for win/share files $(TARGETPFX)%.o : ../win/share/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< @@ -290,6 +376,12 @@ $(TARGETPFX)%.o : ../win/share/%.c $(TARGETPFX)%.o : ../util/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< endif # CROSS_SHARED + +ifdef BUILD_LUA +# Rule for LUA files +$(TARGETPFX)%.o : $(LUATOP)/src/%.c + $(TARGET_CC) $(TARGET_CFLAGS) $(LUA_FLAGS) -o$@ $< +endif # BUILD_LUA # # End of cross-compiling -PRE section #===============-================================================= diff --git a/sys/unix/hints/include/multiw-2.2020 b/sys/unix/hints/include/multiw-2.2020 index b96266ed8..7c956acb5 100644 --- a/sys/unix/hints/include/multiw-2.2020 +++ b/sys/unix/hints/include/multiw-2.2020 @@ -47,6 +47,10 @@ endif endif endif +ifdef WANT_LIBNH +WANT_DEFAULT=shim +endif + # Make sure that a default interface is specified; this doesn't guarantee # sanity for something like 'make WANT_WIN_CURSES=1 WANT_DEFAULT=X11' but # 'makedefs -v' would notice, complain, and quit causing 'make' to quit. diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index ff2d0917d..751eae43d 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -164,6 +164,16 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) +ifdef WANT_LIBNH +CFLAGS += -DSHIM_GRAPHICS -DNOTTYGRAPHICS -DNOSHELL -DLIBNH +WINOBJ = winshim.o +MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) +libnethack.a: $(HOBJ) $(SYSOBJ) $(WINOBJ) ../lib/lua/liblua.a + $(AR) rcs $@ $(HOBJ) $(WINOBJ) ../lib/lua/liblua.a + @echo "$@ built." +winshim.o : ../win/shim/winshim.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< +endif # BUILD_LIBNH #PREFIX=/usr PREFIX=$(wildcard ~)/nh/install diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index aeac9d41b..fbd7724f2 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -62,6 +62,7 @@ endif CFLAGS=$(CCFLAGS) -I../include -DNOTPARMDECL ifndef WANT_WIN_QT +ifndef WANT_LIBNH # these are normally used when compiling nethack's core CFLAGS+=-ansi -pedantic -Wno-long-long # but -ansi forces -std=c90 for C or -std=c++98 for C++; @@ -70,6 +71,8 @@ CFLAGS+=-ansi -pedantic -Wno-long-long #.../qt5/include/QtCore/qcompilerdetection.h:561:6: # error Qt requires a C++11 compiler and yours does not seem to be that. # so we suppress -ansi when the build includes Qt +#LIBNH's winshim requires C99 for the way it is currently coded +endif endif # As of LLVM build 2336.1.00, this gives dozens of spurious messages, so # leave it out by default. @@ -168,6 +171,16 @@ WINOBJ = $(sort $(WINOBJ0)) # prevent duplicates in VARDATND if both X11 and Qt are being supported VARDATND += $(sort $(VARDATND0)) +ifdef WANT_LIBNH +CFLAGS += -DSHIM_GRAPHICS -DNOTTYGRAPHICS -DNOSHELL -DLIBNH +WINOBJ = winshim.o +MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) +libnethack.a: $(HOBJ) $(SYSOBJ) $(WINOBJ) ../lib/lua/liblua.a + $(AR) rcs $@ $(HOBJ) $(WINOBJ) ../lib/lua/liblua.a + @echo "$@ built." +winshim.o : ../win/shim/winshim.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< +endif # BUILD_LIBNH WANT_BUNDLE=1 ifdef WANT_SHARE_INSTALL diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 87e255064..6c1f67b56 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -45,7 +45,17 @@ static void NDECL(wd_message); static boolean wiz_error_flag = FALSE; static struct passwd *NDECL(get_unix_pw); -int +#if defined(CROSSCOMPILE_TARGET) && defined(CROSS_TO_WASM) +/* for cross-compiling to WebAssembly (WASM) */ +#include +/* if WebAssembly, export this API and don't optimize it out */ +#define KEEP EMSCRIPTEN_KEEPALIVE +#else +#define KEEP +#endif + + +int KEEP main(argc, argv) int argc; char *argv[]; diff --git a/util/makedefs.c b/util/makedefs.c index 0d4b61cfd..24c45d676 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1267,10 +1267,18 @@ do_date() #endif Fprintf(ofp, "#define VERSION_SANITY1 0x%08lx%s\n", version.entity_count, ul_sfx); +#ifndef __EMSCRIPTEN__ Fprintf(ofp, "#define VERSION_SANITY2 0x%08lx%s\n", version.struct_sizes1, ul_sfx); Fprintf(ofp, "#define VERSION_SANITY3 0x%08lx%s\n", version.struct_sizes2, ul_sfx); +#else /* __EMSCRIPTEN__ */ + Fprintf(ofp, "#define VERSION_SANITY2 0x%08llx%s\n", version.struct_sizes1, + ul_sfx); + Fprintf(ofp, "#define VERSION_SANITY3 0x%08llx%s\n", version.struct_sizes2, + ul_sfx); +#endif /* !__EMSCRIPTEN__ */ + Fprintf(ofp, "\n"); Fprintf(ofp, "#define VERSION_STRING \"%s\"\n", version_string(buf, ".")); Fprintf(ofp, "#define VERSION_ID \\\n \"%s\"\n", diff --git a/win/shim/winshim.c b/win/shim/winshim.c index d82d21334..eec616f4f 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -5,14 +5,98 @@ /* not an actual windowing port, but a fake win port for libnethack */ #include "hack.h" +#include #ifdef SHIM_GRAPHICS +#include +/* for cross-compiling to WebAssembly (WASM) */ +#ifdef __EMSCRIPTEN__ +#include +#endif + +#undef SHIM_DEBUG + +#ifdef SHIM_DEBUG +#define debugf printf +#else /* !SHIM_DEBUG */ +#define debugf(...) +#endif /* SHIM_DEBUG */ + + +/* shim_graphics_callback is the primary interface to shim graphics, + * call this function with your declared callback function + * and you will receive all the windowing calls + */ +#ifdef __EMSCRIPTEN__ +/************ + * WASM interface + ************/ +EMSCRIPTEN_KEEPALIVE +static char *shim_callback_name = NULL; +void shim_graphics_set_callback(char *cbName) { + if (shim_callback_name != NULL) free(shim_callback_name); + shim_callback_name = strdup(cbName); + /* TODO: free(shim_callback_name) during shutdown? */ +} +void local_callback (const char *cb_name, const char *shim_name, void *ret_ptr, const char *fmt_str, void *args); + +/* A2P = Argument to Pointer */ +#define A2P & +/* P2V = Pointer to Void */ +#define P2V (void *) +#define DECLCB(ret_type, name, fn_args, fmt, ...) \ +ret_type name fn_args { \ + void *args[] = { __VA_ARGS__ }; \ + ret_type ret = (ret_type) 0; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_callback_name) return ret; \ + local_callback(shim_callback_name, #name, (void *)&ret, fmt, args); \ + return ret; \ +} + +#define VDECLCB(name, fn_args, fmt, ...) \ +void name fn_args { \ + void *args[] = { __VA_ARGS__ }; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_callback_name) return; \ + local_callback(shim_callback_name, #name, NULL, fmt, args); \ +} + +#else /* !__EMSCRIPTEN__ */ + +/************ + * libnethack.a interface + ************/ +typedef void(*shim_callback_t)(const char *name, void *ret_ptr, const char *fmt, ...); +static shim_callback_t shim_graphics_callback = NULL; +void shim_graphics_set_callback(shim_callback_t cb) { + shim_graphics_callback = cb; +} + +#define A2P +#define P2V +#define DECLCB(ret_type, name, fn_args, fmt, ...) \ +ret_type name fn_args { \ + ret_type ret = (ret_type) 0; \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return ret; \ + shim_graphics_callback(#name, (void *)&ret, fmt, ## __VA_ARGS__); \ + return ret; \ +} + +#define VDECLCB(name, fn_args, fmt, ...) \ +void name fn_args { \ + debugf("SHIM GRAPHICS: " #name "\n"); \ + if (!shim_graphics_callback) return; \ + shim_graphics_callback(#name, NULL, fmt, ## __VA_ARGS__); \ +} +#endif /* __EMSCRIPTEN__ */ enum win_types { - WINSTUB_MESSAGE = 1, - WINSTUB_MAP, - WINSTUB_MENU, - WINSTUB_EXT + WINSHIM_MESSAGE = 1, + WINSHIM_MAP, + WINSHIM_MENU, + WINSHIM_EXT }; #define VSTUB(name, args) \ @@ -29,60 +113,67 @@ name args { \ #define DECL(name, args) \ void name args; -VSTUB(shim_init_nhwindows,(int *argcp, char **argv)) -VSTUB(shim_player_selection,(void)) -VSTUB(shim_askname,(void)) -VSTUB(shim_get_nh_event,(void)) -VSTUB(shim_exit_nhwindows,(const char *a)) -VSTUB(shim_suspend_nhwindows,(const char *a)) -VSTUB(shim_resume_nhwindows,(void)) -winid STUB(shim_create_nhwindow, WINSTUB_MAP, (int a)) -VSTUB(shim_clear_nhwindow,(winid a)) -VSTUB(shim_display_nhwindow,(winid a, BOOLEAN_P b)) -VSTUB(shim_destroy_nhwindow,(winid a)) -VSTUB(shim_curs,(winid a, int x, int y)) -DECL(shim_putstr,(winid w, int attr, const char *str)) -VSTUB(shim_display_file,(const char *a, BOOLEAN_P b)) -VSTUB(shim_start_menu,(winid w, unsigned long mbehavior)) -VSTUB(shim_add_menu,(winid a, int b, const ANY_P *c, CHAR_P d, CHAR_P e, int f, const char *h, unsigned int k)) -VSTUB(shim_end_menu,(winid a, const char *b)) -int STUB(shim_select_menu,0,(winid a, int b, MENU_ITEM_P **c)) -char STUB(shim_message_menu,'y',(CHAR_P a, int b, const char *c)) -VSTUB(shim_update_inventory,(void)) -VSTUB(shim_mark_synch,(void)) -VSTUB(shim_wait_synch,(void)) -VSTUB(shim_cliparound,(int a, int b)) -VSTUB(shim_update_positionbar,(char *a)) -DECL(shim_print_glyph,(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph)) -DECL(shim_raw_print,(const char *str)) -VSTUB(shim_raw_print_bold,(const char *a)) -int STUB(shim_nhgetch,0,(void)) -int STUB(shim_nh_poskey,0,(int *a, int *b, int *c)) -VSTUB(shim_nhbell,(void)) -int STUB(shim_doprev_message,0,(void)) -char STUB(shim_yn_function,'y',(const char *a, const char *b, CHAR_P c)) -VSTUB(shim_getlin,(const char *a, char *b)) -int STUB(shim_get_ext_cmd,0,(void)) -VSTUB(shim_number_pad,(int a)) -VSTUB(shim_delay_output,(void)) -VSTUB(shim_change_color,(int a, long b, int c)) -VSTUB(shim_change_background,(int a)) -short STUB(set_shim_font_name,0,(winid a, char *b)) -VSTUB(shim_get_color_string,(void)) +VDECLCB(shim_init_nhwindows,(int *argcp, char **argv), "vpp", P2V argcp, P2V argv) +VDECLCB(shim_player_selection,(void), "v") +VDECLCB(shim_askname,(void), "v") +VDECLCB(shim_get_nh_event,(void), "v") +VDECLCB(shim_exit_nhwindows,(const char *str), "vs", P2V str) +VDECLCB(shim_suspend_nhwindows,(const char *str), "vs", P2V str) +VDECLCB(shim_resume_nhwindows,(void), "v") +DECLCB(winid, shim_create_nhwindow, (int type), "ii", A2P type) +VDECLCB(shim_clear_nhwindow,(winid window), "vi", A2P window) +VDECLCB(shim_display_nhwindow,(winid window, BOOLEAN_P blocking), "vii", A2P window, A2P blocking) +VDECLCB(shim_destroy_nhwindow,(winid window), "vi", A2P window) +VDECLCB(shim_curs,(winid a, int x, int y), "viii", A2P a, A2P x, A2P y) +VDECLCB(shim_putstr,(winid w, int attr, const char *str), "viis", A2P w, A2P attr, P2V str) +VDECLCB(shim_display_file,(const char *name, BOOLEAN_P complain), "vsi", P2V name, A2P complain) +VDECLCB(shim_start_menu,(winid window, unsigned long mbehavior), "vii", A2P window, A2P mbehavior) +VDECLCB(shim_add_menu, + (winid window, int glyph, const ANY_P *identifier, CHAR_P ch, CHAR_P gch, int attr, const char *str, unsigned int itemflags), + "viipiiisi", + A2P window, A2P glyph, P2V identifier, A2P ch, A2P gch, A2P attr, P2V str, A2P itemflags) +VDECLCB(shim_end_menu,(winid window, const char *prompt), "vis", A2P window, P2V prompt) +DECLCB(int, shim_select_menu,(winid window, int how, MENU_ITEM_P **menu_list), "iiip", A2P window, A2P how, P2V menu_list) +DECLCB(char, shim_message_menu,(CHAR_P let, int how, const char *mesg), "ciis", A2P let, A2P how, P2V mesg) +VDECLCB(shim_update_inventory,(void), "v") +VDECLCB(shim_mark_synch,(void), "v") +VDECLCB(shim_wait_synch,(void), "v") +VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) +VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) +VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) +VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) +VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) +DECLCB(int, shim_nhgetch,(void), "i") +DECLCB(int, shim_nh_poskey,(int *x, int *y, int *mod), "ippp", P2V x, P2V y, P2V mod) +VDECLCB(shim_nhbell,(void), "v") +DECLCB(int, shim_doprev_message,(void),"iv") +DECLCB(char, shim_yn_function,(const char *query, const char *resp, CHAR_P def), "cssi", P2V query, P2V resp, A2P def) +VDECLCB(shim_getlin,(const char *query, char *bufp), "vsp", P2V query, P2V bufp) +DECLCB(int,shim_get_ext_cmd,(void),"iv") +VDECLCB(shim_number_pad,(int state), "vi", A2P state) +VDECLCB(shim_delay_output,(void), "v") +VDECLCB(shim_change_color,(int color, long rgb, int reverse), "viii", A2P color, A2P rgb, A2P reverse) +VDECLCB(shim_change_background,(int white_or_black), "vi", A2P white_or_black) +DECLCB(short, set_shim_font_name,(winid window_type, char *font_name),"2is", A2P window_type, P2V font_name) +DECLCB(char *,shim_get_color_string,(void),"sv") /* other defs that really should go away (they're tty specific) */ -VSTUB(shim_start_screen, (void)) -VSTUB(shim_end_screen, (void)) -VSTUB(shim_preference_update, (const char *a)) -char *STUB(shim_getmsghistory, (char *)"", (BOOLEAN_P a)) -VSTUB(shim_putmsghistory, (const char *a, BOOLEAN_P b)) -VSTUB(shim_status_init, (void)) -VSTUB(shim_status_enablefield, (int a, const char *b, const char *c, BOOLEAN_P d)) -VSTUB(shim_status_update, (int a, genericptr_t b, int c, int d, int e, unsigned long *f)) +VDECLCB(shim_start_screen, (void), "v") +VDECLCB(shim_end_screen, (void), "v") +VDECLCB(shim_preference_update, (const char *pref), "vp", P2V pref) +DECLCB(char *,shim_getmsghistory, (BOOLEAN_P init), "si", A2P init) +VDECLCB(shim_putmsghistory, (const char *msg, BOOLEAN_P restoring_msghist), "vsi", P2V msg, A2P restoring_msghist) +VDECLCB(shim_status_init, (void), "v") +VDECLCB(shim_status_enablefield, + (int fieldidx, const char *nm, const char *fmt, BOOLEAN_P enable), + "vippi", + A2P fieldidx, P2V nm, P2V fmt, A2P enable) +VDECLCB(shim_status_update, + (int fldidx, genericptr_t ptr, int chg, int percent, int color, unsigned long *colormasks), + "vipiiip", + A2P fldidx, P2V ptr, A2P chg, A2P percent, A2P color, P2V colormasks) - -/* old: | WC_TILED_MAP */ -/* Interface definition, for windows.c */ +/* Interface definition used in windows.c */ struct window_procs shim_procs = { "shim", (0 @@ -140,22 +231,122 @@ struct window_procs shim_procs = { genl_can_suspend_yes, }; -void shim_print_glyph(winid w, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) { - /* map glyph to character and color */ - // (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); +#ifdef __EMSCRIPTEN__ +/* convert the C callback to a JavaScript callback */ +EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *ret_ptr, const char *fmt_str, void *args), { + Asyncify.handleAsync(async () => { + // convert callback arguments to proper JavaScript varaidic arguments + let name = Module.UTF8ToString(shim_name); + let fmt = Module.UTF8ToString(fmt_str); + let cbName = Module.UTF8ToString(cb_name); + // console.log("local_callback:", cbName, fmt, name); - fprintf(stdout, "shim_print_glyph (%d,%d): %c\n", x,y,(char)glyph); - fflush(stdout); -} + let argTypes = fmt.split(""); + let retType = argTypes.shift(); -void shim_raw_print(const char *str) { - fprintf(stdout, "shim_raw_print: %s\n", str); - fflush(stdout); -} + // build array of JavaScript args from WASM parameters + let jsArgs = []; + for (let i = 0; i < argTypes.length; i++) { + let ptr = args + (4*i); + let val = typeLookup(argTypes[i], ptr); + jsArgs.push(val); + } -void shim_putstr(winid w, int attr, const char *str) { - fprintf(stdout, "shim_putstr (win %d): %s\n", w, str); - fflush(stdout); -} + // do the callback + let userCallback = globalThis[cbName]; + let retVal = await runJsLoop(() => userCallback(name, ... jsArgs)); + + // save the return value + setReturn(name, ret_ptr, retType, retVal); + + // convert 'ptr' to the type indicated by 'type' + function typeLookup(type, ptr) { + switch(type) { + case "s": // string + return Module.UTF8ToString(Module.getValue(ptr, "*")); + case "p": // pointer + ptr = Module.getValue(ptr, "*"); + if(!ptr) return 0; // null pointer + return Module.getValue(ptr, "*"); + case "c": // char + return String.fromCharCode(Module.getValue(Module.getValue(ptr, "*"), "i8")); + case "0": /* 2^0 = 1 byte */ + return Module.getValue(Module.getValue(ptr, "*"), "i8"); + case "1": /* 2^1 = 2 bytes */ + return Module.getValue(Module.getValue(ptr, "*"), "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return Module.getValue(Module.getValue(ptr, "*"), "i32"); + case "f": // float + return Module.getValue(Module.getValue(ptr, "*"), "float"); + case "d": // double + return Module.getValue(Module.getValue(ptr, "*"), "double"); + default: + throw new TypeError ("unknown type:" + type); + } + } + + // setTimeout() with value of '0' is similar to setImmediate() (which isn't standard) + // this lets the JS loop run for a tick so that other events can occur + // XXX: I also tried replacing the for(;;) in allmain.c:moveloop() with emscripten_set_main_loop() + // unfortunately that won't work -- if the simulate_infinite_loop arg is false, it falls through; + // if is true, it throws an exception to break out of main(), but doesn't get caught because + // the stack isn't running under main() anymore... + // I think this is suboptimal, but we will have to live with it + async function runJsLoop(cb) { + return new Promise((resolve) => { + setTimeout(() => { + resolve(cb()); + }, 0); + }); + } + + // sets the return value of the function to the type expected + function setReturn(name, ptr, type, value = 0) { + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + if(typeof value !== "string") + throw new TypeError(`expected ${name} return type to be string`); + value=value?value:"(no value)"; + var strPtr = Module.getValue(ptr, "i32"); + Module.stringToUTF8(value, strPtr, 1024); + break; + case "i": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + Module.setValue(ptr, value, "i32"); + break; + case "c": + if(typeof value !== "number" || value < 0 || value > 128) + throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); + Module.setValue(ptr, value, "i8"); + break; + case "f": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + // XXX: I'm not sure why 'double' works and 'float' doesn't + Module.setValue(ptr, value, "double"); + break; + case "d": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + Module.setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } + + function isFloat(n){ + return n === +n && n !== (n|0) && !Number.isInteger(n); + } + } + }); +}) +#endif /* __EMSCRIPTEN__ */ #endif /* SHIM_GRAPHICS */ \ No newline at end of file From b41b8975650627ceceaa8351fb9436974b3461f3 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 14:51:10 -0400 Subject: [PATCH 267/708] remove two unneeded files --- sys/lib/hints/macOS.2020 | 360 --------------------------------------- sys/lib/hints/wasm | 77 --------- 2 files changed, 437 deletions(-) delete mode 100755 sys/lib/hints/macOS.2020 delete mode 100644 sys/lib/hints/wasm diff --git a/sys/lib/hints/macOS.2020 b/sys/lib/hints/macOS.2020 deleted file mode 100755 index 3edd3b768..000000000 --- a/sys/lib/hints/macOS.2020 +++ /dev/null @@ -1,360 +0,0 @@ -# NetHack 3.7 macOS.2020 $NHDT-Date: 1597704793 2020/08/17 22:53:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.69 $ -# Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. -# NetHack may be freely redistributed. See license for details. -# -#--------------------------------------------------------------------- -# MacOS hints file with support for multiple window ports (interfaces) -# Tested on: -# - MacOS Catalina 10.15 -# -# If this doesn't work for some other version of Mac OS X, 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 - -#-PRE xxxx -# macOS X hints file -# - -# 5. Other - -#----------------------------------------------------------------------------- -# You shouldn't need to change anything below here (in the hints file; if -# you're reading this in Makefile augmented by hints, that may not be true). -# - -AR=ar rcu -RANLIB=ranlib - -# XXX -g vs -O should go here, -I../include goes in the makefile -CFLAGS+=-g -I../include -DNOTPARMDECL -CFLAGS+=-Wno-missing-field-initializers -Wimplicit -Wreturn-type -Wformat -Wswitch -Wshadow -Wwrite-strings -CFLAGS+=-DGCC_WARN - -# NetHack sources control -CFLAGS+=-DDLB -CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" -CFLAGS+=-DDLB -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE -#CFLAGS+=-DTIMED_DELAY -#CFLAGS+=-DDUMPLOG -#CFLAGS+=-DCONFIG_ERROR_SECURE=FALSE -CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" -#CFLAGS+=-DCOMPRESS=\"/bin/gzip\" -DCOMPRESS_EXTENSION=\".gz\" -# older binaries use NOCLIPPING, but that disables SIGWINCH -#CFLAGS+=-DNOCLIPPING -CFLAGS+=-DNOMAIL -#CFLAGS+=-DEXTRA_SANITY_CHECKS -#CFLAGS+=-DEDIT_GETLIN -#CFLAGS+=-DSCORE_ON_BOTL -#CFLAGS+=-DMSGHANDLER -#CFLAGS+=-DTTY_TILES_ESCCODES -#CFLAGS+=-DTTY_SOUND_ESCCODES - -CFLAGS+=-DDEFAULT_WINDOW_SYS=\"shim\" -DNOTTYGRAPHICS -DLIBNH - -CFLAGS+= $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 - -VARDATND = -VARDATND0 = -CURSESLIB = - -ifdef WANT_WIN_CHAIN -HINTSRC=$(CHAINSRC) -HINTOBJ=$(CHAINOBJ) -endif # WANT_WIN_CHAIN - -LINK=$(CC) - -# prevent duplicate tile.o in WINOBJ -WINOBJ = $(sort $(WINOBJ0)) -# prevent duplicates in VARDATND if both X11 and Qt are being supported -VARDATND += $(sort $(VARDATND0)) - -WANT_BUNDLE=1 -ifdef WANT_SHARE_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 -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 -PREINSTALL= . sys/unix/hints/macosx.sh user2 $(GAMEUID); \ - . sys/unix/hints/macosx.sh group2 $(GAMEGRP); \ - mkdir $(SHELLDIR); chown $(GAMEUID) $(SHELLDIR) -POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ - $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ - $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ - chmod $(VARFILEPERM) $(HACKDIR)/sysconf; - -else ifdef WANT_SOURCE_INSTALL - -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: -MOREALL=$(MAKE) install -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"$(HACKDIR)/sysconf\" -DSECURE - -else # !WANT_SOURCE_INSTALL - -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 -endif # WANT_DEFAULT X11 - -POSTINSTALL+= sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(HACKDIR)/sysconf; \ - $(CHOWN) $(GAMEUID) $(HACKDIR)/sysconf; \ - $(CHGRP) $(GAMEGRP) $(HACKDIR)/sysconf; \ - chmod $(VARFILEPERM) $(HACKDIR)/sysconf; -ifdef WANT_BUNDLE -# -# Bundle -# -# $(HACKDIR)/$(GAME).app/ -# Contents/ -# Frameworks/ -# Info.plist -# MacOS/ -# $(GAME) -# PkgInfo/ -# PlugIns/ -# Resources/ -# SharedFrameWorks/ -# -BUNDLE = mkdir -p $(HACKDIR)/nethack.app/Contents/MacOS; \ - sys/unix/hints/macosx.sh infoplist > $(HACKDIR)/nethack.app/Contents/Info.plist; \ - mv $(HACKDIR)/nethack $(HACKDIR)/nethack.app/Contents/MacOS/nethack; -ifdef WANT_SHARE_INSTALL -BUNDLE+= chmod $(GAMEPERM) $(HACKDIR)/nethack.app/Contents/MacOS/nethack; -endif - -POSTINSTALL+= $(BUNDLE) -POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ - sed -i '' 's;HACKDIR/$(GAME);HACKDIR/$(GAME).app/Contents/MacOS/$(GAME);' $(SHELLDIR)/$(GAME) ; fi; -endif # WANT_BUNDLE -endif # !WANT_SHARE_INSTALL - -INSTDIR=$(HACKDIR) -VARDIR=$(HACKDIR) - -# ~/Library/Preferences/NetHack Defaults -# OPTIONS=name:player,number_pad,menustyle:partial,!time,showexp -# OPTIONS=hilite_pet,toptenwin,msghistory:200,windowtype:Qt -# -# Install.Qt mentions a patch for macos - it's not there (it seems to be in the Qt binary -# package under the docs directory). - -#-POST -ifdef MAKEFILE_TOP -### -### Packaging -### -# Notes: -# 1) The Apple developer utilities must be installed in the default location. -# 2) Do a normal build before trying to package the game. -# 3) This matches the 3.4.3 Term package, but there are some things that -# should be changed. -# -# Packages that are being distributed must be signed by a Developer ID -# Installer certificate. Set DEVELOPER_CERT to the name of the certificate -# if you wish for your package to be signed for distribution. -# -# If building a package for signing, you must use sudo approriately. -# the binaries and package using sudo but you DO NOT use sudo to sign the -# package. If you use sudo to sign the package, it will fail. -# -# sudo make all -# sudo make build_tty_pkg -# make sign_tty_pkg -# - -ifdef WANT_WIN_TTY -DEVUTIL=/Developer/Applications/Utilities -SVS=$(shell $(NHSROOT)/util/makedefs --svs) -SVSDOT=$(shell $(NHSROOT)/util/makedefs --svs .) - -PKGROOT_UG = PKGROOT/$(PREFIX) -PKGROOT_UGLN = PKGROOT/$(HACKDIR) -PKGROOT_BIN = PKGROOT/$(SHELLDIR) - -#DEVELOPER_CERT = Developer ID Installer: Bart House -DEVELOPER_CERT = NONE - -spotless:: - rm -rf RESOURCES - rm -rf PKG - rm -rf PKGSCRIPTS - rm -rf PKGROOT - rm -f Info.plist - rm -f Distribution.xml - rm -f NetHack-*-mac-Term* - -build_tty_pkg: -ifneq (,$(WANT_WIN_X11)$(WANT_WIN_QT)) - -echo build_tty_pkg only works for a tty-only build - exit 1 -else - rm -rf NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg - $(MAKE) build_package_root - rm -rf RESOURCES - mkdir RESOURCES - #enscript --language=rtf -o - < dat/license >RESOURCES/License.rtf - sys/unix/hints/macosx.sh descplist > RESOURCES/Description.plist - sys/unix/hints/macosx.sh infoplist > Info.plist - - mkdir PKGROOT/Applications - #osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ - # win/macosx/NetHackRecover.applescript - #cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir - osacompile -o PKGROOT/Applications/NetHackRecover.app \ - win/macosx/NetHackRecover.applescript - cp win/macosx/recover.pl $(PKGROOT_UGLN) - - osacompile -o PKGROOT/Applications/NetHackTerm.app \ - win/macosx/NetHackTerm.applescript - - # XXX integrate into Makefile.doc - (cd doc; cat Guidebook.mn | ../util/makedefs --grep --input - --output - \ - | tbl tmac.n - | groff | pstopdf -i -o Guidebook.pdf) - cp doc/Guidebook.pdf $(PKGROOT_UG)/doc/NetHackGuidebook.pdf - - osacompile -o PKGROOT/Applications/NetHackGuidebook.app \ - win/macosx/NetHackGuidebook.applescript - - mkdir -p PKG - pkgbuild --root PKGROOT --identifier org.nethack.term --scripts PKGSCRIPTS PKG/NH-Term.pkg - productbuild --synthesize --product Info.plist --package PKG/NH-Term.pkg Distribution.xml - productbuild --distribution Distribution.xml --resources RESOURCES --package-path PKG NetHack-$(SVS)-mac-Term-unsigned.pkg -ifeq ($(DEVELOPER_CERT),NONE) - cp NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg - hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term-unsigned.dmg - @echo ------------------------------------------- - @echo PACKAGE IS NOT SIGNED FOR DISTRIBUTION!!!!! - @echo =========================================== -else - @echo "run 'make sign_tty_pkg' to complete package" -endif - -sign_tty_pkg: - productsign --timestamp=none --sign "$(DEVELOPER_CERT)" NetHack-$(SVS)-mac-Term-unsigned.pkg NetHack-$(SVS)-mac-Term.pkg || (echo "Package signing failed"; exit 1) - spctl -a -v --type install NetHack-$(SVS)-mac-Term.pkg || (echo "Package not signed properly"; exit 1) - hdiutil create -verbose -srcfolder NetHack-$(SVS)-mac-Term.pkg NetHack-$(SVS)-mac-Term.dmg - -build_package_root: - cd src/.. # make sure we are at TOP - rm -rf PKGROOT - mkdir -p $(PKGROOT_UG)/lib $(PKGROOT_BIN) $(PKGROOT_UG)/man/man6 $(PKGROOT_UG)/doc $(PKGROOT_UGLN) - install -p src/nethack $(PKGROOT_BIN) - # XXX should this be called nethackrecover? - install -p util/recover $(PKGROOT_BIN) - install -p doc/nethack.6 $(PKGROOT_UG)/man/man6 - install -p doc/recover.6 $(PKGROOT_UG)/man/man6 - install -p doc/Guidebook $(PKGROOT_UG)/doc - install -p dat/nhdat $(PKGROOT_UGLN) - sys/unix/hints/macosx.sh editsysconf sys/unix/sysconf $(PKGROOT_UGLN)/sysconf - cd dat; install -p $(DATNODLB) ../$(PKGROOT_UGLN) -# XXX these files should be somewhere else for good Mac form - touch $(PKGROOT_UGLN)/perm $(PKGROOT_UGLN)/record $(PKGROOT_UGLN)/logfile $(PKGROOT_UGLN)/xlogfile - mkdir $(PKGROOT_UGLN)/save -# XXX what about a news file? - - mkdir -p PKGSCRIPTS - echo '#!/bin/sh' > PKGSCRIPTS/postinstall - echo dseditgroup -o create -r '"Games Group"' -s 3600 $(GAMEGRP) >> PKGSCRIPTS/postinstall - echo $(CHOWN) $(GAMEUID) $(HACKDIR) >> PKGSCRIPTS/postinstall - echo $(CHOWN) $(GAMEUID) $(HACKDIR)/* >> PKGSCRIPTS/postinstall - echo $(CHGRP) $(GAMEGRP) $(HACKDIR) >> PKGSCRIPTS/postinstall - echo $(CHGRP) $(GAMEGRP) $(HACKDIR)/* >> PKGSCRIPTS/postinstall - echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall - echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall - echo $(CHOWN) $(GAMEUID) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall - echo $(CHGRP) $(GAMEGRP) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall - echo chmod $(VARDIRPERM) $(HACKDIR) >> PKGSCRIPTS/postinstall - echo chmod $(VARDIRPERM) $(HACKDIR)/save >> PKGSCRIPTS/postinstall - echo chmod $(FILEPERM) $(HACKDIR)/license >> PKGSCRIPTS/postinstall - echo chmod $(FILEPERM) $(HACKDIR)/nhdat >> PKGSCRIPTS/postinstall - echo chmod $(FILEPERM) $(HACKDIR)/symbols >> PKGSCRIPTS/postinstall - echo chmod $(VARFILEPERM) $(HACKDIR)/perm >> PKGSCRIPTS/postinstall - echo chmod $(VARFILEPERM) $(HACKDIR)/record >> PKGSCRIPTS/postinstall - echo chmod $(VARFILEPERM) $(HACKDIR)/logfile >> PKGSCRIPTS/postinstall - echo chmod $(VARFILEPERM) $(HACKDIR)/xlogfile >> PKGSCRIPTS/postinstall - echo chmod $(VARFILEPERM) $(HACKDIR)/sysconf >> PKGSCRIPTS/postinstall - echo chmod $(GAMEPERM) $(SHELLDIR)/nethack >> PKGSCRIPTS/postinstall - echo chmod $(EXEPERM) $(SHELLDIR)/recover >> PKGSCRIPTS/postinstall - chmod 0775 PKGSCRIPTS/postinstall - -endif # end of build_tty_pkg -endif # WANT_WIN_TTY for packaging - -ifdef WANT_WIN_QT -# XXX untested and incomplete (see below) -build_qt_pkg: -ifneq (,$(WANT_WIN_X11)$(WANT_WIN_TTY)) - -echo build_qt_pkg only works for a qt-only build - exit 1 -else - $(MAKE) build_package_root - rm -rf NetHackQt - mkdir -p NetHackQt/NetHackQt.app/nethackdir/save - mkdir NetHackQt/Documentation - cp doc/Guidebook.txt doc/nethack.txt doc/recover.txt NetHackQt/Documentation - - osacompile -o NetHackQt/NetHackQt.app/nethackdir/NetHackRecover.app \ - win/macosx/NetHackRecover.applescript - cp win/macosx/recover.pl NetHackQt/NetHackQt.app/nethackdir - - mkdir -p NetHackQt/NetHackQt.app/Contents/Frameworks - cp $(QTDIR)/libqt-mt.3.dylib NetHackQt/NetHackQt.app/Contents/Frameworks - - mkdir NetHackQt/NetHackQt.app/Contents/MacOS - mv PKGROOT/nethack NetHackQt/NetHackQt.app/Contents/MacOS - - mv PKGROOT/lib/nethackdir NetHackQt/NetHackQt.app/nethackdir - -# XXX still missing: -#NetHackQt/NetHackQt.app -# /Contents -# Info.plist -# Resources/nethack.icns -#NetHackQt/Documentation -#NetHackQtRecover.txt -#NetHack Defaults.txt -#changes.patch XXX is this still needed? why isn't it part of the tree? -# doesn't go here - hdiutil create -verbose -srcfolder NetHackQt NetHack-$(SVS)-macosx-qt.dmg -endif # end of build_qt_pkg -endif # WANT_WIN_QT for packaging -endif # MAKEFILE_TOP diff --git a/sys/lib/hints/wasm b/sys/lib/hints/wasm deleted file mode 100644 index 7f85090af..000000000 --- a/sys/lib/hints/wasm +++ /dev/null @@ -1,77 +0,0 @@ - -#-PRE xxxx -# enscripten WebAssembly config - -WANT_WASM=1 -WASM_DEBUG=1 -WASM_DATA_DIR=$(NHSROOT)/src/wasm-data - -# toolchain -EMCC=emcc -EMAR=emar rcu -EMRANLIB=emranlib - -# link flags -EMCC_LFLAGS=-s SINGLE_FILE=1 -EMCC_LFLAGS=-s WASM=1 -EMCC_LFLAGS+=-s ALLOW_TABLE_GROWTH -EMCC_LFLAGS+=-s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' -EMCC_LFLAGS+=-O3 -EMCC_LFLAGS+=-s MODULARIZE -EMCC_LFLAGS+=-s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' -EMCC_LFLAGS+=-s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", "removeFunction", "UTF8ToString", "getValue", "setValue"]' -EMCC_LFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=0 -EMCC_LFLAGS+=--embed-file wasm-data@/ - -# For a list of EMCC settings: -# https://github.com/emscripten-core/emscripten/blob/master/src/settings.js - -# WASM C flags -EMCC_CFLAGS= -EMCC_CFLAGS+=-Wall -EMCC_CFLAGS+=-Werror -#EMCC_CFLAGS+=-s DISABLE_EXCEPTION_CATCHING=0 -EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=1 -#EMCC_DEBUG_CFLAGS+=-s ASSERTIONS=2 -EMCC_DEBUG_CFLAGS+=-s STACK_OVERFLOW_CHECK=2 -EMCC_DEBUG_CFLAGS+=-s SAFE_HEAP=1 -EMCC_DEBUG_CFLAGS+=-s LLD_REPORT_UNDEFINED=1 -#EMCC_DEBUG_CFLAGS+=-s EXCEPTION_DEBUG=1 -#EMCC_DEBUG_CFLAGS+=-fsanitize=undefined -fsanitize=address -fsanitize=leak -#EMCC_DEBUG_CFLAGS+=-s EXIT_RUNTIME -EMCC_PROD_CFLAGS+=-O3 - -# Nethack C flags -CFLAGS+=-DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE -CFLAGS+=-g -I../include -DNOTPARMDECL -CFLAGS+=-Wall -CFLAGS+=-Werror -CFLAGS+=-DGCC_WARN - -# NetHack sources control -CFLAGS+=-DDLB -CFLAGS+=-DHACKDIR=\"$(HACKDIR)\" -CFLAGS+=-DDLB -#CFLAGS+=-DGREPPATH=\"/usr/bin/grep\" -CFLAGS+=-DNOMAIL - -ifdef WASM_DEBUG -EMCC_CFLAGS+=$(EMCC_DEBUG_CFLAGS) -else -EMCC_CFLAGS+=$(EMCC_PROD_CFLAGS) -endif - -# installation config -# hackdir is the wasm / emscripten embed data root directory -HACKDIR=/ -CHOWN=/usr/bin/true -CHGRP=/usr/bin/true -GAMEPERM = 0700 -VARFILEPERM = 0600 -VARDIRPERM = 0700 - -INSTDIR=$(HACKDIR) -VARDIR=$(HACKDIR) - -#-POST -# no post \ No newline at end of file From de0195191bae3663e5aeda19f0f3d9a22ffdb6d9 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 15:19:58 -0400 Subject: [PATCH 268/708] update original documentation for pr385 Changes to be committed: modified: sys/lib/README.md --- sys/lib/README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sys/lib/README.md b/sys/lib/README.md index 3bc7c283a..8258323b7 100644 --- a/sys/lib/README.md +++ b/sys/lib/README.md @@ -9,11 +9,26 @@ This library has only been built on MacOS, but should work on Linux and other un Building the WASM module requires that you have the [emscripten toolchain / sdk installed](https://emscripten.org/docs/getting_started/downloads.html). 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.2020` +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.2020`; for `nethack.js`: `./setup.sh hints/wasm` 3. `cd ../..` 4. `make` + +[Edit Oct 4, 2020:] +Resulting libaries will be in the `targets/wasm` directory for `CROSS_TO_WASM=1`. +Resulting libaries will be in the `src` directory for `WANT_LIBNH=1`. + +[Original text:] Resulting libaries will be in the `src` directory. WASM also has a npm module that can be published out of `sys/lib/npm-library`. After building the `nethack.js` it can be published by: @@ -92,4 +107,4 @@ function nethackStart(cb, inputModule = {}) { } nethackStart(yourCallbackFunction); -``` \ No newline at end of file +``` From 61185f3405be278828ec4f25d36493d626fb9f18 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 15:26:50 -0400 Subject: [PATCH 269/708] cron daily Files update --- Files | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Files b/Files index db689a079..8e1ed1d3a 100644 --- a/Files +++ b/Files @@ -218,6 +218,22 @@ uhitm.c vault.c version.c vision.c weapon.c were.c wield.c windows.c wizard.c worm.c worn.c write.c zap.c +sys/lib: +(files in top directory) +README.md sysconf + +sys/lib/npm-package: +(files in top directory) +LICENSE.md README.md package.json + +sys/lib/npm-package/src: +(file in top directory) +nethackShim.js + +sys/lib/test: +(files in top directory) +README.md libtest.c run.sh + sys/msdos: (files for MSDOS version) Install.dos Makefile.GCC fetch-cross-compiler.sh @@ -383,6 +399,10 @@ nhsplash.xpm objects.txt other.txt ppmwrite.c renumtiles.pl safeproc.c thintile.c tile.doc tile.h tile2bmp.c tilemap.c tileset.c tiletext.c +win/shim: +(file in top directory) +winshim.c + win/tty: (files for tty versions) getline.c termcap.c topl.c wintty.c From ac4649e63f9daa0d1d9eceac0069559d44239931 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 4 Oct 2020 14:03:04 -0700 Subject: [PATCH 270/708] add globals, constants, and helpers --- sys/lib/libnethackmain.c | 257 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 251 insertions(+), 6 deletions(-) diff --git a/sys/lib/libnethackmain.c b/sys/lib/libnethackmain.c index 83899acb9..cec8c076e 100644 --- a/sys/lib/libnethackmain.c +++ b/sys/lib/libnethackmain.c @@ -7,6 +7,7 @@ #include "hack.h" #include "dlb.h" +#include "date.h" #include #include @@ -559,6 +560,7 @@ void sethanguphandler(handler) void FDECL((*handler), (int)); { +#ifndef NO_SIGNAL #ifdef SA_RESTART /* don't want reads to restart. If SA_RESTART is defined, we know * sigaction exists and can be used to ensure reads won't restart. @@ -580,6 +582,7 @@ void FDECL((*handler), (int)); (void) signal(SIGXCPU, (SIG_RET_TYPE) handler); #endif #endif /* ?SA_RESTART */ +#endif /* !NO_SIGNAL */ } #ifdef PORT_HELP @@ -767,6 +770,8 @@ EM_JS(void, js_helpers_init, (), { installHelper(mapglyphHelper); installHelper(displayInventory); + installHelper(getPointerValue); + installHelper(setPointerValue); // used by print_glyph function mapglyphHelper(glyph, x, y, mgflags) { @@ -802,6 +807,83 @@ EM_JS(void, js_helpers_init, (), { // }); } + // convert 'ptr' to the type indicated by 'type' + function getPointerValue(name, ptr, type) { + // console.log("getPointerValue", name, "0x" + ptr.toString(16), type); + switch(type) { + case "s": // string + // var value = UTF8ToString(getValue(ptr, "*")); + return UTF8ToString(ptr); + case "p": // pointer + if(!ptr) return 0; // null pointer + return getValue(ptr, "*"); + case "c": // char + return String.fromCharCode(getValue(ptr, "i8")); + case "0": /* 2^0 = 1 byte */ + return getValue(ptr, "i8"); + case "1": /* 2^1 = 2 bytes */ + return getValue(ptr, "i16"); + case "2": /* 2^2 = 4 bytes */ + case "i": // integer + case "n": // number + return getValue(ptr, "i32"); + case "f": // float + return getValue(ptr, "float"); + case "d": // double + return getValue(ptr, "double"); + case "o": // overloaded: multiple types + return ptr; + default: + throw new TypeError ("unknown type:" + type); + } + } + + // sets the return value of the function to the type expected + function setPointerValue(name, ptr, type, value = 0) { + // console.log("setPointerValue", name, "0x" + ptr.toString(16), type, value); + switch (type) { + case "p": + throw new Error("not implemented"); + case "s": + if(typeof value !== "string") + throw new TypeError(`expected ${name} return type to be string`); + // value=value?value:"(no value)"; + // var strPtr = getValue(ptr, "i32"); + stringToUTF8(value, ptr, 1024); // TODO: uhh... danger will robinson + break; + case "i": + if(typeof value !== "number" || !Number.isInteger(value)) + throw new TypeError(`expected ${name} return type to be integer`); + setValue(ptr, value, "i32"); + break; + case "c": + if(typeof value !== "number" || value < 0 || value > 128) + throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); + setValue(ptr, value, "i8"); + break; + case "f": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be float`); + // XXX: I'm not sure why 'double' works and 'float' doesn't + setValue(ptr, value, "double"); + break; + case "d": + if(typeof value !== "number" || isFloat(value)) + throw new TypeError(`expected ${name} return type to be double`); + setValue(ptr, value, "double"); + break; + case "v": + break; + default: + throw new Error("unknown type"); + } + + function isFloat(n){ + return n === +n && n !== (n|0) && !Number.isInteger(n); + } + } + + function installHelper(fn, name) { name = name || fn.name; globalThis.nethackGlobal.helpers[name] = fn; @@ -815,10 +897,20 @@ EM_JS(void, js_helpers_init, (), { EM_JS(void, set_const, (char *scope_str, char *name_str, int num), { let scope = UTF8ToString(scope_str); let name = UTF8ToString(name_str); + globalThis.nethackGlobal.constants[scope] = globalThis.nethackGlobal.constants[scope] || {}; globalThis.nethackGlobal.constants[scope][name] = num; globalThis.nethackGlobal.constants[scope][num] = name; }); +#define SET_CONSTANT_STRING(scope, name) set_const_str(scope, #name, name); +EM_JS(void, set_const_str, (char *scope_str, char *name_str, char *input_str), { + let scope = UTF8ToString(scope_str); + let name = UTF8ToString(name_str); + let str = UTF8ToString(input_str); + + globalThis.nethackGlobal.constants[scope] = globalThis.nethackGlobal.constants[scope] || {}; + globalThis.nethackGlobal.constants[scope][name] = str; +}); void js_constants_init() { EM_ASM({ @@ -861,22 +953,175 @@ void js_constants_init() { SET_CONSTANT("STATUS_FIELD", BL_EXP) SET_CONSTANT("STATUS_FIELD", BL_CONDITION) SET_CONSTANT("STATUS_FIELD", MAXBLSTATS) + + // text attributes + SET_CONSTANT("ATTR", ATR_NONE); + SET_CONSTANT("ATTR", ATR_BOLD); + SET_CONSTANT("ATTR", ATR_DIM); + SET_CONSTANT("ATTR", ATR_ULINE); + SET_CONSTANT("ATTR", ATR_BLINK); + SET_CONSTANT("ATTR", ATR_INVERSE); + SET_CONSTANT("ATTR", ATR_URGENT); + SET_CONSTANT("ATTR", ATR_NOHISTORY); + + // conditions + SET_CONSTANT("CONDITION", BL_MASK_BAREH); + SET_CONSTANT("CONDITION", BL_MASK_BLIND); + SET_CONSTANT("CONDITION", BL_MASK_BUSY); + SET_CONSTANT("CONDITION", BL_MASK_CONF); + SET_CONSTANT("CONDITION", BL_MASK_DEAF); + SET_CONSTANT("CONDITION", BL_MASK_ELF_IRON); + SET_CONSTANT("CONDITION", BL_MASK_FLY); + SET_CONSTANT("CONDITION", BL_MASK_FOODPOIS); + SET_CONSTANT("CONDITION", BL_MASK_GLOWHANDS); + SET_CONSTANT("CONDITION", BL_MASK_GRAB); + SET_CONSTANT("CONDITION", BL_MASK_HALLU); + SET_CONSTANT("CONDITION", BL_MASK_HELD); + SET_CONSTANT("CONDITION", BL_MASK_ICY); + SET_CONSTANT("CONDITION", BL_MASK_INLAVA); + SET_CONSTANT("CONDITION", BL_MASK_LEV); + SET_CONSTANT("CONDITION", BL_MASK_PARLYZ); + SET_CONSTANT("CONDITION", BL_MASK_RIDE); + SET_CONSTANT("CONDITION", BL_MASK_SLEEPING); + SET_CONSTANT("CONDITION", BL_MASK_SLIME); + SET_CONSTANT("CONDITION", BL_MASK_SLIPPERY); + SET_CONSTANT("CONDITION", BL_MASK_STONE); + SET_CONSTANT("CONDITION", BL_MASK_STRNGL); + SET_CONSTANT("CONDITION", BL_MASK_STUN); + SET_CONSTANT("CONDITION", BL_MASK_SUBMERGED); + SET_CONSTANT("CONDITION", BL_MASK_TERMILL); + SET_CONSTANT("CONDITION", BL_MASK_TETHERED); + SET_CONSTANT("CONDITION", BL_MASK_TRAPPED); + SET_CONSTANT("CONDITION", BL_MASK_UNCONSC); + SET_CONSTANT("CONDITION", BL_MASK_WOUNDEDL); + SET_CONSTANT("CONDITION", BL_MASK_HOLDING); + + // menu + SET_CONSTANT("MENU_SELECT", PICK_NONE); + SET_CONSTANT("MENU_SELECT", PICK_ONE); + SET_CONSTANT("MENU_SELECT", PICK_ANY); + + // copyright + SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_A); + SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_B); + SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_C); + SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_D); + + // glyphs + SET_CONSTANT("GLYPH", GLYPH_MON_OFF); + SET_CONSTANT("GLYPH", GLYPH_PET_OFF); + SET_CONSTANT("GLYPH", GLYPH_INVIS_OFF); + SET_CONSTANT("GLYPH", GLYPH_DETECT_OFF); + SET_CONSTANT("GLYPH", GLYPH_BODY_OFF); + SET_CONSTANT("GLYPH", GLYPH_RIDDEN_OFF); + SET_CONSTANT("GLYPH", GLYPH_OBJ_OFF); + SET_CONSTANT("GLYPH", GLYPH_CMAP_OFF); + SET_CONSTANT("GLYPH", GLYPH_EXPLODE_OFF); + SET_CONSTANT("GLYPH", GLYPH_ZAP_OFF); + SET_CONSTANT("GLYPH", GLYPH_SWALLOW_OFF); + SET_CONSTANT("GLYPH", GLYPH_WARNING_OFF); + SET_CONSTANT("GLYPH", GLYPH_STATUE_OFF); + SET_CONSTANT("GLYPH", GLYPH_UNEXPLORED_OFF); + SET_CONSTANT("GLYPH", GLYPH_NOTHING_OFF); + SET_CONSTANT("GLYPH", MAX_GLYPH); + SET_CONSTANT("GLYPH", NO_GLYPH); + SET_CONSTANT("GLYPH", GLYPH_INVISIBLE); + SET_CONSTANT("GLYPH", GLYPH_UNEXPLORED); + SET_CONSTANT("GLYPH", GLYPH_NOTHING); + + // colors + SET_CONSTANT("COLORS", CLR_BLACK); + SET_CONSTANT("COLORS", CLR_RED); + SET_CONSTANT("COLORS", CLR_GREEN); + SET_CONSTANT("COLORS", CLR_BROWN); + SET_CONSTANT("COLORS", CLR_BLUE); + SET_CONSTANT("COLORS", CLR_MAGENTA); + SET_CONSTANT("COLORS", CLR_CYAN); + SET_CONSTANT("COLORS", CLR_GRAY); + SET_CONSTANT("COLORS", NO_COLOR); + SET_CONSTANT("COLORS", CLR_ORANGE); + SET_CONSTANT("COLORS", CLR_BRIGHT_GREEN); + SET_CONSTANT("COLORS", CLR_YELLOW); + SET_CONSTANT("COLORS", CLR_BRIGHT_BLUE); + SET_CONSTANT("COLORS", CLR_BRIGHT_MAGENTA); + SET_CONSTANT("COLORS", CLR_BRIGHT_CYAN); + SET_CONSTANT("COLORS", CLR_WHITE); + SET_CONSTANT("COLORS", CLR_MAX); + + // color attributes (?) + SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_DIM); + SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_BLINK); + SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_ULINE); + SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_INVERSE); + SET_CONSTANT("COLOR_ATTR", HL_ATTCLR_BOLD); + SET_CONSTANT("COLOR_ATTR", BL_ATTCLR_MAX); } /*** * Globals ***/ +#define CREATE_GLOBAL(var, type) create_global(#var, (void *)&var, type); +#define CREATE_GLOBAL_FROM_ARRAY(base, iter, path, end_expr, type) \ + for(iter = 0; end_expr; iter++) { \ + snprintf(buf, BUFSZ, #base ".%d." #path, iter); \ + create_global(buf, (void *)(&(base[iter].path)), type); \ + } + +void create_global (char *name, void *ptr, char *type); + void js_globals_init() { - // printf("js_globals_init\n"); + // int i; + // char buf[BUFSZ]; + printf("js_globals_init\n"); - // player name - // g.plname + EM_ASM({ + globalThis.nethackGlobal = globalThis.nethackGlobal || {}; + globalThis.nethackGlobal.globals = globalThis.nethackGlobal.globals || {}; + }); - // bottom line stats - // g.blstats - // g.now_or_before_idx + /* globals */ + CREATE_GLOBAL(g.plname, "s"); + + /* window globals */ + CREATE_GLOBAL(WIN_MAP, "i"); + CREATE_GLOBAL(WIN_MESSAGE, "i"); + CREATE_GLOBAL(WIN_INVEN, "i"); + CREATE_GLOBAL(WIN_STATUS, "i"); } +EM_JS(void, create_global, (char *name_str, void *ptr, char *type_str), { + let name = UTF8ToString(name_str); + let type = UTF8ToString(type_str); + + // get helpers + let getPointerValue = globalThis.nethackGlobal.helpers.getPointerValue; + let setPointerValue = globalThis.nethackGlobal.helpers.setPointerValue; + + let { obj, prop } = createPath(globalThis.nethackGlobal.globals, name); + + // setters / getters with bound pointers + Object.defineProperty(obj, prop, { + get: getPointerValue.bind(null, name, ptr, type), + set: setPointerValue.bind(null, name, ptr, type), + configurable: true, + enumerable: true + }); + + function createPath(obj, path) { + path = path.split("."); + let i; + for (i = 0; i < path.length - 1; i++) { + // obj[path[i]] = obj[path[i]] || {}; + if (obj[path[i]] === undefined) { + obj[path[i]] = {}; + } + obj = obj[path[i]]; + } + + return { obj, prop: path[i] }; + } +}) + #endif /*libnethack.c*/ From dc1c85faa42c2bfc36e31810f55ae45162ffc7cd Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 4 Oct 2020 14:04:56 -0700 Subject: [PATCH 271/708] more friendly javascript arguments --- win/shim/winshim.c | 158 +++++++++++++++++++++------------------------ 1 file changed, 75 insertions(+), 83 deletions(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 8218b7382..2910f0be6 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -262,6 +262,10 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r let cbName = UTF8ToString(cb_name); // console.log("local_callback:", cbName, fmt, name); + // get pointer / type conversion helpers + let getPointerValue = globalThis.nethackGlobal.helpers.getPointerValue; + let setPointerValue = globalThis.nethackGlobal.helpers.setPointerValue; + reentryMutexLock(name); let argTypes = fmt.split(""); @@ -271,7 +275,7 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r let jsArgs = []; for (let i = 0; i < argTypes.length; i++) { let ptr = args + (4*i); - let val = typeLookup(argTypes[i], ptr); + let val = getArg(name, ptr, argTypes[i]); jsArgs.push(val); } @@ -281,7 +285,7 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r let userCallback = globalThis[cbName]; runJsEventLoop(() => userCallback.call(this, name, ... jsArgs)).then((retVal) => { // save the return value - setReturn(name, ret_ptr, retType, retVal); + setPointerValue(name, ret_ptr, retType, retVal); // return setTimeout(() => { reentryMutexUnlock(); @@ -289,37 +293,6 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r }, 0); }); - - // convert 'ptr' to the type indicated by 'type' - function typeLookup(type, ptr) { - switch(type) { - case "s": // string - return UTF8ToString(getValue(ptr, "*")); - case "p": // pointer - ptr = getValue(ptr, "*"); - if(!ptr) return 0; // null pointer - return getValue(ptr, "*"); - case "c": // char - return String.fromCharCode(getValue(getValue(ptr, "*"), "i8")); - case "0": /* 2^0 = 1 byte */ - return getValue(getValue(ptr, "*"), "i8"); - case "1": /* 2^1 = 2 bytes */ - return getValue(getValue(ptr, "*"), "i16"); - case "2": /* 2^2 = 4 bytes */ - case "i": // integer - case "n": // number - return getValue(getValue(ptr, "*"), "i32"); - case "f": // float - return getValue(getValue(ptr, "*"), "float"); - case "d": // double - return getValue(getValue(ptr, "*"), "double"); - case "o": // overloaded: multiple types - return ptr; - default: - throw new TypeError ("unknown type:" + type); - } - } - // make callback arguments friendly: convert numbers to strings where possible function decodeArgs(name, args) { // if (!globalThis.nethackGlobal.makeArgsFriendly) return; @@ -333,14 +306,77 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r args[0] = globalThis.nethackGlobal.constants["STATUS_FIELD"][args[0]]; // arg[1] is a string unless it is BL_CONDITION, BL_RESET, BL_FLUSH, BL_CHARACTERISTICS if(["BL_CONDITION", "BL_RESET", "BL_FLUSH", "BL_CHARACTERISTICS"].indexOf(args[0] && args[1]) < 0) { - args[1] = typeLookup("s", args[1]); + args[1] = getArg(name, args[1], "s"); } else { - args[1] = typeLookup("p", args[1]); + args[1] = getArg(name, args[1], "p"); } break; + case "shim_display_file": + args[1] = !!args[1]; + case "shim_display_nhwindow": + args[0] = decodeWindow(args[0]); + args[1] = !!args[1]; + break; + case "shim_getmsghistory": + args[0] = !!args[0]; + break; + case "shim_putmsghistory": + args[1] = !!args[1]; + break; + case "shim_status_enablefield": + console.log("shim_status_enablefield arg 1:", args[1]); + args[3] = !!args[3]; + break; + case "shim_add_menu": + args[0] = decodeWindow(args[0]); + // args[1] = mapglyphHelper(args[1]); + // args[5] = decodeAttr(args[5]); + break; + case "shim_putstr": + args[0] = decodeWindow(args[0]); + break; + case "shim_select_menu": + args[0] = decodeWindow(args[0]); + args[1] = decodeSelected(args[1]); + break; + case "shim_clear_nhwindow": + case "shim_destroy_nhwindow": + case "shim_curs": + case "shim_start_menu": + case "shim_end_menu": + case "shim_print_glyph": + args[0] = decodeWindow(args[0]); + break; } } + function decodeWindow(winid) { + let { WIN_MAP, WIN_INVEN, WIN_STATUS, WIN_MESSAGE } = globalThis.nethackGlobal.globals; + switch(winid) { + case WIN_MAP: return "WIN_MAP"; + case WIN_MESSAGE: return "WIN_MESSAGE"; + case WIN_STATUS: return "WIN_STATUS"; + case WIN_INVEN: return "WIN_INVEN"; + default: return winid; + } + // return winid; + } + + function decodeSelected(how) { + let { PICK_NONE, PICK_ONE, PICK_ANY } = globalThis.nethackGlobal.constants.MENU_SELECT; + switch(how) { + case PICK_NONE: return "PICK_NONE"; + case PICK_ONE: return "PICK_ONE"; + case PICK_ANY: return "PICK_ANY"; + default: return how; + } + + } + + function getArg(name, ptr, type) { + return (type === "o")?ptr:getPointerValue(name, getValue(ptr, "*"), type); + } + // setTimeout() with value of '0' is similar to setImmediate() (but setImmediate isn't standard) // this lets the JS loop run for a tick so that other events can occur // XXX: I also tried replacing the for(;;) in allmain.c:moveloop() with emscripten_set_main_loop() @@ -357,60 +393,16 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r }); } - // sets the return value of the function to the type expected - function setReturn(name, ptr, type, value = 0) { - switch (type) { - case "p": - throw new Error("not implemented"); - case "s": - if(typeof value !== "string") - throw new TypeError(`expected ${name} return type to be string`); - value=value?value:"(no value)"; - var strPtr = getValue(ptr, "i32"); - stringToUTF8(value, strPtr, 1024); - break; - case "i": - if(typeof value !== "number" || !Number.isInteger(value)) - throw new TypeError(`expected ${name} return type to be integer`); - setValue(ptr, value, "i32"); - break; - case "c": - if(typeof value !== "number" || value < 0 || value > 128) - throw new TypeError(`expected ${name} return type to be integer representing an ASCII character`); - setValue(ptr, value, "i8"); - break; - case "f": - if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be float`); - // XXX: I'm not sure why 'double' works and 'float' doesn't - setValue(ptr, value, "double"); - break; - case "d": - if(typeof value !== "number" || isFloat(value)) - throw new TypeError(`expected ${name} return type to be double`); - setValue(ptr, value, "double"); - break; - case "v": - break; - default: - throw new Error("unknown type"); - } - - function isFloat(n){ - return n === +n && n !== (n|0) && !Number.isInteger(n); - } - } - function reentryMutexLock(name) { globalThis.nethackGlobal = globalThis.nethackGlobal || {}; - if(globalThis.nethackGlobal.shimPreventReentry) { - throw new Error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimPreventReentry}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); + if(globalThis.nethackGlobal.shimFunctionRunning) { + throw new Error(`'${name}' attempting second call to 'local_callback' before '${globalThis.nethackGlobal.shimFunctionRunning}' has finished, will crash emscripten Asyncify. For details see: emscripten.org/docs/porting/asyncify.html#reentrancy`); } - globalThis.nethackGlobal.shimPreventReentry = name; + globalThis.nethackGlobal.shimFunctionRunning = name; } function reentryMutexUnlock() { - globalThis.nethackGlobal.shimPreventReentry = null; + globalThis.nethackGlobal.shimFunctionRunning = null; } }); }) From 49ef50fc54b9b4917c1e5bcaea1d6f3b235e6de7 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 4 Oct 2020 16:34:59 -0700 Subject: [PATCH 272/708] Makefile.src: avoid extra feedback while linking Recently added cross-compile stuff had resulted in an extra line of feedback when linking: 'true;'. Suppress that. Also, I think 'AWK=nawk' was needed for Solaris or maybe even SunOS. Switch 'make depend' to use ordinary awk by default since most systems have Posix-compliant awk these days and OSX doesn't have nawk. --- sys/unix/Makefile.src | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 8977c5127..2e4be5114 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -1,5 +1,5 @@ # NetHack Makefile. -# NetHack 3.7 Makefile.src $NHDT-Date: 1600904413 2020/09/23 23:40:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.108 $ +# NetHack 3.7 Makefile.src $NHDT-Date: 1601854487 2020/10/04 23:34:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.111 $ # Copyright (c) 2018 by Pasi Kallinen # NetHack may be freely redistributed. See license for details. @@ -425,9 +425,9 @@ GAMEBIN = $(GAME) # RANDOBJ = $(TARGETPFX)random.o RANDOBJ = - # used by `make depend' to reconstruct this Makefile; you shouldn't need this -AWK = nawk +# at all but can override with 'make AWK=nawk' or 'make AWK=gawk' if necessary +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 @@ -487,6 +487,13 @@ AT_V1 := @ AT = $(AT_V$(QUIETCC)) # Verbosity, end +# 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 +CLEANMORE=@true +PACKAGE=@true + + MAKEDEFS = ../util/makedefs # -lm required by lua @@ -615,7 +622,7 @@ all: $(GAME) @echo "" pregame: - true; $(PREGAME) + $(PREGAME) $(GAME): pregame $(SYSTEM) @echo "$(GAME) is up to date." @@ -790,7 +797,7 @@ tags: $(CSOURCES) clean: -rm -f *.o $(HACK_H) $(CONFIG_H) - true; $(CLEANMORE) + $(CLEANMORE) spotless: clean -rm -f a.out core $(GAMEBIN) Sys* @@ -800,7 +807,7 @@ spotless: clean -rm -f ../win/gnome/gn_rip.h package: - true; $(PACKAGE) + $(PACKAGE) @echo packaging complete. depend: ../sys/unix/depend.awk \ From 15c1cb648d2665762a3250fc130d3d7e8aeb5669 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 20:05:29 -0400 Subject: [PATCH 273/708] integrate updates made to PR earlier on Oct 4 --- sys/unix/hints/include/cross-post.2020 | 4 ++-- sys/unix/hints/include/cross-pre.2020 | 21 ++++++++++++--------- sys/unix/hints/linux.2020 | 11 ++++++++--- sys/unix/hints/macOS.2020 | 11 ++++++++--- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 74228ce6c..a4c2d0a9c 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -161,7 +161,7 @@ $(TARGETPFX)recover.exe : $(TARGETPFX)recover.o $(TARGET_LINK) $(TARGET_LFLAGS) $(TARGETPFX)recover.o -o $@ endif # CROSS_SHARED # -ifdef BUILD_LUA +ifdef BUILD_TARGET_LUA # Lua lib $(LUACROSSLIB): $(LUALIBOBJS) if [ -f $@ ]; then rm $@; fi; @@ -206,7 +206,7 @@ $(TARGETPFX)lundump.o : $(LUATOP)/src/lundump.c $(TARGETPFX)lutf8lib.o : $(LUATOP)/src/lutf8lib.c $(TARGETPFX)lvm.o : $(LUATOP)/src/lvm.c $(TARGETPFX)lzio.o : $(LUATOP)/src/lzio.c -endif # BUILD_LUA +endif # BUILD_TARGET_LUA ifdef BUILD_PDCURSES ifdef WANT_WIN_CURSES diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 8118c0610..0b1f71737 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -5,7 +5,7 @@ # ifdef CROSS_TO_MSDOS -BUILD_LUA=1 +BUILD_TARGET_LUA=1 BUILD_PDCURSES=1 CROSS_SHARED=1 override TARGET = msdos @@ -15,7 +15,7 @@ override TARGET_LIBS= endif ifdef CROSS_TO_AMIGA -BUILD_LUA=1 +BUILD_TARGET_LUA=1 BUILD_PDCURSES=1 CROSS_SHARED=1 override TARGET = amiga @@ -25,14 +25,14 @@ override TARGET_LIBS= endif ifdef CROSS_TO_WASM -BUILD_LUA=1 +BUILD_TARGET_LUA=1 override TARGET = wasm override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ override TARGET_LIBS= endif -ifdef BUILD_LUA +ifdef BUILD_TARGET_LUA #===============-================================================= # LUA library # Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz @@ -65,7 +65,7 @@ BUILDMORE += $(LUACROSSLIB) override TARGET_LIBS += $(LUACROSSLIB) -lm else LUAINCL= -endif # BUILD_LUA +endif # BUILD_TARGET_LUA ifdef BUILD_PDCURSES #===============-================================================= @@ -333,11 +333,11 @@ override TARGET_CFLAGS = $(EMCC_CFLAGS) -c \ override TARGET_CXXFLAGS = $(TARGET_CFLAGS) override TARGET_LINK = $(TARGET_CC) override TARGET_LFLAGS= $(EMCC_LFLAGS) -override SYSSRC = ../sys/unix/unixmain.c \ +override SYSSRC = ../sys/lib/libnethackmain.c \ ../sys/share/ioctl.c ../sys/share/unixtty.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c \ ../win/shim/winshim.c -override SYSOBJ= $(TARGETPFX)unixmain.o \ +override SYSOBJ= $(TARGETPFX)libnethackmain.o \ $(TARGETPFX)ioctl.o $(TARGETPFX)unixtty.o \ $(TARGETPFX)unixunix.o $(TARGETPFX)unixres.o \ $(TARGETPFX)winshim.o @@ -354,6 +354,9 @@ CLEANMORE += rm -f -r $(TARGETDIR) # Rule for file in sys/unix $(TARGETPFX)%.o : ../sys/unix/%.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< +# Rule for file in sys/lib +$(TARGETPFX)%.o : ../sys/lib/%.c + $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< # Rule for files in win/shim $(TARGETPFX)%.o : ../win/shim/%.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< @@ -377,11 +380,11 @@ $(TARGETPFX)%.o : ../util/%.c $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< endif # CROSS_SHARED -ifdef BUILD_LUA +ifdef BUILD_TARGET_LUA # Rule for LUA files $(TARGETPFX)%.o : $(LUATOP)/src/%.c $(TARGET_CC) $(TARGET_CFLAGS) $(LUA_FLAGS) -o$@ $< -endif # BUILD_LUA +endif # BUILD_TARGET_LUA # # End of cross-compiling -PRE section #===============-================================================= diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 751eae43d..2780cbb77 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -166,10 +166,15 @@ VARDATND += $(sort $(VARDATND0)) ifdef WANT_LIBNH CFLAGS += -DSHIM_GRAPHICS -DNOTTYGRAPHICS -DNOSHELL -DLIBNH -WINOBJ = winshim.o +LIBNHSYSSRC = ../sys/lib/libnethackmain.c \ + ../sys/share/ioctl.c ../sys/share/unixtty.c \ + ../sys/unix/unixunix.c ../sys/unix/unixres.c \ + ../win/shim/winshim.c +LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ + unixres.o winshim.o MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) -libnethack.a: $(HOBJ) $(SYSOBJ) $(WINOBJ) ../lib/lua/liblua.a - $(AR) rcs $@ $(HOBJ) $(WINOBJ) ../lib/lua/liblua.a +libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a + $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index fbd7724f2..7d2005832 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -173,10 +173,15 @@ VARDATND += $(sort $(VARDATND0)) ifdef WANT_LIBNH CFLAGS += -DSHIM_GRAPHICS -DNOTTYGRAPHICS -DNOSHELL -DLIBNH -WINOBJ = winshim.o +LIBNHSYSSRC = ../sys/lib/libnethackmain.c \ + ../sys/share/ioctl.c ../sys/share/unixtty.c \ + ../sys/unix/unixunix.c ../sys/unix/unixres.c \ + ../win/shim/winshim.c +LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ + unixres.o winshim.o MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) -libnethack.a: $(HOBJ) $(SYSOBJ) $(WINOBJ) ../lib/lua/liblua.a - $(AR) rcs $@ $(HOBJ) $(WINOBJ) ../lib/lua/liblua.a +libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a + $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< From 11b5f29e07bb35ce3ea5586aa2dadc53a0ba2f01 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 20:07:57 -0400 Subject: [PATCH 274/708] merging conflict fixup --- include/global.h | 11 ++--------- src/rip.c | 36 ++++++++++++++++++------------------ 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/include/global.h b/include/global.h index 4581137ef..caa32847b 100644 --- a/include/global.h +++ b/include/global.h @@ -331,15 +331,8 @@ struct version_info { unsigned long incarnation; /* actual version number */ unsigned long feature_set; /* bitmask of config settings */ unsigned long entity_count; /* # of monsters and objects */ -#ifndef __EMSCRIPTEN__ unsigned long struct_sizes1; /* size of key structs */ unsigned long struct_sizes2; /* size of more key structs */ -#else /* __EMSCRIPTEN__ */ - /* 'long' in WASM is 4 bytes, which is too small to hold version numbers - * such as: VERSION_SANITY2 */ - unsigned long long struct_sizes1; /* size of key structs */ - unsigned long long struct_sizes2; /* size of more key structs */ -#endif /* !__EMSCRIPTEN__ */ }; struct savefile_info { @@ -403,7 +396,7 @@ struct savefile_info { /* PANICTRACE: Always defined for NH_DEVEL_STATUS != NH_STATUS_RELEASED but only for supported platforms. */ -#if defined(UNIX) && !defined(__EMSCRIPTEN__) +#ifdef UNIX #if (NH_DEVEL_STATUS != NH_STATUS_RELEASED) /* see end.c */ #if !defined(CROSS_TO_WASM) @@ -421,7 +414,7 @@ struct savefile_info { #if defined(MACOSX) #define PANICTRACE_LIBC #endif -#if defined(UNIX) && !defined(__EMSCRIPTEN__) /* no popen in WASM */ +#ifdef UNIX #if !defined(CROSS_TO_WASM) /* no popen in WASM */ #define PANICTRACE_GDB #endif diff --git a/src/rip.c b/src/rip.c index c9d518aea..634d816d2 100644 --- a/src/rip.c +++ b/src/rip.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 rip.c $NHDT-Date: 1596498204 2020/08/03 23:43:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.32 $ */ +/* NetHack 3.7 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. */ @@ -61,12 +61,10 @@ static const char *rip_txt[] = { }; #define STONE_LINE_CENT 19 /* char[] element of center of stone face */ #endif /* NH320_DEDICATION */ -#define STONE_LINE_LEN \ - 16 /* # chars that fit on one line \ - * (note 1 ' ' border) \ - */ -#define NAME_LINE 6 /* *char[] line # for player name */ -#define GOLD_LINE 7 /* *char[] line # for amount of gold */ +#define STONE_LINE_LEN 16 /* # chars that fit on one line + * (note 1 ' ' border) */ +#define NAME_LINE 6 /* *char[] line # for player name */ +#define GOLD_LINE 7 /* *char[] line # for amount of gold */ #define DEATH_LINE 8 /* *char[] line # for death description */ #define YEAR_LINE 12 /* *char[] line # for year */ @@ -91,9 +89,9 @@ time_t when; register char **dp; register char *dpx; char buf[BUFSZ]; - long year; register int x; - int line; + int line, year; + long cash; g.rip = dp = (char **) alloc(sizeof(rip_txt)); for (x = 0; rip_txt[x]; ++x) @@ -101,13 +99,15 @@ time_t when; dp[x] = (char *) 0; /* Put name on stone */ - Sprintf(buf, "%s", g.plname); - buf[STONE_LINE_LEN] = 0; + Sprintf(buf, "%.*s", (int) STONE_LINE_LEN, g.plname); center(NAME_LINE, buf); /* Put $ on stone */ - Sprintf(buf, "%ld Au", g.done_money); - buf[STONE_LINE_LEN] = 0; /* It could be a *lot* of gold :-) */ + cash = max(g.done_money, 0L); + /* arbitrary upper limit; practical upper limit is quite a bit less */ + if (cash > 999999999L) + cash = 999999999L; + Sprintf(buf, "%ld Au", cash); center(GOLD_LINE, buf); /* Put together death description */ @@ -115,11 +115,11 @@ time_t when; /* Put death type on stone */ for (line = DEATH_LINE, dpx = buf; line < YEAR_LINE; line++) { - register int i, i0; char tmpchar; + int i, i0 = (int) strlen(dpx); - if ((i0 = strlen(dpx)) > STONE_LINE_LEN) { - for (i = STONE_LINE_LEN; ((i0 > STONE_LINE_LEN) && i); i--) + if (i0 > STONE_LINE_LEN) { + for (i = STONE_LINE_LEN; (i > 0) && (i0 > STONE_LINE_LEN); --i) if (dpx[i] == ' ') i0 = i; if (!i) @@ -136,8 +136,8 @@ time_t when; } /* Put year on stone */ - year = yyyymmdd(when) / 10000L; - Sprintf(buf, "%4ld", year); + year = (int) ((yyyymmdd(when) / 10000L) % 10000L); + Sprintf(buf, "%4d", year); center(YEAR_LINE, buf); #ifdef DUMPLOG From 60dbb4c12f7facdfb10cade49e61e643be82fdd5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 20:09:28 -0400 Subject: [PATCH 275/708] the .gitignore doesn't match the target locations on the merged code Leave it be for now. --- .gitignore | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.gitignore b/.gitignore index aa171205f..366cf938f 100644 --- a/.gitignore +++ b/.gitignore @@ -87,10 +87,3 @@ targets/* #test.js #sys/lib/npm-package/build/nethack.js #sys/lib/npm-package/build/nethack.wasm -src/libnethack.a -/libtest.c -/nhlibtest -/run.sh -/test.js -sys/lib/npm-package/build/nethack.js -sys/lib/npm-package/build/nethack.wasm From 7bf5172f2ee0de175122412df071daf94a2ca683 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 20:14:45 -0400 Subject: [PATCH 276/708] unixmain and libnethackmain diverged in the updated PR put unixmain back the way it was, now that libnethackmain is in the tree after all. --- sys/unix/unixmain.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 6c1f67b56..87e255064 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -45,17 +45,7 @@ static void NDECL(wd_message); static boolean wiz_error_flag = FALSE; static struct passwd *NDECL(get_unix_pw); -#if defined(CROSSCOMPILE_TARGET) && defined(CROSS_TO_WASM) -/* for cross-compiling to WebAssembly (WASM) */ -#include -/* if WebAssembly, export this API and don't optimize it out */ -#define KEEP EMSCRIPTEN_KEEPALIVE -#else -#define KEEP -#endif - - -int KEEP +int main(argc, argv) int argc; char *argv[]; From d8961b00678199549491002bb880c2e0c845f27b Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 20:48:09 -0400 Subject: [PATCH 277/708] updates for LIBNH build --- sys/unix/hints/linux.2020 | 5 +++++ sys/unix/hints/macOS.2020 | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 2780cbb77..c8312452c 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -172,10 +172,15 @@ LIBNHSYSSRC = ../sys/lib/libnethackmain.c \ ../win/shim/winshim.c LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ unixres.o winshim.o +#don't bother building the game executable as it will fail +#without winshim +override GAME= MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." +libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< endif # BUILD_LIBNH diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 7d2005832..31673dded 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -179,13 +179,18 @@ LIBNHSYSSRC = ../sys/lib/libnethackmain.c \ ../win/shim/winshim.c LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ unixres.o winshim.o +#don't bother building the game executable as it will fail +#without winshim +override GAME= MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." +libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< -endif # BUILD_LIBNH +endif # WANT_LIBNH WANT_BUNDLE=1 ifdef WANT_SHARE_INSTALL From ac493aa455b9790f5b653fd7f9d04e158825717e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 21:12:03 -0400 Subject: [PATCH 278/708] placement of libnethack targets required adjusting From -PRE to -POST section --- sys/unix/hints/linux.2020 | 19 +++++++++++-------- sys/unix/hints/macOS.2020 | 16 +++++++++------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index c8312452c..b9119d5c0 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -176,14 +176,7 @@ LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ #without winshim override GAME= MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) -libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a - $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a - @echo "$@ built." -libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) - $(CC) $(CFLAGS) -c -o$@ $< -winshim.o : ../win/shim/winshim.c $(HACK_H) - $(CC) $(CFLAGS) -c -o$@ $< -endif # BUILD_LIBNH +endif # WANT_LIBNH #PREFIX=/usr PREFIX=$(wildcard ~)/nh/install @@ -231,3 +224,13 @@ GAMEPERM = 0755 # #-INCLUDE cross-post.2020 # +ifdef WANT_LIBNH +libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a + $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a + @echo "$@ built." +libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< +winshim.o : ../win/shim/winshim.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< +endif # WANT_LIBNH +# diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 31673dded..44a1106bc 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -183,13 +183,6 @@ LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ #without winshim override GAME= MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) -libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a - $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a - @echo "$@ built." -libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) - $(CC) $(CFLAGS) -c -o$@ $< -winshim.o : ../win/shim/winshim.c $(HACK_H) - $(CC) $(CFLAGS) -c -o$@ $< endif # WANT_LIBNH WANT_BUNDLE=1 @@ -301,6 +294,15 @@ VARDIR=$(HACKDIR) #-INCLUDE cross-pre.2020 # #-POST +ifdef WANT_LIBNH +libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a + $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a + @echo "$@ built." +libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< +winshim.o : ../win/shim/winshim.c $(HACK_H) + $(CC) $(CFLAGS) -c -o$@ $< +endif # WANT_LIBNH ifdef MAKEFILE_TOP ### From ab5c8dff0552e657573901192f5031c2f3a79f73 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 4 Oct 2020 21:14:59 -0400 Subject: [PATCH 279/708] cron daily Files update --- Files | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Files b/Files index 8e1ed1d3a..9aedfce0c 100644 --- a/Files +++ b/Files @@ -220,16 +220,20 @@ zap.c sys/lib: (files in top directory) -README.md sysconf +README.md libnethackmain.c sysconf sys/lib/npm-package: (files in top directory) -LICENSE.md README.md package.json +LICENSE.md README.md package-lock.json package.json sys/lib/npm-package/src: (file in top directory) nethackShim.js +sys/lib/npm-package/test: +(file in top directory) +test.js + sys/lib/test: (files in top directory) README.md libtest.c run.sh From 43112cec01a9d545a66740da1c3d4cfca9d7db2c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 5 Oct 2020 09:24:42 -0400 Subject: [PATCH 280/708] clear a -Wshadow warning in options.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit options.c options.c: In function ‘match_optname’: options.c:5734:27: warning: declaration of ‘opt_name’ shadows a global declaration [-Wshadow] const char *user_string, *opt_name; ^~~~~~~~ In file included from options.c:52:0: ../include/optlist.h:56:1: note: shadowed declaration is here opt_##a, ^ ../include/optlist.h:307:5: note: in expansion of macro ‘NHOPTC’ NHOPTC(name, PL_NSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, ^~~~~~ --- src/options.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/options.c b/src/options.c index f505b5523..f8ddb2f5e 100644 --- a/src/options.c +++ b/src/options.c @@ -5730,8 +5730,8 @@ int len; substring of a particular option name; option string might have a colon or equals sign and arbitrary value appended to it */ boolean -match_optname(user_string, opt_name, min_length, val_allowed) -const char *user_string, *opt_name; +match_optname(user_string, optn_name, min_length, val_allowed) +const char *user_string, *optn_name; int min_length; boolean val_allowed; { @@ -5741,7 +5741,7 @@ boolean val_allowed; len = length_without_val(user_string, len); return (boolean) (len >= min_length - && !strncmpi(opt_name, user_string, len)); + && !strncmpi(optn_name, user_string, len)); } void From 37339abebda18fb01b0edb14c6996150001d1ea9 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 5 Oct 2020 17:17:07 +0300 Subject: [PATCH 281/708] Fix dropping const from params --- include/extern.h | 2 +- src/do.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/extern.h b/include/extern.h index 101293ab7..0689c4d9f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -424,7 +424,7 @@ E void FDECL(schedule_goto, (d_level *, BOOLEAN_P, BOOLEAN_P, int, E void NDECL(deferred_goto); E boolean FDECL(revive_corpse, (struct obj *)); E void FDECL(revive_mon, (ANY_P *, long)); -E boolean FDECL(cmd_safety_prevention, (char *, char *, int *)); +E boolean FDECL(cmd_safety_prevention, (const char *, const char *, int *)); E int NDECL(donull); E int NDECL(dowipe); E void FDECL(legs_in_no_shape, (const char *, BOOLEAN_P)); diff --git a/src/do.c b/src/do.c index 3156e5132..c891a94d4 100644 --- a/src/do.c +++ b/src/do.c @@ -1984,8 +1984,8 @@ long timeout UNUSED; boolean cmd_safety_prevention(cmddesc, act, flagcounter) -char *cmddesc; -char *act; +const char *cmddesc; +const char *act; int *flagcounter; { if (flags.safe_wait && !iflags.menu_requested From d7a52cf0c455ac2f66d4e11a1a4933e6e9620172 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 5 Oct 2020 16:26:27 -0700 Subject: [PATCH 282/708] Qt menu search Remove a 'TODO' for once. Have the popup that's used to accept the target string--after clicking on [search] or typing ':' to initiate menu search+select operation--force keyboard focus to itself. Menu searching worked without this, but only if you manually clicked on the search popup prior to typing the target string. Failure to do so resulted in typed characters being used to select menu entries. --- doc/fixes37.0 | 5 ++++- win/Qt/qt_menu.cpp | 2 -- win/Qt/qt_streq.cpp | 7 +++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 04e64186e..b68978a00 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.318 $ $NHDT-Date: 1601600393 2020/10/02 00:59:53 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.321 $ $NHDT-Date: 1601940384 2020/10/05 23:26:24 $ General Fixes and Modified Features ----------------------------------- @@ -430,6 +430,9 @@ Qt: 3.6 catchup - show unexplored locations as unexplored rather than as stone Qt: tried to honor 'showexp' but the value was unintentionally suppressed by [lack of definition for] obsolete conditional EXP_ON_BOTL Qt: implement --More-- prompt to support MSGTYPE=stop +Qt: for menu search, don't require clicking on the search target popup before + typing target string (was using typed letters to make menu selections + if player didn't click on the popup first) Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 1da9426d7..d2cf8eee1 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -6,8 +6,6 @@ // // TODO: -// search behaves weirdly unless you click in the line-edit dialog box -// after clicking on the [search] button to pop that up; // implement next_page, prev_page, first_page, and last_page to work // like they do for X11: scroll menu window as if it were paginated; // entering a count that uses more digits than the previous biggest count diff --git a/win/Qt/qt_streq.cpp b/win/Qt/qt_streq.cpp index b37ab305f..96133edec 100644 --- a/win/Qt/qt_streq.cpp +++ b/win/Qt/qt_streq.cpp @@ -83,6 +83,13 @@ bool NetHackQtStringRequestor::Get(char* buffer, int maxchar) #endif centerOnMain(this); show(); + // Make sure that setFocus() really does change keyboard focus. + // This allows typing to go directly to the NetHackQtLineEdit + // widget without clicking on or in it first. Not needed for + // qt_getline() but is needed for menu Search to prevent typed + // characters being treated as making menu selections. + if (!input.isActiveWindow()) + input.activateWindow(); input.setFocus(); exec(); From dc47c4631474b4cbf85a7b269b393840c2beaf76 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 6 Oct 2020 01:47:19 -0400 Subject: [PATCH 283/708] more wasm cross-compiling follow-up --- sys/unix/Makefile.top | 7 +++- sys/unix/hints/include/cross-post.2020 | 17 +++++---- sys/unix/hints/include/cross-pre.2020 | 49 +++++++++++++++++--------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 89a273221..c0e5433a3 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -94,8 +94,10 @@ DATNODLB = $(VARDATND) license symbols DATDLB = $(DATHELP) dungeon.lua tribute $(SPEC_LEVS) $(QUEST_LEVS) $(VARDATD) DAT = $(DATNODLB) $(DATDLB) +ALLDEP = $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb + # first target is also the default target for 'make' without any arguments -all: $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb +all: $(ALLDEP) true; $(MOREALL) @echo "Done." @@ -205,6 +207,9 @@ dlb: ( cd util ; $(MAKE) dlb ) ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) +wasm: + ( cd src ; $(MAKE) $(WASM_TARGET) ) + package: $(GAME) recover $(VARDAT) spec_levs ( cd src ; $(MAKE) $(PACKAGE) ) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index a4c2d0a9c..1822dbd12 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -120,24 +120,23 @@ amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp endif # CROSS_TO_AMIGA ifdef CROSS_TO_WASM -$(WASM_TARGET): $(HOBJ) $(LUACROSSLIB) Makefile $(WASM_DATA_DIR) +$(WASM_TARGET): pregame $(HOBJ) $(LUACROSSLIB) $(WASM_DATA_DIR) -rm $@ - $(TARGET_CC) $(EMCC_LFLAGS) $(EMCC_CFLAGS) -o $@ \ + $(TARGET_CC) $(TARGET_LFLAGS) $(TARGET_CFLAGS) -o $@ \ $(HOBJ) $(TARGET_LIBS) -$(WASM_DATA_DIR): - -mkdir -p $(WASM_DATA_DIR) +$(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat touch $(WASM_DATA_DIR)/perm touch $(WASM_DATA_DIR)/record touch $(WASM_DATA_DIR)/logfile touch $(WASM_DATA_DIR)/xlogfile - ( cd ..; $(MAKE) dlb ) - ( cd ..; $(MAKE) dofiles-dlb ) cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf + +$(WASM_DATA_DIR)/nhdat: + ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dlb ) + ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dofiles-dlb ) + # -.PHONY: wasmpkg -wasmpkg: - @echo "$(WASM_TARGET) done." $(TARGETPFX)unixmain.o : ../sys/unix/unixmain.c $(HACK_H) $(TARGETPFX)unixres.o : ../sys/unix/unixres.c $(HACK_H) $(TARGETPFX)unixunix.o : ../sys/unix/unixunix.c $(HACK_H) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 0b1f71737..4fe0f9fac 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -5,6 +5,7 @@ # ifdef CROSS_TO_MSDOS +CROSS=1 BUILD_TARGET_LUA=1 BUILD_PDCURSES=1 CROSS_SHARED=1 @@ -15,6 +16,7 @@ override TARGET_LIBS= endif ifdef CROSS_TO_AMIGA +CROSS=1 BUILD_TARGET_LUA=1 BUILD_PDCURSES=1 CROSS_SHARED=1 @@ -25,6 +27,7 @@ override TARGET_LIBS= endif ifdef CROSS_TO_WASM +CROSS=1 BUILD_TARGET_LUA=1 override TARGET = wasm override TARGETDIR=../targets/$(TARGET) @@ -32,6 +35,12 @@ override TARGETPFX = $(TARGETDIR)/ override TARGET_LIBS= endif +ifdef CROSS +override PREGAME= +override CLEANMORE= +override PACKAGE= +endif + ifdef BUILD_TARGET_LUA #===============-================================================= # LUA library @@ -61,7 +70,8 @@ LUAOBJFILES4 = $(TARGETPFX)lstring.o $(TARGETPFX)lstrlib.o \ LUALIBOBJS = $(LUAOBJFILES1) $(LUAOBJFILES2) $(LUAOBJFILES3) $(LUAOBJFILES4) LUACROSSLIB = $(TARGETPFX)lua$(subst .,,$(LUA_VERSION)).a LUAINCL = -I$(LUASRCDIR) -BUILDMORE += $(LUACROSSLIB) +override BUILDMORE += $(LUACROSSLIB) ; +override CLEANMORE += rm -f $(LUACROSSLIB) ; override TARGET_LIBS += $(LUACROSSLIB) -lm else LUAINCL= @@ -110,7 +120,8 @@ ifdef CROSS_TO_AMIGA PDCINCL += -I$(PDCTOP)/sdl1 -I/opt/amiga/m68k-amigaos/include/SDL override TARGET_LIBS += -lSDL endif -BUILDMORE += $(PDCLIB) +override BUILDMORE += $(PDCLIB) ; +override CLEANMORE += rm -f $(PDCLIB) ; # Rules for PDCurses files $(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< @@ -173,10 +184,10 @@ override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ override WINLIB= override LUALIB= override GAMEBIN = $(TARGETPFX)nethack.exe -override PACKAGE= dospkg +override PACKAGE = dospkg +override PREGAME += mkdir -p $(TARGETDIR) ; +override CLEANMORE += rm -f -r $(TARGETDIR) ; VARDATND += nhtiles.bmp -PREGAME = mkdir -p $(TARGETDIR) -CLEANMORE += rm -f -r $(TARGETDIR) # ifdef WANT_WIN_CURSES # rules for pdcurses dos-specific files @@ -262,9 +273,9 @@ override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ override WINLIB= override LUALIB= override GAMEBIN = $(TARGETPFX)nethack -override PACKAGE= amigapkg -PREGAME = mkdir -p $(TARGETDIR) -CLEANMORE += rm -r $(TARGETDIR) +override PACKAGE = amigapkg +override PREGAME += mkdir -p $(TARGETDIR) ; +override CLEANMORE += rm -r $(TARGETDIR) ; # ../util/txt2iff # ifdef WANT_WIN_CURSES @@ -284,9 +295,10 @@ ifdef CROSS_TO_WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= # -WASM_DATA_DIR = $(TARGETPFX)wasm-data/ +WASM_DATA_DIR = $(TARGETPFX)wasm-data WASM_TARGET = $(TARGETPFX)nethack.js -EMCC_LFLAGS = -s SINGLE_FILE=1 +EMCC_LFLAGS = +#EMCC_LFLAGS += -s SINGLE_FILE=1 EMCC_LFLAGS += -s WASM=1 EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' @@ -303,7 +315,7 @@ EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR) # WASM C flags EMCC_CFLAGS= EMCC_CFLAGS += -Wall -EMCC_CFLAGS += -Werror +#EMCC_CFLAGS += -Werror #EMCC_CFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 EMCC_DEBUG_CFLAGS += -s ASSERTIONS=1 #EMCC_DEBUG_CFLAGS += -s ASSERTIONS=2 @@ -325,7 +337,7 @@ endif override TARGET_CC = emcc override TARGET_CXX = emcc override TARGET_AR = emar -override TARGET_CFLAGS = $(EMCC_CFLAGS) -c \ +override TARGET_CFLAGS = $(EMCC_CFLAGS) \ -I../include \ $(LUAINCL) -DDLB $(PDCURSESDEF) \ -DNOTTYGRAPHICS -DSHIM_GRAPHICS -DDEFAULT_WINDOW_SYS=\"shim\" \ @@ -343,14 +355,17 @@ override SYSOBJ= $(TARGETPFX)libnethackmain.o \ $(TARGETPFX)winshim.o override WINLIB = emranlib override LUALIB= -override PACKAGE= wasmpkg override REGEXOBJ = $(TARGETPFX)posixregex.o +override WINOBJ= +#override INSTDIR = $(WASM_DATA_DIR) +#override PACKAGE= wasmpkg +#override MOREALL = ( cd src ; $(MAKE) $(WASM_TARGET) ) +override GAME= +override ALLDEP = wasm +override PREGAME += mkdir -p $(TARGETDIR)/wasm-data ; +override CLEANMORE += rm -rf $(TARGETDIR) ; RANLIB=$(EMRANLIB) #VARDATND += nhtiles.bmp -override GAME= -MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) $(WASM_TARGET) ) -PREGAME = mkdir -p $(TARGETDIR) -CLEANMORE += rm -f -r $(TARGETDIR) # Rule for file in sys/unix $(TARGETPFX)%.o : ../sys/unix/%.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< From a8d31910eca02e5212565fda01c1d80d7508b03c Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 6 Oct 2020 02:01:30 -0400 Subject: [PATCH 284/708] target lua build was missing -c on cross-compile --- sys/unix/hints/include/cross-pre.2020 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 4fe0f9fac..7700b0baa 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -382,23 +382,23 @@ ifdef WANT_WIN_CURSES ifdef BUILD_PDCURSES # Rules for PDCurses files $(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c - $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -o$@ $< + $(TARGET_CC) $(PDCINCL) $(TARGET_CFLAGS) -c -o$@ $< endif # BUILD_PDCURSES endif # WANT_WIN_CURSES ifdef CROSS_SHARED # Rules for win/share files $(TARGETPFX)%.o : ../win/share/%.c - $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< + $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< # Rules for util files heading for target $(TARGETPFX)%.o : ../util/%.c - $(TARGET_CC) $(TARGET_CFLAGS) -o$@ $< + $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< endif # CROSS_SHARED ifdef BUILD_TARGET_LUA # Rule for LUA files $(TARGETPFX)%.o : $(LUATOP)/src/%.c - $(TARGET_CC) $(TARGET_CFLAGS) $(LUA_FLAGS) -o$@ $< + $(TARGET_CC) $(TARGET_CFLAGS) -c $(LUA_FLAGS) -o$@ $< endif # BUILD_TARGET_LUA # # End of cross-compiling -PRE section From b68f960c59a7cffa0a62abad9521e8fdb321c07b Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 6 Oct 2020 02:15:25 -0400 Subject: [PATCH 285/708] temporarily turn off the msdos cross-compile on travis --- .travis.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b1e388a0..51de236a7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -136,21 +136,21 @@ matrix: - cd src - cp ../sys/winnt/Makefile.gcc ./Makefile - mingw32-make LUA_VERSION=$LUA_VERSION install - - name: msdos-linux-focal-djgpp-crosscompile - os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 - dist: focal - compiler: gcc - script: -# - export -# - export GCCVER=gcc550 - - export GCCVER=gcc1010 - - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ - - make fetch-lua - - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - - sh sys/msdos/fetch-cross-compiler.sh - - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all - - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package +# - name: msdos-linux-focal-djgpp-crosscompile +# os: linux +# env: HINTS=linux.2020 LUA_VERSION=5.4.0 +# dist: focal +# compiler: gcc +# script: +## - export +## - export GCCVER=gcc550 +# - export GCCVER=gcc1010 +# - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ +# - make fetch-lua +# - test -d "lib/lua-$LUA_VERSION/src" || exit 0 +# - sh sys/msdos/fetch-cross-compiler.sh +# - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all +# - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package exclude: # - os: osx # osx_image: xcode10.3 From 724e5fba25fa9a524de175b0da358e6f08120e41 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 6 Oct 2020 02:26:40 -0400 Subject: [PATCH 286/708] adding ; was inappropriate for BUILDMORE list of dependencies --- sys/unix/hints/include/cross-pre.2020 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 7700b0baa..c9bc0a51f 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -37,6 +37,7 @@ endif ifdef CROSS override PREGAME= +override BUILDMORE= override CLEANMORE= override PACKAGE= endif @@ -70,7 +71,7 @@ LUAOBJFILES4 = $(TARGETPFX)lstring.o $(TARGETPFX)lstrlib.o \ LUALIBOBJS = $(LUAOBJFILES1) $(LUAOBJFILES2) $(LUAOBJFILES3) $(LUAOBJFILES4) LUACROSSLIB = $(TARGETPFX)lua$(subst .,,$(LUA_VERSION)).a LUAINCL = -I$(LUASRCDIR) -override BUILDMORE += $(LUACROSSLIB) ; +override BUILDMORE += $(LUACROSSLIB) override CLEANMORE += rm -f $(LUACROSSLIB) ; override TARGET_LIBS += $(LUACROSSLIB) -lm else @@ -120,7 +121,7 @@ ifdef CROSS_TO_AMIGA PDCINCL += -I$(PDCTOP)/sdl1 -I/opt/amiga/m68k-amigaos/include/SDL override TARGET_LIBS += -lSDL endif -override BUILDMORE += $(PDCLIB) ; +override BUILDMORE += $(PDCLIB) override CLEANMORE += rm -f $(PDCLIB) ; # Rules for PDCurses files $(TARGETPFX)%.o : $(PDCTOP)/pdcurses/%.c From cb2b710b224d1839b4a6c5f07d556883f127dcec Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 6 Oct 2020 11:00:33 -0400 Subject: [PATCH 287/708] update Cross-compiling document for PR385 Web Assemply and libnethack Credit: The initial Web Assembly cross compile was found in a pull request: https://github.com/NetHack/NetHack/pull/385 by apowers313. The pull request was merged with some accompanying NetHack source tree integration changes in early October 2020. Cross-compiler used: emscripten Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html Here's a brief guide to obtaining the cross-compiler sources via git and building it on your system. For Ubuntu, the build prerequisite packages for building the compiler can be easily obtained: sudo apt-get install python3 cmake default-jre For macOS, you will need to install Xcode, git, cmake, Python 3.5 or new (at time of this writing). After installing the prerequite packages above, obtain the cross-compiler via git and build it from the directory of your choice using steps similar to these: git clone https://github.com/emscripten-core/emsdk.git cd emsdk git pull ./emsdk install latest ./emsdk activate latest source ./emsdk_env.sh The steps above reflect what was outlined at this url at the time of writing: https://emscripten.org/docs/getting_started/downloads.html That is the definitive source and trumps anything documented here. On your linux host, prepare to cross-compile NetHack as follows: cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. make fetch-lua On your macOS host, prepare to cross-compile NetHack as follows: cd sys/unix ; sh setup.sh hints/macOS.2020 ; cd ../.. make fetch-lua Then, cross-compile to targets/wasm as follows: make CROSS_TO_WASM=1 You can build src/nethacklib.a from pull request 385 as follows: make WANT_LIBNH=1 Do not add any additional windowport interfaces to your build (such as WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 or WANT_WIN_QT=1) as those aren't applicable to the Web Assembly or nethacklib builds. A "shim" pseudo-windowport is included from pull request 385. Result: As mentioned, the wasm cross-compile will end up in targets/wasm and the nethacklib.a will end up src. The cross-compiler hints additions are enclosed inside ifdef sections and shouldn't interfere with the non-cross-compile builds using hints/linux.2020 or hints/macOS.2020. --- Cross-compiling | 77 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/Cross-compiling b/Cross-compiling index aa561df6c..96253755d 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -1,4 +1,4 @@ -Cross-compiling NetHack 3.7 Last edit: September 29, 2020 +Cross-compiling NetHack 3.7 Last edit: October 6, 2020 The NetHack 3.7 build process differs from the build process of previous versions in some important ways that make it possible to use a cross-compiler @@ -18,6 +18,7 @@ Part B Contents: B3. What needs to be built for the TARGET? B4. Case sample: msdos B5. Case sample: amiga (started but incomplete) + B6. Case sample: Web Assembly, libnethack -------------------------------------------------------------------------------- Part A - Cross-compiling NetHack @@ -611,5 +612,79 @@ Cross-compiler url: https://github.com/bebbo/amiga-gcc If you make headway, or are successful getting a working copy of NetHack going on the amiga, drop us a note at devteam@nethack.org. + + +--------------------------------+ + | B6. Case sample: Web Assembly | + +--------------------------------+ + +Credit: The initial Web Assembly cross compile was found in a pull request: + https://github.com/NetHack/NetHack/pull/385 + by apowers313. The pull request was merged with some accompanying + NetHack source tree integration changes in early October 2020. + +Cross-compiler used: emscripten +Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html + + Here's a brief guide to obtaining the cross-compiler sources via git and + building it on your system. + + For Ubuntu, the build prerequisite packages for building the compiler can + be easily obtained: + + sudo apt-get install python3 cmake default-jre + + For macOS, you will need to install Xcode, git, cmake, Python 3.5 or new + (at time of this writing). + + After installing the prerequite packages above, obtain the cross-compiler + via git and build it from the directory of your choice using steps similar + to these: + + git clone https://github.com/emscripten-core/emsdk.git + cd emsdk + git pull + ./emsdk install latest + ./emsdk activate latest + source ./emsdk_env.sh + + The steps above reflect what was outlined at this url at the time + of writing: + + https://emscripten.org/docs/getting_started/downloads.html + + That is the definitive source and trumps anything documented here. + + On your linux host, prepare to cross-compile NetHack as follows: + + cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. + make fetch-lua + + On your macOS host, prepare to cross-compile NetHack as follows: + + cd sys/unix ; sh setup.sh hints/macOS.2020 ; cd ../.. + make fetch-lua + + Then, cross-compile to targets/wasm as follows: + + make CROSS_TO_WASM=1 + + You can build src/nethacklib.a from pull request 385 as follows: + + make WANT_LIBNH=1 + + Do not add any additional windowport interfaces to your build + (such as WANT_WIN_TTY=1 WANT_WIN_CURSES=1 WANT_WIN_X11=1 or + WANT_WIN_QT=1) as those aren't applicable to the Web Assembly + or nethacklib builds. A "shim" pseudo-windowport is included + from pull request 385. + + Result: As mentioned, the wasm cross-compile will end up in + targets/wasm and the nethacklib.a will end up + src. + + The cross-compiler hints additions are enclosed inside ifdef sections + and shouldn't interfere with the non-cross-compile builds using + hints/linux.2020 or hints/macOS.2020. + --- From 7277b4a4156dca99074b088b7df5ec19f31feef8 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 6 Oct 2020 09:09:09 -0700 Subject: [PATCH 288/708] Qt menus, mostly item counts Don't allow the user to construct a count value when operating on a pick-none menu where counts aren't meaningful. Unfortunately that can still be done on pick-one or pick-any menus which don't happen to have any entries where a count is applicable. Allow a count to be optionally started with '#'. Note that if there is an entry using '#' for the selector letter (probably inventory that has something in the overflow slot), typing '#' will select the entry instead of initiating a count. Flail about a bit trying to get menu size correct--failed on this front. --- win/Qt/qt_menu.cpp | 104 ++++++++++++++++++++++++++++++++------------- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index d2cf8eee1..07834f7c0 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -6,6 +6,8 @@ // // TODO: +// inventory menus reuse the same menu window over and over (in the core); +// it isn't resizing properly to reflect each new instance's content; // implement next_page, prev_page, first_page, and last_page to work // like they do for X11: scroll menu window as if it were paginated; // entering a count that uses more digits than the previous biggest count @@ -65,11 +67,14 @@ int NetHackQtMenuListBox::TotalWidth() const int NetHackQtMenuListBox::TotalHeight() const { - int height = 0; + int row, height = 0; - for (int row = 0; row < rowCount(); ++row) { + for (row = 0; row < rowCount(); ++row) { height += rowHeight(row); } + // include extra height so that there will be a blank gap after the + // last entry to show that there is nothing to scroll forward too + height += (row > 0) ? (rowHeight(row - 1) / 2) : 7; return height; } @@ -80,9 +85,41 @@ QSize NetHackQtMenuListBox::sizeHint() const return QSize(TotalWidth()+hsize, TotalHeight()+hsize); } +// +// FIXME: +// Inventory displays reuse the same menu window and so far this +// is not updating the size as intended. The size of the first +// instance persists. +// + +// resize current menu window and the table (rows of entries) inside it +void NetHackQtMenuWindow::MenuResize() +{ + // when this was just 'adjustSize()', our sizeHints() was not + // being called so explicitly indicate the table widget + table->adjustSize(); + this->adjustSize(); + + // Temporary? workaround for scrolling becoming wedged if using + // all/none/invert removes all counts so we narrow a non-empty + // count column to empty. [That can take away the horizontal + // scroll bar but should not be affecting the vertical one, yet + // is (Qt 5.11.3).] Typing any digit restored normal scrolling + // and the only significant thing about that is that it updates + // the prompt line which is outside the table of menu items where + // scrolling takes place. Oddly, both prompt changes are needed + // (possibly the unnecessary space in the first is being optimized + // away but the second call to remove it isn't aware of that, or + // perhaps the 'fix' only happens when the line gets shorter). + prompt.setText(promptstr + " "); + prompt.setText(promptstr); + // [Later: becoming wedged doesn't just occur after shrinking the + // count column and seems to be triggered by table->adjustSize().] +} + // Table view columns (0..4): // -// [pick-count] [check-box] [glyph] [accel] [string] +// [pick-count] [check-box] [object-glyph] [selector-letter] [description] // // pick-count is normally empty and gets wider as needed. // @@ -155,11 +192,22 @@ NetHackQtMenuWindow::~NetHackQtMenuWindow() QWidget* NetHackQtMenuWindow::Widget() { return this; } +// +// Note: inventory menus reuse the same menu window over and over +// so StartMenu(), AddMenu(), EndMenu(), and SelectMenu() +// can't rely on the MenuWindow constructor for initialization. +// + void NetHackQtMenuWindow::StartMenu() { - table->setRowCount((itemcount=0)); - next_accel=0; - has_glyphs=false; + itemcount = 0; + table->setRowCount(itemcount); + next_accel = 0; + has_glyphs = false; + biggestcount = 0L; + countdigits = 0; + ClearCount(); // reset 'counting' flag and digit string 'countstr' + ClearSearch(); // reset 'searching' flag } NetHackQtMenuWindow::MenuItem::MenuItem() : @@ -258,10 +306,11 @@ int NetHackQtMenuWindow::SelectMenu(int h, MENU_ITEM_P **menu_list) } PadMenuColumns(::iflags.menu_tab_sep ? true : false); + MenuResize(); + //old FIXME: size for compact mode //resize(this->width(), parent()->height()*7/8); move(0, 0); - adjustSize(); centerOnMain(this); exec(); @@ -396,23 +445,7 @@ void NetHackQtMenuWindow::UpdateCountColumn(long newcount) PadMenuColumns(false); - // Temporary? workaround for scrolling becoming wedged if using - // all/none/invert removes all counts so we narrow a non-empty - // count column to empty. [That can take away the horizontal - // scroll bar but should not be affecting the vertical one, yet - // is (Qt 5.11.3).] Typing any digit restored normal scrolling - // and the only significant thing about that is that it updates - // the prompt line which is outside the table of menu items where - // scrolling takes place. Oddly, both prompt changes are needed - // (possibly the unnecessary space in the first is being optimized - // away but the second call to remove it isn't aware of that). - prompt.setText(promptstr + " "); - prompt.setText(promptstr); - - // when this was just 'adjustSize()', our sizeHints() was not - // being called so explicitly indicate the table widget - table->adjustSize(); - this->adjustSize(); + MenuResize(); table->repaint(); } @@ -599,7 +632,7 @@ void NetHackQtMenuWindow::WidenColumn(int column, int width) void NetHackQtMenuWindow::InputCount(char key) { - if (key == '\b' || key == '\177') { + if (key == '\b' || key == '\177' || how == PICK_NONE) { if (counting) { if (countstr.isEmpty()) ClearCount(); @@ -608,6 +641,15 @@ void NetHackQtMenuWindow::InputCount(char key) } } else { counting = true; + // starting a count (enforced by caller) with '#' is optional; + // if used, show visible '0' + if (key == '#') + key = '0'; + // if we have non-zero digit and are currently showing visible '0', + // replace instead of append; doesn't attempt to handle multiple + // leading zeroes--they won't affect the outcome, just look odd + else if (key > '0' && countstr == "0") + countstr = ""; countstr += QChar(key); } if (counting) @@ -655,7 +697,9 @@ void NetHackQtMenuWindow::keyPressEvent(QKeyEvent *key_event) reject(); } else if (key == '\r' || key == '\n' || key == ' ') { accept(); - } else if (('0' <= key && key <= '9') || key == '\b' || key == '\177') { + } else if (('0' <= key && key <= '9') + || (key == '#' && !counting) + || key == '\b' || key == '\177') { InputCount(key); } else if (key == MENU_SELECT_ALL || key == MENU_SELECT_PAGE) { All(); @@ -925,12 +969,12 @@ void NetHackQtTextWindow::UseRIP(int how, time_t when) { // Code from X11 windowport #define STONE_LINE_LEN 16 /* # chars that fit on one line */ -#define NAME_LINE 0 /* line # for player name */ -#define GOLD_LINE 1 /* line # for amount of gold */ +#define NAME_LINE 0 /* line # for player name */ +#define GOLD_LINE 1 /* line # for amount of gold */ #define DEATH_LINE 2 /* line # for death description */ -#define YEAR_LINE 6 /* line # for year */ +#define YEAR_LINE 6 /* line # for year */ -static char** rip_line=0; + static char **rip_line = 0; if (!rip_line) { rip_line=new char*[YEAR_LINE+1]; for (int i=0; i Date: Tue, 6 Oct 2020 09:15:32 -0700 Subject: [PATCH 289/708] left out of "Qt menus, mostly item counts" --- win/Qt/qt_menu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index a6aadf51c..59720009e 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -129,6 +129,7 @@ private: void AddRow(int row, const MenuItem& mi); void WidenColumn(int column, int width); void PadMenuColumns(bool split_descr); + void MenuResize(); void UpdateCountColumn(long newcount); void ClearSearch(); From e2e9bca3f74fb0ed492895f029b1918b3c4c41ce Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 6 Oct 2020 09:42:59 -0700 Subject: [PATCH 290/708] Qt "paperdoll" as command button Clicking on the paper doll inventory subset window will cause the '*' command (#seeall) to execute. They convey the same information (unless multiple leashes or multiple light sources are in use; seeall lists all of them instead of just the first of each) but the doll shows the info with a small grid of map tiles and seeall shows it with an inventory display of worn and wielded items plus tools in active use. Ideally it should show information about a specific item as a "tool tip" when the mouse hovers over one of the doll slots. I don't know whether I'll ever attempt to tackle that or even if that's feasible with Qt. Perhaps use right click instead. --- doc/fixes37.0 | 7 +++++-- win/Qt/qt_inv.cpp | 19 ++++++++++++++++++- win/Qt/qt_inv.h | 3 +++ win/Qt/qt_main.cpp | 7 +++++++ win/Qt/qt_main.h | 3 ++- 5 files changed, 35 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b68978a00..378797cfe 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.321 $ $NHDT-Date: 1601940384 2020/10/05 23:26:24 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.322 $ $NHDT-Date: 1602002574 2020/10/06 16:42:54 $ General Fixes and Modified Features ----------------------------------- @@ -564,8 +564,11 @@ user_sounds: provide an experimental mechanism for terminal-side sounds similar act on it) Qt: the "paper doll" inventory subset can be controlled via the "Qt Settings" dialog box ("Preferences..." on OSX) -Qt: draw a border around each tile in the paper door inventory; when BUC is +Qt: draw a border around each tile in the paper doll inventory; when BUC is known for a doll item, change the border's color and thicken it +Qt: clicking on the paper doll runs the #seeall command (inventory of wielded + and worn items plus tools [lamps, leashes] actively in use; in other + words, same set of things whose tiles are used to populate the doll) NetHack Community Patches (or Variation) Included diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index f6cc6a92e..b6e408af6 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -20,6 +20,7 @@ extern "C" { #include "qt_post.h" #include "qt_inv.h" #include "qt_glyph.h" +#include "qt_main.h" #include "qt_set.h" namespace nethack_qt_ { @@ -52,12 +53,14 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, if (nhobj) { border = BORDER_DEFAULT; +#ifdef ENHANCED_PAPERDOLL if (Role_if('P') && !Blind) nhobj->bknown = 1; if (nhobj->bknown) border = nhobj->cursed ? BORDER_CURSED : !nhobj->blessed ? BORDER_UNCURSED : BORDER_BLESSED; +#endif glyph = obj_to_glyph(nhobj, rn2_on_display_rng); } else { border = NO_BORDER; @@ -153,7 +156,7 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const h = (1 + qt_settings->dollHeight + 1) * 6; } #else - if (iflags.wc_tiles_map) { + if (iflags.wc_tiled_map) { w = (1 + qt_settings->glyphs().width() + 1) * 3; h = (1 + qt_settings->glyphs().height() + 1) * 6; } @@ -164,4 +167,18 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const } } +// ENHANCED_PAPERDOLL - clicking on the PaperDoll runs #seeall +void NetHackQtInvUsageWindow::mousePressEvent(QMouseEvent *event UNUSED) +{ +#ifdef ENHANCED_PAPERDOLL + char cmdbuf[32]; + Strcpy(cmdbuf, "#"); + (void) cmdname_from_func(doprinuse, &cmdbuf[1], FALSE); + // queue up #seeall as if user had typed it; we don't execute doprinuse() + // directly because the program might not be ready for the next command + QWidget *main = NetHackQtBind::mainWidget(); + (static_cast (main))->DollClickToKeys(cmdbuf); +#endif +} + } // namespace nethack_qt_ diff --git a/win/Qt/qt_inv.h b/win/Qt/qt_inv.h index 4c74b8a6a..9c38128c5 100644 --- a/win/Qt/qt_inv.h +++ b/win/Qt/qt_inv.h @@ -16,6 +16,9 @@ public: virtual void paintEvent(QPaintEvent*); virtual QSize sizeHint(void) const; +protected: + virtual void mousePressEvent(QMouseEvent *event); + private: void drawWorn(QPainter& painter, obj*, int x, int y, bool canbe=true); }; diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index de4dff75c..6378f48e1 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -990,6 +990,13 @@ void NetHackQtMainWindow::doKeys(const QString& k) qApp->exit(); } +// ENHANCED_PAPERDOLL - player clicked on PaperDoll window +void NetHackQtMainWindow::DollClickToKeys(const char *cmds) +{ + keysink.Put(cmds); + qApp->exit(); +} + void NetHackQtMainWindow::AddMessageWindow(NetHackQtMessageWindow* window) { message=window; diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index fbec9fb63..b21c60cfc 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -49,8 +49,9 @@ public: void fadeHighlighting(bool before_key); - // this is unconditional in case qt_main.h comes before qt_set.h + // these are unconditional in case qt_main.h comes before qt_set.h void resizePaperDoll(bool); // ENHANCED_PAPERDOLL + void DollClickToKeys(const char *); // ENHANCED_PAPERDOLL public slots: void doMenuItem(QAction *); From da8558e26211d3b31a55ef30d8e45921b723e9b6 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 6 Oct 2020 15:20:25 -0700 Subject: [PATCH 291/708] Qt status panel as command button Clicking on the status panel runs ^X to show character and status information without abbreviations. The code needed is identical to what's now used for clicking on the paper doll inventory panel except for the command to execute. --- doc/fixes37.0 | 3 ++- win/Qt/qt_stat.cpp | 21 +++++++++++++++++---- win/Qt/qt_stat.h | 1 + 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 378797cfe..0246efc53 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.322 $ $NHDT-Date: 1602002574 2020/10/06 16:42:54 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ $NHDT-Date: 1602022805 2020/10/06 22:20:05 $ General Fixes and Modified Features ----------------------------------- @@ -569,6 +569,7 @@ Qt: draw a border around each tile in the paper doll inventory; when BUC is Qt: clicking on the paper doll runs the #seeall command (inventory of wielded and worn items plus tools [lamps, leashes] actively in use; in other words, same set of things whose tiles are used to populate the doll) +Qt: clicking on the status window runs the #attributes command (^X) NetHack Community Patches (or Variation) Included diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 7ba03c549..7da64cfc6 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -396,13 +396,13 @@ void NetHackQtStatusWindow::fadeHighlighting() * the other. So only do our update when we update the second line. * * Information on the first line: - * name, attributes, alignment, score + * name, Str/Dex/&c characteristics, alignment, score * * Information on the second line: * dlvl, gold, hp, power, ac, {level & exp or HD **} * status (hunger, encumbrance, sick, stun, conf, halu, blind), time * - * [**] HD is shown instead of level and exp if mtimedone is non-zero. + * [**] HD is shown instead of level and exp when hero is polymorphed. */ void NetHackQtStatusWindow::updateStats() { @@ -553,8 +553,7 @@ void NetHackQtStatusWindow::updateStats() score.setLabel(""); } - if (first_set) - { + if (first_set) { first_set=false; name.highlightWhenChanging(); @@ -604,4 +603,18 @@ void NetHackQtStatusWindow::checkTurnEvents() { } +// clicking on status window runs #attributes (^X) +void NetHackQtStatusWindow::mousePressEvent(QMouseEvent *event UNUSED) +{ + // same code as NetHackQtInvUsageWindow::mousePressEvent except for func + char cmdbuf[32]; + Strcpy(cmdbuf, "#"); + (void) cmdname_from_func(doattributes, &cmdbuf[1], FALSE); + // queue up #attribues as if user had typed it; we don't execute + // doattributes() directly because the program might not be ready + // for a command right now + QWidget *main = NetHackQtBind::mainWidget(); + (static_cast (main))->DollClickToKeys(cmdbuf); +} + } // namespace nethack_qt_ diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index 2b7382289..a8d27cb95 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -27,6 +27,7 @@ public: void fadeHighlighting(); protected: + virtual void mousePressEvent(QMouseEvent *event); //RLC void resizeEvent(QResizeEvent*); private slots: From eb4288e6085c48b00fae9d0369e52cfd9a8cf509 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 7 Oct 2020 04:19:55 -0700 Subject: [PATCH 292/708] Qt click-to-command Consolidate some recently added duplicated code. --- win/Qt/qt_inv.cpp | 9 ++------- win/Qt/qt_main.cpp | 19 +++++++++++++------ win/Qt/qt_main.h | 5 +++-- win/Qt/qt_stat.cpp | 9 +-------- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index b6e408af6..5379a33fa 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -167,17 +167,12 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const } } -// ENHANCED_PAPERDOLL - clicking on the PaperDoll runs #seeall +// ENHANCED_PAPERDOLL - clicking on the PaperDoll runs #seeall ('*') void NetHackQtInvUsageWindow::mousePressEvent(QMouseEvent *event UNUSED) { #ifdef ENHANCED_PAPERDOLL - char cmdbuf[32]; - Strcpy(cmdbuf, "#"); - (void) cmdname_from_func(doprinuse, &cmdbuf[1], FALSE); - // queue up #seeall as if user had typed it; we don't execute doprinuse() - // directly because the program might not be ready for the next command QWidget *main = NetHackQtBind::mainWidget(); - (static_cast (main))->DollClickToKeys(cmdbuf); + (static_cast (main))->FuncAsCommand(doprinuse); #endif } diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 6378f48e1..40276b195 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -982,19 +982,26 @@ void NetHackQtMainWindow::doGuidebook(bool) } #endif +void NetHackQtMainWindow::doKeys(const char *cmds) +{ + keysink.Put(cmds); + qApp->exit(); +} + void NetHackQtMainWindow::doKeys(const QString& k) { /* [this should probably be using toLocal8Bit(); toAscii() is not offered as an alternative...] */ - keysink.Put(k.toLatin1().constData()); - qApp->exit(); + doKeys(k.toLatin1().constData()); } -// ENHANCED_PAPERDOLL - player clicked on PaperDoll window -void NetHackQtMainWindow::DollClickToKeys(const char *cmds) +// queue up the command name for a function, as if user had typed it +void NetHackQtMainWindow::FuncAsCommand(int NDECL((*func))) { - keysink.Put(cmds); - qApp->exit(); + char cmdbuf[32]; + Strcpy(cmdbuf, "#"); + (void) cmdname_from_func(func, &cmdbuf[1], FALSE); + doKeys(cmdbuf); } void NetHackQtMainWindow::AddMessageWindow(NetHackQtMessageWindow* window) diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index b21c60cfc..17719fabb 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -49,9 +49,9 @@ public: void fadeHighlighting(bool before_key); - // these are unconditional in case qt_main.h comes before qt_set.h + void FuncAsCommand(int NDECL((*func))); + // this is unconditional in case qt_main.h comes before qt_set.h void resizePaperDoll(bool); // ENHANCED_PAPERDOLL - void DollClickToKeys(const char *); // ENHANCED_PAPERDOLL public slots: void doMenuItem(QAction *); @@ -59,6 +59,7 @@ public slots: void doAbout(bool); void doQuit(bool); //RLC void doGuidebook(bool); + void doKeys(const char *); void doKeys(const QString&); protected: diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 7da64cfc6..6d200fe10 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -606,15 +606,8 @@ void NetHackQtStatusWindow::checkTurnEvents() // clicking on status window runs #attributes (^X) void NetHackQtStatusWindow::mousePressEvent(QMouseEvent *event UNUSED) { - // same code as NetHackQtInvUsageWindow::mousePressEvent except for func - char cmdbuf[32]; - Strcpy(cmdbuf, "#"); - (void) cmdname_from_func(doattributes, &cmdbuf[1], FALSE); - // queue up #attribues as if user had typed it; we don't execute - // doattributes() directly because the program might not be ready - // for a command right now QWidget *main = NetHackQtBind::mainWidget(); - (static_cast (main))->DollClickToKeys(cmdbuf); + (static_cast (main))->FuncAsCommand(doattributes); } } // namespace nethack_qt_ From b0e71f68bc107aeb218df3726c05c5654958a34a Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 7 Oct 2020 09:09:51 -0400 Subject: [PATCH 293/708] small monsters seeping through their shirt The code is slightly different than in the PR which left out the noncorporeal case. Closes #397 --- doc/fixes37.0 | 1 + src/worn.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 0246efc53..6b92c5b02 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -270,6 +270,7 @@ make piranhas faster and give them extra bite attack fire sources can ignite candles, lamps, and potions of oil for multiple drop ('D') with menustyle traditional or combination, if the only object class player picked was '$' then it operated on all classes +small monsters could seep through their shirt Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/worn.c b/src/worn.c index de97f2b7f..24dfdd998 100644 --- a/src/worn.c +++ b/src/worn.c @@ -917,7 +917,8 @@ boolean polyspot; } if ((otmp = which_armor(mon, W_ARMU)) != 0) { if (vis) { - if (sliparm(mon->data)) + /* sliparm checks whirly, noncorporeal, and small or under */ + if (sliparm(mdat) && !(mdat->msize <= MZ_SMALL)) pline("%s seeps right through %s shirt!", Monnam(mon), ppronoun); else From 1b0a9f8e31be620c98634ebd62c580ae9ba0e255 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 7 Oct 2020 09:23:41 -0400 Subject: [PATCH 294/708] follow-up to previous --- src/worn.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/worn.c b/src/worn.c index 24dfdd998..ad52e2474 100644 --- a/src/worn.c +++ b/src/worn.c @@ -892,6 +892,9 @@ boolean polyspot; m_useup(mon, otmp); } } else if (sliparm(mdat)) { + /* sliparm checks whirly, noncorporeal, and small or under */ + boolean passes_thru_clothes = !(mdat->msize <= MZ_SMALL); + if ((otmp = which_armor(mon, W_ARM)) != 0) { if (vis) pline("%s armor falls around %s!", s_suffix(Monnam(mon)), @@ -917,8 +920,7 @@ boolean polyspot; } if ((otmp = which_armor(mon, W_ARMU)) != 0) { if (vis) { - /* sliparm checks whirly, noncorporeal, and small or under */ - if (sliparm(mdat) && !(mdat->msize <= MZ_SMALL)) + if (passes_thru_clothes) pline("%s seeps right through %s shirt!", Monnam(mon), ppronoun); else From 342323eb15cee143f6668373777834b27b9b9e48 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 8 Oct 2020 10:18:44 -0700 Subject: [PATCH 295/708] Qt menu hack Prevent a small inventory menu as the first one shown from forcing all subsequent ones from being the same short height by forcing it to have room for at least 15 lines. Temporary hack until someone figures out why resizing the reused WIN_INVEN isn't working. Does not affect non-inventory menus which get created on demand and destroyed when done so don't need to change size to fit different contents. --- win/Qt/qt_bind.cpp | 2 +- win/Qt/qt_menu.cpp | 50 +++++++++++++++++++++++++++++++++++++--------- win/Qt/qt_menu.h | 8 +++++--- win/Qt/qt_win.cpp | 3 ++- win/Qt/qt_win.h | 18 +++++++++-------- 5 files changed, 59 insertions(+), 22 deletions(-) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 821772eef..0e1f362a8 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -396,7 +396,7 @@ void NetHackQtBind::qt_display_file(const char *filename, BOOLEAN_P must_exist) void NetHackQtBind::qt_start_menu(winid wid, unsigned long mbehavior UNUSED) { NetHackQtWindow* window=id_to_window[(int)wid]; - window->StartMenu(); + window->StartMenu(wid == WIN_INVEN); } void NetHackQtBind::qt_add_menu(winid wid, int glyph, diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 07834f7c0..3a6062ee1 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -8,6 +8,13 @@ // TODO: // inventory menus reuse the same menu window over and over (in the core); // it isn't resizing properly to reflect each new instance's content; +// [temporary 'fix' allocates at least 15 lines in case a really short +// subset is displayed before a full inventory; but all inventory menus +// will be padded to that length when they might otherwise show all the +// entries with less, and inventories which have more will need to be +// scrolled to see the excess even if a taller menu would fit on the +// screen; code now has to distinguish between inventory menu and +// 'other' menu so that the latter isn't padded too] // implement next_page, prev_page, first_page, and last_page to work // like they do for X11: scroll menu window as if it were paginated; // entering a count that uses more digits than the previous biggest count @@ -67,22 +74,44 @@ int NetHackQtMenuListBox::TotalWidth() const int NetHackQtMenuListBox::TotalHeight() const { - int row, height = 0; + int row, rowheight, height = 0; for (row = 0; row < rowCount(); ++row) { height += rowHeight(row); } + // 20: arbitrary; should always have at least 1 row so it shouldn't matter + rowheight = (row > 0) ? rowHeight(row - 1) : 20; + + // + // FIXME: + // The core reuses one window for inventory displays and this + // part of sizeHint() is working for the initial size but is + // ineffective for later resizes. + // + + // TEMPORARY: + // in case first inventory menu displayed is a short one pad it + // with blank lines so later long ones won't be far too short + if ((dynamic_cast (parent()))->is_invent) { + if (row < 15) + height += (15 - row) * rowheight; + } + // include extra height so that there will be a blank gap after the // last entry to show that there is nothing to scroll forward too - height += (row > 0) ? (rowHeight(row - 1) / 2) : 7; + height += rowheight / 2; return height; } QSize NetHackQtMenuListBox::sizeHint() const { - QScrollBar *hscroll = horizontalScrollBar(); - int hsize = hscroll ? hscroll->height() : 0; - return QSize(TotalWidth()+hsize, TotalHeight()+hsize); + QScrollBar *hscroll = horizontalScrollBar(), + *vscroll = verticalScrollBar(); + int hsize = (hscroll && hscroll->isVisible()) ? hscroll->height() : 0, + vsize = (vscroll && vscroll->isVisible()) ? vscroll->width() : 0; + hsize += MENU_WIDTH_SLOP, vsize += MENU_WIDTH_SLOP; + // note: a vertical scrollbar affects widget width, a horizontal one height + return QSize(TotalWidth() + vsize, TotalHeight() + hsize); } // @@ -125,12 +154,13 @@ void NetHackQtMenuWindow::MenuResize() // NetHackQtMenuWindow::NetHackQtMenuWindow(QWidget *parent) : QDialog(parent), + is_invent(false), // reset to True when window is core's WIN_INVEN table(new NetHackQtMenuListBox()), prompt(0), biggestcount(0L), // largest subset amount that user has entered countdigits(0), // number of digits needed by biggestcount counting(false), // user has typed a digit and more might follow - searching(false) + searching(false) // user has begun entering a search target string { // setFont() was in SelectMenu(), in time to be rendered but too late // when measuring the width and height that will be needed @@ -198,7 +228,7 @@ QWidget* NetHackQtMenuWindow::Widget() { return this; } // can't rely on the MenuWindow constructor for initialization. // -void NetHackQtMenuWindow::StartMenu() +void NetHackQtMenuWindow::StartMenu(bool using_WIN_INVEN) { itemcount = 0; table->setRowCount(itemcount); @@ -208,6 +238,8 @@ void NetHackQtMenuWindow::StartMenu() countdigits = 0; ClearCount(); // reset 'counting' flag and digit string 'countstr' ClearSearch(); // reset 'searching' flag + + is_invent = using_WIN_INVEN; } NetHackQtMenuWindow::MenuItem::MenuItem() : @@ -1149,10 +1181,10 @@ void NetHackQtMenuOrTextWindow::PutStr(int attr, const QString& text) } // Menu -void NetHackQtMenuOrTextWindow::StartMenu() +void NetHackQtMenuOrTextWindow::StartMenu(bool using_WIN_INVEN) { if (!actual) actual=new NetHackQtMenuWindow(parent); - actual->StartMenu(); + actual->StartMenu(using_WIN_INVEN); } void NetHackQtMenuOrTextWindow::AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index 59720009e..b61a9305b 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -56,13 +56,15 @@ public: virtual QWidget* Widget(); - virtual void StartMenu(); + virtual void StartMenu(bool using_WIN_INVEN = false); virtual void AddMenu(int glyph, const ANY_P *identifier, char ch, char gch, int attr, const QString& str, unsigned itemflags); virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); + bool is_invent; // using core's WIN_INVEN + public slots: void All(); void ChooseNone(); @@ -169,7 +171,7 @@ private: class NetHackQtMenuOrTextWindow : public NetHackQtWindow { private: NetHackQtWindow* actual; - QWidget *parent; + QWidget *parent; public: NetHackQtMenuOrTextWindow(QWidget *parent = NULL); @@ -183,7 +185,7 @@ public: virtual void PutStr(int attr, const QString& text); // Menu - virtual void StartMenu(); + virtual void StartMenu(bool using_WIN_INVENT = false); virtual void AddMenu(int glyph, const ANY_P *identifier, char ch, char gch, int attr, const QString& str, unsigned itemflags); diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 12d101496..3fd51edf9 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -99,7 +99,8 @@ void NetHackQtWindow::Display(bool block UNUSED) { puts("unexpected Display"); } bool NetHackQtWindow::Destroy() { return true; } void NetHackQtWindow::CursorTo(int x UNUSED,int y UNUSED) { puts("unexpected CursorTo"); } void NetHackQtWindow::PutStr(int attr UNUSED, const QString& text UNUSED) { puts("unexpected PutStr"); } -void NetHackQtWindow::StartMenu() { puts("unexpected StartMenu"); } +void NetHackQtWindow::StartMenu(bool using_WIN_INVEN UNUSED) + { puts("unexpected StartMenu"); } void NetHackQtWindow::AddMenu(int glyph UNUSED, const ANY_P* identifier UNUSED, char ch UNUSED, char gch UNUSED, int attr UNUSED, const QString& str UNUSED, unsigned itemflags UNUSED) diff --git a/win/Qt/qt_win.h b/win/Qt/qt_win.h index 486bf4ec6..daa6e0d1d 100644 --- a/win/Qt/qt_win.h +++ b/win/Qt/qt_win.h @@ -2,8 +2,9 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// Qt Binding for NetHack 3.4 +// Qt Binding for NetHack 3.7 // +// [original comment from Warwick] // Unfortunately, this doesn't use Qt as well as I would like, // primarily because NetHack is fundamentally a getkey-type // program rather than being event driven (hence the ugly key @@ -21,24 +22,25 @@ public: NetHackQtWindow(); virtual ~NetHackQtWindow(); - virtual QWidget* Widget() =0; + virtual QWidget* Widget() = 0; virtual void Clear(); virtual void Display(bool block); virtual bool Destroy(); - virtual void CursorTo(int x,int y); + virtual void CursorTo(int x, int y); virtual void PutStr(int attr, const QString& text); void PutStr(int attr, const char *text) { PutStr(attr, QString::fromUtf8(text).replace(QChar(0x200B), "")); } - virtual void StartMenu(); - virtual void AddMenu(int glyph, const ANY_P* identifier, char ch, char gch, int attr, - const QString& str, unsigned itemflags); + virtual void StartMenu(bool using_WIN_INVEN = false); + virtual void AddMenu(int glyph, const ANY_P* identifier, + char ch, char gch, int attr, + const QString& str, unsigned itemflags); virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); - virtual void ClipAround(int x,int y); - virtual void PrintGlyph(int x,int y,int glyph); + virtual void ClipAround(int x, int y); + virtual void PrintGlyph(int x, int y, int glyph); virtual void UseRIP(int how, time_t when); int nhid; From 5dcc328759e5cefbeb99f20657979d6fde04bd94 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 8 Oct 2020 13:49:24 -0400 Subject: [PATCH 296/708] be more consistent with CROSS_TO_target macro names for cross-compiles -DCROSS_TO_MSDOS msdos cross-compile (djgpp cross-compiler) -DCROSS_TO_AMIGA Amiga cross-compile -DCROSS_TO_WASM wasm cross-compile (emscripten) --- include/extern.h | 2 +- include/pcconf.h | 6 +++--- outdated/include/amiconf.h | 8 ++++---- outdated/sys/amiga/amidos.c | 2 +- outdated/sys/amiga/amigst.c | 2 +- outdated/sys/amiga/amiwind.c | 6 +++--- outdated/sys/amiga/winamenu.c | 2 +- outdated/sys/amiga/winami.c | 4 ++-- outdated/sys/amiga/winchar.c | 4 ++-- outdated/sys/amiga/winfuncs.c | 6 +++--- outdated/sys/amiga/winkey.c | 2 +- outdated/sys/amiga/winreq.c | 6 +++--- outdated/sys/amiga/winstr.c | 2 +- sys/share/pcmain.c | 2 +- sys/share/pcsys.c | 6 +++--- sys/unix/hints/include/cross-pre.2020 | 8 ++++---- 16 files changed, 34 insertions(+), 34 deletions(-) diff --git a/include/extern.h b/include/extern.h index 0689c4d9f..52b28f616 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2150,7 +2150,7 @@ E void NDECL(deliver_splev_message); /* ### random.c ### */ #if defined(RANDOM) && !defined(__GO32__) /* djgpp has its own random */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA E void FDECL(srandom, (unsigned)); E char *FDECL(initstate, (unsigned, char *, int)); E char *FDECL(setstate, (char *)); diff --git a/include/pcconf.h b/include/pcconf.h index 86ce2efe7..5e0445eba 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -35,7 +35,7 @@ /*#define OVERLAY */ /* Manual overlay definition (MSC 6.0ax only) */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #define SHELL /* via exec of COMMAND.COM */ #endif @@ -90,7 +90,7 @@ #define ANSI_DEFAULT #endif -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #define RANDOM /* have Berkeley random(3) */ #endif @@ -105,7 +105,7 @@ #include /* Provides prototypes of exit(), spawn() */ #endif -#ifdef AMIGA_CROSS +#ifdef CROSS_TO_AMIGA #include #endif diff --git a/outdated/include/amiconf.h b/outdated/include/amiconf.h index 5215515d8..477c9248a 100644 --- a/outdated/include/amiconf.h +++ b/outdated/include/amiconf.h @@ -14,7 +14,7 @@ #include /* get time_t defined before use! */ -#ifdef AMIGA_CROSS +#ifdef CROSS_TO_AMIGA #include #include #endif @@ -56,7 +56,7 @@ typedef long off_t; #define DLBFILE2 "nhsdat" /* sound library */ #endif -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #define FILENAME_CMP stricmp /* case insensitive */ #else #define FILENAME_CMP strcmpi /* case insensitive */ @@ -76,7 +76,7 @@ typedef long off_t; #define MFLOPPY /* You'll probably want this; provides assistance \ * for typical personal computer configurations \ */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #define RANDOM #endif @@ -149,7 +149,7 @@ extern char *FDECL(gets, (char *)); #define TEXTCOLOR /* Use colored monsters and objects */ #define HACKFONT /* Use special hack.font */ -#ifndef AMIGA_CROSS /* issues with prototype and spawnl */ +#ifndef CROSS_TO_AMIGA /* issues with prototype and spawnl */ #define SHELL /* Have a shell escape command (!) */ #endif #define MAIL /* Get mail at unexpected occasions */ diff --git a/outdated/sys/amiga/amidos.c b/outdated/sys/amiga/amidos.c index 4f2413008..402e29535 100644 --- a/outdated/sys/amiga/amidos.c +++ b/outdated/sys/amiga/amidos.c @@ -29,7 +29,7 @@ #endif /* Prototypes */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/amiwind.p" #include "NH:sys/amiga/winami.p" #include "NH:sys/amiga/amidos.p" diff --git a/outdated/sys/amiga/amigst.c b/outdated/sys/amiga/amigst.c index 64cdc2f0e..8f6a74f64 100644 --- a/outdated/sys/amiga/amigst.c +++ b/outdated/sys/amiga/amigst.c @@ -36,7 +36,7 @@ #include #endif -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/winami.p" #include "NH:sys/amiga/amiwind.p" #include "NH:sys/amiga/amidos.p" diff --git a/outdated/sys/amiga/amiwind.c b/outdated/sys/amiga/amiwind.c index 9654fb5d9..456b727c9 100644 --- a/outdated/sys/amiga/amiwind.c +++ b/outdated/sys/amiga/amiwind.c @@ -3,7 +3,7 @@ /* Copyright (c) Kenneth Lorber, Bethesda, Maryland 1993,1996 */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" @@ -26,7 +26,7 @@ static int BufferGetchar(void); static void ProcessMessage(register struct IntuiMessage *message); #define BufferQueueChar(ch) (KbdBuffer[KbdBuffered++] = (ch)) -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA struct Library *ConsoleDevice; #else struct Device * @@ -36,7 +36,7 @@ struct Device * ConsoleDevice; #endif -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/amimenu.c" #else #include "amimenu.c" diff --git a/outdated/sys/amiga/winamenu.c b/outdated/sys/amiga/winamenu.c index cf1d75376..4762bc8a4 100644 --- a/outdated/sys/amiga/winamenu.c +++ b/outdated/sys/amiga/winamenu.c @@ -3,7 +3,7 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" diff --git a/outdated/sys/amiga/winami.c b/outdated/sys/amiga/winami.c index 0a9bd2951..3e743fb38 100644 --- a/outdated/sys/amiga/winami.c +++ b/outdated/sys/amiga/winami.c @@ -3,7 +3,7 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" @@ -15,7 +15,7 @@ #include "dlb.h" -#ifdef AMIGA_CROSS +#ifdef CROSS_TO_AMIGA #define strnicmp strncmpi #endif diff --git a/outdated/sys/amiga/winchar.c b/outdated/sys/amiga/winchar.c index 020b721ed..9fb0508dc 100644 --- a/outdated/sys/amiga/winchar.c +++ b/outdated/sys/amiga/winchar.c @@ -14,14 +14,14 @@ #ifdef TESTING #include "hack.h" #else -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:src/tile.c" #else #include "../src/tile.c" #endif #endif -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:win/share/tile.h" #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" diff --git a/outdated/sys/amiga/winfuncs.c b/outdated/sys/amiga/winfuncs.c index 130d66cc9..dfbae4312 100644 --- a/outdated/sys/amiga/winfuncs.c +++ b/outdated/sys/amiga/winfuncs.c @@ -3,7 +3,7 @@ */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" @@ -17,7 +17,7 @@ #include "date.h" extern struct TagItem scrntags[]; -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA extern struct Library *ConsoleDevice; #else extern struct Device * @@ -792,7 +792,7 @@ amii_create_nhwindow(type) register int type; } ConsoleDevice = -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA (struct Library *) #else (struct Device * diff --git a/outdated/sys/amiga/winkey.c b/outdated/sys/amiga/winkey.c index 0964f0574..9534c0c6d 100644 --- a/outdated/sys/amiga/winkey.c +++ b/outdated/sys/amiga/winkey.c @@ -2,7 +2,7 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" diff --git a/outdated/sys/amiga/winreq.c b/outdated/sys/amiga/winreq.c index fecf2b4ce..af4c303de 100644 --- a/outdated/sys/amiga/winreq.c +++ b/outdated/sys/amiga/winreq.c @@ -2,7 +2,7 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" @@ -45,7 +45,7 @@ struct NewWindow StrWindow = { &String, NULL, NULL, NULL, NULL, 5, 5, 0xffff, 0xffff, CUSTOMSCREEN }; -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/colorwin.c" #else #include "colorwin.c" @@ -58,7 +58,7 @@ struct NewWindow StrWindow = { #define GADOKAY 6 #define GADCANCEL 7 -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/clipwin.c" #else #include "clipwin.c" diff --git a/outdated/sys/amiga/winstr.c b/outdated/sys/amiga/winstr.c index d74e566a0..cbca9ba4b 100644 --- a/outdated/sys/amiga/winstr.c +++ b/outdated/sys/amiga/winstr.c @@ -2,7 +2,7 @@ /* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993. */ /* NetHack may be freely redistributed. See license for details. */ -#ifndef AMIGA_CROSS +#ifndef CROSS_TO_AMIGA #include "NH:sys/amiga/windefs.h" #include "NH:sys/amiga/winext.h" #include "NH:sys/amiga/winproto.h" diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 633c1f13a..2367c84ea 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -754,7 +754,7 @@ char *str; } #endif /* EXEPATH */ -#ifdef AMIGA_CROSS +#ifdef CROSS_TO_AMIGA void msmsg VA_DECL(const char *, fmt) { diff --git a/sys/share/pcsys.c b/sys/share/pcsys.c index c027827c4..af30e4423 100644 --- a/sys/share/pcsys.c +++ b/sys/share/pcsys.c @@ -12,10 +12,10 @@ #include #include -#if !defined(MSDOS) && !defined(WIN_CE) && !defined(AMIGA_CROSS) +#if !defined(MSDOS) && !defined(WIN_CE) && !defined(CROSS_TO_AMIGA) #include #endif -#if defined(__GO32__) || defined(AMIGA_CROSS) +#if defined(__GO32__) || defined(CROSS_TO_AMIGA) #define P_WAIT 0 #define P_NOWAIT 1 #endif @@ -154,7 +154,7 @@ const char *str; #ifdef TOS msmsg("Hit %s.", str); #else -#ifdef AMIGA_CROSS +#ifdef CROSS_TO_AMIGA (void) printf("Hit %s.", str); #else msmsg("Hit %s.", str); diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index c9bc0a51f..ec87da241 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -163,7 +163,7 @@ override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar override TARGET_STUBEDIT = ../lib/djgpp/i586-pc-msdosdjgpp/bin/stubedit override TARGET_CFLAGS = -c -O -I../include -I../sys/msdos -I../win/share \ $(LUAINCL) -DDLB $(PDCURSESDEF) \ - -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET + -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_MSDOS override TARGET_CXXFLAGS = $(TARGET_CFLAGS) override TARGET_LINK = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc override TARGET_LFLAGS= @@ -235,9 +235,9 @@ override TARGET_STUBEDIT= override TARGET_CFLAGS = -c -O $(TOOLARCH) \ -I../include -I../outdated/include \ -I../outdated/sys/amiga -I../win/share \ - $(LUAINCL) -DAMIGA -DAMIGA_CROSS $(PDCURSESDEF) \ - -DUSE_TILES -DCROSSCOMPILE -DCROSSCOMPILE_TARGET \ - -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0 \(12.13.2020)\"" + $(LUAINCL) -DAMIGA -DUSE_TILES $(PDCURSESDEF) \ + -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_AMIGA \ + -DAMIGA_VERSION_STRING=\""VER: NetHack 3.7.0\"" override TARGET_CXXFLAGS = $(TARGET_CFLAGS) ifeq "$(REGEXOBJ)" "$(TARGETPFX)cppregex.o" override TARGET_LINK = $(TARGET_CXX) From dde561810d6fef8751f1794753dff889c0def3d3 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 8 Oct 2020 11:24:11 -0700 Subject: [PATCH 297/708] Qt prompt highlighting When qt_yn_function() or qt_more() is asking for a single character response, typing anything will cause the prompt line in the message window to stop being highlighted. If they reject what's been typed, they beep (--More-- doesn't start beeping until second rejection); change both of them to also rehighlight the prompt line to give a visual indication that the question/acknowledgement is still being asked. --- win/Qt/qt_bind.cpp | 12 ++++++++++++ win/Qt/qt_msg.cpp | 8 ++++++++ win/Qt/qt_msg.h | 1 + 3 files changed, 21 insertions(+) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 0e1f362a8..5fb65f980 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -588,6 +588,11 @@ char NetHackQtBind::qt_more() default: if (++complain > 1) NetHackQtBind::qt_nhbell(); + // typing anything caused the most recent message line + // (which happens to our prompt) from having highlighting + // be removed; put that back + if (mesgwin) + mesgwin->RehighlightPrompt(); retry = true; break; } @@ -669,6 +674,13 @@ char NetHackQtBind::qt_yn_function(const char *question_, Strcpy(cbuf, visctrl(def)); } 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 + NetHackQtMessageWindow + *mesgwin = main ? main->GetMessageWindow() : NULL; + if (mesgwin) + mesgwin->RehighlightPrompt(); // and try again... } } else { diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index bdd8f535c..c9c3537b8 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -184,6 +184,14 @@ void NetHackQtMessageWindow::AddToStr(const char *answer) } } +// used when yn_function() or more() rejects player's input and tries again +void NetHackQtMessageWindow::RehighlightPrompt() +{ + // selects most recent message, which causes it to be highlighted + if (list && list->count()) + list->setCurrentRow(list->count() - 1); +} + // are there any highlighted messages? bool NetHackQtMessageWindow::hilit_mesgs() { diff --git a/win/Qt/qt_msg.h b/win/Qt/qt_msg.h index c3cd4275c..ca84acaf5 100644 --- a/win/Qt/qt_msg.h +++ b/win/Qt/qt_msg.h @@ -30,6 +30,7 @@ public: void setMap(NetHackQtMapWindow2*); + void RehighlightPrompt(); bool hilit_mesgs(); void unhighlight_mesgs(); // for adding the answer for yn() to its prompt string From de80dd2437abcbf3bd8c890e8acf4ed49bf23494 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 9 Oct 2020 08:52:46 -0400 Subject: [PATCH 298/708] cross-compile fix-up --- sys/unix/Makefile.src | 3 ++- util/makedefs.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 2e4be5114..51b7e06c8 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -572,7 +572,8 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h dgn_file.h # the following .o's _must_ be made before any others (for makedefs) -HOSTOBJ = monst.o objects.o alloc.o drawing.o +FIRSTOBJ = monst.o objects.o +HOSTOBJ = $(FIRSTOBJ) alloc.o drawing.o HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)apply.o $(TARGETPFX)artifact.o $(TARGETPFX)attrib.o \ diff --git a/util/makedefs.c b/util/makedefs.c index 24c45d676..f8636c893 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1296,7 +1296,9 @@ do_date() Fprintf(ofp, "#define NETHACK_%sGIT_BRANCH \"%s\"\n", xpref, gitbranch); } +#if !defined(CROSSCOMPILE) || !defined(CROSSCOMPILE_TARGET) Fprintf(ofp, "#endif /* !CROSSCOMPILE || !CROSSCOMPILE_TARGET */\n"); +#endif Fprintf(ofp, "\n"); #ifdef AMIGA { From a09a41f9a34de818db1c093c936a30497916a90d Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 9 Oct 2020 08:54:36 -0400 Subject: [PATCH 299/708] more wasm build This issue https://github.com/NetHack/NetHack/issues/398 reported some issues with the wasm build. Attempt to resolve some of those. --- sys/unix/hints/include/cross-post.2020 | 6 +++-- sys/unix/hints/include/cross-pre.2020 | 37 +++++++++++++++++++------- 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 1822dbd12..de41a6628 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -120,7 +120,7 @@ amigapkg: $(GAMEBIN) $(TARGETPFX)recover.exe ../dat/nhtiles.bmp endif # CROSS_TO_AMIGA ifdef CROSS_TO_WASM -$(WASM_TARGET): pregame $(HOBJ) $(LUACROSSLIB) $(WASM_DATA_DIR) +$(WASM_TARGET): pregame $(HOSTOBJ) $(HOBJ) $(LUACROSSLIB) $(WASM_DATA_DIR) -rm $@ $(TARGET_CC) $(TARGET_LFLAGS) $(TARGET_CFLAGS) -o $@ \ $(HOBJ) $(TARGET_LIBS) @@ -132,7 +132,7 @@ $(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat touch $(WASM_DATA_DIR)/xlogfile cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf -$(WASM_DATA_DIR)/nhdat: +$(WASM_DATA_DIR)/nhdat: $(WASM_VARDAT) ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dlb ) ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dofiles-dlb ) @@ -143,6 +143,8 @@ $(TARGETPFX)unixunix.o : ../sys/unix/unixunix.c $(HACK_H) $(TARGETPFX)ioctl.o : ../sys/share/ioctl.c $(HACK_H) $(TARGETPFX)unixtty.o : ../sys/share/unixtty.c $(HACK_H) $(TARGETPFX)winshim.o : ../win/shim/winshim.c $(HACK_H) +$(TARGETPFX)libnethackmain.o : ../sys/lib/libnethackmain.c \ + $(HACK_H) ../include/date.h endif # CROSS_TO_WASM # diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index ec87da241..fd279b4ee 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -338,11 +338,30 @@ endif override TARGET_CC = emcc override TARGET_CXX = emcc override TARGET_AR = emar -override TARGET_CFLAGS = $(EMCC_CFLAGS) \ - -I../include \ - $(LUAINCL) -DDLB $(PDCURSESDEF) \ - -DNOTTYGRAPHICS -DSHIM_GRAPHICS -DDEFAULT_WINDOW_SYS=\"shim\" \ - -DCROSSCOMPILE -DCROSSCOMPILE_TARGET -DCROSS_TO_WASM -DLIBNH +WASM_CFLAGS = -Wall -Wextra -Wno-missing-field-initializers +WASM_CFLAGS += -Wimplicit -Wreturn-type -Wunused -Wformat -Wswitch +WASM_CFLAGS += -Wshadow +# WASM_CFLAGS += -Wwrite-strings +# WASM_CFLAGS += -Werror +# Nethack C flags +WASM_CFLAGS += $(WINCFLAGS) #WINCFLAGS set from multiw-2.2020 +WASM_CFLAGS += -DSYSCF -DSYSCF_FILE=\"/sysconf\" -DSECURE +WASM_CFLAGS += -g -I../include -DNOTPARMDECL +WASM_CFLAGS += -DGCC_WARN +# NetHack sources control +WASM_CFLAGS += -DDLB +WASM_CFLAGS += -DHACKDIR=\"$(HACKDIR)\" +WASM_CFLAGS += -DDEFAULT_WINDOW_SYS=\"shim\" \ +#override TARGET_CFLAGS += -DGREPPATH=\"/usr/bin/grep\" +WASM_CFLAGS += -DNOMAIL +WASM_CFLAGS += $(LUAINCL) +WASM_CFLAGS += -DNOTTYGRAPHICS -DSHIM_GRAPHICS -DLIBNH +WASM_CFLAGS += -DCROSSCOMPILE +WASM_TARGET_CFLAGS = -DCROSSCOMPILE_TARGET -DCROSS_TO_WASM +# For src Makefile +override CFLAGS = $(WASM_CFLAGS) +override TARGET_CFLAGS = $(EMCC_CFLAGS) $(WASM_CFLAGS) $(WASM_TARGET_CFLAGS) +# override TARGET_CXXFLAGS = $(TARGET_CFLAGS) override TARGET_LINK = $(TARGET_CC) override TARGET_LFLAGS= $(EMCC_LFLAGS) @@ -358,11 +377,11 @@ override WINLIB = emranlib override LUALIB= override REGEXOBJ = $(TARGETPFX)posixregex.o override WINOBJ= -#override INSTDIR = $(WASM_DATA_DIR) -#override PACKAGE= wasmpkg -#override MOREALL = ( cd src ; $(MAKE) $(WASM_TARGET) ) +# don't bother Making regular NetHack executable override GAME= -override ALLDEP = wasm +# the real VARDAT hasn't been defined yet for use in ALLDEP override +WASM_DAT = bogusmon data engrave epitaph oracles options quest.lua rumors +override ALLDEP = include/nhlua.h $(WASM_DAT) wasm spec_levs check-dlb override PREGAME += mkdir -p $(TARGETDIR)/wasm-data ; override CLEANMORE += rm -rf $(TARGETDIR) ; RANLIB=$(EMRANLIB) From 139b138b78238ca63b2f6c4a538a9b5f0da9b3be Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 9 Oct 2020 09:05:56 -0400 Subject: [PATCH 300/708] follow-up bit make variable had changed in PRE but not in POST --- sys/unix/hints/include/cross-post.2020 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index de41a6628..f36c11bf2 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -132,7 +132,7 @@ $(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat touch $(WASM_DATA_DIR)/xlogfile cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf -$(WASM_DATA_DIR)/nhdat: $(WASM_VARDAT) +$(WASM_DATA_DIR)/nhdat: $(WASM_DAT) ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dlb ) ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dofiles-dlb ) From 3e399848771d4d525b81ab57c4905d9ba3580f6c Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 9 Oct 2020 09:18:51 -0400 Subject: [PATCH 301/708] more wasm dependency order tinkering --- sys/unix/hints/include/cross-post.2020 | 2 +- sys/unix/hints/include/cross-pre.2020 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index f36c11bf2..f7fda70ab 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -132,7 +132,7 @@ $(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat touch $(WASM_DATA_DIR)/xlogfile cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf -$(WASM_DATA_DIR)/nhdat: $(WASM_DAT) +$(WASM_DATA_DIR)/nhdat: ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dlb ) ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dofiles-dlb ) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index fd279b4ee..05f1b15a5 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -381,7 +381,7 @@ override WINOBJ= override GAME= # the real VARDAT hasn't been defined yet for use in ALLDEP override WASM_DAT = bogusmon data engrave epitaph oracles options quest.lua rumors -override ALLDEP = include/nhlua.h $(WASM_DAT) wasm spec_levs check-dlb +override ALLDEP = include/nhlua.h $(WASM_DAT) spec_levs check-dlb wasm override PREGAME += mkdir -p $(TARGETDIR)/wasm-data ; override CLEANMORE += rm -rf $(TARGETDIR) ; RANLIB=$(EMRANLIB) From 017448addf23224ac1cf19ab61466c41c2f330de Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 9 Oct 2020 09:36:55 -0400 Subject: [PATCH 302/708] re-enable the MSDOS cross-compile on travis-ci --- .travis.yml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 51de236a7..0b1e388a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -136,21 +136,21 @@ matrix: - cd src - cp ../sys/winnt/Makefile.gcc ./Makefile - mingw32-make LUA_VERSION=$LUA_VERSION install -# - name: msdos-linux-focal-djgpp-crosscompile -# os: linux -# env: HINTS=linux.2020 LUA_VERSION=5.4.0 -# dist: focal -# compiler: gcc -# script: -## - export -## - export GCCVER=gcc550 -# - export GCCVER=gcc1010 -# - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ -# - make fetch-lua -# - test -d "lib/lua-$LUA_VERSION/src" || exit 0 -# - sh sys/msdos/fetch-cross-compiler.sh -# - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all -# - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package + - name: msdos-linux-focal-djgpp-crosscompile + os: linux + env: HINTS=linux.2020 LUA_VERSION=5.4.0 + dist: focal + compiler: gcc + script: +# - export +# - export GCCVER=gcc550 + - export GCCVER=gcc1010 + - cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ + - make fetch-lua + - test -d "lib/lua-$LUA_VERSION/src" || exit 0 + - sh sys/msdos/fetch-cross-compiler.sh + - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all + - make LUA_VERSION=$LUA_VERSION WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package exclude: # - os: osx # osx_image: xcode10.3 From d20394c4bc96aebce86d87e5cc59bbb1e85b348f Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 9 Oct 2020 08:45:03 -0700 Subject: [PATCH 303/708] unix/Makefile.utl Replace use of $(LINK) with $(CLINK) or $(CXXLINK) as warranted. When the Qt interface is enabled, the utility programs were all (except dlb) being linked with C++ support. That didn't cause any problems, just looked wrong. Link them as C instead of C++. Two actually do need C++ support (and still have it) but both are dead: 'tile2beos' because the source file doesn't exist (not even in 'outdated'), 'tileedit' because it won't build with Qt5. I didn't bother with QUIETCC support for them. There were still a couple of references to dgn_comp (for the lint target; just in the name of a macro, not its value); remove those. --- sys/unix/Makefile.utl | 48 +++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 751395c7a..a2530e49e 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -1,5 +1,5 @@ # Makefile for NetHack's utility programs. -# NetHack 3.7 Makefile.utl $NHDT-Date: 1596498292 2020/08/03 23:44:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.51 $ +# NetHack 3.7 Makefile.utl $NHDT-Date: 1602258295 2020/10/09 15:44:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.53 $ # Copyright (c) 2018 by Robert Patrick Rankin # NetHack may be freely redistributed. See license for details. @@ -120,6 +120,10 @@ QUIETCC=0 # in Makefile.src; these use '$(CC) $(LFLAGS)' and ought to be changed to use # $(LD) or $(LINK) as appropriate [quiet mode echoes a misleading $< value] +# [LINK might be defined to use $(CXX); we don't want that here.] +CLINK=$(CC) +CXXLINK=$(CXX) + # ---------------------------------------- # # Nothing below this line should have to be changed. @@ -131,7 +135,7 @@ QUIETCC=0 ACTUAL_CC := $(CC) ACTUAL_CXX := $(CXX) ACTUAL_LD := $(LD) -ACTUAL_LINK := $(LINK) +ACTUAL_CLINK := $(CLINK) CC_V0 = $(ACTUAL_CC) CC_V = $(CC_V0) @@ -146,7 +150,7 @@ CXX = $(CXX_V$(QUIETCC)) # LD and LINK might be based on invoking CC and may not be able to substitute # for QUIETCC, so feedback from them is handled differently (via $AT) LD = $(ACTUAL_LD) -LINK = $(ACTUAL_LINK) +CLINK = $(ACTUAL_CLINK) AT_V0 := AT_V := $(AT_V0) @@ -162,7 +166,7 @@ HACK_H = ../src/hack.h-t MAKESRC = makedefs.c ../src/mdlib.c RECOVSRC = recover.c DLBSRC = dlb_main.c -UTILSRCS = $(MAKESRC) panic.c $(DGNCOMPSRC) $(RECOVSRC) $(DLBSRC) +UTILSRCS = $(MAKESRC) panic.c $(RECOVSRC) $(DLBSRC) # files that define all monsters and objects CMONOBJ = ../src/monst.c ../src/objects.c @@ -192,7 +196,7 @@ DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) TARGETPFX= TARGET_CC = $(CC) TARGET_CFLAGS = $(CFLAGS) -TARGET_LINK = $(LINK) +TARGET_CLINK = $(CLINK) TARGET_LFLAGS = $(LFLAGS) TARGET_CXX = $(CXX) TARGET_CXXFLAGS = $(CXXFLAGS) @@ -200,7 +204,7 @@ TARGET_CXXFLAGS = $(CXXFLAGS) # dependencies for makedefs # makedefs: $(MAKEOBJS) mdgrep.h - $(LINK) $(LFLAGS) -o makedefs $(MAKEOBJS) + $(CLINK) $(LFLAGS) -o makedefs $(MAKEOBJS) makedefs.o: makedefs.c ../src/mdlib.c $(CONFIG_H) ../include/permonst.h \ ../include/objclass.h ../include/monsym.h \ @@ -239,13 +243,14 @@ panic.o: panic.c $(CONFIG_H) # with all of extern.h's functions to complain about, we drown in # 'defined but not used' without -u lintdgn: - @lint -axhu -I../include -DLINT $(DGNCOMPSRC) $(CALLOC) | sed '/_flsbuf/d' + @lint -axhu -I../include -DLINT $(UTILSRCS) $(CALLOC) \ + | sed '/_flsbuf/d' # dependencies for recover # recover: $(RECOVOBJS) - $(LINK) $(LFLAGS) -o recover $(RECOVOBJS) $(LIBS) + $(CLINK) $(LFLAGS) -o recover $(RECOVOBJS) $(LIBS) recover.o: recover.c $(CONFIG_H) ../include/date.h @@ -253,7 +258,7 @@ recover.o: recover.c $(CONFIG_H) ../include/date.h # dependencies for dlb # dlb: $(DLBOBJS) - $(CC) $(LFLAGS) -o dlb $(DLBOBJS) $(LIBS) + $(CLINK) $(LFLAGS) -o dlb $(DLBOBJS) $(LIBS) dlb_main.o: dlb_main.c $(CONFIG_H) ../include/dlb.h ../include/date.h $(CC) $(CFLAGS) -c dlb_main.c -o $@ @@ -268,24 +273,25 @@ PPMWRITERS = ppmwrite.o tileutils: tilemap gif2txt txt2ppm tile2x11 gif2txt: $(GIFREADERS) $(TEXT_IO) - $(LINK) $(LFLAGS) -o gif2txt $(GIFREADERS) $(TEXT_IO) $(LIBS) + $(CLINK) $(LFLAGS) -o gif2txt $(GIFREADERS) $(TEXT_IO) $(LIBS) txt2ppm: $(PPMWRITERS) $(TEXT_IO) - $(LINK) $(LFLAGS) -o txt2ppm $(PPMWRITERS) $(TEXT_IO) $(LIBS) + $(CLINK) $(LFLAGS) -o txt2ppm $(PPMWRITERS) $(TEXT_IO) $(LIBS) tile2x11: tile2x11.o $(TEXT_IO) - $(LINK) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) $(LIBS) + $(CLINK) $(LFLAGS) -o tile2x11 tile2x11.o $(TEXT_IO) $(LIBS) tile2img.ttp: tile2img.o bitmfile.o $(TEXT_IO) - $(LINK) $(LFLAGS) -o tile2img.ttp tile2img.o bitmfile.o $(TEXT_IO) $(LIBS) + $(CLINK) $(LFLAGS) -o tile2img.ttp tile2img.o bitmfile.o \ + $(TEXT_IO) $(LIBS) tile2bmp: tile2bmp.o $(TEXT_IO) - $(LINK) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO) + $(CLINK) $(LFLAGS) -o tile2bmp tile2bmp.o $(TEXT_IO) xpm2img.ttp: xpm2img.o bitmfile.o - $(LINK) $(LFLAGS) -o xpm2img.ttp xpm2img.o bitmfile.o $(LIBS) + $(CLINK) $(LFLAGS) -o xpm2img.ttp xpm2img.o bitmfile.o $(LIBS) tile2beos: tile2beos.o $(TEXT_IO) - $(LINK) $(LFLAGS) -o tile2beos tile2beos.o $(TEXT_IO) -lbe + $(CXXLINK) $(LFLAGS) -o tile2beos tile2beos.o $(TEXT_IO) -lbe #--compiling and linking in one step leaves extra debugging files (in their # own subdirectories!) on OSX; compile and link separately to suppress @@ -293,7 +299,7 @@ tile2beos: tile2beos.o $(TEXT_IO) #tilemap: ../win/share/tilemap.c $(HACK_H) # $(CC) $(CFLAGS) $(LFLAGS) -o tilemap ../win/share/tilemap.c $(LIBS) tilemap: tilemap.o - $(LINK) $(LFLAGS) -o tilemap tilemap.o $(LIBS) + $(CLINK) $(LFLAGS) -o tilemap tilemap.o $(LIBS) ../src/tile.c: tilemap ./tilemap @@ -336,10 +342,12 @@ bitmfile.o: ../win/gem/bitmfile.c ../include/bitmfile.h tile2beos.o: ../win/BeOS/tile2beos.cpp $(HACK_H) ../include/tile.h $(CXX) $(CFLAGS) -c ../win/BeOS/tile2beos.cpp -o $@ -tileedit: tileedit.cpp $(TEXT_IO) +# note: tileedit.cpp was developed for Qt2 and will not compile using Qt5 +tileedit.o: ../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 - $(CC) -o tileedit -I../include -I$(QTDIR)/include -L$(QTDIR)/lib \ - tileedit.cpp $(TEXT_IO) -lqt + $(CXXLINK) -o tileedit -L$(QTDIR)/lib tileedit.o $(TEXT_IO) -lqt # using dependencies like # ../src/foo:: From c154dd2609f0012726b1be77cd51104ae1c67e47 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 9 Oct 2020 12:02:26 -0700 Subject: [PATCH 304/708] fix #K2393 - brass lantern hit by water Don't extinguish a brass lantern when hit by water unless it is being submerged. --- doc/fixes37.0 | 3 ++- include/extern.h | 3 ++- src/apply.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++- src/trap.c | 18 +++++++-------- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 6b92c5b02..56101a98d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.323 $ $NHDT-Date: 1602022805 2020/10/06 22:20:05 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.325 $ $NHDT-Date: 1602270140 2020/10/09 19:02:20 $ General Fixes and Modified Features ----------------------------------- @@ -271,6 +271,7 @@ fire sources can ignite candles, lamps, and potions of oil for multiple drop ('D') with menustyle traditional or combination, if the only object class player picked was '$' then it operated on all classes small monsters could seep through their shirt +don't snuff brass lantern when it's hit by water unless it is submerged Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 52b28f616..83a1cd30f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1600933440 2020/09/24 07:44:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.859 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1602270114 2020/10/09 19:01:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.867 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -47,6 +47,7 @@ E void FDECL(check_leash, (XCHAR_P, XCHAR_P)); E boolean FDECL(um_dist, (XCHAR_P, XCHAR_P, XCHAR_P)); E boolean FDECL(snuff_candle, (struct obj *)); E boolean FDECL(snuff_lit, (struct obj *)); +E boolean FDECL(splash_lit, (struct obj *)); E boolean FDECL(catch_lit, (struct obj *)); E void FDECL(use_unicorn_horn, (struct obj **)); E boolean FDECL(tinnable, (struct obj *)); diff --git a/src/apply.c b/src/apply.c index faef080bf..32e33f97f 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1597090815 2020/08/10 20:20:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.327 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1602270122 2020/10/09 19:02:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.328 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1346,6 +1346,63 @@ struct obj *obj; return FALSE; } +/* called when lit object is hit by water */ +boolean +splash_lit(obj) +struct obj *obj; +{ + boolean result, dunk = FALSE; + + /* lantern won't be extinguished by a rust trap or rust monster attack + but will be if submerged or placed into a container or swallowed by + a monster (for mobile light source handling, not because it ought + to stop being lit in all those situations...) */ + if (obj->lamplit && obj->otyp == BRASS_LANTERN) { + struct monst *mtmp; + boolean useeit = FALSE, uhearit = FALSE, snuff = TRUE; + + if (obj->where == OBJ_INVENT) { + useeit = !Blind; + uhearit = !Deaf; + /* underwater light sources aren't allowed but if hero + is just entering water, Underwater won't be set yet */ + dunk = (is_pool(u.ux, u.uy) + && ((!Levitation && !Flying && !Wwalking) + || Is_waterlevel(&u.uz))); + snuff = FALSE; + } else if (obj->where == OBJ_MINVENT + /* don't assume that lit lantern has been swallowed; + a nymph might have stolen it or picked it up */ + && ((mtmp = obj->ocarry), humanoid(mtmp->data))) { + xchar x, y; + + useeit = get_obj_location(obj, &x, &y, 0) && cansee(x, y); + uhearit = couldsee(x, y) && distu(x, y) < 5 * 5; + dunk = (is_pool(mtmp->mx, mtmp->my) + && ((!is_flyer(mtmp->data) && !is_floater(mtmp->data)) + || Is_waterlevel(&u.uz))); + snuff = FALSE; + } + + if (useeit || uhearit) + pline("%s %s%s%s.", Yname2(obj), + uhearit ? "crackles" : "", + (uhearit && useeit) ? " and " : "", + useeit ? "flickers" : ""); + if (!dunk && !snuff) + return FALSE; + } + + result = snuff_lit(obj); + + /* this is simpler when we wait until after lantern has been snuffed */ + if (dunk) { + /* drain some of the battery but don't short it out entirely */ + obj->age -= (obj->age > 200L) ? 100L : (obj->age / 2L); + } + return result; +} + /* Called when potentially lightable object is affected by fire_damage(). Return TRUE if object was lit and FALSE otherwise --ALI */ boolean diff --git a/src/trap.c b/src/trap.c index 7aa3f3e71..5ba5bdc74 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1596498220 2020/08/03 23:43:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.362 $ */ +/* NetHack 3.7 trap.c $NHDT-Date: 1602270123 2020/10/09 19:02:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.364 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1149,10 +1149,7 @@ unsigned trflags; if (u.twoweap || (uwep && bimanual(uwep))) (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE); glovecheck: - (void) water_damage(uarmg, "gauntlets", TRUE); - /* Not "metal gauntlets" since it gets called - * even if it's leather for the message - */ + (void) water_damage(uarmg, gloves_simple_name(uarmg), TRUE); break; case 2: pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM)); @@ -1160,10 +1157,12 @@ unsigned trflags; goto glovecheck; default: pline("%s you!", A_gush_of_water_hits); + /* note: exclude primary and seconary weapons from splashing + because cases 1 and 2 target them [via water_damage()] */ for (otmp = g.invent; otmp; otmp = otmp->nobj) if (otmp->lamplit && otmp != uwep && (otmp != uswapwep || !u.twoweap)) - (void) snuff_lit(otmp); + (void) splash_lit(otmp); if (uarmc) (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE); else if (uarm) @@ -2344,7 +2343,7 @@ register struct monst *mtmp; (void) water_damage(target, 0, TRUE); glovecheck: target = which_armor(mtmp, W_ARMG); - (void) water_damage(target, "gauntlets", TRUE); + (void) water_damage(target, gloves_simple_name(target), TRUE); break; case 2: if (in_sight) @@ -2357,8 +2356,9 @@ register struct monst *mtmp; pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp)); for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) if (otmp->lamplit + /* exclude weapon(s) because cases 1 and 2 do them */ && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0) - (void) snuff_lit(otmp); + (void) splash_lit(otmp); if ((target = which_armor(mtmp, W_ARMC)) != 0) (void) water_damage(target, cloak_simple_name(target), TRUE); @@ -3538,7 +3538,7 @@ boolean force; if (!obj) return ER_NOTHING; - if (snuff_lit(obj)) + if (splash_lit(obj)) return ER_DAMAGED; if (!ostr) From 3d6551a70e3f3ca212d4a6141aa816a193c9c4c7 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 10 Oct 2020 11:31:16 +0300 Subject: [PATCH 305/708] Lua: Allow matching any wall A 'w' in a map fragment will match any wall (IS_WALL macro): des.replace_terrain({ mapfragment = "w", toterrain = "F" }); --- src/sp_lev.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index 446e78258..f11099af2 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -197,6 +197,9 @@ static struct monst *invent_carrying_monster = (struct monst *) 0; * end of no 'g.' */ +#define TYP_CANNOT_MATCH(typ) \ + ((typ) == MAX_TYPE || (typ) == INVALID_TYPE) + /* Does typ match with levl[][].typ, considering special types MATCH_WALL and MAX_TYPE (aka transparency)? */ static boolean @@ -277,7 +280,7 @@ struct mapfragment *mf; else if (!mapfrag_canmatch(mf)) { mapfrag_free(&mf); return "mapfragment needs to have odd height and width"; - } else if (mapfrag_get(mf, (mf->wid/2), (mf->hei/2)) >= MAX_TYPE) { + } else if (TYP_CANNOT_MATCH(mapfrag_get(mf, (mf->wid/2), (mf->hei/2)))) { mapfrag_free(&mf); return "mapfragment center must be valid terrain"; } From 55d1d547a679d18d19f09edd86f9b331d2aab769 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Oct 2020 08:55:43 -0400 Subject: [PATCH 306/708] silence some util/makdefs.c src/mdlib warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In file included from makedefs.c:213:0: ../src/mdlib.c: In function ‘runtime_info_init’: ../src/mdlib.c:808:12: warning: variable ‘timeresult’ set but not used [-Wunused-but-set-variable] time_t timeresult; ^~~~~~~~~~ makedefs.c: In function ‘do_date’: makedefs.c:1140:16: warning: unused variable ‘ind’ [-Wunused-variable] const char ind[] = " "; ^~~ makedefs.c:1139:9: warning: unused variable ‘steps’ [-Wunused-variable] int steps = 0; ^~~~~ makedefs.c: In function ‘do_monstr’: makedefs.c:1934:12: warning: variable ‘j’ set but not used [-Wunused-but-set-variable] int i, j; ^ --- src/mdlib.c | 38 +++++++++++++++++--------------------- util/makedefs.c | 6 ++---- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/src/mdlib.c b/src/mdlib.c index e0fef5a64..623333df8 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -799,6 +799,8 @@ build_options() void runtime_info_init() { +#if !defined(MAKEDEFS_C) && defined(CROSSCOMPILE_TARGET) \ + && defined(__DATE__) && defined(__TIME__) int i; char tmpbuf[BUFSZ], *strp; const char *mth[] = { @@ -806,12 +808,15 @@ runtime_info_init() "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; struct tm t = {0}; time_t timeresult; +#endif if (!done_runtime_opt_init_once) { done_runtime_opt_init_once = 1; build_savebones_compat_string(); /* construct the current version number */ make_version(); +#if !defined(MAKEDEFS_C) && defined(CROSSCOMPILE_TARGET) +#if defined(__DATE__) && defined(__TIME__) /* * In a cross-compiled environment, you can't execute * the target binaries during the build, so we can't @@ -831,8 +836,6 @@ runtime_info_init() * gcc, msvc, clang __TIME__ "23:59:01" * */ - -#if defined(__DATE__) && defined(__TIME__) if (sizeof __DATE__ + sizeof __TIME__ + sizeof "123" < sizeof rttimebuf) Sprintf(rttimebuf, "%s %s", __DATE__, __TIME__); @@ -859,35 +862,28 @@ runtime_info_init() extract_field(tmpbuf, rttimebuf, 2, 18); /* sec */ t.tm_sec = atoi(tmpbuf); timeresult = mktime(&t); -#if !defined(MAKEDEFS_C) && defined(CROSSCOMPILE_TARGET) BUILD_TIME = (unsigned long) timeresult; BUILD_DATE = rttimebuf; -#endif -#else /* __DATE__ && __TIME__ */ - nhUse(strp); + } #endif /* __DATE__ && __TIME__ */ - -#if !defined(MAKEDEFS_C) && defined(CROSSCOMPILE_TARGET) - VERSION_NUMBER = version.incarnation; - VERSION_FEATURES = version.feature_set; + VERSION_NUMBER = version.incarnation; + VERSION_FEATURES = version.feature_set; #ifdef MD_IGNORED_FEATURES - IGNORED_FEATURES = MD_IGNORED_FEATURES; + IGNORED_FEATURES = MD_IGNORED_FEATURES; #endif - VERSION_SANITY1 = version.entity_count; - VERSION_SANITY2 = version.struct_sizes1; - VERSION_SANITY3 = version.struct_sizes2; - - VERSION_STRING = strdup(version_string(tmpbuf, ".")); - VERSION_ID = strdup(version_id_string(tmpbuf, BUILD_DATE)); - COPYRIGHT_BANNER_C = strdup(bannerc_string(tmpbuf, BUILD_DATE)); + VERSION_SANITY1 = version.entity_count; + VERSION_SANITY2 = version.struct_sizes1; + VERSION_SANITY3 = version.struct_sizes2; + VERSION_STRING = strdup(version_string(tmpbuf, ".")); + VERSION_ID = strdup(version_id_string(tmpbuf, BUILD_DATE)); + COPYRIGHT_BANNER_C = strdup(bannerc_string(tmpbuf, BUILD_DATE)); #ifdef NETHACK_HOST_GIT_SHA - NETHACK_GIT_SHA = strdup(NETHACK_HOST_GIT_SHA); + NETHACK_GIT_SHA = strdup(NETHACK_HOST_GIT_SHA); #endif #ifdef NETHACK_HOST_GIT_BRANCH - NETHACK_GIT_BRANCH = strdup(NETHACK_HOST_GIT_BRANCH); + NETHACK_GIT_BRANCH = strdup(NETHACK_HOST_GIT_BRANCH); #endif #endif /* !MAKEDEFS_C && CROSSCOMPILE_TARGET */ - } idxopttext = 0; build_options(); } diff --git a/util/makedefs.c b/util/makedefs.c index f8636c893..3d81f4ab8 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1136,8 +1136,6 @@ do_date() char *c, cbuf[60], buf[BUFSZ]; const char *ul_sfx; #if defined(CROSSCOMPILE) && !defined(CROSSCOMPILE_TARGET) - int steps = 0; - const char ind[] = " "; const char *xpref = "HOST_"; #else const char *xpref = (const char *) 0; @@ -1931,7 +1929,7 @@ void do_monstr() { struct permonst *ptr; - int i, j; + int i; /* Don't break anything for ports that haven't been updated. */ printf("DEPRECATION WARNINGS:\n"); @@ -1973,7 +1971,7 @@ do_monstr() /* output derived monstr values as a comment */ Fprintf(ofp, "\n\n/*\n * default mons[].difficulty values\n *\n"); - for (ptr = &mons[0], j = 0; ptr->mlet; ptr++) { + for (ptr = &mons[0]; ptr->mlet; ptr++) { i = mstrength(ptr); Fprintf(ofp, "%-24s %2u\n", ptr->mname, (unsigned int) (uchar) i); } From 062152d62ed25400e19af4298c60f1b832e3eb16 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 10 Oct 2020 11:46:02 -0700 Subject: [PATCH 307/708] fix github issue #399 - [not] fixing chest lock Use ansimpleoname() instead of doname() to describe the key or lock pick or credit card when reporting "You can't fix a chest's broken lock with a ." doname() includes BUC status when known and feedback mentioning a particular bless/curse state on the tool that can't be used to fix the lock suggests that some other bless/curse state might be viable. --- doc/fixes37.0 | 6 +++++- src/lock.c | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 56101a98d..0c1d1ea4d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.325 $ $NHDT-Date: 1602270140 2020/10/09 19:02:20 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ $NHDT-Date: 1602355548 2020/10/10 18:45:48 $ General Fixes and Modified Features ----------------------------------- @@ -272,6 +272,10 @@ for multiple drop ('D') with menustyle traditional or combination, if the only object class player picked was '$' then it operated on all classes small monsters could seep through their shirt don't snuff brass lantern when it's hit by water unless it is submerged +when reporting that hero can't repair a chest's broken lock with key/pick/card + just describe the base item without BUC, user assigned name, &c since + "You can't repair a chest's lock with an uncursed key." implicitly + suggests that you might be able to do so with a blessed or cursed one Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/lock.c b/src/lock.c index ceb430941..b14256856 100644 --- a/src/lock.c +++ b/src/lock.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 lock.c $NHDT-Date: 1596498173 2020/08/03 23:42:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.99 $ */ +/* NetHack 3.7 lock.c $NHDT-Date: 1602355548 2020/10/10 18:45:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -480,7 +480,8 @@ struct obj *container; /* container, for autounlock */ } if (otmp->obroken) { - You_cant("fix its broken lock with %s.", doname(pick)); + You_cant("fix its broken lock with %s.", + ansimpleoname(pick)); return PICKLOCK_LEARNED_SOMETHING; } else if (picktyp == CREDIT_CARD && !otmp->olocked) { /* credit cards are only good for unlocking */ From 48fa4fa5dd47e41e6e42bd7d7f04e452dc43640d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Oct 2020 16:28:17 -0400 Subject: [PATCH 308/708] more warning bits --- include/obj.h | 1 + src/display.c | 10 ++++------ src/dokick.c | 5 +++-- src/invent.c | 9 ++++++--- src/mdlib.c | 12 +++++++++++- src/mkobj.c | 2 +- src/options.c | 12 ++++++++++-- src/restore.c | 8 +++++--- src/sp_lev.c | 3 +-- src/sys.c | 7 ++++--- win/tty/wintty.c | 8 ++++---- 11 files changed, 50 insertions(+), 27 deletions(-) diff --git a/include/obj.h b/include/obj.h index d6577da91..88c4902d0 100644 --- a/include/obj.h +++ b/include/obj.h @@ -115,6 +115,7 @@ struct obj { #define leashmon corpsenm /* gets m_id of attached pet */ #define fromsink corpsenm /* a potion from a sink */ #define novelidx corpsenm /* 3.6 tribute - the index of the novel title */ +#define migr_species corpsenm /* species to endow for MIGR_TO_SPECIES */ int usecount; /* overloaded for various things that tally */ #define spestudied usecount /* # of times a spellbook has been studied */ unsigned oeaten; /* nutrition left in food, if partly eaten */ diff --git a/src/display.c b/src/display.c index 0efe1582c..89e7c95a5 100644 --- a/src/display.c +++ b/src/display.c @@ -2075,17 +2075,15 @@ int x, y, a, b, c; /* Return the wall mode for a T wall. */ static int set_twall(x0, y0, x1, y1, x2, y2, x3, y3) +#ifdef WA_VERBOSE int x0, y0; /* used #if WA_VERBOSE */ +#else +int x0, y0 UNUSED; +#endif int x1, y1, x2, y2, x3, y3; { int wmode, is_1, is_2, is_3; -#ifndef WA_VERBOSE - /* non-verbose more_than_one() doesn't use these */ - nhUse(x0); - nhUse(y0); -#endif - is_1 = check_pos(x1, y1, WM_T_LONG); is_2 = check_pos(x2, y2, WM_T_BL); is_3 = check_pos(x3, y3, WM_T_BR); diff --git a/src/dokick.c b/src/dokick.c index 5564c84c5..979f1315c 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1708,7 +1708,8 @@ unsigned long deliverflags; if ((where & MIGR_TO_SPECIES) == 0) continue; - if ((mtmp->data->mflags2 & DELIVER_PM) == otmp->corpsenm) { + if (otmp->migr_species != NON_PM + && (mtmp->data->mflags2 & DELIVER_PM) == (unsigned) otmp->migr_species) { obj_extract_self(otmp); otmp->owornmask = 0L; otmp->ox = otmp->oy = 0; @@ -1725,7 +1726,7 @@ unsigned long deliverflags; } free_oname(otmp); } - otmp->corpsenm = NON_PM; + otmp->migr_species = NON_PM; (void) add_to_minv(mtmp, otmp); cnt++; if (maxobj && cnt >= maxobj) diff --git a/src/invent.c b/src/invent.c index eeb540449..cfc80f5eb 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1884,11 +1884,14 @@ register const char *let, *word; void silly_thing(word, otmp) const char *word; +#ifdef OBSOLETE_HANDLING struct obj *otmp; -{ -#if 1 /* 'P','R' vs 'W','T' handling is obsolete */ - nhUse(otmp); #else +struct obj *otmp UNUSED; +#endif +{ +#ifdef OBSOLETE_HANDLING + /* 'P','R' vs 'W','T' handling is obsolete */ const char *s1, *s2, *s3; int ocls = otmp->oclass, otyp = otmp->otyp; diff --git a/src/mdlib.c b/src/mdlib.c index 623333df8..bbd85225b 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -60,7 +60,6 @@ static char *FDECL(version_string, (char *, const char *)); static char *FDECL(version_id_string, (char *, const char *)); static char *FDECL(bannerc_string, (char *, const char *)); -static int FDECL(case_insensitive_comp, (const char *, const char *)); static void NDECL(make_version); static char *FDECL(eos, (char *)); #if 0 @@ -74,6 +73,11 @@ static int FDECL(mkstemp, (char *)); #endif #endif /* MAKEDEFS_C || FOR_RUNTIME */ +#if defined(MAKEDEFS_C) || defined(FOR_RUNTIME) || defined(WIN32) \ + || (defined(CROSSCOMPILE_TARGET) && defined(__DATE__) && defined(__TIME__)) +static int FDECL(case_insensitive_comp, (const char *, const char *)); +#endif + #if !defined(MAKEDEFS_C) && defined(WIN32) extern int GUILaunched; #endif @@ -88,7 +92,10 @@ static void FDECL(opt_out_words, (char *, int *)); static void NDECL(build_savebones_compat_string); static int idxopttext, done_runtime_opt_init_once = 0; #define MAXOPT 40 +#if !defined(MAKEDEFS_C) && defined(CROSSCOMPILE_TARGET) \ + && defined(__DATE__) && defined(__TIME__) static char rttimebuf[MAXOPT]; +#endif static char *opttext[120] = { 0 }; char optbuf[BUFSZ]; static struct version_info version; @@ -348,6 +355,8 @@ char *template; #endif /* HAS_NO_MKSTEMP */ #endif /* MAKEDEFS_C || FOR_RUNTIME */ +#if defined(MAKEDEFS_C) || defined(FOR_RUNTIME) || defined(WIN32) \ + || (defined(CROSSCOMPILE_TARGET) && defined(__DATE__) && defined(__TIME__)) static int case_insensitive_comp(s1, s2) const char *s1; @@ -367,6 +376,7 @@ const char *s2; } return u1 - u2; } +#endif static char * eos(str) diff --git a/src/mkobj.c b/src/mkobj.c index 6c3d8b4a9..d894ae920 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -210,7 +210,7 @@ boolean init, artif; otmp = mksobj(otyp, init, artif); add_to_migration(otmp); otmp->owornmask = (long) MIGR_TO_SPECIES; - otmp->corpsenm = mflags2; + otmp->migr_species = mflags2; return otmp; } diff --git a/src/options.c b/src/options.c index f8ddb2f5e..ac50af936 100644 --- a/src/options.c +++ b/src/options.c @@ -304,7 +304,10 @@ register char *opts; boolean tinitial, tfrom_file; { char *op; - boolean negated, got_match = FALSE, has_val = FALSE; + boolean negated, got_match = FALSE; +#if 0 + boolean has_val = FALSE; +#endif int i, matchidx = -1, optresult = optn_err, optlen, optlen_wo_val; boolean retval = TRUE; @@ -345,11 +348,16 @@ boolean tinitial, tfrom_file; optlen = (int) strlen(opts); optlen_wo_val = length_without_val(opts, optlen); if (optlen_wo_val < optlen) { +#if 0 has_val = TRUE; +#endif optlen = optlen_wo_val; - } else { + } +#if 0 + else { has_val = FALSE; } +#endif for (i = 0; i < OPTCOUNT; ++i) { got_match = FALSE; diff --git a/src/restore.c b/src/restore.c index 816ca3f8e..ea75d54da 100644 --- a/src/restore.c +++ b/src/restore.c @@ -954,7 +954,11 @@ struct cemetery **cemeteryaddr; static void rest_levl(nhfp, rlecomp) NHFILE *nhfp; +#ifdef RLECOMP boolean rlecomp; +#else +boolean rlecomp UNUSED; +#endif { #ifdef RLECOMP short i, j; @@ -984,9 +988,7 @@ boolean rlecomp; } return; } -#else /* !RLECOMP */ - nhUse(rlecomp); -#endif /* ?RLECOMP */ +#endif /* RLECOMP */ if (nhfp->structlevel) { mread(nhfp->fd, (genericptr_t) levl, sizeof levl); } diff --git a/src/sp_lev.c b/src/sp_lev.c index f11099af2..c469d9747 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -3076,7 +3076,7 @@ lua_State *L; static int find_montype(L, s) -lua_State *L; +lua_State *L UNUSED; const char *s; { int i; @@ -3084,7 +3084,6 @@ const char *s; for (i = LOW_PM; i < NUMMONS; i++) if (!strcmpi(mons[i].mname, s)) return i; - nhUse(L); return NON_PM; } diff --git a/src/sys.c b/src/sys.c index 8ef533980..650c20e08 100644 --- a/src/sys.c +++ b/src/sys.c @@ -130,9 +130,9 @@ extern const struct attack c_sa_no[NATTK]; void sysopt_seduce_set(val) +#if 0 int val; { -#if 0 /* * Attack substitution is now done on the fly in getmattk(mhitu.c). */ @@ -144,8 +144,9 @@ int val; mons[PM_SUCCUBUS].mattk[x] = setval[x]; } #else - nhUse(val); -#endif /*0*/ +int val UNUSED; +{ +#endif return; } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 73f390df2..8af5db634 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -3592,7 +3592,11 @@ tty_nhgetch() /*ARGSUSED*/ int tty_nh_poskey(x, y, mod) +#if defined(WIN32CON) int *x, *y, *mod; +#else +int *x UNUSED, *y UNUSED, *mod UNUSED; +#endif { int i; @@ -3612,10 +3616,6 @@ int *x, *y, *mod; if (ttyDisplay && ttyDisplay->toplin == 1) ttyDisplay->toplin = 2; #else /* !WIN32CON */ - nhUse(x); - nhUse(y); - nhUse(mod); - i = tty_nhgetch(); #endif /* ?WIN32CON */ return i; From 3e66cbd78171e3898397ffffda805eec6f7d5e10 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Oct 2020 16:41:09 -0400 Subject: [PATCH 309/708] more warnings --- src/display.c | 2 +- src/options.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/display.c b/src/display.c index 89e7c95a5..1c4707b04 100644 --- a/src/display.c +++ b/src/display.c @@ -2078,7 +2078,7 @@ set_twall(x0, y0, x1, y1, x2, y2, x3, y3) #ifdef WA_VERBOSE int x0, y0; /* used #if WA_VERBOSE */ #else -int x0, y0 UNUSED; +int x0 UNUSED, y0 UNUSED; #endif int x1, y1, x2, y2, x3, y3; { diff --git a/src/options.c b/src/options.c index ac50af936..39e69c9f1 100644 --- a/src/options.c +++ b/src/options.c @@ -7586,7 +7586,7 @@ doset() /* changing options via menu by Per Liboriussen */ (void) parseoptions(buf, setinitial, fromfile); } else { /* compound option */ - int k = opt_indx, reslt; + int k = opt_indx, reslt UNUSED; if (allopt[k].has_handler && allopt[k].optfn) { reslt = (*allopt[k].optfn)(allopt[k].idx, do_handler, From 848f37207d78e08e737736a7a1d538760285ebc4 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 10 Oct 2020 14:17:58 -0700 Subject: [PATCH 310/708] Add text mentioning that LUA sources must be copied into tree. --- sys/winnt/Install.nt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/winnt/Install.nt b/sys/winnt/Install.nt index 22c9f4484..98bd029d4 100644 --- a/sys/winnt/Install.nt +++ b/sys/winnt/Install.nt @@ -51,11 +51,16 @@ version. You can use one of the following build environments: | vs2017 - /--------------------------------------------------------\ | Building And Running Using Visual Studio 2017 | \--------------------------------------------------------/ +Before proceeding, please obtain the lua-5.4.0 sources and copy them to +the new directory lib\lua-5.4.0\src. This source can be obtain either from +http://www.lua.org/ftp/lua-5.4.0.tar.gz or from the git hub mirror +https://github.com/lua/lua.git using the tag 'v5.4.0'. The build expects +to find lua files such as 'lua.h' at 'lib\lua-5.4.0\src\lua.h'. + If you are NOT using Visual Studio 2017 IDE, or you prefer to build using a Make utility and a Makefile proceed to "Building Using Make". From bb04a9b04183f8706a59aa04496909689cd3d6a5 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 10 Oct 2020 15:15:59 -0700 Subject: [PATCH 311/708] Support both VS 2017 and VS 2019 without making changes to project files. Renamed 'vs2017' folder to 'vs'. --- .travis.yml | 2 +- Files | 6 ++--- sys/winnt/Install.nt | 22 ++++++------------ sys/winnt/Makefile.msc | 2 +- win/win32/{vs2017 => vs}/.gitattributes | 0 win/win32/{vs2017 => vs}/.gitignore | 0 .../Images/BadgeLogo.scale-100.png | Bin .../Images/BadgeLogo.scale-125.png | Bin .../Images/BadgeLogo.scale-150.png | Bin .../Images/BadgeLogo.scale-200.png | Bin .../Images/BadgeLogo.scale-400.png | Bin .../Images/LargeTile.scale-100.png | Bin .../Images/LargeTile.scale-125.png | Bin .../Images/LargeTile.scale-150.png | Bin .../Images/LargeTile.scale-200.png | Bin .../Images/LargeTile.scale-400.png | Bin .../Images/LockScreenLogo.scale-200.png | Bin .../Images/SmallTile.scale-100.png | Bin .../Images/SmallTile.scale-125.png | Bin .../Images/SmallTile.scale-150.png | Bin .../Images/SmallTile.scale-200.png | Bin .../Images/SmallTile.scale-400.png | Bin .../Images/SplashScreen.scale-100.png | Bin .../Images/SplashScreen.scale-125.png | Bin .../Images/SplashScreen.scale-150.png | Bin .../Images/SplashScreen.scale-200.png | Bin .../Images/SplashScreen.scale-400.png | Bin .../Images/Square150x150Logo.scale-100.png | Bin .../Images/Square150x150Logo.scale-125.png | Bin .../Images/Square150x150Logo.scale-150.png | Bin .../Images/Square150x150Logo.scale-200.png | Bin .../Images/Square150x150Logo.scale-400.png | Bin ...x44Logo.altform-unplated_targetsize-16.png | Bin ...44Logo.altform-unplated_targetsize-256.png | Bin ...x44Logo.altform-unplated_targetsize-32.png | Bin ...x44Logo.altform-unplated_targetsize-48.png | Bin .../Images/Square44x44Logo.scale-100.png | Bin .../Images/Square44x44Logo.scale-125.png | Bin .../Images/Square44x44Logo.scale-150.png | Bin .../Images/Square44x44Logo.scale-200.png | Bin .../Images/Square44x44Logo.scale-400.png | Bin .../Images/Square44x44Logo.targetsize-16.png | Bin .../Images/Square44x44Logo.targetsize-24.png | Bin ...x44Logo.targetsize-24_altform-unplated.png | Bin .../Images/Square44x44Logo.targetsize-256.png | Bin .../Images/Square44x44Logo.targetsize-32.png | Bin .../Images/Square44x44Logo.targetsize-48.png | Bin .../Images/StoreLogo.backup.png | Bin .../Images/StoreLogo.scale-100.png | Bin .../Images/StoreLogo.scale-125.png | Bin .../Images/StoreLogo.scale-150.png | Bin .../Images/StoreLogo.scale-200.png | Bin .../Images/StoreLogo.scale-400.png | Bin .../Images/Wide310x150Logo.scale-100.png | Bin .../Images/Wide310x150Logo.scale-125.png | Bin .../Images/Wide310x150Logo.scale-150.png | Bin .../Images/Wide310x150Logo.scale-200.png | Bin .../Images/Wide310x150Logo.scale-400.png | Bin win/win32/{vs2017 => vs}/NetHack.sln | 0 win/win32/{vs2017 => vs}/NetHack.vcxproj | 0 .../NetHackPackage.appxmanifest | 0 .../{vs2017 => vs}/NetHackPackage.wapproj | 0 .../{vs2017 => vs}/NetHackProperties.props | 0 win/win32/{vs2017 => vs}/NetHackW.vcxproj | 0 win/win32/{vs2017 => vs}/PDCurses.vcxproj | 0 .../Package.StoreAssociation.xml | 0 win/win32/{vs2017 => vs}/ScreenShot.PNG | Bin win/win32/{vs2017 => vs}/afterdlb.proj | 0 win/win32/{vs2017 => vs}/aftermakedefs.proj | 0 win/win32/{vs2017 => vs}/afternethack.proj | 0 win/win32/{vs2017 => vs}/afterrecover.proj | 0 win/win32/{vs2017 => vs}/aftertile2bmp.proj | 0 win/win32/{vs2017 => vs}/aftertilemap.proj | 0 win/win32/{vs2017 => vs}/afteruudecode.proj | 0 win/win32/{vs2017 => vs}/build.bat | 0 win/win32/{vs2017 => vs}/common.props | 0 win/win32/{vs2017 => vs}/config.props | 0 win/win32/{vs2017 => vs}/console.props | 0 win/win32/{vs2017 => vs}/default.props | 3 +-- win/win32/{vs2017 => vs}/default_dll.props | 2 +- win/win32/{vs2017 => vs}/default_lib.props | 2 +- win/win32/{vs2017 => vs}/dirs.props | 0 win/win32/{vs2017 => vs}/dlb.vcxproj | 0 win/win32/{vs2017 => vs}/dll.props | 0 win/win32/{vs2017 => vs}/files.props | 0 win/win32/{vs2017 => vs}/makedefs.vcxproj | 0 win/win32/{vs2017 => vs}/nh340key.def | 0 win/win32/{vs2017 => vs}/nh340key.vcxproj | 0 win/win32/{vs2017 => vs}/nhdefkey.def | 0 win/win32/{vs2017 => vs}/nhdefkey.vcxproj | 0 win/win32/{vs2017 => vs}/nhraykey.def | 0 win/win32/{vs2017 => vs}/nhraykey.vcxproj | 0 win/win32/{vs2017 => vs}/recover.vcxproj | 0 win/win32/{vs2017 => vs}/tile2bmp.vcxproj | 0 win/win32/{vs2017 => vs}/tilemap.vcxproj | 0 win/win32/{vs2017 => vs}/tiles.vcxproj | 0 win/win32/{vs2017 => vs}/travisci.sh | 0 win/win32/{vs2017 => vs}/uudecode.vcxproj | 0 98 files changed, 15 insertions(+), 24 deletions(-) rename win/win32/{vs2017 => vs}/.gitattributes (100%) rename win/win32/{vs2017 => vs}/.gitignore (100%) rename win/win32/{vs2017 => vs}/Images/BadgeLogo.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/BadgeLogo.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/BadgeLogo.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/BadgeLogo.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/BadgeLogo.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/LargeTile.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/LargeTile.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/LargeTile.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/LargeTile.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/LargeTile.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/LockScreenLogo.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/SmallTile.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/SmallTile.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/SmallTile.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/SmallTile.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/SmallTile.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/SplashScreen.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/SplashScreen.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/SplashScreen.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/SplashScreen.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/SplashScreen.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/Square150x150Logo.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/Square150x150Logo.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/Square150x150Logo.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/Square150x150Logo.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/Square150x150Logo.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.altform-unplated_targetsize-16.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.altform-unplated_targetsize-256.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.altform-unplated_targetsize-32.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.altform-unplated_targetsize-48.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.targetsize-16.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.targetsize-24.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.targetsize-24_altform-unplated.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.targetsize-256.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.targetsize-32.png (100%) rename win/win32/{vs2017 => vs}/Images/Square44x44Logo.targetsize-48.png (100%) rename win/win32/{vs2017 => vs}/Images/StoreLogo.backup.png (100%) rename win/win32/{vs2017 => vs}/Images/StoreLogo.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/StoreLogo.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/StoreLogo.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/StoreLogo.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/StoreLogo.scale-400.png (100%) rename win/win32/{vs2017 => vs}/Images/Wide310x150Logo.scale-100.png (100%) rename win/win32/{vs2017 => vs}/Images/Wide310x150Logo.scale-125.png (100%) rename win/win32/{vs2017 => vs}/Images/Wide310x150Logo.scale-150.png (100%) rename win/win32/{vs2017 => vs}/Images/Wide310x150Logo.scale-200.png (100%) rename win/win32/{vs2017 => vs}/Images/Wide310x150Logo.scale-400.png (100%) rename win/win32/{vs2017 => vs}/NetHack.sln (100%) rename win/win32/{vs2017 => vs}/NetHack.vcxproj (100%) rename win/win32/{vs2017 => vs}/NetHackPackage.appxmanifest (100%) rename win/win32/{vs2017 => vs}/NetHackPackage.wapproj (100%) rename win/win32/{vs2017 => vs}/NetHackProperties.props (100%) rename win/win32/{vs2017 => vs}/NetHackW.vcxproj (100%) rename win/win32/{vs2017 => vs}/PDCurses.vcxproj (100%) rename win/win32/{vs2017 => vs}/Package.StoreAssociation.xml (100%) rename win/win32/{vs2017 => vs}/ScreenShot.PNG (100%) rename win/win32/{vs2017 => vs}/afterdlb.proj (100%) rename win/win32/{vs2017 => vs}/aftermakedefs.proj (100%) rename win/win32/{vs2017 => vs}/afternethack.proj (100%) rename win/win32/{vs2017 => vs}/afterrecover.proj (100%) rename win/win32/{vs2017 => vs}/aftertile2bmp.proj (100%) rename win/win32/{vs2017 => vs}/aftertilemap.proj (100%) rename win/win32/{vs2017 => vs}/afteruudecode.proj (100%) rename win/win32/{vs2017 => vs}/build.bat (100%) rename win/win32/{vs2017 => vs}/common.props (100%) rename win/win32/{vs2017 => vs}/config.props (100%) rename win/win32/{vs2017 => vs}/console.props (100%) rename win/win32/{vs2017 => vs}/default.props (91%) rename win/win32/{vs2017 => vs}/default_dll.props (90%) rename win/win32/{vs2017 => vs}/default_lib.props (90%) rename win/win32/{vs2017 => vs}/dirs.props (100%) rename win/win32/{vs2017 => vs}/dlb.vcxproj (100%) rename win/win32/{vs2017 => vs}/dll.props (100%) rename win/win32/{vs2017 => vs}/files.props (100%) rename win/win32/{vs2017 => vs}/makedefs.vcxproj (100%) rename win/win32/{vs2017 => vs}/nh340key.def (100%) rename win/win32/{vs2017 => vs}/nh340key.vcxproj (100%) rename win/win32/{vs2017 => vs}/nhdefkey.def (100%) rename win/win32/{vs2017 => vs}/nhdefkey.vcxproj (100%) rename win/win32/{vs2017 => vs}/nhraykey.def (100%) rename win/win32/{vs2017 => vs}/nhraykey.vcxproj (100%) rename win/win32/{vs2017 => vs}/recover.vcxproj (100%) rename win/win32/{vs2017 => vs}/tile2bmp.vcxproj (100%) rename win/win32/{vs2017 => vs}/tilemap.vcxproj (100%) rename win/win32/{vs2017 => vs}/tiles.vcxproj (100%) rename win/win32/{vs2017 => vs}/travisci.sh (100%) rename win/win32/{vs2017 => vs}/uudecode.vcxproj (100%) diff --git a/.travis.yml b/.travis.yml index 0b1e388a0..ceba99f72 100644 --- a/.travis.yml +++ b/.travis.yml @@ -122,7 +122,7 @@ matrix: os: windows language: shell script: - - ./win/win32/vs2017/travisci.sh + - ./win/win32/vs/travisci.sh - name: windows-mingw os: windows # install: choco install mingw diff --git a/Files b/Files index 9aedfce0c..5eb31b35a 100644 --- a/Files +++ b/Files @@ -429,8 +429,8 @@ record.uu resource.h rip.uu splash.uu tiles-mingw32.mak tiles.mak winMS.h -win/win32/vs2017: -(files for Visual Studio 2017 Community Edition builds) +win/win32/vs: +(files for Visual Studio 2017 or 2019 Community Edition builds) NetHack.sln NetHack.vcxproj NetHackPackage.appxmanifest NetHackPackage.wapproj NetHackProperties.props NetHackW.vcxproj @@ -452,7 +452,7 @@ recover.vcxproj tile2bmp.vcxproj tilemap.vcxproj tiles.vcxproj travisci.sh uudecode.vcxproj -win/win32/vs2017/Images: +win/win32/vs/Images: (files for Visual Studio 2017 Community Edition builds) BadgeLogo.scale-100.png BadgeLogo.scale-125.png diff --git a/sys/winnt/Install.nt b/sys/winnt/Install.nt index 98bd029d4..5deb4dccb 100644 --- a/sys/winnt/Install.nt +++ b/sys/winnt/Install.nt @@ -49,10 +49,10 @@ version. You can use one of the following build environments: | | | | | | share winnt tty win32 Lua-5.4.0 pdcurses | - vs2017 + vs /--------------------------------------------------------\ -| Building And Running Using Visual Studio 2017 | +| Building And Running Using Visual Studio 2017 or 2019 | \--------------------------------------------------------/ Before proceeding, please obtain the lua-5.4.0 sources and copy them to @@ -61,23 +61,15 @@ http://www.lua.org/ftp/lua-5.4.0.tar.gz or from the git hub mirror https://github.com/lua/lua.git using the tag 'v5.4.0'. The build expects to find lua files such as 'lua.h' at 'lib\lua-5.4.0\src\lua.h'. -If you are NOT using Visual Studio 2017 IDE, or you prefer to build +If you are NOT using Visual Studio 2017 or 2019 IDE, or you prefer to build using a Make utility and a Makefile proceed to "Building Using Make". -When using either Visual Studio 2017, you simply need to load the +When using either Visual Studio 2017 or 2019, you simply need to load the solution file within the IDE, build the solution and run the version of NetHack you wish to run. -The Visual Studio 2017 NetHack solution file can be found here: - win\win32\vs2017\NetHack.sln - -You can use that same win\win32\vs2017\NetHack.sln with Visual Studio 2019, -but you may have to retarget the projects: - Windows SDK Version: 10.0.17763.0 [ There have been some reports of - difficulties if you instead choose - "10.0 (latest installed version)" ] - Platform Toolset: Upgrade to v142 - +The Visual Studio NetHack solution file can be found here: + win\win32\vs\NetHack.sln Before executing the steps to build listed in the next paragraph, decide if you want to include optional curses window-port. See @@ -94,7 +86,7 @@ You can also build all the projects for all platforms and configurations using a "build.bat" batch file found in the same directory as the solution. Open a developer command prompt for the version of Visual Studio you are -using. Change to the directory win\win32\vs2017 and run "build.bat". +using. Change to the directory win\win32\vs and run "build.bat". * Optional curses window-port support * diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 546d346e4..d079e64db 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -593,7 +593,7 @@ VSVER=2999 #untested future version !include ! ENDIF -#These will be in the environment variables with one of the VS2017 +#These will be in the environment variables with one of the Visual Studio #developer command prompts. #VSCMD_ARG_HOST_ARCH=x64 #VSCMD_ARG_TGT_ARCH=x86 diff --git a/win/win32/vs2017/.gitattributes b/win/win32/vs/.gitattributes similarity index 100% rename from win/win32/vs2017/.gitattributes rename to win/win32/vs/.gitattributes diff --git a/win/win32/vs2017/.gitignore b/win/win32/vs/.gitignore similarity index 100% rename from win/win32/vs2017/.gitignore rename to win/win32/vs/.gitignore diff --git a/win/win32/vs2017/Images/BadgeLogo.scale-100.png b/win/win32/vs/Images/BadgeLogo.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/BadgeLogo.scale-100.png rename to win/win32/vs/Images/BadgeLogo.scale-100.png diff --git a/win/win32/vs2017/Images/BadgeLogo.scale-125.png b/win/win32/vs/Images/BadgeLogo.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/BadgeLogo.scale-125.png rename to win/win32/vs/Images/BadgeLogo.scale-125.png diff --git a/win/win32/vs2017/Images/BadgeLogo.scale-150.png b/win/win32/vs/Images/BadgeLogo.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/BadgeLogo.scale-150.png rename to win/win32/vs/Images/BadgeLogo.scale-150.png diff --git a/win/win32/vs2017/Images/BadgeLogo.scale-200.png b/win/win32/vs/Images/BadgeLogo.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/BadgeLogo.scale-200.png rename to win/win32/vs/Images/BadgeLogo.scale-200.png diff --git a/win/win32/vs2017/Images/BadgeLogo.scale-400.png b/win/win32/vs/Images/BadgeLogo.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/BadgeLogo.scale-400.png rename to win/win32/vs/Images/BadgeLogo.scale-400.png diff --git a/win/win32/vs2017/Images/LargeTile.scale-100.png b/win/win32/vs/Images/LargeTile.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/LargeTile.scale-100.png rename to win/win32/vs/Images/LargeTile.scale-100.png diff --git a/win/win32/vs2017/Images/LargeTile.scale-125.png b/win/win32/vs/Images/LargeTile.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/LargeTile.scale-125.png rename to win/win32/vs/Images/LargeTile.scale-125.png diff --git a/win/win32/vs2017/Images/LargeTile.scale-150.png b/win/win32/vs/Images/LargeTile.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/LargeTile.scale-150.png rename to win/win32/vs/Images/LargeTile.scale-150.png diff --git a/win/win32/vs2017/Images/LargeTile.scale-200.png b/win/win32/vs/Images/LargeTile.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/LargeTile.scale-200.png rename to win/win32/vs/Images/LargeTile.scale-200.png diff --git a/win/win32/vs2017/Images/LargeTile.scale-400.png b/win/win32/vs/Images/LargeTile.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/LargeTile.scale-400.png rename to win/win32/vs/Images/LargeTile.scale-400.png diff --git a/win/win32/vs2017/Images/LockScreenLogo.scale-200.png b/win/win32/vs/Images/LockScreenLogo.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/LockScreenLogo.scale-200.png rename to win/win32/vs/Images/LockScreenLogo.scale-200.png diff --git a/win/win32/vs2017/Images/SmallTile.scale-100.png b/win/win32/vs/Images/SmallTile.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/SmallTile.scale-100.png rename to win/win32/vs/Images/SmallTile.scale-100.png diff --git a/win/win32/vs2017/Images/SmallTile.scale-125.png b/win/win32/vs/Images/SmallTile.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/SmallTile.scale-125.png rename to win/win32/vs/Images/SmallTile.scale-125.png diff --git a/win/win32/vs2017/Images/SmallTile.scale-150.png b/win/win32/vs/Images/SmallTile.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/SmallTile.scale-150.png rename to win/win32/vs/Images/SmallTile.scale-150.png diff --git a/win/win32/vs2017/Images/SmallTile.scale-200.png b/win/win32/vs/Images/SmallTile.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/SmallTile.scale-200.png rename to win/win32/vs/Images/SmallTile.scale-200.png diff --git a/win/win32/vs2017/Images/SmallTile.scale-400.png b/win/win32/vs/Images/SmallTile.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/SmallTile.scale-400.png rename to win/win32/vs/Images/SmallTile.scale-400.png diff --git a/win/win32/vs2017/Images/SplashScreen.scale-100.png b/win/win32/vs/Images/SplashScreen.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/SplashScreen.scale-100.png rename to win/win32/vs/Images/SplashScreen.scale-100.png diff --git a/win/win32/vs2017/Images/SplashScreen.scale-125.png b/win/win32/vs/Images/SplashScreen.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/SplashScreen.scale-125.png rename to win/win32/vs/Images/SplashScreen.scale-125.png diff --git a/win/win32/vs2017/Images/SplashScreen.scale-150.png b/win/win32/vs/Images/SplashScreen.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/SplashScreen.scale-150.png rename to win/win32/vs/Images/SplashScreen.scale-150.png diff --git a/win/win32/vs2017/Images/SplashScreen.scale-200.png b/win/win32/vs/Images/SplashScreen.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/SplashScreen.scale-200.png rename to win/win32/vs/Images/SplashScreen.scale-200.png diff --git a/win/win32/vs2017/Images/SplashScreen.scale-400.png b/win/win32/vs/Images/SplashScreen.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/SplashScreen.scale-400.png rename to win/win32/vs/Images/SplashScreen.scale-400.png diff --git a/win/win32/vs2017/Images/Square150x150Logo.scale-100.png b/win/win32/vs/Images/Square150x150Logo.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/Square150x150Logo.scale-100.png rename to win/win32/vs/Images/Square150x150Logo.scale-100.png diff --git a/win/win32/vs2017/Images/Square150x150Logo.scale-125.png b/win/win32/vs/Images/Square150x150Logo.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/Square150x150Logo.scale-125.png rename to win/win32/vs/Images/Square150x150Logo.scale-125.png diff --git a/win/win32/vs2017/Images/Square150x150Logo.scale-150.png b/win/win32/vs/Images/Square150x150Logo.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/Square150x150Logo.scale-150.png rename to win/win32/vs/Images/Square150x150Logo.scale-150.png diff --git a/win/win32/vs2017/Images/Square150x150Logo.scale-200.png b/win/win32/vs/Images/Square150x150Logo.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/Square150x150Logo.scale-200.png rename to win/win32/vs/Images/Square150x150Logo.scale-200.png diff --git a/win/win32/vs2017/Images/Square150x150Logo.scale-400.png b/win/win32/vs/Images/Square150x150Logo.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/Square150x150Logo.scale-400.png rename to win/win32/vs/Images/Square150x150Logo.scale-400.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-16.png b/win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-16.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-16.png rename to win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-16.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-256.png b/win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-256.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-256.png rename to win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-256.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-32.png b/win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-32.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-32.png rename to win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-32.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-48.png b/win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-48.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.altform-unplated_targetsize-48.png rename to win/win32/vs/Images/Square44x44Logo.altform-unplated_targetsize-48.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.scale-100.png b/win/win32/vs/Images/Square44x44Logo.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.scale-100.png rename to win/win32/vs/Images/Square44x44Logo.scale-100.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.scale-125.png b/win/win32/vs/Images/Square44x44Logo.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.scale-125.png rename to win/win32/vs/Images/Square44x44Logo.scale-125.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.scale-150.png b/win/win32/vs/Images/Square44x44Logo.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.scale-150.png rename to win/win32/vs/Images/Square44x44Logo.scale-150.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.scale-200.png b/win/win32/vs/Images/Square44x44Logo.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.scale-200.png rename to win/win32/vs/Images/Square44x44Logo.scale-200.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.scale-400.png b/win/win32/vs/Images/Square44x44Logo.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.scale-400.png rename to win/win32/vs/Images/Square44x44Logo.scale-400.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.targetsize-16.png b/win/win32/vs/Images/Square44x44Logo.targetsize-16.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.targetsize-16.png rename to win/win32/vs/Images/Square44x44Logo.targetsize-16.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.targetsize-24.png b/win/win32/vs/Images/Square44x44Logo.targetsize-24.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.targetsize-24.png rename to win/win32/vs/Images/Square44x44Logo.targetsize-24.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.targetsize-24_altform-unplated.png b/win/win32/vs/Images/Square44x44Logo.targetsize-24_altform-unplated.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.targetsize-24_altform-unplated.png rename to win/win32/vs/Images/Square44x44Logo.targetsize-24_altform-unplated.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.targetsize-256.png b/win/win32/vs/Images/Square44x44Logo.targetsize-256.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.targetsize-256.png rename to win/win32/vs/Images/Square44x44Logo.targetsize-256.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.targetsize-32.png b/win/win32/vs/Images/Square44x44Logo.targetsize-32.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.targetsize-32.png rename to win/win32/vs/Images/Square44x44Logo.targetsize-32.png diff --git a/win/win32/vs2017/Images/Square44x44Logo.targetsize-48.png b/win/win32/vs/Images/Square44x44Logo.targetsize-48.png similarity index 100% rename from win/win32/vs2017/Images/Square44x44Logo.targetsize-48.png rename to win/win32/vs/Images/Square44x44Logo.targetsize-48.png diff --git a/win/win32/vs2017/Images/StoreLogo.backup.png b/win/win32/vs/Images/StoreLogo.backup.png similarity index 100% rename from win/win32/vs2017/Images/StoreLogo.backup.png rename to win/win32/vs/Images/StoreLogo.backup.png diff --git a/win/win32/vs2017/Images/StoreLogo.scale-100.png b/win/win32/vs/Images/StoreLogo.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/StoreLogo.scale-100.png rename to win/win32/vs/Images/StoreLogo.scale-100.png diff --git a/win/win32/vs2017/Images/StoreLogo.scale-125.png b/win/win32/vs/Images/StoreLogo.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/StoreLogo.scale-125.png rename to win/win32/vs/Images/StoreLogo.scale-125.png diff --git a/win/win32/vs2017/Images/StoreLogo.scale-150.png b/win/win32/vs/Images/StoreLogo.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/StoreLogo.scale-150.png rename to win/win32/vs/Images/StoreLogo.scale-150.png diff --git a/win/win32/vs2017/Images/StoreLogo.scale-200.png b/win/win32/vs/Images/StoreLogo.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/StoreLogo.scale-200.png rename to win/win32/vs/Images/StoreLogo.scale-200.png diff --git a/win/win32/vs2017/Images/StoreLogo.scale-400.png b/win/win32/vs/Images/StoreLogo.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/StoreLogo.scale-400.png rename to win/win32/vs/Images/StoreLogo.scale-400.png diff --git a/win/win32/vs2017/Images/Wide310x150Logo.scale-100.png b/win/win32/vs/Images/Wide310x150Logo.scale-100.png similarity index 100% rename from win/win32/vs2017/Images/Wide310x150Logo.scale-100.png rename to win/win32/vs/Images/Wide310x150Logo.scale-100.png diff --git a/win/win32/vs2017/Images/Wide310x150Logo.scale-125.png b/win/win32/vs/Images/Wide310x150Logo.scale-125.png similarity index 100% rename from win/win32/vs2017/Images/Wide310x150Logo.scale-125.png rename to win/win32/vs/Images/Wide310x150Logo.scale-125.png diff --git a/win/win32/vs2017/Images/Wide310x150Logo.scale-150.png b/win/win32/vs/Images/Wide310x150Logo.scale-150.png similarity index 100% rename from win/win32/vs2017/Images/Wide310x150Logo.scale-150.png rename to win/win32/vs/Images/Wide310x150Logo.scale-150.png diff --git a/win/win32/vs2017/Images/Wide310x150Logo.scale-200.png b/win/win32/vs/Images/Wide310x150Logo.scale-200.png similarity index 100% rename from win/win32/vs2017/Images/Wide310x150Logo.scale-200.png rename to win/win32/vs/Images/Wide310x150Logo.scale-200.png diff --git a/win/win32/vs2017/Images/Wide310x150Logo.scale-400.png b/win/win32/vs/Images/Wide310x150Logo.scale-400.png similarity index 100% rename from win/win32/vs2017/Images/Wide310x150Logo.scale-400.png rename to win/win32/vs/Images/Wide310x150Logo.scale-400.png diff --git a/win/win32/vs2017/NetHack.sln b/win/win32/vs/NetHack.sln similarity index 100% rename from win/win32/vs2017/NetHack.sln rename to win/win32/vs/NetHack.sln diff --git a/win/win32/vs2017/NetHack.vcxproj b/win/win32/vs/NetHack.vcxproj similarity index 100% rename from win/win32/vs2017/NetHack.vcxproj rename to win/win32/vs/NetHack.vcxproj diff --git a/win/win32/vs2017/NetHackPackage.appxmanifest b/win/win32/vs/NetHackPackage.appxmanifest similarity index 100% rename from win/win32/vs2017/NetHackPackage.appxmanifest rename to win/win32/vs/NetHackPackage.appxmanifest diff --git a/win/win32/vs2017/NetHackPackage.wapproj b/win/win32/vs/NetHackPackage.wapproj similarity index 100% rename from win/win32/vs2017/NetHackPackage.wapproj rename to win/win32/vs/NetHackPackage.wapproj diff --git a/win/win32/vs2017/NetHackProperties.props b/win/win32/vs/NetHackProperties.props similarity index 100% rename from win/win32/vs2017/NetHackProperties.props rename to win/win32/vs/NetHackProperties.props diff --git a/win/win32/vs2017/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj similarity index 100% rename from win/win32/vs2017/NetHackW.vcxproj rename to win/win32/vs/NetHackW.vcxproj diff --git a/win/win32/vs2017/PDCurses.vcxproj b/win/win32/vs/PDCurses.vcxproj similarity index 100% rename from win/win32/vs2017/PDCurses.vcxproj rename to win/win32/vs/PDCurses.vcxproj diff --git a/win/win32/vs2017/Package.StoreAssociation.xml b/win/win32/vs/Package.StoreAssociation.xml similarity index 100% rename from win/win32/vs2017/Package.StoreAssociation.xml rename to win/win32/vs/Package.StoreAssociation.xml diff --git a/win/win32/vs2017/ScreenShot.PNG b/win/win32/vs/ScreenShot.PNG similarity index 100% rename from win/win32/vs2017/ScreenShot.PNG rename to win/win32/vs/ScreenShot.PNG diff --git a/win/win32/vs2017/afterdlb.proj b/win/win32/vs/afterdlb.proj similarity index 100% rename from win/win32/vs2017/afterdlb.proj rename to win/win32/vs/afterdlb.proj diff --git a/win/win32/vs2017/aftermakedefs.proj b/win/win32/vs/aftermakedefs.proj similarity index 100% rename from win/win32/vs2017/aftermakedefs.proj rename to win/win32/vs/aftermakedefs.proj diff --git a/win/win32/vs2017/afternethack.proj b/win/win32/vs/afternethack.proj similarity index 100% rename from win/win32/vs2017/afternethack.proj rename to win/win32/vs/afternethack.proj diff --git a/win/win32/vs2017/afterrecover.proj b/win/win32/vs/afterrecover.proj similarity index 100% rename from win/win32/vs2017/afterrecover.proj rename to win/win32/vs/afterrecover.proj diff --git a/win/win32/vs2017/aftertile2bmp.proj b/win/win32/vs/aftertile2bmp.proj similarity index 100% rename from win/win32/vs2017/aftertile2bmp.proj rename to win/win32/vs/aftertile2bmp.proj diff --git a/win/win32/vs2017/aftertilemap.proj b/win/win32/vs/aftertilemap.proj similarity index 100% rename from win/win32/vs2017/aftertilemap.proj rename to win/win32/vs/aftertilemap.proj diff --git a/win/win32/vs2017/afteruudecode.proj b/win/win32/vs/afteruudecode.proj similarity index 100% rename from win/win32/vs2017/afteruudecode.proj rename to win/win32/vs/afteruudecode.proj diff --git a/win/win32/vs2017/build.bat b/win/win32/vs/build.bat similarity index 100% rename from win/win32/vs2017/build.bat rename to win/win32/vs/build.bat diff --git a/win/win32/vs2017/common.props b/win/win32/vs/common.props similarity index 100% rename from win/win32/vs2017/common.props rename to win/win32/vs/common.props diff --git a/win/win32/vs2017/config.props b/win/win32/vs/config.props similarity index 100% rename from win/win32/vs2017/config.props rename to win/win32/vs/config.props diff --git a/win/win32/vs2017/console.props b/win/win32/vs/console.props similarity index 100% rename from win/win32/vs2017/console.props rename to win/win32/vs/console.props diff --git a/win/win32/vs2017/default.props b/win/win32/vs/default.props similarity index 91% rename from win/win32/vs2017/default.props rename to win/win32/vs/default.props index e0bc58136..a8b166609 100644 --- a/win/win32/vs2017/default.props +++ b/win/win32/vs/default.props @@ -4,7 +4,7 @@ Application false MultiByte - v141 + $(DefaultPlatformToolset) $(BinDir) @@ -14,5 +14,4 @@ false true - diff --git a/win/win32/vs2017/default_dll.props b/win/win32/vs/default_dll.props similarity index 90% rename from win/win32/vs2017/default_dll.props rename to win/win32/vs/default_dll.props index 51d90a3ee..cf1306958 100644 --- a/win/win32/vs2017/default_dll.props +++ b/win/win32/vs/default_dll.props @@ -4,7 +4,7 @@ DynamicLibrary false MultiByte - v141 + $(DefaultPlatformToolset) true diff --git a/win/win32/vs2017/default_lib.props b/win/win32/vs/default_lib.props similarity index 90% rename from win/win32/vs2017/default_lib.props rename to win/win32/vs/default_lib.props index 61bf2ecaa..ce33f4abc 100644 --- a/win/win32/vs2017/default_lib.props +++ b/win/win32/vs/default_lib.props @@ -4,7 +4,7 @@ StaticLibrary false MultiByte - v141 + $(DefaultPlatformToolset) true diff --git a/win/win32/vs2017/dirs.props b/win/win32/vs/dirs.props similarity index 100% rename from win/win32/vs2017/dirs.props rename to win/win32/vs/dirs.props diff --git a/win/win32/vs2017/dlb.vcxproj b/win/win32/vs/dlb.vcxproj similarity index 100% rename from win/win32/vs2017/dlb.vcxproj rename to win/win32/vs/dlb.vcxproj diff --git a/win/win32/vs2017/dll.props b/win/win32/vs/dll.props similarity index 100% rename from win/win32/vs2017/dll.props rename to win/win32/vs/dll.props diff --git a/win/win32/vs2017/files.props b/win/win32/vs/files.props similarity index 100% rename from win/win32/vs2017/files.props rename to win/win32/vs/files.props diff --git a/win/win32/vs2017/makedefs.vcxproj b/win/win32/vs/makedefs.vcxproj similarity index 100% rename from win/win32/vs2017/makedefs.vcxproj rename to win/win32/vs/makedefs.vcxproj diff --git a/win/win32/vs2017/nh340key.def b/win/win32/vs/nh340key.def similarity index 100% rename from win/win32/vs2017/nh340key.def rename to win/win32/vs/nh340key.def diff --git a/win/win32/vs2017/nh340key.vcxproj b/win/win32/vs/nh340key.vcxproj similarity index 100% rename from win/win32/vs2017/nh340key.vcxproj rename to win/win32/vs/nh340key.vcxproj diff --git a/win/win32/vs2017/nhdefkey.def b/win/win32/vs/nhdefkey.def similarity index 100% rename from win/win32/vs2017/nhdefkey.def rename to win/win32/vs/nhdefkey.def diff --git a/win/win32/vs2017/nhdefkey.vcxproj b/win/win32/vs/nhdefkey.vcxproj similarity index 100% rename from win/win32/vs2017/nhdefkey.vcxproj rename to win/win32/vs/nhdefkey.vcxproj diff --git a/win/win32/vs2017/nhraykey.def b/win/win32/vs/nhraykey.def similarity index 100% rename from win/win32/vs2017/nhraykey.def rename to win/win32/vs/nhraykey.def diff --git a/win/win32/vs2017/nhraykey.vcxproj b/win/win32/vs/nhraykey.vcxproj similarity index 100% rename from win/win32/vs2017/nhraykey.vcxproj rename to win/win32/vs/nhraykey.vcxproj diff --git a/win/win32/vs2017/recover.vcxproj b/win/win32/vs/recover.vcxproj similarity index 100% rename from win/win32/vs2017/recover.vcxproj rename to win/win32/vs/recover.vcxproj diff --git a/win/win32/vs2017/tile2bmp.vcxproj b/win/win32/vs/tile2bmp.vcxproj similarity index 100% rename from win/win32/vs2017/tile2bmp.vcxproj rename to win/win32/vs/tile2bmp.vcxproj diff --git a/win/win32/vs2017/tilemap.vcxproj b/win/win32/vs/tilemap.vcxproj similarity index 100% rename from win/win32/vs2017/tilemap.vcxproj rename to win/win32/vs/tilemap.vcxproj diff --git a/win/win32/vs2017/tiles.vcxproj b/win/win32/vs/tiles.vcxproj similarity index 100% rename from win/win32/vs2017/tiles.vcxproj rename to win/win32/vs/tiles.vcxproj diff --git a/win/win32/vs2017/travisci.sh b/win/win32/vs/travisci.sh similarity index 100% rename from win/win32/vs2017/travisci.sh rename to win/win32/vs/travisci.sh diff --git a/win/win32/vs2017/uudecode.vcxproj b/win/win32/vs/uudecode.vcxproj similarity index 100% rename from win/win32/vs2017/uudecode.vcxproj rename to win/win32/vs/uudecode.vcxproj From c5c43ad00abae1bdd62d0cda4cab69b746a2dbd9 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sat, 10 Oct 2020 18:24:07 -0400 Subject: [PATCH 312/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Files b/Files index 5eb31b35a..4b1474fbd 100644 --- a/Files +++ b/Files @@ -430,7 +430,7 @@ splash.uu tiles-mingw32.mak tiles.mak winMS.h win/win32/vs: -(files for Visual Studio 2017 or 2019 Community Edition builds) +(files for Visual Studio 2017 Community Edition builds) NetHack.sln NetHack.vcxproj NetHackPackage.appxmanifest NetHackPackage.wapproj NetHackProperties.props NetHackW.vcxproj From 9599fa27df62d113d9ef96074dd671b033547a65 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Oct 2020 18:38:25 -0400 Subject: [PATCH 313/708] update win/win32/vs/.gitattributes text --- win/win32/vs/.gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/win32/vs/.gitattributes b/win/win32/vs/.gitattributes index 041653ea8..f9d4fff5d 100644 --- a/win/win32/vs/.gitattributes +++ b/win/win32/vs/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_Visual_Studio_2017_Community_Edition_builds) +* NH_filestag=(file%s_for_Visual_Studio_2017_or_2019_Community_Edition_builds) From cc50aa036df44b4e329554933be0958d66290f24 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 10 Oct 2020 16:28:41 -0700 Subject: [PATCH 314/708] Update files heading to reflect that we support VS 2017 and 2019. --- win/win32/vs/.gitattributes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/win32/vs/.gitattributes b/win/win32/vs/.gitattributes index 041653ea8..f9d4fff5d 100644 --- a/win/win32/vs/.gitattributes +++ b/win/win32/vs/.gitattributes @@ -1 +1 @@ -* NH_filestag=(file%s_for_Visual_Studio_2017_Community_Edition_builds) +* NH_filestag=(file%s_for_Visual_Studio_2017_or_2019_Community_Edition_builds) From d6719ea0db723c5b2d4b3713eb0a3f474955f2b6 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 10 Oct 2020 19:36:36 -0400 Subject: [PATCH 315/708] cron daily Files update --- Files | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Files b/Files index 4b1474fbd..f12e09304 100644 --- a/Files +++ b/Files @@ -430,7 +430,7 @@ splash.uu tiles-mingw32.mak tiles.mak winMS.h win/win32/vs: -(files for Visual Studio 2017 Community Edition builds) +(files for Visual Studio 2017 or 2019 Community Edition builds) NetHack.sln NetHack.vcxproj NetHackPackage.appxmanifest NetHackPackage.wapproj NetHackProperties.props NetHackW.vcxproj @@ -453,7 +453,7 @@ tilemap.vcxproj tiles.vcxproj travisci.sh uudecode.vcxproj win/win32/vs/Images: -(files for Visual Studio 2017 Community Edition builds) +(files for Visual Studio 2017 or 2019 Community Edition builds) BadgeLogo.scale-100.png BadgeLogo.scale-125.png BadgeLogo.scale-150.png From 75f852f27755acca1922b08c7d93ea8671342ec1 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 09:08:27 -0400 Subject: [PATCH 316/708] cross-compiles need not build host native lua library Because some Makefile.top dependencies triggered the build of the host native lua library, the cross-compiles were building it needlessly. Make it a make variable so that it can be overridden by cross-compile recipes in sys/unix/hints/include/cross-*.2020 --- sys/unix/Makefile.top | 7 ++++--- sys/unix/hints/include/cross-pre.2020 | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index c0e5433a3..e87cd4133 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -94,6 +94,7 @@ DATNODLB = $(VARDATND) license symbols DATDLB = $(DATHELP) dungeon.lua tribute $(SPEC_LEVS) $(QUEST_LEVS) $(VARDATD) DAT = $(DATNODLB) $(DATDLB) +TOPLUALIB = lib/lua/liblua.a ALLDEP = $(GAME) recover Guidebook $(VARDAT) spec_levs check-dlb # first target is also the default target for 'make' without any arguments @@ -104,7 +105,7 @@ all: $(ALLDEP) $(GAME): lua_support ( cd src ; $(MAKE) $(GAME) ) -lua_support: lib/lua/liblua.a include/nhlua.h +lua_support: $(TOPLUALIB) include/nhlua.h @true lib/lua-$(LUA_VERSION)/src/liblua.a: lib/lua-$(LUA_VERSION)/src/lua.h ( cd lib/lua-$(LUA_VERSION)/src \ @@ -112,7 +113,7 @@ lib/lua-$(LUA_VERSION)/src/liblua.a: lib/lua-$(LUA_VERSION)/src/lua.h lib/lua/liblua.a: lib/lua-$(LUA_VERSION)/src/liblua.a @( if [ ! -d lib/lua ] ; then mkdir -p lib/lua ; fi ) cp lib/lua-$(LUA_VERSION)/src/liblua.a $@ -include/nhlua.h: lib/lua/liblua.a +include/nhlua.h: $(TOPLUALIB) echo '/* nhlua.h - generated by top Makefile */' > $@ @echo '#include "../lib/lua-$(LUA_VERSION)/src/lua.h"' >> $@ @sed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' \ @@ -207,7 +208,7 @@ dlb: ( cd util ; $(MAKE) dlb ) ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) -wasm: +wasm: include/nhlua.h ( cd src ; $(MAKE) $(WASM_TARGET) ) package: $(GAME) recover $(VARDAT) spec_levs diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 05f1b15a5..1c8a60dab 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -184,6 +184,7 @@ override SYSOBJ= $(TARGETPFX)pcmain.o $(TARGETPFX)msdos.o \ $(TARGETPFX)tileset.o $(TARGETPFX)tile.o override WINLIB= override LUALIB= +override TOPLUALIB= override GAMEBIN = $(TARGETPFX)nethack.exe override PACKAGE = dospkg override PREGAME += mkdir -p $(TARGETDIR) ; @@ -273,6 +274,7 @@ override SYSOBJ = $(TARGETPFX)amidos.o $(TARGETPFX)amigst.o \ # ../util/txt2iff.o override WINLIB= override LUALIB= +override TOPLUALIB= override GAMEBIN = $(TARGETPFX)nethack override PACKAGE = amigapkg override PREGAME += mkdir -p $(TARGETDIR) ; @@ -375,6 +377,7 @@ override SYSOBJ= $(TARGETPFX)libnethackmain.o \ $(TARGETPFX)winshim.o override WINLIB = emranlib override LUALIB= +override TOPLUALIB= override REGEXOBJ = $(TARGETPFX)posixregex.o override WINOBJ= # don't bother Making regular NetHack executable From eaa8b99eea6830c49f6cde98d8ab0d9ac69c3168 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 09:16:23 -0400 Subject: [PATCH 317/708] follow-up bit remove an unnecessary dependency for top Makefile wasm --- 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 e87cd4133..78e7238a7 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -208,7 +208,7 @@ dlb: ( cd util ; $(MAKE) dlb ) ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) -wasm: include/nhlua.h +wasm: ( cd src ; $(MAKE) $(WASM_TARGET) ) package: $(GAME) recover $(VARDAT) spec_levs From d4e97cc650b4ac9ad446b299b01c09a057506816 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 09:43:15 -0400 Subject: [PATCH 318/708] libnethackmain.c includes date.h --- sys/unix/hints/linux.2020 | 2 +- sys/unix/hints/macOS.2020 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index b9119d5c0..16941cbf7 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -228,7 +228,7 @@ ifdef WANT_LIBNH libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." -libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) +libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) ../include/date.h $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 44a1106bc..f9e3c8f58 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -298,7 +298,7 @@ ifdef WANT_LIBNH libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." -libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) +libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) ../include/date.h $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< From 0adb64e3846d57d8fb1787ae58f7bfed2e47b26a Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 10:51:46 -0400 Subject: [PATCH 319/708] get this working: "make wasm" --- sys/unix/Makefile.top | 2 +- sys/unix/hints/include/cross-post.2020 | 3 +-- sys/unix/hints/include/cross-pre.2020 | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 78e7238a7..740c8b979 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -209,7 +209,7 @@ dlb: ( cd dat ; LC_ALL=C ; ../util/dlb cf nhdat $(DATDLB) ) wasm: - ( cd src ; $(MAKE) $(WASM_TARGET) ) + ( cd src ; $(MAKE) CROSS_TO_WASM=1 ../targets/wasm/nethack.js ) package: $(GAME) recover $(VARDAT) spec_levs ( cd src ; $(MAKE) $(PACKAGE) ) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index f7fda70ab..9d43248b9 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -133,8 +133,7 @@ $(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf $(WASM_DATA_DIR)/nhdat: - ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dlb ) - ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' dofiles-dlb ) + ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' $(WASMDEP) dofiles-dlb ) # $(TARGETPFX)unixmain.o : ../sys/unix/unixmain.c $(HACK_H) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 1c8a60dab..d51a9bdde 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -384,7 +384,8 @@ override WINOBJ= override GAME= # the real VARDAT hasn't been defined yet for use in ALLDEP override WASM_DAT = bogusmon data engrave epitaph oracles options quest.lua rumors -override ALLDEP = include/nhlua.h $(WASM_DAT) spec_levs check-dlb wasm +WASMDEP = include/nhlua.h $(WASM_DAT) spec_levs check-dlb +override ALLDEP = $(WASMDEP) wasm override PREGAME += mkdir -p $(TARGETDIR)/wasm-data ; override CLEANMORE += rm -rf $(TARGETDIR) ; RANLIB=$(EMRANLIB) From 6806c30a59969da59b4329aacd35dcce852fc4f4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 13:33:51 -0400 Subject: [PATCH 320/708] adopt some integration suggestions sys/lib -> sys/libnh sys/lib/libnethackmain.c -> sys/libnh/libnhmain.c libnethack.a -> libnh.a --- sys/{lib => libnh}/README.md | 0 sys/{lib/libnethackmain.c => libnh/libnhmain.c} | 4 ++-- sys/{lib => libnh}/npm-package/LICENSE.md | 0 sys/{lib => libnh}/npm-package/README.md | 0 sys/{lib => libnh}/npm-package/package-lock.json | 0 sys/{lib => libnh}/npm-package/package.json | 0 sys/{lib => libnh}/npm-package/src/nethackShim.js | 0 sys/{lib => libnh}/npm-package/test/test.js | 0 sys/{lib => libnh}/sysconf | 0 sys/{lib => libnh}/test/README.md | 0 sys/{lib => libnh}/test/libtest.c | 0 sys/{lib => libnh}/test/run.sh | 0 sys/unix/Makefile.src | 2 +- sys/unix/hints/include/cross-post.2020 | 4 ++-- sys/unix/hints/include/cross-pre.2020 | 8 ++++---- sys/unix/hints/linux.2020 | 10 +++++----- sys/unix/hints/macOS.2020 | 10 +++++----- 17 files changed, 19 insertions(+), 19 deletions(-) rename sys/{lib => libnh}/README.md (100%) rename sys/{lib/libnethackmain.c => libnh/libnhmain.c} (99%) rename sys/{lib => libnh}/npm-package/LICENSE.md (100%) rename sys/{lib => libnh}/npm-package/README.md (100%) rename sys/{lib => libnh}/npm-package/package-lock.json (100%) rename sys/{lib => libnh}/npm-package/package.json (100%) rename sys/{lib => libnh}/npm-package/src/nethackShim.js (100%) rename sys/{lib => libnh}/npm-package/test/test.js (100%) rename sys/{lib => libnh}/sysconf (100%) rename sys/{lib => libnh}/test/README.md (100%) rename sys/{lib => libnh}/test/libtest.c (100%) rename sys/{lib => libnh}/test/run.sh (100%) diff --git a/sys/lib/README.md b/sys/libnh/README.md similarity index 100% rename from sys/lib/README.md rename to sys/libnh/README.md diff --git a/sys/lib/libnethackmain.c b/sys/libnh/libnhmain.c similarity index 99% rename from sys/lib/libnethackmain.c rename to sys/libnh/libnhmain.c index cec8c076e..200159955 100644 --- a/sys/lib/libnethackmain.c +++ b/sys/libnh/libnhmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixmain.c $NHDT-Date: 1596498297 2020/08/03 23:44:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 3.7 libnhmain.c $NHDT-Date: 1596498297 2020/08/03 23:44:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1124,4 +1124,4 @@ EM_JS(void, create_global, (char *name_str, void *ptr, char *type_str), { #endif -/*libnethack.c*/ +/*libnhmain.c*/ diff --git a/sys/lib/npm-package/LICENSE.md b/sys/libnh/npm-package/LICENSE.md similarity index 100% rename from sys/lib/npm-package/LICENSE.md rename to sys/libnh/npm-package/LICENSE.md diff --git a/sys/lib/npm-package/README.md b/sys/libnh/npm-package/README.md similarity index 100% rename from sys/lib/npm-package/README.md rename to sys/libnh/npm-package/README.md diff --git a/sys/lib/npm-package/package-lock.json b/sys/libnh/npm-package/package-lock.json similarity index 100% rename from sys/lib/npm-package/package-lock.json rename to sys/libnh/npm-package/package-lock.json diff --git a/sys/lib/npm-package/package.json b/sys/libnh/npm-package/package.json similarity index 100% rename from sys/lib/npm-package/package.json rename to sys/libnh/npm-package/package.json diff --git a/sys/lib/npm-package/src/nethackShim.js b/sys/libnh/npm-package/src/nethackShim.js similarity index 100% rename from sys/lib/npm-package/src/nethackShim.js rename to sys/libnh/npm-package/src/nethackShim.js diff --git a/sys/lib/npm-package/test/test.js b/sys/libnh/npm-package/test/test.js similarity index 100% rename from sys/lib/npm-package/test/test.js rename to sys/libnh/npm-package/test/test.js diff --git a/sys/lib/sysconf b/sys/libnh/sysconf similarity index 100% rename from sys/lib/sysconf rename to sys/libnh/sysconf diff --git a/sys/lib/test/README.md b/sys/libnh/test/README.md similarity index 100% rename from sys/lib/test/README.md rename to sys/libnh/test/README.md diff --git a/sys/lib/test/libtest.c b/sys/libnh/test/libtest.c similarity index 100% rename from sys/lib/test/libtest.c rename to sys/libnh/test/libtest.c diff --git a/sys/lib/test/run.sh b/sys/libnh/test/run.sh similarity index 100% rename from sys/lib/test/run.sh rename to sys/libnh/test/run.sh diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 51b7e06c8..335d71853 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -300,7 +300,7 @@ WINGNOMEOBJ = WINGEMSRC = WINGEMOBJ = -# Files for Shim windowing interface for libnethack -- doesn't do anything, +# 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 diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index 9d43248b9..add7de1d0 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -130,7 +130,7 @@ $(WASM_DATA_DIR): $(WASM_DATA_DIR)/nhdat touch $(WASM_DATA_DIR)/record touch $(WASM_DATA_DIR)/logfile touch $(WASM_DATA_DIR)/xlogfile - cp ../sys/lib/sysconf $(WASM_DATA_DIR)/sysconf + cp ../sys/libnh/sysconf $(WASM_DATA_DIR)/sysconf $(WASM_DATA_DIR)/nhdat: ( cd ..; $(MAKE) INSTDIR='$(WASM_DATA_DIR)' $(WASMDEP) dofiles-dlb ) @@ -142,7 +142,7 @@ $(TARGETPFX)unixunix.o : ../sys/unix/unixunix.c $(HACK_H) $(TARGETPFX)ioctl.o : ../sys/share/ioctl.c $(HACK_H) $(TARGETPFX)unixtty.o : ../sys/share/unixtty.c $(HACK_H) $(TARGETPFX)winshim.o : ../win/shim/winshim.c $(HACK_H) -$(TARGETPFX)libnethackmain.o : ../sys/lib/libnethackmain.c \ +$(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c \ $(HACK_H) ../include/date.h endif # CROSS_TO_WASM # diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index d51a9bdde..0e9816627 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -367,11 +367,11 @@ override TARGET_CFLAGS = $(EMCC_CFLAGS) $(WASM_CFLAGS) $(WASM_TARGET_CFLAGS) override TARGET_CXXFLAGS = $(TARGET_CFLAGS) override TARGET_LINK = $(TARGET_CC) override TARGET_LFLAGS= $(EMCC_LFLAGS) -override SYSSRC = ../sys/lib/libnethackmain.c \ +override SYSSRC = ../sys/libnh/libnhmain.c \ ../sys/share/ioctl.c ../sys/share/unixtty.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c \ ../win/shim/winshim.c -override SYSOBJ= $(TARGETPFX)libnethackmain.o \ +override SYSOBJ= $(TARGETPFX)libnhmain.o \ $(TARGETPFX)ioctl.o $(TARGETPFX)unixtty.o \ $(TARGETPFX)unixunix.o $(TARGETPFX)unixres.o \ $(TARGETPFX)winshim.o @@ -393,8 +393,8 @@ RANLIB=$(EMRANLIB) # Rule for file in sys/unix $(TARGETPFX)%.o : ../sys/unix/%.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< -# Rule for file in sys/lib -$(TARGETPFX)%.o : ../sys/lib/%.c +# Rule for file in sys/libnh +$(TARGETPFX)%.o : ../sys/libnh/%.c $(TARGET_CC) $(TARGET_CFLAGS) -c -o$@ $< # Rule for files in win/shim $(TARGETPFX)%.o : ../win/shim/%.c diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 16941cbf7..f730ff602 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -166,16 +166,16 @@ VARDATND += $(sort $(VARDATND0)) ifdef WANT_LIBNH CFLAGS += -DSHIM_GRAPHICS -DNOTTYGRAPHICS -DNOSHELL -DLIBNH -LIBNHSYSSRC = ../sys/lib/libnethackmain.c \ +LIBNHSYSSRC = ../sys/libnh/libnhmain.c \ ../sys/share/ioctl.c ../sys/share/unixtty.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c \ ../win/shim/winshim.c -LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ +LIBNHSYSOBJ= libnhmain.o ioctl.o unixtty.o unixunix.o \ unixres.o winshim.o #don't bother building the game executable as it will fail #without winshim override GAME= -MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) +MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnh.a ) endif # WANT_LIBNH #PREFIX=/usr @@ -225,10 +225,10 @@ GAMEPERM = 0755 #-INCLUDE cross-post.2020 # ifdef WANT_LIBNH -libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a +libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." -libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) ../include/date.h +libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) ../include/date.h $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index f9e3c8f58..fb739731e 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -173,16 +173,16 @@ VARDATND += $(sort $(VARDATND0)) ifdef WANT_LIBNH CFLAGS += -DSHIM_GRAPHICS -DNOTTYGRAPHICS -DNOSHELL -DLIBNH -LIBNHSYSSRC = ../sys/lib/libnethackmain.c \ +LIBNHSYSSRC = ../sys/libnh/libnhmain.c \ ../sys/share/ioctl.c ../sys/share/unixtty.c \ ../sys/unix/unixunix.c ../sys/unix/unixres.c \ ../win/shim/winshim.c -LIBNHSYSOBJ= libnethackmain.o ioctl.o unixtty.o unixunix.o \ +LIBNHSYSOBJ= libnhmain.o ioctl.o unixtty.o unixunix.o \ unixres.o winshim.o #don't bother building the game executable as it will fail #without winshim override GAME= -MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnethack.a ) +MOREALL += ( cd src ; $(MAKE) pregame ; $(MAKE) libnh.a ) endif # WANT_LIBNH WANT_BUNDLE=1 @@ -295,10 +295,10 @@ VARDIR=$(HACKDIR) # #-POST ifdef WANT_LIBNH -libnethack.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a +libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." -libnethackmain.o : ../sys/lib/libnethackmain.c $(HACK_H) ../include/date.h +libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) ../include/date.h $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< From d9395dcd23c4dd585e4ea42181069fbc38b4f796 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 13:42:12 -0400 Subject: [PATCH 321/708] more integration suggestion adoption --- sys/libnh/libnhmain.c | 1 - sys/unix/hints/include/cross-post.2020 | 3 +-- sys/unix/hints/linux.2020 | 2 +- sys/unix/hints/macOS.2020 | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 200159955..fe5ea55e7 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -7,7 +7,6 @@ #include "hack.h" #include "dlb.h" -#include "date.h" #include #include diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index add7de1d0..b2d45c787 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -142,8 +142,7 @@ $(TARGETPFX)unixunix.o : ../sys/unix/unixunix.c $(HACK_H) $(TARGETPFX)ioctl.o : ../sys/share/ioctl.c $(HACK_H) $(TARGETPFX)unixtty.o : ../sys/share/unixtty.c $(HACK_H) $(TARGETPFX)winshim.o : ../win/shim/winshim.c $(HACK_H) -$(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c \ - $(HACK_H) ../include/date.h +$(TARGETPFX)libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) endif # CROSS_TO_WASM # diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index f730ff602..2d536f4ff 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -228,7 +228,7 @@ ifdef WANT_LIBNH libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." -libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) ../include/date.h +libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index fb739731e..85f9b3208 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -298,7 +298,7 @@ ifdef WANT_LIBNH libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a @echo "$@ built." -libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) ../include/date.h +libnhmain.o : ../sys/libnh/libnhmain.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< winshim.o : ../win/shim/winshim.c $(HACK_H) $(CC) $(CFLAGS) -c -o$@ $< From e4473de5860104a03a9524e470cdb66bd213e01d Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 11 Oct 2020 14:29:16 -0400 Subject: [PATCH 322/708] cron daily Files update --- Files | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Files b/Files index f12e09304..511936008 100644 --- a/Files +++ b/Files @@ -218,23 +218,23 @@ uhitm.c vault.c version.c vision.c weapon.c were.c wield.c windows.c wizard.c worm.c worn.c write.c zap.c -sys/lib: +sys/libnh: (files in top directory) -README.md libnethackmain.c sysconf +README.md libnhmain.c sysconf -sys/lib/npm-package: +sys/libnh/npm-package: (files in top directory) LICENSE.md README.md package-lock.json package.json -sys/lib/npm-package/src: +sys/libnh/npm-package/src: (file in top directory) nethackShim.js -sys/lib/npm-package/test: +sys/libnh/npm-package/test: (file in top directory) test.js -sys/lib/test: +sys/libnh/test: (files in top directory) README.md libtest.c run.sh From 267228d0ddcc06e0e7070efc213bab56c23d2347 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 13 Oct 2020 13:41:57 -0700 Subject: [PATCH 323/708] Qt toolbar 'rest' button An issue in the core made the "Zz" button in the Qt toolbar only work if rest_on_space was enabled. cmd_from_func() was returning ' ' instead of '.' for the keystroke to run the rest command. --- doc/fixes37.0 | 4 +++- src/cmd.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 0c1d1ea4d..3797a96b3 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.326 $ $NHDT-Date: 1602355548 2020/10/10 18:45:48 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.327 $ $NHDT-Date: 1602621704 2020/10/13 20:41:44 $ General Fixes and Modified Features ----------------------------------- @@ -439,6 +439,8 @@ Qt: implement --More-- prompt to support MSGTYPE=stop Qt: for menu search, don't require clicking on the search target popup before typing target string (was using typed letters to make menu selections if player didn't click on the popup first) +Qt: rest ("Zz") button on the toolbar only worked when 'rest_on_space' was On + (core issue, not Qt's fault) Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/src/cmd.c b/src/cmd.c index 19ae95498..b870f0d46 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1597069374 2020/08/10 14:22:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.422 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1602621705 2020/10/13 20:41:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.423 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2272,9 +2272,18 @@ int NDECL((*fn)); { int i; - for (i = 0; i < 256; ++i) + /* skip NUL; allowing it would wreak havoc */ + for (i = 1; i < 256; ++i) { + /* skip space; we'll use it below as last resort if no other + keystroke invokes space's command */ + if (i == ' ') + continue; + if (g.Cmd.commands[i] && g.Cmd.commands[i]->ef_funct == fn) return (char) i; + } + if (g.Cmd.commands[' '] && g.Cmd.commands[' ']->ef_funct == fn) + return ' '; return '\0'; } From 7011b10f649ef8a267c3fb568a42670b6705f5cb Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 13 Oct 2020 14:05:52 -0700 Subject: [PATCH 324/708] Qt "Get" -> "Pick up" Both the toolbar button for pick up and the action menu entry for pick up were labeled "Get". That's confusing for an experienced player who is looking for "Pick up". Rename both of them. Also, consolidate repetitive code used to set up toolbar buttons. --- doc/fixes37.0 | 3 +- win/Qt/qt_main.cpp | 99 ++++++++++++++++++++++++---------------------- win/Qt/qt_main.h | 2 + 3 files changed, 55 insertions(+), 49 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3797a96b3..f32d792cd 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.327 $ $NHDT-Date: 1602621704 2020/10/13 20:41:44 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.328 $ $NHDT-Date: 1602623144 2020/10/13 21:05:44 $ General Fixes and Modified Features ----------------------------------- @@ -441,6 +441,7 @@ Qt: for menu search, don't require clicking on the search target popup before if player didn't click on the popup first) Qt: rest ("Zz") button on the toolbar only worked when 'rest_on_space' was On (core issue, not Qt's fault) +Qt: rename toolbar button "Get" and action menu choice "Get" to "Pick up" Qt+QSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 40276b195..73d56f080 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -294,7 +294,7 @@ static const char * fire_xpm[] = { " . o ", " o "}; /* XPM */ -static const char * get_xpm[] = { +static const char * pickup_xpm[] = { "12 13 3 1", " c None", ". c #000000000000", @@ -478,10 +478,10 @@ aboutMsg() class SmallToolButton : public QToolButton { public: - SmallToolButton(const QPixmap & pm, const QString &textLabel, - const QString& grouptext, - QObject * receiver, const char* slot, - QWidget * parent) : + SmallToolButton(const QPixmap &pm, const QString &textLabel, + const QString &grouptext, + QObject *receiver, const char *slot, + QWidget *parent) : QToolButton(parent) { setIcon(QIcon(pm)); @@ -599,12 +599,13 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : /* { act1, "Fight\tShift+F", "F", 3}, */ { act1, "Fire from quiver", 2, dofire}, { act1, "Force", 3, doforce}, - { act1, "Get", 2, dopickup}, { act1, "Jump", 3, dojump}, { act2, "Kick", 2, dokick}, { act2, "Loot", 3, doloot}, { act2, "Open door", 3, doopen}, { act2, "Pay", 3, dopay}, + // calling this "Get" was confusing to experienced players + { act1, "Pick up (was Get)", 3, dopickup}, { act2, "Rest", 2, donull}, { act2, "Ride", 3, doride}, { act2, "Search", 3, dosearch}, @@ -762,51 +763,37 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : game->addAction("Quit NetHack", this, SLOT(doQuit(bool))); #endif + // order changed: was Again, Get, Kick, Throw, Fire, Drop, Eat, Rest + // now Again, PickUp, Drop, Kick, Throw, Fire, Eat, Rest QSignalMapper* sm = new QSignalMapper(this); - connect(sm, SIGNAL(mapped(const QString&)), this, SLOT(doKeys(const QString&))); - QToolButton* tb; - char actchar[32]; - tb = new SmallToolButton( QPixmap(again_xpm),"Again","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", g.Cmd.spkeys[NHKF_DOAGAIN]); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(get_xpm),"Get","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(dopickup)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(kick_xpm),"Kick","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(dokick)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(throw_xpm),"Throw","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(dothrow)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(fire_xpm),"Fire","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(dofire)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(drop_xpm),"Drop","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(doddrop)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(eat_xpm),"Eat","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(doeat)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); - tb = new SmallToolButton( QPixmap(rest_xpm),"Rest","Action", sm, SLOT(map()), toolbar ); - Sprintf(actchar, "%c", cmd_from_func(donull)); - sm->setMapping(tb, actchar ); - toolbar->addWidget(tb); + connect(sm, SIGNAL(mapped(const QString&)), + this, SLOT(doKeys(const QString&))); + // 'donull' is a placeholder here; AddToolButton() will fix it up + AddToolButton(toolbar, sm, "Again", donull, QPixmap(again_xpm)); + // this used to be called "Get" which is confusing to experienced players + AddToolButton(toolbar, sm, "Pick up", dopickup, QPixmap(pickup_xpm)); + AddToolButton(toolbar, sm, "Drop", doddrop, QPixmap(drop_xpm)); + AddToolButton(toolbar, sm, "Kick", dokick, QPixmap(kick_xpm)); + AddToolButton(toolbar, sm, "Throw", dothrow, QPixmap(throw_xpm)); + AddToolButton(toolbar, sm, "Fire", dofire, QPixmap(fire_xpm)); + AddToolButton(toolbar, sm, "Eat", doeat, QPixmap(eat_xpm)); + AddToolButton(toolbar, sm, "Rest", donull, QPixmap(rest_xpm)); - connect(game,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); - connect(apparel,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); - connect(act1,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); + connect(game, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); + connect(apparel, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); + connect(act1, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); if (act2 != act1) - connect(act2,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); - connect(magic,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); - connect(info,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); - connect(help,SIGNAL(triggered(QAction *)),this,SLOT(doMenuItem(QAction *))); + connect(act2, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); + connect(magic, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); + connect(info, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); + connect(help, SIGNAL(triggered(QAction *)), + this, SLOT(doMenuItem(QAction *))); #ifdef KDE setMenu (menubar); @@ -854,6 +841,22 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : } } +void NetHackQtMainWindow::AddToolButton(QToolBar *toolbar, QSignalMapper *sm, + const char *name, int NDECL((*func)), + QPixmap xpm) +{ + QToolButton *tb = new SmallToolButton(xpm, QString(name), "Action", + sm, SLOT(map()), toolbar); + char actchar[32]; + // the ^A command is just a keystroke, not a full blown command function + if (!strcmp(name, "Again")) + (void) strkitten(actchar, ::g.Cmd.spkeys[NHKF_DOAGAIN]); + else + Sprintf(actchar, "%c", cmd_from_func(func)); + sm->setMapping(tb, actchar); + toolbar->addWidget(tb); +} + void NetHackQtMainWindow::zoomMap() { qt_settings->toggleGlyphSize(); diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index 17719fabb..e998e63dd 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -77,6 +77,8 @@ private slots: private: void ShowIfReady(); + void AddToolButton(QToolBar *toolbar, QSignalMapper *sm, + const char *name, int NDECL((*func)), QPixmap xpm); #ifdef KDE KMenuBar* menubar; From 6a443226d18ab5f35a5e7b8de58af5f9507ba8ff Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 14 Oct 2020 03:02:55 -0700 Subject: [PATCH 325/708] Qt toolbar: add button for 'search' The toolbar contains do-Again, Pick up, Drop, Kick, Throw, Fire, Eat, and Rest. Insert Search in front of Rest since it's useful in its own right and some players prefer it even when resting. Includes a new 12x13 icon; a tiny magnifying glass shown straight on is something I can manage. --- doc/fixes37.0 | 5 +++-- win/Qt/qt_main.cpp | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f32d792cd..0aff91687 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.328 $ $NHDT-Date: 1602623144 2020/10/13 21:05:44 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.329 $ $NHDT-Date: 1602669770 2020/10/14 10:02:50 $ General Fixes and Modified Features ----------------------------------- @@ -442,7 +442,7 @@ Qt: for menu search, don't require clicking on the search target popup before Qt: rest ("Zz") button on the toolbar only worked when 'rest_on_space' was On (core issue, not Qt's fault) Qt: rename toolbar button "Get" and action menu choice "Get" to "Pick up" -Qt+QSX: fix control key +Qt+OSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" for making persistent Qt customizations to "nethack->Preferences..." @@ -579,6 +579,7 @@ Qt: clicking on the paper doll runs the #seeall command (inventory of wielded and worn items plus tools [lamps, leashes] actively in use; in other words, same set of things whose tiles are used to populate the doll) Qt: clicking on the status window runs the #attributes command (^X) +Qt: add a Search button to the toolbar NetHack Community Patches (or Variation) Included diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 73d56f080..00765d8a9 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -352,6 +352,25 @@ static const char * eat_xpm[] = { " oo oo ", " oo oo "}; /* XPM */ +static const char * search_xpm[] = { +"12 13 3 1", +" c None", +". c #FFFFFFFF0000", +"X c #7F0000000000", +" ", +" XXXXX ", +" X ... X ", +" X.....X ", +" X.....X ", +" X ... X ", +" XXXXX ", +" X ", +" X ", +" X ", +" X ", +" X ", +" "}; +/* XPM */ static const char * rest_xpm[] = { "12 13 2 1", " c None", @@ -777,6 +796,7 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : AddToolButton(toolbar, sm, "Throw", dothrow, QPixmap(throw_xpm)); AddToolButton(toolbar, sm, "Fire", dofire, QPixmap(fire_xpm)); AddToolButton(toolbar, sm, "Eat", doeat, QPixmap(eat_xpm)); + AddToolButton(toolbar, sm, "Search", dosearch, QPixmap(search_xpm)); AddToolButton(toolbar, sm, "Rest", donull, QPixmap(rest_xpm)); connect(game, SIGNAL(triggered(QAction *)), From 42b466e87b2fd04ae88ac7bb4627321f8e112709 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 14 Oct 2020 09:25:45 -0700 Subject: [PATCH 326/708] artifact.h formatting The automated reformatting way back when left artifact.h in need of manual fixup, particularly SPFX_HPHDAM. --- include/artifact.h | 56 ++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/include/artifact.h b/include/artifact.h index b10d75160..b91e3602e 100644 --- a/include/artifact.h +++ b/include/artifact.h @@ -1,43 +1,40 @@ -/* NetHack 3.7 artifact.h $NHDT-Date: 1596498526 2020/08/03 23:48:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.7 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. */ #ifndef ARTIFACT_H #define ARTIFACT_H +/* clang-format off */ -#define SPFX_NONE 0x00000000L /* no special effects, just a bonus */ -#define SPFX_NOGEN 0x00000001L /* item is special, bequeathed by gods */ -#define SPFX_RESTR 0x00000002L /* item is restricted - can't be named */ -#define SPFX_INTEL 0x00000004L /* item is self-willed - intelligent */ -#define SPFX_SPEAK 0x00000008L /* item can speak (not implemented) */ -#define SPFX_SEEK 0x00000010L /* item helps you search for things */ -#define SPFX_WARN 0x00000020L /* item warns you of danger */ -#define SPFX_ATTK 0x00000040L /* item has a special attack (attk) */ -#define SPFX_DEFN 0x00000080L /* item has a special defence (defn) */ -#define SPFX_DRLI 0x00000100L /* drains a level from monsters */ +#define SPFX_NONE 0x00000000L /* no special effects, just a bonus */ +#define SPFX_NOGEN 0x00000001L /* item is special, bequeathed by gods */ +#define SPFX_RESTR 0x00000002L /* item is restricted - can't be named */ +#define SPFX_INTEL 0x00000004L /* item is self-willed - intelligent */ +#define SPFX_SPEAK 0x00000008L /* item can speak (not implemented) */ +#define SPFX_SEEK 0x00000010L /* item helps you search for things */ +#define SPFX_WARN 0x00000020L /* item warns you of danger */ +#define SPFX_ATTK 0x00000040L /* item has a special attack (attk) */ +#define SPFX_DEFN 0x00000080L /* item has a special defence (defn) */ +#define SPFX_DRLI 0x00000100L /* drains a level from monsters */ #define SPFX_SEARCH 0x00000200L /* helps searching */ #define SPFX_BEHEAD 0x00000400L /* beheads monsters */ #define SPFX_HALRES 0x00000800L /* blocks hallucinations */ -#define SPFX_ESP 0x00001000L /* ESP (like amulet of ESP) */ -#define SPFX_STLTH 0x00002000L /* Stealth */ -#define SPFX_REGEN 0x00004000L /* Regeneration */ +#define SPFX_ESP 0x00001000L /* ESP (like amulet of ESP) */ +#define SPFX_STLTH 0x00002000L /* Stealth */ +#define SPFX_REGEN 0x00004000L /* Regeneration */ #define SPFX_EREGEN 0x00008000L /* Energy Regeneration */ #define SPFX_HSPDAM 0x00010000L /* 1/2 spell damage (on player) in combat */ -#define SPFX_HPHDAM \ - 0x00020000L /* 1/2 physical damage (on player) in combat */ -#define SPFX_TCTRL 0x00040000L /* Teleportation Control */ -#define SPFX_LUCK 0x00080000L /* Increase Luck (like Luckstone) */ -#define SPFX_DMONS 0x00100000L /* attack bonus on one monster type */ -#define SPFX_DCLAS 0x00200000L /* attack bonus on monsters w/ symbol mtype \ - */ -#define SPFX_DFLAG1 0x00400000L /* attack bonus on monsters w/ mflags1 flag \ - */ -#define SPFX_DFLAG2 0x00800000L /* attack bonus on monsters w/ mflags2 flag \ - */ -#define SPFX_DALIGN 0x01000000L /* attack bonus on non-aligned monsters */ -#define SPFX_DBONUS 0x01F00000L /* attack bonus mask */ -#define SPFX_XRAY 0x02000000L /* gives X-RAY vision to player */ +#define SPFX_HPHDAM 0x00020000L /* 1/2 physical damage (on player) in combat */ +#define SPFX_TCTRL 0x00040000L /* Teleportation Control */ +#define SPFX_LUCK 0x00080000L /* Increase Luck (like Luckstone) */ +#define SPFX_DMONS 0x00100000L /* attack bonus on one monster type */ +#define SPFX_DCLAS 0x00200000L /* attack bonus on monsters w/ symbol mtype */ +#define SPFX_DFLAG1 0x00400000L /* attack bonus on monsters w/ mflags1 flag */ +#define SPFX_DFLAG2 0x00800000L /* attack bonus on monsters w/ mflags2 flag */ +#define SPFX_DALIGN 0x01000000L /* attack bonus on non-aligned monsters */ +#define SPFX_DBONUS 0x01F00000L /* attack bonus mask */ +#define SPFX_XRAY 0x02000000L /* gives X-RAY vision to player */ #define SPFX_REFLECT 0x04000000L /* Reflection */ #define SPFX_PROTECT 0x08000000L /* Protection */ @@ -52,7 +49,7 @@ struct artifact { aligntyp alignment; /* alignment of bequeathing gods */ short role; /* character role associated with */ short race; /* character race associated with */ - long cost; /* price when sold to hero (default 100 x base cost) */ + long cost; /* price when sold to hero (default 100 x base cost) */ char acolor; /* color to use if artifact 'glows' */ }; @@ -69,4 +66,5 @@ enum invoke_prop_types { CREATE_AMMO }; +/* clang-format on */ #endif /* ARTIFACT_H */ From a0c6118c97b214d3a643d57aecfe6b54cc7cdad6 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 14 Oct 2020 16:06:25 -0700 Subject: [PATCH 327/708] Qt paperdoll - tool tips used to describe items New for Qt, moving the mouse over one of the slots in the paperdoll inventory subset and letting it pause there will use Qt's tool tip mechanism to give a description of the item under the pointer, if there is one, or of what the slot would contain when there isn't. So "e - uncursed leather gloves (being worn)" or "no gloves" when the pointer is over the glove slot. If you do something with the keyboard to make the paperdoll change while the mouse is still hovering, you'll need to move the pointer slightly to have Qt recheck for tool tip at that spot. It may be feasible to force an immediate update, but I'm satisfied with how it's working. Interestingly, you can move pointer and hover while yn_function() has asked you to pick an inventory item and is waiting for an answer. Mostly useful for Take-off/Remove or #adjust. --- doc/fixes37.0 | 4 +- win/Qt/qt_glyph.cpp | 3 +- win/Qt/qt_inv.cpp | 171 +++++++++++++++++++++++++++++++++++--------- win/Qt/qt_inv.h | 8 ++- 4 files changed, 149 insertions(+), 37 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 0aff91687..905af1491 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.329 $ $NHDT-Date: 1602669770 2020/10/14 10:02:50 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.330 $ $NHDT-Date: 1602716771 2020/10/14 23:06:11 $ General Fixes and Modified Features ----------------------------------- @@ -575,6 +575,8 @@ Qt: the "paper doll" inventory subset can be controlled via the "Qt Settings" dialog box ("Preferences..." on OSX) Qt: draw a border around each tile in the paper doll inventory; when BUC is known for a doll item, change the border's color and thicken it +Qt: letting the mouse hover over the paper doll shows a tool tip describing + the object--or lack of same--in the slot under the pointer Qt: clicking on the paper doll runs the #seeall command (inventory of wielded and worn items plus tools [lamps, leashes] actively in use; in other words, same set of things whose tiles are used to populate the doll) diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 1585d9ca9..7edbefa99 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -101,8 +101,9 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, { int wd = width(), ht = height(), + yoffset = 1, // tiny extra margin at top lox = cellx * (wd + 2), - loy = celly * (ht + 2); + loy = celly * (ht + 2) + yoffset; drawGlyph(painter, glyph, lox + 1, loy + 1); diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 5379a33fa..0139a56f1 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -43,10 +43,25 @@ NetHackQtInvUsageWindow::NetHackQtInvUsageWindow(QWidget* parent) : QWidget(parent) { setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + // needed to enable tool tips + setMouseTracking(true); + + for (int x = 0; x <= 2; ++x) + for (int y = 0; y <= 5; ++y) + tips[x][y] = NULL; } -void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, - int x, int y, bool canbe) +NetHackQtInvUsageWindow::~NetHackQtInvUsageWindow() +{ + for (int x = 0; x <= 2; ++x) + for (int y = 0; y <= 5; ++y) + if (tips[x][y]) + free((void *) tips[x][y]), tips[x][y] = NULL; +} + +void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, + int x, int y, // cell index, not pixels + const char *alttip, bool canbe) { short int glyph; int border; @@ -54,16 +69,39 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter& painter, obj* nhobj, if (nhobj) { border = BORDER_DEFAULT; #ifdef ENHANCED_PAPERDOLL + // color margin around cell containing item whose BUC state is known if (Role_if('P') && !Blind) nhobj->bknown = 1; if (nhobj->bknown) border = nhobj->cursed ? BORDER_CURSED : !nhobj->blessed ? BORDER_UNCURSED : BORDER_BLESSED; + + // set up a tool tip describing the item that will be displayed here + char *itmnam = xprname(nhobj, (char *) 0, nhobj->invlet, TRUE, 0L, 0L); + if (tips[x][y] && strlen(itmnam) > strlen(tips[x][y])) + free((void *) tips[x][y]), tips[x][y] = NULL; + + if (tips[x][y]) + Strcpy(tips[x][y], itmnam); + else + tips[x][y] = dupstr(itmnam); #endif glyph = obj_to_glyph(nhobj, rn2_on_display_rng); } else { border = NO_BORDER; +#ifdef ENHANCED_PAPERDOLL + // caller passes an alternative tool tip for empty cells + if (tips[x][y] && (!alttip || strlen(alttip) > strlen(tips[x][y]))) + free((void *) tips[x][y]), tips[x][y] = NULL; + + if (tips[x][y]) // above guarantees that test fails if alttip is Null + Strcpy(tips[x][y], alttip); + else if (alttip) + tips[x][y] = dupstr(alttip); +#else + nhUse(alttip); +#endif glyph = canbe ? cmap_to_glyph(S_room) : GLYPH_UNEXPLORED; } qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border); @@ -92,51 +130,66 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) qt_settings->doll_is_shown = false; if (!qt_settings->doll_is_shown) return; + // set glyphs() for the paperdoll; might be different size than map's qt_settings->glyphs().setSize(qt_settings->dollWidth, qt_settings->dollHeight); + + /* for drawWorn()'s use of obj->invlet */ + if (!flags.invlet_constant) + reassign(); #endif QPainter painter; painter.begin(this); - // Blanks - drawWorn(painter, 0, 0, 5, false); - drawWorn(painter, 0, 2, 5, false); - if (u.twoweap) // empty alt weapon slot, show uswapwep in shield slot - drawWorn(painter, 0, 0, 0, false); - - // TODO: render differently if known to be non-removable (known cursed) - drawWorn(painter, uarm, 1, 3); // Armour - drawWorn(painter, uarmc, 1, 2); // Cloak - drawWorn(painter, uarmh, 1, 0); // Helmet - // shield slot varies depending upon weapon usage - if (u.twoweap) - drawWorn(painter, uswapwep, 0, 1); // Secondary weapon, in use - else if (uwep && bimanual(uwep)) - drawWorn(painter, uwep, 0, 1); // Two-handed weapon shown twice + // String argument is for a tool tip when the object in question is Null. + // + // left column + /* uswapwep slot varies depending upon dual-wielding state; + shown in shield slot when actively wielded, so uswapwep slot is empty + then and an alternate tool tip is used to explain that emptiness */ + if (!u.twoweap) + drawWorn(painter, uswapwep, 0, 0, "no alternate weapon"); else - drawWorn(painter, uarms, 0, 1); // Shield (might be blank) - drawWorn(painter, uarmg, 0, 2); // Gloves - drawWorn(painter, uarmf, 1, 5); // Shoes (feet) - drawWorn(painter, uarmu, 1, 4); // Undershirt - drawWorn(painter, uleft, 0, 3); // RingL - drawWorn(painter, uright, 2, 3); // RingR + drawWorn(painter, NULL, 0, 0, "secondary weapon is wielded"); + /* shield slot varies depending upon weapon usage; + no alt tool tip is needed for first two cases because object will + never be Null when the corresponding tests pass */ + if (u.twoweap) + drawWorn(painter, uswapwep, 0, 1, NULL); // secondary weapon, in use + else if (uwep && bimanual(uwep)) + drawWorn(painter, uwep, 0, 1, NULL); // two-handed uwep shown twice + else + drawWorn(painter, uarms, 0, 1, "no shield"); + drawWorn(painter, uarmg, 0, 2, "no gloves"); + drawWorn(painter, uleft, 0, 3, "no left ring"); + /* light source and leash aren't unique and don't have pointers defined */ + drawWorn(painter, find_tool(LEASH), 0, 4, "no leashes in use"); + drawWorn(painter, NULL, 0, 5, NULL, false); // always blank - drawWorn(painter, uwep, 2, 1); // Weapon - drawWorn(painter, !u.twoweap ? uswapwep : NULL, 0, 0); // Alternate weapon - drawWorn(painter, uquiver, 2, 2); // Quiver - drawWorn(painter, uamul, 1, 1); // Amulet - drawWorn(painter, ublindf, 2, 0); // Blindfold/Towel/Lenses + // middle column; no unused slots + drawWorn(painter, uarmh, 1, 0, "no helmet"); + drawWorn(painter, uamul, 1, 1, "no amulet"); + drawWorn(painter, uarmc, 1, 2, "no cloak"); + drawWorn(painter, uarm, 1, 3, "no suit"); + drawWorn(painter, uarmu, 1, 4, "no shirt"); + drawWorn(painter, uarmf, 1, 5, "no boots"); - // light source and leash aren't unique and don't have pointers defined - drawWorn(painter, find_tool(LEASH), 0, 4); - // OIL_LAMP matches lit candles, lamps, lantern, and candelabrum (and will - // also duplicate Sunsword when it is wielded and shown in the uwep slot) - drawWorn(painter, find_tool(OIL_LAMP), 2, 4); + // right column + drawWorn(painter, ublindf, 2, 0, "no eyewear"); // blindfold/towel/lenses + drawWorn(painter, uwep, 2, 1, "no weapon"); + drawWorn(painter, uquiver, 2, 2, "nothing readied for firing"); // quiver + drawWorn(painter, uright, 2, 3, "no right ring"); + /* OIL_LAMP matches lit candles, lamps, lantern, and candelabrum + (and might also duplicate Sunsword when it is wielded--hence lit-- + depending upon whether another light source precedes it in invent) */ + drawWorn(painter, find_tool(OIL_LAMP), 2, 4, "no active light sources"); + drawWorn(painter, NULL, 2, 5, NULL, false); // always blank painter.end(); #ifdef ENHANCED_PAPERDOLL + // reset glyphs() to the ones being used for the map qt_settings->glyphs().setSize(qt_settings->tileWidth, qt_settings->tileHeight); #endif @@ -145,7 +198,7 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) QSize NetHackQtInvUsageWindow::sizeHint(void) const { if (qt_settings) { - int w = 0, h = 0; + int w = 0, h = 1; // one pixel margin at top // 1+X+1: one pixel border surrounding each tile in the paper doll, // so +1 left and +1 right, also +1 above and +1 below #ifdef ENHANCED_PAPERDOLL @@ -167,6 +220,56 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const } } +// ENHANCED_PAPERDOLL - called when a tool tip is triggered by hovering mouse +bool NetHackQtInvUsageWindow::tooltip_event(QHelpEvent *tipevent) +{ +#ifdef ENHANCED_PAPERDOLL + if (iflags.wc_ascii_map) + qt_settings->doll_is_shown = false; + if (!qt_settings->doll_is_shown) { + tipevent->ignore(); + return false; + } + int wd = qt_settings->dollWidth, + ht = qt_settings->dollHeight; + + // inverse of drawBorderedCell(); + int yoffset = 1, // tiny extra margin at top + ex = tipevent->pos().x(), + ey = tipevent->pos().y() - yoffset, + // KISS: treat 1-pixel margin around cells as part of enclosed cell + cellx = ex / (wd + 2), + celly = ey / (ht + 2); + + const char *tip = (cellx >= 0 && cellx <= 2 && celly >= 0 && celly <= 5) + ? tips[cellx][celly] : NULL; + if (tip && *tip) { + QToolTip::showText(tipevent->globalPos(), QString(tip)); + } else { + QToolTip::hideText(); + tipevent->ignore(); + } +#else + nhUse(tipevent); +#endif /* ENHANCED_PAPERDOLL */ + return true; +} + +// ENHANCED_PAPERDOLL - event handler is necessary to support tool tips +bool NetHackQtInvUsageWindow::event(QEvent *event) +{ +#ifdef ENHANCED_PAPERDOLL + if (event->type() == QEvent::ToolTip) { + QHelpEvent *tipevent = static_cast (event); + return tooltip_event(tipevent); + } +#endif + // with this routine intercepting events, we need to pass along + // paint and mouse-press events to have them handled + return QWidget::event(event); + +} + // ENHANCED_PAPERDOLL - clicking on the PaperDoll runs #seeall ('*') void NetHackQtInvUsageWindow::mousePressEvent(QMouseEvent *event UNUSED) { diff --git a/win/Qt/qt_inv.h b/win/Qt/qt_inv.h index 9c38128c5..2566c8f79 100644 --- a/win/Qt/qt_inv.h +++ b/win/Qt/qt_inv.h @@ -13,14 +13,20 @@ namespace nethack_qt_ { class NetHackQtInvUsageWindow : public QWidget { public: NetHackQtInvUsageWindow(QWidget* parent); + virtual ~NetHackQtInvUsageWindow(); virtual void paintEvent(QPaintEvent*); virtual QSize sizeHint(void) const; protected: + virtual bool event(QEvent *event); virtual void mousePressEvent(QMouseEvent *event); private: - void drawWorn(QPainter& painter, obj*, int x, int y, bool canbe=true); + void drawWorn(QPainter &painter, obj *nhobj, int x, int y, + const char *alttip, bool canbe=true); + bool tooltip_event(QHelpEvent *tipevent); + + char *tips[3][6]; // PAPERDOLL is a grid of 3x6 cells for tiles }; } // namespace nethack_qt_ From 4c933fbf3caf73f2677cad777cb93303f8f4251c Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 15 Oct 2020 09:38:52 -0400 Subject: [PATCH 328/708] recognize visual studio 2019 16.7.6 in sys/winnt/Makefile.msc --- sys/winnt/Makefile.msc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index d079e64db..28322938f 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -540,7 +540,7 @@ rc=Rc # Visual Studio we are using. We set VSVER to 0000 to flag any version that # is too old or untested. # -#NMAKE version 1427291110 is distributed with latest VS 2019 +#NMAKE version 1427291120 from latest VS 2019 (October 13, 2020 version 16.7.6) #!MESSAGE $(MAKEFLAGS) #!MESSAGE $(MAKEDIR) @@ -564,9 +564,9 @@ VSVER=2013 VSVER=2015 !ELSEIF ($(MAKEVERSION) > 1411000000) && ($(MAKEVERSION) < 1416270312) VSVER=2017 -!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1427291111) +!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1427291121) VSVER=$(VSNEWEST) -!ELSEIF ($(MAKEVERSION) > 1427291110) +!ELSEIF ($(MAKEVERSION) > 1427291120) VSVER=2999 #untested future version !ENDIF From 9d3dfd59f9bacdfecb113a648547367c09f8fedc Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 15 Oct 2020 18:22:26 -0700 Subject: [PATCH 329/708] Qt paperdoll - slight reorganization Three-way swap: move blindfold to alt-weapon slot, alt-weapon to quiver slot, and quiver to former blindfold slot. Affects first and third rows of the 6x3 grid. Before |After x H b | b H q S a w | S a w G C q | G C x [x=alt-weapon, H=helmet, b=blindfold, S=shield, a=amulet, w=weapon, G=gloves, C=cloak, q=quiver; bottom three rows not changed so not shown.] --- win/Qt/qt_inv.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 0139a56f1..a5e9a3c1b 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -111,9 +111,9 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) { // 0 1 2 two dual // hander wielding - // 0 x H b x H b . H b + // 0 b H q b H q b H q // 1 S " w W " W X " w - // 2 G C q G C q G C q + // 2 G C x G C x G C . // 3 = A = = A = = A = // 4 l U L l U L l U L // 5 . F . . F . . F . @@ -145,13 +145,7 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // String argument is for a tool tip when the object in question is Null. // // left column - /* uswapwep slot varies depending upon dual-wielding state; - shown in shield slot when actively wielded, so uswapwep slot is empty - then and an alternate tool tip is used to explain that emptiness */ - if (!u.twoweap) - drawWorn(painter, uswapwep, 0, 0, "no alternate weapon"); - else - drawWorn(painter, NULL, 0, 0, "secondary weapon is wielded"); + drawWorn(painter, ublindf, 0, 0, "no eyewear"); // bf|towel|lenses /* shield slot varies depending upon weapon usage; no alt tool tip is needed for first two cases because object will never be Null when the corresponding tests pass */ @@ -176,9 +170,15 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) drawWorn(painter, uarmf, 1, 5, "no boots"); // right column - drawWorn(painter, ublindf, 2, 0, "no eyewear"); // blindfold/towel/lenses + drawWorn(painter, uquiver, 2, 0, "nothing readied for firing"); // quiver drawWorn(painter, uwep, 2, 1, "no weapon"); - drawWorn(painter, uquiver, 2, 2, "nothing readied for firing"); // quiver + /* uswapwep slot varies depending upon dual-wielding state; + shown in shield slot when actively wielded, so uswapwep slot is empty + then and an alternate tool tip is used to explain that emptiness */ + if (!u.twoweap) + drawWorn(painter, uswapwep, 2, 2, "no alternate weapon"); + else + drawWorn(painter, NULL, 2, 2, "secondary weapon is wielded"); drawWorn(painter, uright, 2, 3, "no right ring"); /* OIL_LAMP matches lit candles, lamps, lantern, and candelabrum (and might also duplicate Sunsword when it is wielded--hence lit-- From b6125b8f7846c66c0285fe8299cad940d27f9539 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 16 Oct 2020 19:10:17 +0300 Subject: [PATCH 330/708] Pre-populate teleport destination prompt with travel destination This has been implemented in multiple variants, and seems like a small but useful quality of life improvement. --- doc/fixes37.0 | 1 + src/teleport.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 905af1491..f9c67c946 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -276,6 +276,7 @@ when reporting that hero can't repair a chest's broken lock with key/pick/card just describe the base item without BUC, user assigned name, &c since "You can't repair a chest's lock with an uncursed key." implicitly suggests that you might be able to do so with a blessed or cursed one +pre-populate teleport destination prompt with travel destination Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/teleport.c b/src/teleport.c index f51001a7e..e72ac2d38 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -528,6 +528,11 @@ struct obj *scroll; learnscroll(scroll); cc.x = u.ux; cc.y = u.uy; + if (iflags.travelcc.x != 0 || iflags.travelcc.y != 0) { + /* The player showed some interest in traveling here; + * pre-suggest this coordinate. */ + cc = iflags.travelcc; + } if (getpos(&cc, TRUE, "the desired position") < 0) return; /* abort */ /* possible extensions: introduce a small error if From a9e490413197c9c523ead73c79948f6d03978e3d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 17 Oct 2020 12:08:47 +0300 Subject: [PATCH 331/708] Reset travel destination if reached via teleport --- src/teleport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/teleport.c b/src/teleport.c index e72ac2d38..8157f512c 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -528,7 +528,7 @@ struct obj *scroll; learnscroll(scroll); cc.x = u.ux; cc.y = u.uy; - if (iflags.travelcc.x != 0 || iflags.travelcc.y != 0) { + if (isok(iflags.travelcc.x, iflags.travelcc.y)) { /* The player showed some interest in traveling here; * pre-suggest this coordinate. */ cc = iflags.travelcc; @@ -540,6 +540,7 @@ struct obj *scroll; if (teleok(cc.x, cc.y, FALSE)) { /* for scroll, discover it regardless of destination */ teleds(cc.x, cc.y, TELEDS_TELEPORT); + iflags.travelcc.x = iflags.travelcc.y = 0; return; } pline("Sorry..."); From 5ddafa5c81df07553b5ebe5bfc01e6502baec243 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 17 Oct 2020 12:13:17 +0300 Subject: [PATCH 332/708] Only reset if we actually went to travel destination --- src/teleport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/teleport.c b/src/teleport.c index 8157f512c..f23643aeb 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -540,7 +540,8 @@ struct obj *scroll; if (teleok(cc.x, cc.y, FALSE)) { /* for scroll, discover it regardless of destination */ teleds(cc.x, cc.y, TELEDS_TELEPORT); - iflags.travelcc.x = iflags.travelcc.y = 0; + if (iflags.travelcc.x == cc.x && iflags.travelcc.y == cc.y) + iflags.travelcc.x = iflags.travelcc.y = 0; return; } pline("Sorry..."); From fc6b49130329409095c9c40f9ffe33e52c55d93f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 17 Oct 2020 16:48:07 +0300 Subject: [PATCH 333/708] Fix thinko in reset travel dest condition --- src/teleport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/teleport.c b/src/teleport.c index f23643aeb..0e47f9735 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -540,7 +540,7 @@ struct obj *scroll; if (teleok(cc.x, cc.y, FALSE)) { /* for scroll, discover it regardless of destination */ teleds(cc.x, cc.y, TELEDS_TELEPORT); - if (iflags.travelcc.x == cc.x && iflags.travelcc.y == cc.y) + if (iflags.travelcc.x == u.ux && iflags.travelcc.y == u.uy) iflags.travelcc.x = iflags.travelcc.y = 0; return; } From 9a6bc0fd8f7cf7bfd6be0eba89e7fef0c397a50c Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 17 Oct 2020 11:10:00 -0700 Subject: [PATCH 334/708] Qt status window icon alignment When the game windows were initialized, the anhk icon for alignment was centered relative to Lawful/Neutral/Chaotic label but during the first status update it noticeably shifted left. Non-blank hunger or encumbrance states could change from centered to left justified when they were present and the icon was replaced. Oddly, resetting the 'centered' attribute for the widget wasn't sufficient to fix this. Running the resize code for that widget did. Another case of trial and error to make things work the way they ought. Also, don't highlight a change in alignment or dungeon location as "got worse" if the internal numeric value went down instead of up; always highlight as "got better" for those two fields. There ought to be a third choice for just "changed" but that would have been more complicated. --- doc/fixes37.0 | 5 ++++- win/Qt/qt_icon.cpp | 25 ++++++++++++++++++------- win/Qt/qt_icon.h | 1 + win/Qt/qt_stat.cpp | 30 +++++++++++++++++++++--------- 4 files changed, 44 insertions(+), 17 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f9c67c946..a9655feb1 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.330 $ $NHDT-Date: 1602716771 2020/10/14 23:06:11 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.332 $ $NHDT-Date: 1602958104 2020/10/17 18:08:24 $ General Fixes and Modified Features ----------------------------------- @@ -443,6 +443,9 @@ Qt: for menu search, don't require clicking on the search target popup before Qt: rest ("Zz") button on the toolbar only worked when 'rest_on_space' was On (core issue, not Qt's fault) Qt: rename toolbar button "Get" and action menu choice "Get" to "Pick up" +Qt: status icons for alignment|hunger|encumbrance which started out centered + relative to the label text below them would shift to being left + justified when status got updated Qt+OSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 27b578420..2e027b3f5 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -52,15 +52,16 @@ void NetHackQtLabelledIcon::setLabel(const QString& t, bool lower) if (!label) { label=new QLabel(this); label->setFont(font()); - resizeEvent(0); } if (label->text() != t) { label->setText(t); - highlight(lower==low_is_good ? hl_good : hl_bad); + ForceResize(); + highlight((lower == low_is_good) ? hl_good : hl_bad); } } -void NetHackQtLabelledIcon::setLabel(const QString& t, long v, long cv, const QString& tail) +void NetHackQtLabelledIcon::setLabel(const QString& t, long v, long cv, + const QString& tail) { QString buf; if (v==NoNum) { @@ -72,16 +73,19 @@ void NetHackQtLabelledIcon::setLabel(const QString& t, long v, long cv, const QS prev_value=cv; } -void NetHackQtLabelledIcon::setLabel(const QString& t, long v, const QString& tail) +void NetHackQtLabelledIcon::setLabel(const QString& t, long v, + const QString& tail) { setLabel(t,v,v,tail); } void NetHackQtLabelledIcon::setIcon(const QPixmap& i) { - if (icon) icon->setPixmap(i); - else { icon=new QLabel(this); icon->setPixmap(i); resizeEvent(0); } - icon->resize(i.width(),i.height()); + if (!icon) + icon = new QLabel(this); + icon->setPixmap(i); + ForceResize(); + icon->resize(i.width(), i.height()); } void NetHackQtLabelledIcon::setFont(const QFont& f) @@ -171,6 +175,13 @@ void NetHackQtLabelledIcon::unhighlight() } } +// used when label (most status fields) or pixmap (alignment, hunger, +// encumbrance) changes value +void NetHackQtLabelledIcon::ForceResize() +{ + this->resizeEvent((QResizeEvent *) NULL); +} + void NetHackQtLabelledIcon::resizeEvent(QResizeEvent*) { setAlignments(); diff --git a/win/Qt/qt_icon.h b/win/Qt/qt_icon.h index f1974ba44..eda5c5689 100644 --- a/win/Qt/qt_icon.h +++ b/win/Qt/qt_icon.h @@ -24,6 +24,7 @@ public: void highlightWhenChanging(); void lowIsGood(); void dissipateHighlight(); + void ForceResize(); virtual void show(); virtual QSize sizeHint() const; diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 6d200fe10..02fb15772 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -344,7 +344,7 @@ void NetHackQtStatusWindow::resizeEvent(QResizeEvent*) /* * Set all widget values to a null string. This is used after all spacings * have been calculated so that when the window is popped up we don't get all - * kinds of funny values being displayed. + * kinds of funny values being displayed. [Actually it isn't used at all.] */ void NetHackQtStatusWindow::nullOut() { @@ -436,6 +436,7 @@ void NetHackQtStatusWindow::updateStats() } else { hunger.setIcon(u.uhs ? p_hungry : p_satiated); hunger.setLabel(hung); + hunger.ForceResize(); hunger.show(); } const char *enc = enc_stat[near_capacity()]; @@ -444,6 +445,7 @@ void NetHackQtStatusWindow::updateStats() } else { encumber.setIcon(p_encumber[near_capacity() - 1]); encumber.setLabel(enc); + encumber.ForceResize(); encumber.show(); } if (Stoned) stoned.show(); else stoned.hide(); @@ -468,6 +470,7 @@ void NetHackQtStatusWindow::updateStats() if (Stunned) stunned.show(); else stunned.hide(); if (Confusion) confused.show(); else confused.hide(); if (Hallucination) hallu.show(); else hallu.hide(); + // [pr - Why is blind handled differently from other on/off conditions?] if (Blind) { blind.setLabel("Blind"); blind.show(); @@ -490,12 +493,13 @@ void NetHackQtStatusWindow::updateStats() name.setLabel(buf2, NetHackQtLabelledIcon::NoNum, u.ulevel); char buf3[BUFSZ]; - if (describe_level(buf3)) { - dlevel.setLabel(buf3,true); - } else { - buf.sprintf("%s, level ", g.dungeons[u.uz.dnum].dname); - dlevel.setLabel(buf,(long)::depth(&u.uz)); + if (!describe_level(buf3)) { + Sprintf(buf3, "%s, level %d", + g.dungeons[u.uz.dnum].dname, ::depth(&u.uz)); } + // false: always highlight as 'change for the better' regardless of + // new depth compared to old + dlevel.setLabel(buf3, false); gold.setLabel("Au:", money_cnt(g.invent)); @@ -521,13 +525,14 @@ void NetHackQtStatusWindow::updateStats() } buf.sprintf("/%d", u.uenmax); power.setLabel("Pow:", u.uen, buf); - ac.setLabel("AC:",(long)u.uac); + ac.setLabel("AC:", (long) u.uac); //if (::flags.showexp) { // exp.setLabel("Exp:", (long) u.uexp); //} else { - // 'exp' now only used to pad the line that Xp/Exp is displayed on + // 'exp' is now only used to pad the line that Xp/Exp is displayed on exp.setLabel(""); //} + text = NULL; if (u.ualign.type==A_CHAOTIC) { align.setIcon(p_chaotic); text = "Chaotic"; @@ -538,7 +543,14 @@ void NetHackQtStatusWindow::updateStats() align.setIcon(p_lawful); text = "Lawful"; } - align.setLabel(text); + if (text) { + // false: don't highlight as 'became lower' even if the internal + // numeric value is becoming lower (N -> C, L -> N || C) + align.setLabel(text, false); + // without this, the ankh pixmap shifts from centered to left + // justified relative to the label text for some unknown reason... + align.ForceResize(); + } if (::flags.time) time.setLabel("Time:", (long) g.moves); From f38cb63714c9db1e1f3ae7cd6e712e1e056a673d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 18 Oct 2020 19:18:38 +0300 Subject: [PATCH 335/708] Spitting monsters try to stay away from melee range --- doc/fixes37.0 | 3 ++- src/monmove.c | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a9655feb1..87010a021 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -134,7 +134,8 @@ male hero poly'd into nymph chooses charm vs seduce message based on being male rather than on all nymphs being female but charm message was using hardcoded pronouns She,her for target monster--wrong for male target and noticable if " finishes taking off his suit" is given -hostile monsters with launcher and ammo try to stay away from melee range +hostile monsters with a spit attack or launcher and ammo try to stay away + from melee range allow displacing peaceful creatures unicorn horns don't restore attribute loss anymore when a shop is changed from food to health food, change room type to match diff --git a/src/monmove.c b/src/monmove.c index 8842f1b66..a16336ff0 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1015,10 +1015,11 @@ register int after; > ((ygold = findgold(g.invent)) ? ygold->quan : 0L)))) appr = -1; - /* hostile monsters with ranged thrown weapons try to stay away */ + /* hostiles with ranged weapons or spit attack try to stay away */ if (!mtmp->mpeaceful && (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) < 5*5) - && m_canseeu(mtmp) && m_has_launcher_and_ammo(mtmp)) + && m_canseeu(mtmp) && + (m_has_launcher_and_ammo(mtmp) || attacktype(mtmp->data, AT_SPIT))) appr = -1; if (!should_see && can_track(ptr)) { From 3a31587ca9492e789f4cd9896f2d9f1c04cb4cf5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 18 Oct 2020 20:20:55 +0300 Subject: [PATCH 336/708] Prevent ghosts from being renamed (via xNetHack) --- doc/fixes37.0 | 1 + src/do_name.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 87010a021..eef41adc9 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -278,6 +278,7 @@ when reporting that hero can't repair a chest's broken lock with key/pick/card "You can't repair a chest's lock with an uncursed key." implicitly suggests that you might be able to do so with a blessed or cursed one pre-populate teleport destination prompt with travel destination +ghosts cannot be renamed Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/do_name.c b/src/do_name.c index 2725f4955..cc58b3290 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1196,7 +1196,8 @@ do_mname() || mtmp->data->msound <= MS_ANIMAL)) { if (!alreadynamed(mtmp, monnambuf, buf)) verbalize("I'm %s, not %s.", shkname(mtmp), buf); - } else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk) { + } else if (mtmp->ispriest || mtmp->isminion || mtmp->isshk + || mtmp->data == &mons[PM_GHOST]) { if (!alreadynamed(mtmp, monnambuf, buf)) pline("%s will not accept the name %s.", upstart(monnambuf), buf); } else From 8fcc02fb813f4e5289a40d2746fef4a6b491d12b Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 11:45:22 -0700 Subject: [PATCH 337/708] fix stash merge conflict --- sys/libnh/libnhmain.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index fe5ea55e7..2a11d4d25 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -1071,7 +1071,6 @@ void create_global (char *name, void *ptr, char *type); void js_globals_init() { // int i; // char buf[BUFSZ]; - printf("js_globals_init\n"); EM_ASM({ globalThis.nethackGlobal = globalThis.nethackGlobal || {}; From 69264684bd0891f9905611613f08925c400e8490 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 11:47:56 -0700 Subject: [PATCH 338/708] fix build path --- sys/libnh/npm-package/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/libnh/npm-package/package.json b/sys/libnh/npm-package/package.json index e39a7d201..0d2e13937 100644 --- a/sys/libnh/npm-package/package.json +++ b/sys/libnh/npm-package/package.json @@ -4,9 +4,9 @@ "description": "The original NetHack rogue-like game built as a WebAssembly module", "main": "src/nethackShim.js", "scripts": { - "test": "node test/test.js", + "test": "npm run build && node test/test.js", "clean": "rm ./build/nethack.js; rm ./build/nethack.wasm; true", - "build": "cp ../../../src/nethack.js ../../../src/nethack.wasm ./build", + "build": "mkdir build; cp ../../../targets/wasm/nethack.js ../../../targets/wasm/nethack.wasm ./build", "prepack": "npm run build" }, "keywords": [ From c91ec0068f192b80c5bc0fa1711a32074dc9919e Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 11:49:34 -0700 Subject: [PATCH 339/708] update to new build system --- sys/libnh/test/run.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sys/libnh/test/run.sh b/sys/libnh/test/run.sh index b89ab55d9..e930684c4 100755 --- a/sys/libnh/test/run.sh +++ b/sys/libnh/test/run.sh @@ -2,11 +2,13 @@ if [ x$1 == "xlib" ]; then echo Doing lib... - make spotless - cd sys/lib + if [ -f Makefile ]; then + make spotless + fi + cd sys/unix ./setup.sh hints/macOS.2020 cd ../.. - make + make WANT_LIBNH=1 fi if [ x$1 == "xrunlib" ]; then @@ -19,15 +21,17 @@ fi if [ x$1 == "xwasm" ]; then echo Doing wasm... - make spotless - cd sys/lib - ./setup.sh hints/wasm + if [ -f Makefile ]; then + make spotless + fi + cd sys/unix + ./setup.sh hints/macOS.2020 cd ../.. - make + make CROSS_TO_WASM=1 fi if [ x$1 == "xrunwasm" ]; then - cd sys/lib/npm-package && node test/test.js + cd sys/lib/npm-package && npm run build && node test/test.js fi if [ x$1 == "xbin" ]; then From 6598b3d2d0c3a630aea1325f6483781096d09200 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 11:54:42 -0700 Subject: [PATCH 340/708] wasm requires HACKDIR for embedded files --- sys/unix/hints/macOS.2020 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index 85f9b3208..e6fae4c06 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -281,6 +281,11 @@ POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ endif # WANT_BUNDLE endif # !WANT_SHARE_INSTALL +ifdef CROSS_TO_WASM +HACKDIR=/ +PREFIX= +endif # !CROSS_TO_WASM + INSTDIR=$(HACKDIR) VARDIR=$(HACKDIR) @@ -294,6 +299,7 @@ VARDIR=$(HACKDIR) #-INCLUDE cross-pre.2020 # #-POST + ifdef WANT_LIBNH libnh.a: $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a $(AR) rcs $@ $(HOBJ) $(LIBNHSYSOBJ) ../lib/lua/liblua.a From 5e5324c25b39ab2993924a70131149961caacdcb Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 11:55:04 -0700 Subject: [PATCH 341/708] fix build flags --- sys/unix/hints/include/cross-pre.2020 | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 0e9816627..73eec2337 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -32,7 +32,7 @@ BUILD_TARGET_LUA=1 override TARGET = wasm override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ -override TARGET_LIBS= +override TARGET_LIBS= endif ifdef CROSS @@ -246,7 +246,7 @@ else override TARGET_LINK = $(TARGET_CC) endif override TARGET_LFLAGS= $(TOOLARCH) -#override TARGET_LIBS += +#override TARGET_LIBS += VARDATND += nhtiles.bmp override SYSSRC = ../outdated/sys/amiga/amidos.c ../outdated/sys/amiga/amigst.c \ ../outdated/sys/amiga/amimenu.c ../outdated/sys/amiga/amirip.c \ @@ -298,10 +298,12 @@ ifdef CROSS_TO_WASM # originally from https://github.com/NetHack/NetHack/pull/385 #===============-================================================= # +WASM_DEBUG = 1 WASM_DATA_DIR = $(TARGETPFX)wasm-data WASM_TARGET = $(TARGETPFX)nethack.js EMCC_LFLAGS = #EMCC_LFLAGS += -s SINGLE_FILE=1 +EMCC_LFLAGS += -DHACKDIR=\"$(HACKDIR)\" EMCC_LFLAGS += -s WASM=1 EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' @@ -311,23 +313,28 @@ EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' EMCC_LFLAGS += -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", \ "removeFunction", "UTF8ToString", "getValue", "setValue"]' EMCC_LFLAGS += -s ERROR_ON_UNDEFINED_SYMBOLS=0 -EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR) +# XXX: the "@/" at the end of "--embed-file" tells emscripten to embed the files +# in the root directory, otherwise they will end up in the $(WASM_DATA_DIR) path +EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR)@/ # For a list of EMCC settings: # https://github.com/emscripten-core/emscripten/blob/master/src/settings.js # # WASM C flags -EMCC_CFLAGS= +EMCC_CFLAGS = EMCC_CFLAGS += -Wall -#EMCC_CFLAGS += -Werror +EMCC_CFLAGS += -Werror +EMCC_CFLAGS #EMCC_CFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 -EMCC_DEBUG_CFLAGS += -s ASSERTIONS=1 -#EMCC_DEBUG_CFLAGS += -s ASSERTIONS=2 +#EMCC_DEBUG_CFLAGS += -s ASSERTIONS=1 +EMCC_DEBUG_CFLAGS += -s ASSERTIONS=2 EMCC_DEBUG_CFLAGS += -s STACK_OVERFLOW_CHECK=2 EMCC_DEBUG_CFLAGS += -s SAFE_HEAP=1 EMCC_DEBUG_CFLAGS += -s LLD_REPORT_UNDEFINED=1 -#EMCC_DEBUG_CFLAGS += -s EXCEPTION_DEBUG=1 +EMCC_DEBUG_CFLAGS += -s EXCEPTION_DEBUG=1 #EMCC_DEBUG_CFLAGS += -fsanitize=undefined -fsanitize=address -fsanitize=leak -#EMCC_DEBUG_CFLAGS += -s EXIT_RUNTIME +EMCC_DEBUG_CFLAGS += -s EXIT_RUNTIME=1 +# XXX: if --profiling isn't included then any error dumps 10MB of WASM to the screen rather than a useful message +EMCC_DEBUG_CFLAGS += --profiling EMCC_PROD_CFLAGS += -O3 ifdef WASM_DEBUG EMCC_CFLAGS += $(EMCC_DEBUG_CFLAGS) From 03e9eb6dd66c08a0f337e752f0e5887f942928be Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 13:21:07 -0700 Subject: [PATCH 342/708] fix NO_SIGNAL --- src/files.c | 2 +- src/save.c | 2 +- sys/libnh/libnhmain.c | 7 ++++--- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/files.c b/src/files.c index f3c171111..dd7245861 100644 --- a/src/files.c +++ b/src/files.c @@ -630,10 +630,10 @@ clearlocks() #endif #ifndef NO_SIGNAL (void) signal(SIGINT, SIG_IGN); -#endif #if defined(UNIX) || defined(VMS) sethanguphandler((void FDECL((*), (int) )) SIG_IGN); #endif +#endif /* NO_SIGNAL */ /* can't access maxledgerno() before dungeons are created -dlc */ for (x = (g.n_dgns ? maxledgerno() : 0); x >= 0; x--) delete_levelfile(x); /* not all levels need be present */ diff --git a/src/save.c b/src/save.c index c3864d5b0..a15ce5860 100644 --- a/src/save.c +++ b/src/save.c @@ -101,10 +101,10 @@ dosave0() return 0; fq_save = fqname(g.SAVEF, SAVEPREFIX, 1); /* level files take 0 */ +#ifndef NO_SIGNAL #if defined(UNIX) || defined(VMS) sethanguphandler((void FDECL((*), (int) )) SIG_IGN); #endif -#ifndef NO_SIGNAL (void) signal(SIGINT, SIG_IGN); #endif diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 2a11d4d25..844f385d0 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -555,11 +555,11 @@ whoami() return FALSE; } +#ifndef NO_SIGNAL void sethanguphandler(handler) void FDECL((*handler), (int)); { -#ifndef NO_SIGNAL #ifdef SA_RESTART /* don't want reads to restart. If SA_RESTART is defined, we know * sigaction exists and can be used to ensure reads won't restart. @@ -581,8 +581,8 @@ void FDECL((*handler), (int)); (void) signal(SIGXCPU, (SIG_RET_TYPE) handler); #endif #endif /* ?SA_RESTART */ -#endif /* !NO_SIGNAL */ } +#endif /* !NO_SIGNAL */ #ifdef PORT_HELP void @@ -1003,7 +1003,8 @@ void js_constants_init() { // copyright SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_A); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_B); - SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_C); + // XXX: not set for cross-compile + //SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_C); SET_CONSTANT_STRING("COPYRIGHT", COPYRIGHT_BANNER_D); // glyphs From 6863730b63415861a64822c30f36d1eaf2d5e47b Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 13:21:40 -0700 Subject: [PATCH 343/708] remove wasm --- sys/unix/hints/macOS.2020 | 5 ----- 1 file changed, 5 deletions(-) diff --git a/sys/unix/hints/macOS.2020 b/sys/unix/hints/macOS.2020 index e6fae4c06..283f1a779 100755 --- a/sys/unix/hints/macOS.2020 +++ b/sys/unix/hints/macOS.2020 @@ -281,11 +281,6 @@ POSTINSTALL+= if test -f $(SHELLDIR)/$(GAME); then \ endif # WANT_BUNDLE endif # !WANT_SHARE_INSTALL -ifdef CROSS_TO_WASM -HACKDIR=/ -PREFIX= -endif # !CROSS_TO_WASM - INSTDIR=$(HACKDIR) VARDIR=$(HACKDIR) From b43b035321dc7ee7d0234a941822e84aaf847726 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Mon, 19 Oct 2020 13:22:02 -0700 Subject: [PATCH 344/708] fix wasm runtime errors --- sys/unix/hints/include/cross-pre.2020 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 73eec2337..562a1934d 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -29,6 +29,8 @@ endif ifdef CROSS_TO_WASM CROSS=1 BUILD_TARGET_LUA=1 +HACKDIR=/ +PREFIX= override TARGET = wasm override TARGETDIR=../targets/$(TARGET) override TARGETPFX = $(TARGETDIR)/ @@ -309,7 +311,7 @@ EMCC_LFLAGS += -s ALLOW_TABLE_GROWTH EMCC_LFLAGS += -s ASYNCIFY -s ASYNCIFY_IMPORTS='["local_callback"]' EMCC_LFLAGS += -O3 EMCC_LFLAGS += -s MODULARIZE -EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback"]' +EMCC_LFLAGS += -s EXPORTED_FUNCTIONS='["_main", "_shim_graphics_set_callback", "_mapglyph", "_display_inventory"]' EMCC_LFLAGS += -s EXPORTED_RUNTIME_METHODS='["cwrap", "ccall", "addFunction", \ "removeFunction", "UTF8ToString", "getValue", "setValue"]' EMCC_LFLAGS += -s ERROR_ON_UNDEFINED_SYMBOLS=0 @@ -323,7 +325,7 @@ EMCC_LFLAGS += --embed-file $(WASM_DATA_DIR)@/ EMCC_CFLAGS = EMCC_CFLAGS += -Wall EMCC_CFLAGS += -Werror -EMCC_CFLAGS +EMCC_CFLAGS += -DNO_SIGNAL #EMCC_CFLAGS += -s DISABLE_EXCEPTION_CATCHING=0 #EMCC_DEBUG_CFLAGS += -s ASSERTIONS=1 EMCC_DEBUG_CFLAGS += -s ASSERTIONS=2 From 7795d82be6d7fea6e01c08ff1061d4347c6a79f5 Mon Sep 17 00:00:00 2001 From: Bart House Date: Wed, 10 Jul 2019 22:16:08 -0700 Subject: [PATCH 345/708] Improved readability of topline state management. --- include/wintty.h | 6 ++++++ win/tty/getline.c | 6 +++--- win/tty/topl.c | 24 ++++++++++++------------ win/tty/wintty.c | 43 ++++++++++++++++++++++++------------------- 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/include/wintty.h b/include/wintty.h index 702d8dece..2d0b05fd2 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -52,6 +52,12 @@ struct WinDesc { #define WIN_STOP 1 /* for NHW_MESSAGE; stops output */ #define WIN_LOCKHISTORY 2 /* for NHW_MESSAGE; suppress history updates */ +/* topline states */ +#define TOPLINE_EMPTY 0 /* empty */ +#define TOPLINE_NEED_MORE 1 /* non-empty, need --More-- */ +#define TOPLINE_NON_EMPTY 2 /* non-empty, no --More-- required */ +#define TOPLINE_SPECIAL_PROMPT 3 /* special prompt state */ + /* descriptor for tty-based displays -- all the per-display data */ struct DisplayDesc { short rows, cols; /* width and height of tty display */ diff --git a/win/tty/getline.c b/win/tty/getline.c index 1f87c1874..8925f6b4a 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -52,10 +52,10 @@ getlin_hook_proc hook; struct WinDesc *cw = wins[WIN_MESSAGE]; boolean doprev = 0; - if (ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) + if (ttyDisplay->toplin == TOPLINE_NEED_MORE && !(cw->flags & WIN_STOP)) more(); cw->flags &= ~WIN_STOP; - ttyDisplay->toplin = 3; /* special prompt state */ + ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; ttyDisplay->inread++; /* issue the prompt */ @@ -193,7 +193,7 @@ getlin_hook_proc hook; } else tty_nhbell(); } - ttyDisplay->toplin = 2; /* nonempty, no --More-- required */ + ttyDisplay->toplin = TOPLINE_NON_EMPTY; ttyDisplay->inread--; clear_nhwindow(WIN_MESSAGE); /* clean up after ourselves */ diff --git a/win/tty/topl.c b/win/tty/topl.c index eb16e146a..859a75fab 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -138,7 +138,7 @@ const char *str; end_glyphout(); /* in case message printed during graphics output */ putsyms(str); cl_end(); - ttyDisplay->toplin = 1; + ttyDisplay->toplin = TOPLINE_NEED_MORE; if (ttyDisplay->cury && otoplin != 3) more(); } @@ -151,7 +151,7 @@ const char *str; struct WinDesc *cw = wins[WIN_MESSAGE]; if (!(cw->flags & WIN_STOP)) { - if (ttyDisplay->cury && ttyDisplay->toplin == 2) + if (ttyDisplay->cury && ttyDisplay->toplin == TOPLINE_NON_EMPTY) tty_clear_nhwindow(WIN_MESSAGE); cw->curx = cw->cury = 0; @@ -159,8 +159,8 @@ const char *str; cl_end(); addtopl(str); - if (ttyDisplay->cury && ttyDisplay->toplin != 3) - ttyDisplay->toplin = 2; + if (ttyDisplay->cury && ttyDisplay->toplin != TOPLINE_SPECIAL_PROMPT) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; } } @@ -196,7 +196,7 @@ const char *s; tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury); putsyms(s); cl_end(); - ttyDisplay->toplin = 1; + ttyDisplay->toplin = TOPLINE_NEED_MORE; } void @@ -236,7 +236,7 @@ more() home(); cl_end(); } - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; ttyDisplay->inmore = 0; } @@ -252,7 +252,7 @@ register const char *bp; /* If there is room on the line, print message on same line */ /* But messages like "You die..." deserve their own line */ n0 = strlen(bp); - if ((ttyDisplay->toplin == 1 || (cw->flags & WIN_STOP)) + if ((ttyDisplay->toplin == TOPLINE_NEED_MORE || (cw->flags & WIN_STOP)) && cw->cury == 0 && n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */ && (notdied = strncmp(bp, "You die", 7)) != 0) { @@ -263,9 +263,9 @@ register const char *bp; addtopl(bp); return; } else if (!(cw->flags & WIN_STOP)) { - if (ttyDisplay->toplin == 1) { + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) { more(); - } else if (cw->cury) { /* for when flags.toplin == 2 && cury > 1 */ + } else if (cw->cury) { /* for toplin == TOPLINE_NON_EMPTY && cury > 1 */ docorner(1, cw->cury + 1); /* reset cury = 0 if redraw screen */ cw->curx = cw->cury = 0; /* from home--cls() & docorner(1,n) */ } @@ -381,10 +381,10 @@ char def; char prompt[BUFSZ]; yn_number = 0L; - if (ttyDisplay->toplin == 1 && !(cw->flags & WIN_STOP)) + if (ttyDisplay->toplin == TOPLINE_NEED_MORE && !(cw->flags & WIN_STOP)) more(); cw->flags &= ~WIN_STOP; - ttyDisplay->toplin = 3; /* special prompt state */ + ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; ttyDisplay->inread++; if (resp) { char *rb, respbuf[QBUFSZ]; @@ -531,7 +531,7 @@ char def; dumplogmsg(g.toplines); #endif ttyDisplay->inread--; - ttyDisplay->toplin = 2; + ttyDisplay->toplin = TOPLINE_NON_EMPTY; if (ttyDisplay->intr) ttyDisplay->intr--; if (wins[WIN_MESSAGE]->cury) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 8af5db634..1cf55a7a9 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -348,7 +348,7 @@ int sig_unused UNUSED; new_status_window(); if (u.ux) { i = ttyDisplay->toplin; - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; docrt(); bot(); ttyDisplay->toplin = i; @@ -436,7 +436,7 @@ char **argv UNUSED; /* set up tty descriptor */ ttyDisplay = (struct DisplayDesc *) alloc(sizeof (struct DisplayDesc)); - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; ttyDisplay->rows = hgt; ttyDisplay->cols = wid; ttyDisplay->curx = ttyDisplay->cury = 0; @@ -1652,12 +1652,12 @@ winid window; switch (cw->type) { case NHW_MESSAGE: - if (ttyDisplay->toplin) { + if (ttyDisplay->toplin != TOPLINE_EMPTY) { home(); cl_end(); if (cw->cury) docorner(1, cw->cury + 1); - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; } break; case NHW_STATUS: @@ -2353,12 +2353,13 @@ boolean blocking; /* with ttys, all windows are blocking */ switch (cw->type) { case NHW_MESSAGE: - if (ttyDisplay->toplin == 1) { + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) { more(); - ttyDisplay->toplin = 1; /* more resets this */ + ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(window); + /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ } else - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; cw->curx = cw->cury = 0; if (!cw->active) iflags.window_inited = TRUE; @@ -2366,8 +2367,8 @@ boolean blocking; /* with ttys, all windows are blocking */ case NHW_MAP: end_glyphout(); if (blocking) { - if (!ttyDisplay->toplin) - ttyDisplay->toplin = 1; + if (ttyDisplay->toplin != TOPLINE_EMPTY) + ttyDisplay->toplin = TOPLINE_NEED_MORE; tty_display_nhwindow(WIN_MESSAGE, TRUE); return; } @@ -2397,7 +2398,7 @@ boolean blocking; /* with ttys, all windows are blocking */ cw->offx = 0; if (cw->type == NHW_MENU) cw->offy = 0; - if (ttyDisplay->toplin == 1) + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) tty_display_nhwindow(WIN_MESSAGE, TRUE); #ifdef H2344_BROKEN if (cw->maxrow >= (int) ttyDisplay->rows @@ -2413,7 +2414,7 @@ boolean blocking; /* with ttys, all windows are blocking */ cl_eos(); } else clear_screen(); - ttyDisplay->toplin = 0; + ttyDisplay->toplin = TOPLINE_EMPTY; } else { if (WIN_MESSAGE != WIN_ERR) tty_clear_nhwindow(WIN_MESSAGE); @@ -2442,8 +2443,9 @@ winid window; switch (cw->type) { case NHW_MESSAGE: - if (ttyDisplay->toplin) + if (ttyDisplay->toplin != TOPLINE_EMPTY) tty_display_nhwindow(WIN_MESSAGE, TRUE); + /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ /*FALLTHRU*/ case NHW_STATUS: case NHW_BASE: @@ -3194,10 +3196,11 @@ const char *mesg; response to a prompt, we'll assume that the display is up to date */ tty_putstr(WIN_MESSAGE, 0, mesg); /* if `mesg' didn't wrap (triggering --More--), force --More-- now */ - if (ttyDisplay->toplin == 1) { + if (ttyDisplay->toplin == TOPLINE_NEED_MORE) { more(); - ttyDisplay->toplin = 1; /* more resets this */ + ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(WIN_MESSAGE); + /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ } /* normally means skip further messages, but in this case it means cancel the current prompt; any other messages should @@ -3237,7 +3240,7 @@ tty_wait_synch() (void) fflush(stdout); } else if (ttyDisplay->inread > g.program_state.gameover) { /* this can only happen if we were reading and got interrupted */ - ttyDisplay->toplin = 3; + ttyDisplay->toplin = TOPLINE_SPECIAL_PROMPT; /* do this twice; 1st time gets the Quit? message again */ (void) tty_doprev_message(); (void) tty_doprev_message(); @@ -3570,8 +3573,9 @@ tty_nhgetch() i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ else if (i == EOF) i = '\033'; /* same for EOF */ - if (ttyDisplay && ttyDisplay->toplin == 1) - ttyDisplay->toplin = 2; + /* topline has been seen - we can clear need for more */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; #ifdef TTY_TILES_ESCCODES { /* hack to force output of the window select code */ @@ -3613,8 +3617,9 @@ int *x UNUSED, *y UNUSED, *mod UNUSED; i = ntposkey(x, y, mod); if (!i && mod && (*mod == 0 || *mod == EOF)) i = '\033'; /* map NUL or EOF to ESC, nethack doesn't expect either */ - if (ttyDisplay && ttyDisplay->toplin == 1) - ttyDisplay->toplin = 2; + /* topline has been seen - we can clear need for more */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; #else /* !WIN32CON */ i = tty_nhgetch(); #endif /* ?WIN32CON */ From 783efd35241242a028c2811adcff8d49a5bf2b91 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 11 Jul 2019 20:46:19 -0700 Subject: [PATCH 346/708] Remove the remapping of snprintf to _snprintf when compiling with MSC. _snprintf and snprintf have one very important semantic difference. _snprintf does NOT add terminating null character when the buffer limit is reached while snprintf guarantees a terminating null character. It was a mistake to make this naming change hiding the fact that the semantics don't match what the developer might expect. --- include/ntconf.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/ntconf.h b/include/ntconf.h index 5f86971d4..5a7d0ed78 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -156,14 +156,6 @@ extern void FDECL(interject, (int)); #define strncmpi(a, b, c) strnicmp(a, b, c) #endif -#ifdef _MSC_VER -/* Visual Studio defines this in their own headers, which we don't use */ -#ifndef snprintf -#define snprintf _snprintf -#pragma warning( \ - disable : 4996) /* deprecation warning suggesting snprintf_s */ -#endif -#endif #include #include From dde11630e8eeb89f2cebf649723c8a363cb15322 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 11 Jul 2019 20:55:27 -0700 Subject: [PATCH 347/708] Modified nhassert_failed to call impossoible. --- sys/winnt/winnt.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index cc314ef07..8f44163dd 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -486,18 +486,11 @@ char *buf; /* nhassert_failed is called when an nhassert's condition is false */ void nhassert_failed(const char * exp, const char * file, int line) { - char message[128]; - _snprintf(message, sizeof(message), - "NHASSERT(%s) in '%s' at line %d\n", exp, file, line); + char message[BUFSZ]; + snprintf(message, sizeof(message), + "NHASSERT(%s) in '%s' at line %d", exp, file, line); - if (IsDebuggerPresent()) { - OutputDebugStringA(message); - DebugBreak(); - } - - // strip off the newline - message[strlen(message) - 1] = '\0'; - error(message); + impossible(message); } void From 3842da9dbde163b6fa66e4bf8b8afe2d52e7c46c Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 11 Jul 2019 22:01:39 -0700 Subject: [PATCH 348/708] Added nhassert to core. --- include/extern.h | 1 + include/global.h | 4 ++-- include/ntconf.h | 10 ---------- src/pline.c | 6 ++++++ sys/winnt/winnt.c | 10 ---------- 5 files changed, 9 insertions(+), 22 deletions(-) diff --git a/include/extern.h b/include/extern.h index 83a1cd30f..ca480cf0d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2020,6 +2020,7 @@ E void VDECL(verbalize, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(raw_printf, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(impossible, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(config_error_add, (const char *, ...)) PRINTF_F(1, 2); +E void FDECL(nhassert_failed, (const char *, const char *, int)); /* ### polyself.c ### */ diff --git a/include/global.h b/include/global.h index caa32847b..23350a12c 100644 --- a/include/global.h +++ b/include/global.h @@ -427,8 +427,8 @@ struct savefile_info { /* Supply nhassert macro if not supplied by port */ #ifndef nhassert -#define nhassert(e) ((void)0) +#define nhassert(expression) (void)((!!(expression)) || \ + (nhassert_failed(#expression, __FILE__, __LINE__), 0)) #endif - #endif /* GLOBAL_H */ diff --git a/include/ntconf.h b/include/ntconf.h index 5a7d0ed78..45a8ce266 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -273,16 +273,6 @@ extern int FDECL(set_win32_option, (const char *, const char *)); extern int FDECL(alternative_palette, (char *)); #endif -#ifdef NDEBUG -#define nhassert(expression) ((void)0) -#else -extern void FDECL(nhassert_failed, (const char * exp, const char * file, - int line)); - -#define nhassert(expression) (void)((!!(expression)) || \ - (nhassert_failed(#expression, __FILE__, __LINE__), 0)) -#endif - #define nethack_enter(argc, argv) nethack_enter_winnt() extern void FDECL(nethack_exit, (int)) NORETURN; extern boolean FDECL(file_exists, (const char *)); diff --git a/src/pline.c b/src/pline.c index cc03ebd44..03c041c03 100644 --- a/src/pline.c +++ b/src/pline.c @@ -619,4 +619,10 @@ VA_DECL(const char *, str) #endif } +/* nhassert_failed is called when an nhassert's condition is false */ +void nhassert_failed(const char * exp, const char * file, int line) +{ + impossible("NHASSERT(%s) in '%s' at line %d", exp, file, line); +} + /*pline.c*/ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 8f44163dd..238b78549 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -483,16 +483,6 @@ char *buf; } #endif /* RUNTIME_PORT_ID */ -/* nhassert_failed is called when an nhassert's condition is false */ -void nhassert_failed(const char * exp, const char * file, int line) -{ - char message[BUFSZ]; - snprintf(message, sizeof(message), - "NHASSERT(%s) in '%s' at line %d", exp, file, line); - - impossible(message); -} - void nethack_exit(code) int code; From 93ce6857d317989cbbe1d8afbf218f70a474bfb5 Mon Sep 17 00:00:00 2001 From: Bart House Date: Fri, 12 Jul 2019 18:40:34 -0700 Subject: [PATCH 349/708] Tweaks to nhassert implementation. Change to warnings on MSC build. --- include/extern.h | 2 +- include/global.h | 2 +- include/ntconf.h | 11 +++++++++++ src/pline.c | 15 +++++++++++++-- sys/winnt/winnt.c | 16 ++++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index ca480cf0d..18f81ea48 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2020,7 +2020,7 @@ E void VDECL(verbalize, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(raw_printf, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(impossible, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(config_error_add, (const char *, ...)) PRINTF_F(1, 2); -E void FDECL(nhassert_failed, (const char *, const char *, int)); +E void FDECL(nhassert_failed, (const char *, int)); /* ### polyself.c ### */ diff --git a/include/global.h b/include/global.h index 23350a12c..cfd81ddbf 100644 --- a/include/global.h +++ b/include/global.h @@ -428,7 +428,7 @@ struct savefile_info { /* Supply nhassert macro if not supplied by port */ #ifndef nhassert #define nhassert(expression) (void)((!!(expression)) || \ - (nhassert_failed(#expression, __FILE__, __LINE__), 0)) + (nhassert_failed(__FILE__, __LINE__), 0)) #endif #endif /* GLOBAL_H */ diff --git a/include/ntconf.h b/include/ntconf.h index 45a8ce266..711c83914 100644 --- a/include/ntconf.h +++ b/include/ntconf.h @@ -144,6 +144,8 @@ extern void FDECL(interject, (int)); #ifndef HAS_STDINT_H #define HAS_STDINT_H /* force include of stdint.h in integer.h */ #endif +/* Turn on some additional warnings */ +#pragma warning(3:4389) #endif /* _MSC_VER */ /* The following is needed for prototypes of certain functions */ @@ -281,4 +283,13 @@ extern boolean FDECL(file_newer, (const char *, const char *)); #include "system.h" #endif +/* Override the default version of nhassert. The default version is unable + * to generate a string form of the expression due to the need to be + * compatible with compilers which do not support macro stringization (i.e. + * #x to turn x into its string form). + */ +extern void FDECL(nt_assert_failed, (const char *, const char *, int)); +#define nhassert(expression) (void)((!!(expression)) || \ + (nt_assert_failed(#expression, __FILE__, __LINE__), 0)) + #endif /* NTCONF_H */ diff --git a/src/pline.c b/src/pline.c index 03c041c03..0c69a13e4 100644 --- a/src/pline.c +++ b/src/pline.c @@ -620,9 +620,20 @@ VA_DECL(const char *, str) } /* nhassert_failed is called when an nhassert's condition is false */ -void nhassert_failed(const char * exp, const char * file, int line) +void +nhassert_failed(filepath, line) + const char * filepath; + int line; { - impossible("NHASSERT(%s) in '%s' at line %d", exp, file, line); + const char * filename; + + /* attempt to get filename from path. TODO: we really need a port provided + * function to return a filename from a path */ + filename = strrchr(filepath, '/'); + filename = (filename == NULL ? strrchr(filepath, '\\') : filename); + filename = (filename == NULL ? filepath : filename + 1); + + impossible("nhassert failed in file '%s' at line %d", filename, line); } /*pline.c*/ diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 238b78549..09ee0c9b4 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -717,6 +717,22 @@ sys_random_seed(VOID_ARGS) return ourseed; } +/* nt_assert_failed is called when an nhassert's condition is false */ +void +nt_assert_failed(expression, filepath, line) + const char * expression; + const char * filepath; + int line; +{ + const char * filename; + + /* get file name from path */ + filename = strrchr(filepath, '\\'); + filename = (filename == NULL ? filepath : filename + 1); + impossible("nhassert(%s) failed in file '%s' at line %d", + expression, filename, line); +} + #endif /* WIN32 */ /*winnt.c*/ From 362fd6ffbf624f004ce75d241ffb01126f9ec694 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 13 Jul 2019 16:00:14 -0700 Subject: [PATCH 350/708] Add stopping in the debugger when nhassert() is hit in the windows port. When stopping in the debugger after having called impossible, the windowing state will have been modified since the assertion was hit. This made examining state that caused the nhassert to fire no longer possible. To avoid this issue, we now detect the debugger and stop in the debugger prior to impossible. --- sys/winnt/winnt.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sys/winnt/winnt.c b/sys/winnt/winnt.c index 09ee0c9b4..f34a68397 100644 --- a/sys/winnt/winnt.c +++ b/sys/winnt/winnt.c @@ -726,9 +726,19 @@ nt_assert_failed(expression, filepath, line) { const char * filename; - /* get file name from path */ filename = strrchr(filepath, '\\'); filename = (filename == NULL ? filepath : filename + 1); + + if (IsDebuggerPresent()) { + char message[BUFSIZ]; + snprintf(message, sizeof(message), + "nhassert(%s) failed in file '%s' at line %d", + expression, filename, line); + OutputDebugStringA(message); + DebugBreak(); + } + + /* get file name from path */ impossible("nhassert(%s) failed in file '%s' at line %d", expression, filename, line); } From aee1509979cc4fc12a2765d8bf7602ed1550b0d6 Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 11 Jul 2019 21:04:29 -0700 Subject: [PATCH 351/708] Fixed bug with inmore and toplin state management. When fuzzing, we would increment ttyDisplay->inmore but then prematurely exit more() leaving ttyDisplay->inmore set. Under various conditions, we can request to remember the topline when the topline had not yet been acknowledged leaving toplin state in an inappropriate state. --- win/tty/topl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/win/tty/topl.c b/win/tty/topl.c index 859a75fab..d3ad9f6ed 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -139,7 +139,7 @@ const char *str; putsyms(str); cl_end(); ttyDisplay->toplin = TOPLINE_NEED_MORE; - if (ttyDisplay->cury && otoplin != 3) + if (ttyDisplay->cury && otoplin != TOPLINE_SPECIAL_PROMPT) more(); } @@ -204,12 +204,15 @@ more() { struct WinDesc *cw = wins[WIN_MESSAGE]; - /* avoid recursion -- only happens from interrupts */ - if (ttyDisplay->inmore++) - return; if (iflags.debug_fuzzer) return; + /* avoid recursion -- only happens from interrupts */ + if (ttyDisplay->inmore) + return; + + ttyDisplay->inmore++; + if (ttyDisplay->toplin) { tty_curs(BASE_WINDOW, cw->curx + 1, cw->cury); if (cw->curx >= CO - 8) @@ -256,6 +259,7 @@ register const char *bp; && cw->cury == 0 && n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */ && (notdied = strncmp(bp, "You die", 7)) != 0) { + nhassert(strlen(g.toplines) == cw->curx); Strcat(g.toplines, " "); Strcat(g.toplines, bp); cw->curx += 2; @@ -309,6 +313,7 @@ char c; if (ttyDisplay->curx == 0 && ttyDisplay->cury > 0) tty_curs(BASE_WINDOW, CO, (int) ttyDisplay->cury - 1); backsp(); + nhassert(ttyDisplay->curx > 0); ttyDisplay->curx--; cw->curx = ttyDisplay->curx; return; @@ -686,6 +691,13 @@ boolean restoring_msghist; } if (msg) { + /* Caller is asking us to remember a top line that needed more. + Should we call more? This can happen when the player has set + iflags.force_invmenu and they attempt to shoot with nothing in + the quiver. */ + if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) + ttyDisplay->toplin = TOPLINE_NON_EMPTY; + /* move most recent message to history, make this become most recent */ remember_topl(); Strcpy(g.toplines, msg); @@ -693,6 +705,9 @@ boolean restoring_msghist; dumplogmsg(g.toplines); #endif } else if (snapshot_mesgs) { + nhassert(ttyDisplay == NULL || + ttyDisplay->toplin != TOPLINE_NEED_MORE); + /* done putting arbitrary messages in; put the snapshot ones back */ for (idx = 0; snapshot_mesgs[idx]; ++idx) { remember_topl(); From 2c752cce6968ea2e8b88a8687bd8116da6bddbff Mon Sep 17 00:00:00 2001 From: Bart House Date: Thu, 11 Jul 2019 20:58:20 -0700 Subject: [PATCH 352/708] Added assertions to check toplin state. --- win/tty/wintty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 1cf55a7a9..44445f761 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -2357,7 +2357,7 @@ boolean blocking; /* with ttys, all windows are blocking */ more(); ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(window); - /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ + nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); } else ttyDisplay->toplin = TOPLINE_EMPTY; cw->curx = cw->cury = 0; @@ -2445,7 +2445,7 @@ winid window; case NHW_MESSAGE: if (ttyDisplay->toplin != TOPLINE_EMPTY) tty_display_nhwindow(WIN_MESSAGE, TRUE); - /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ + nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); /*FALLTHRU*/ case NHW_STATUS: case NHW_BASE: @@ -3200,7 +3200,7 @@ const char *mesg; more(); ttyDisplay->toplin = TOPLINE_NEED_MORE; /* more resets this */ tty_clear_nhwindow(WIN_MESSAGE); - /* nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); */ + nhassert(ttyDisplay->toplin == TOPLINE_EMPTY); } /* normally means skip further messages, but in this case it means cancel the current prompt; any other messages should From a9deeb69c9f5eabbd72b8e8f238bb7134467e699 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 13 Jul 2019 10:53:53 -0700 Subject: [PATCH 353/708] Removing assertion that does not hold under all scenarios. When we save gamestate as part of making an insurance snapshot, we will save message history which will clear toplines but leaving window state in tack including the need for more. --- win/tty/topl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/win/tty/topl.c b/win/tty/topl.c index d3ad9f6ed..1802d6944 100644 --- a/win/tty/topl.c +++ b/win/tty/topl.c @@ -259,7 +259,6 @@ register const char *bp; && cw->cury == 0 && n0 + (int) strlen(g.toplines) + 3 < CO - 8 /* room for --More-- */ && (notdied = strncmp(bp, "You die", 7)) != 0) { - nhassert(strlen(g.toplines) == cw->curx); Strcat(g.toplines, " "); Strcat(g.toplines, bp); cw->curx += 2; From b4c4491229726113b58c4445ccd29b5627b07b7f Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 19 Oct 2020 16:19:01 -0700 Subject: [PATCH 354/708] Fix sign/unsigned comparison bug. We are comparing a signed char with unsigned int. The signed char will be sign exetended when converted to unsigned int causing an unexpected result. --- src/teleport.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/teleport.c b/src/teleport.c index 0e47f9735..cb8bb4f40 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1191,10 +1191,10 @@ struct monst *mtmp; sent out of his room (caller might resort to goodpos() if we report failure here, so this isn't full prevention) */ if (mtmp->isshk && inhishop(mtmp)) { - if (levl[x][y].roomno != ESHK(mtmp)->shoproom) + if (levl[x][y].roomno != (unsigned char) ESHK(mtmp)->shoproom) return FALSE; } else if (mtmp->ispriest && inhistemple(mtmp)) { - if (levl[x][y].roomno != EPRI(mtmp)->shroom) + if (levl[x][y].roomno != (unsigned char) EPRI(mtmp)->shroom) return FALSE; } /* current location is */ From d1404d345c3ce18163fbde53ac90dcc2af5ca6aa Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 18 Oct 2020 16:13:52 -0700 Subject: [PATCH 355/708] Fix compiler warning. --- src/sp_lev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index c469d9747..f3e2fe1a3 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -4393,7 +4393,7 @@ int lit; break; case 0: case 1: - if (levl[x][y].lit == lit) + if (levl[x][y].lit == (unsigned int) lit) selection_setpoint(x, y, ret, 1); break; } From c33a9ed94ad8f08464aab0588355e62f84087ac5 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 17 Oct 2020 17:25:00 -0700 Subject: [PATCH 356/708] Add inlcude files to NetHackW project. Add cpp.hint file. --- win/win32/vs/NetHackW.vcxproj | 93 +++++++++++++++++++++++++++++++++-- win/win32/vs/cpp.hint | 6 +++ 2 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 win/win32/vs/cpp.hint diff --git a/win/win32/vs/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj index 5f8f7a415..afc39bbcc 100644 --- a/win/win32/vs/NetHackW.vcxproj +++ b/win/win32/vs/NetHackW.vcxproj @@ -51,8 +51,8 @@ - true - false + true + false @@ -244,6 +244,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -257,6 +341,9 @@ + + + @@ -267,4 +354,4 @@ - + \ No newline at end of file diff --git a/win/win32/vs/cpp.hint b/win/win32/vs/cpp.hint new file mode 100644 index 000000000..4f77429fe --- /dev/null +++ b/win/win32/vs/cpp.hint @@ -0,0 +1,6 @@ +// Hint files help the Visual Studio IDE interpret Visual C++ identifiers +// such as names of functions and macros. +// For more information see https://go.microsoft.com/fwlink/?linkid=865984 +#define E +#define NDECL(x) x +#define FDECL(x, y) x y From 5880da9269e485168d3c4d31364420ab6f9a6281 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 18 Oct 2020 14:56:15 -0700 Subject: [PATCH 357/708] Add cpp.hint file to NetHack project. --- win/win32/vs/NetHack.vcxproj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/win/win32/vs/NetHack.vcxproj b/win/win32/vs/NetHack.vcxproj index d31325331..3905afd7b 100644 --- a/win/win32/vs/NetHack.vcxproj +++ b/win/win32/vs/NetHack.vcxproj @@ -299,6 +299,9 @@ + + + From 566dde868359786f3c865e93c99365b67a5eb96c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 20 Oct 2020 19:19:54 +0300 Subject: [PATCH 358/708] Match object description via single function making the code more readable. Instead of doing strcmp(OBJ_DESCR(objects[otyp]), "foo"), just call objdescr_is(obj, "foo") (via xNetHack) --- include/extern.h | 1 + src/apply.c | 2 +- src/eat.c | 2 +- src/mon.c | 2 +- src/mondata.c | 3 +-- src/muse.c | 6 ++---- src/o_init.c | 20 ++++++++++++++++++++ src/potion.c | 28 ++++++++++++---------------- src/spell.c | 2 +- src/steed.c | 6 ++---- 10 files changed, 42 insertions(+), 30 deletions(-) diff --git a/include/extern.h b/include/extern.h index 18f81ea48..51b62d1bb 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1776,6 +1776,7 @@ E void NDECL(nttty_exit); E void NDECL(init_objects); E void FDECL(obj_shuffle_range, (int, int *, int *)); E int NDECL(find_skates); +E boolean FDECL(objdescr_is, (struct obj *, const char *)); E void NDECL(oinit); E void FDECL(savenames, (NHFILE *)); E void FDECL(restnames, (NHFILE *)); diff --git a/src/apply.c b/src/apply.c index 32e33f97f..a43e3b730 100644 --- a/src/apply.c +++ b/src/apply.c @@ -3406,7 +3406,7 @@ struct obj *obj; boolean fillmsg = FALSE; int expltype = EXPL_MAGICAL; char confirm[QBUFSZ], buf[BUFSZ]; - boolean is_fragile = (!strcmp(OBJ_DESCR(objects[obj->otyp]), "balsa")); + boolean is_fragile = objdescr_is(obj, "balsa"); if (!paranoid_query(ParanoidBreakwand, safe_qbuf(confirm, diff --git a/src/eat.c b/src/eat.c index 17040fc9e..ffc36dd25 100644 --- a/src/eat.c +++ b/src/eat.c @@ -2134,7 +2134,7 @@ eatspecial() pline("Yuck%c", otmp->blessed ? '!' : '.'); else if (otmp->oclass == SCROLL_CLASS /* check description after checking for specific scrolls */ - && !strcmpi(OBJ_DESCR(objects[otmp->otyp]), "YUM YUM")) + && objdescr_is(otmp, "YUM YUM")) pline("Yum%c", otmp->blessed ? '!' : '.'); else pline("Needs salt..."); diff --git a/src/mon.c b/src/mon.c index c90ddcb28..85279ae2e 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1114,7 +1114,7 @@ struct monst *mtmp; distant_name(otmp, doname)); /* give this one even if !verbose */ if (otmp->oclass == SCROLL_CLASS - && !strcmpi(OBJ_DESCR(objects[otmp->otyp]), "YUM YUM")) + && objdescr_is(otmp, "YUM YUM")) pline("Yum%c", otmp->blessed ? '!' : '.'); } else { if (flags.verbose) diff --git a/src/mondata.c b/src/mondata.c index d84ce949a..e3e5444d8 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -271,8 +271,7 @@ struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */ o = (mdef == &g.youmonst) ? g.invent : mdef->minvent; for (; o; o = o->nobj) if ((o->owornmask & W_ARMH) - && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0 - && !strcmp(s, "visored helmet")) + && objdescr_is(o, "visored helmet")) return FALSE; } diff --git a/src/muse.c b/src/muse.c index f14f979ff..31f88fbd6 100644 --- a/src/muse.c +++ b/src/muse.c @@ -57,11 +57,9 @@ struct obj *obj; if (obj->oclass == POTION_CLASS) { coord cc; static const char *empty = "The potion turns out to be empty."; - const char *potion_descr; struct monst *mtmp; - potion_descr = OBJ_DESCR(objects[obj->otyp]); - if (potion_descr && !strcmp(potion_descr, "milky")) { + if (objdescr_is(obj, "milky")) { if (!(g.mvitals[PM_GHOST].mvflags & G_GONE) && !rn2(POTION_OCCUPANT_CHANCE(g.mvitals[PM_GHOST].born))) { if (!enexto(&cc, mon->mx, mon->my, &mons[PM_GHOST])) @@ -87,7 +85,7 @@ struct obj *obj; return 2; } } - if (potion_descr && !strcmp(potion_descr, "smoky") + if (objdescr_is(obj, "smoky") && !(g.mvitals[PM_DJINNI].mvflags & G_GONE) && !rn2(POTION_OCCUPANT_CHANCE(g.mvitals[PM_DJINNI].born))) { if (!enexto(&cc, mon->mx, mon->my, &mons[PM_DJINNI])) diff --git a/src/o_init.c b/src/o_init.c index 1ea5085c4..0ef30c222 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -282,6 +282,26 @@ shuffle_all() return; } +/* Return TRUE if the provided string matches the unidentified description of + * the provided object. */ +boolean +objdescr_is(obj, descr) +struct obj *obj; +const char *descr; +{ + const char *objdescr; + + if (!obj) { + impossible("objdescr_is: null obj"); + return FALSE; + } + + objdescr = OBJ_DESCR(objects[obj->otyp]); + if (!objdescr) + return FALSE; /* no obj description, no match */ + return !strcmp(objdescr, descr); +} + /* find the object index for snow boots; used [once] by slippery ice code */ int find_skates() diff --git a/src/potion.c b/src/potion.c index 0785ebb1f..4b12acb32 100644 --- a/src/potion.c +++ b/src/potion.c @@ -486,7 +486,6 @@ int dodrink() { register struct obj *otmp; - const char *potion_descr; if (Strangled) { pline("If you can't breathe air, how can you drink liquid?"); @@ -538,21 +537,18 @@ dodrink() } otmp->in_use = TRUE; /* you've opened the stopper */ - potion_descr = OBJ_DESCR(objects[otmp->otyp]); - if (potion_descr) { - if (!strcmp(potion_descr, "milky") - && !(g.mvitals[PM_GHOST].mvflags & G_GONE) - && !rn2(POTION_OCCUPANT_CHANCE(g.mvitals[PM_GHOST].born))) { - ghost_from_bottle(); - useup(otmp); - return 1; - } else if (!strcmp(potion_descr, "smoky") - && !(g.mvitals[PM_DJINNI].mvflags & G_GONE) - && !rn2(POTION_OCCUPANT_CHANCE(g.mvitals[PM_DJINNI].born))) { - djinni_from_bottle(otmp); - useup(otmp); - return 1; - } + if (objdescr_is(otmp, "milky") + && !(g.mvitals[PM_GHOST].mvflags & G_GONE) + && !rn2(POTION_OCCUPANT_CHANCE(g.mvitals[PM_GHOST].born))) { + ghost_from_bottle(); + useup(otmp); + return 1; + } else if (objdescr_is(otmp, "smoky") + && !(g.mvitals[PM_DJINNI].mvflags & G_GONE) + && !rn2(POTION_OCCUPANT_CHANCE(g.mvitals[PM_DJINNI].born))) { + djinni_from_bottle(otmp); + useup(otmp); + return 1; } return dopotion(otmp); } diff --git a/src/spell.c b/src/spell.c index 312ca4475..160a8ed5d 100644 --- a/src/spell.c +++ b/src/spell.c @@ -446,7 +446,7 @@ register struct obj *spellbook; /* attempting to read dull book may make hero fall asleep */ if (!confused && !Sleep_resistance - && !strcmp(OBJ_DESCR(objects[booktype]), "dull")) { + && objdescr_is(spellbook, "dull")) { const char *eyes; int dullbook = rnd(25) - ACURR(A_WIS); diff --git a/src/steed.c b/src/steed.c index 84e18aa63..ae6d9a5da 100644 --- a/src/steed.c +++ b/src/steed.c @@ -114,12 +114,10 @@ struct obj *otmp; } if (Confusion || Fumbling || Glib) chance -= 20; - else if (uarmg && (s = OBJ_DESCR(objects[uarmg->otyp])) != (char *) 0 - && !strncmp(s, "riding ", 7)) + else if (uarmg && objdescr_is(uarmg, "riding gloves")) /* Bonus for wearing "riding" (but not fumbling) gloves */ chance += 10; - else if (uarmf && (s = OBJ_DESCR(objects[uarmf->otyp])) != (char *) 0 - && !strncmp(s, "riding ", 7)) + else if (uarmf && objdescr_is(uarmf, "riding boots")) /* ... or for "riding boots" */ chance += 10; if (otmp->cursed) From d1c7f26d4b8ed08103073d5c470920165d6020fb Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 20 Oct 2020 19:37:51 -0400 Subject: [PATCH 359/708] clear a couple of new warnings mondata.c:198:17: warning: unused variable 's' [-Wunused-variable] const char *s; ^ 1 warning generated. steed.c:43:17: warning: unused variable 's' [-Wunused-variable] const char *s; ^ 1 warning generated. --- src/mondata.c | 1 - src/steed.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/mondata.c b/src/mondata.c index e3e5444d8..497beef06 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -195,7 +195,6 @@ struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */ boolean is_you = (mdef == &g.youmonst); boolean check_visor = FALSE; struct obj *o; - const char *s; /* no eyes protect against all attacks for now */ if (!haseyes(mdef->data)) diff --git a/src/steed.c b/src/steed.c index ae6d9a5da..e380a4c5c 100644 --- a/src/steed.c +++ b/src/steed.c @@ -40,7 +40,6 @@ struct obj *otmp; struct monst *mtmp; struct permonst *ptr; int chance; - const char *s; if (!u_handsy()) return 0; From 7e3a739ef93fb532e2d637d252cbefc14f723129 Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 20 Oct 2020 20:14:27 -0700 Subject: [PATCH 360/708] Add stringization of nhassert expression. --- include/extern.h | 2 +- include/global.h | 2 +- src/pline.c | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index 51b62d1bb..b743db206 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2021,7 +2021,7 @@ E void VDECL(verbalize, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(raw_printf, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(impossible, (const char *, ...)) PRINTF_F(1, 2); E void VDECL(config_error_add, (const char *, ...)) PRINTF_F(1, 2); -E void FDECL(nhassert_failed, (const char *, int)); +E void FDECL(nhassert_failed, (const char *, const char *, int)); /* ### polyself.c ### */ diff --git a/include/global.h b/include/global.h index cfd81ddbf..23350a12c 100644 --- a/include/global.h +++ b/include/global.h @@ -428,7 +428,7 @@ struct savefile_info { /* Supply nhassert macro if not supplied by port */ #ifndef nhassert #define nhassert(expression) (void)((!!(expression)) || \ - (nhassert_failed(__FILE__, __LINE__), 0)) + (nhassert_failed(#expression, __FILE__, __LINE__), 0)) #endif #endif /* GLOBAL_H */ diff --git a/src/pline.c b/src/pline.c index 0c69a13e4..96715481a 100644 --- a/src/pline.c +++ b/src/pline.c @@ -621,7 +621,8 @@ VA_DECL(const char *, str) /* nhassert_failed is called when an nhassert's condition is false */ void -nhassert_failed(filepath, line) +nhassert_failed(expression, filepath, line) + const char* expression; const char * filepath; int line; { @@ -633,7 +634,7 @@ nhassert_failed(filepath, line) filename = (filename == NULL ? strrchr(filepath, '\\') : filename); filename = (filename == NULL ? filepath : filename + 1); - impossible("nhassert failed in file '%s' at line %d", filename, line); + impossible("nhassert(%s) failed in file '%s' at line %d", expression, filename, line); } /*pline.c*/ From 1cc26106bf35667783520e8b57a08dd499e220c4 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Fri, 23 Oct 2020 11:02:59 +0200 Subject: [PATCH 361/708] Tossed upwards objects got two times half physical damage reduction --- doc/fixes37.0 | 1 + src/dothrow.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index eef41adc9..c72819118 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -279,6 +279,7 @@ when reporting that hero can't repair a chest's broken lock with key/pick/card suggests that you might be able to do so with a blessed or cursed one pre-populate teleport destination prompt with travel destination ghosts cannot be renamed +tossed upwards objects got two times half physical damage reduction Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/dothrow.c b/src/dothrow.c index 18e3a77d1..6719dc9d8 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1071,7 +1071,7 @@ boolean hitsroof; } hitfloor(obj, TRUE); g.thrownobj = 0; - losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN); + losehp(dmg, "falling object", KILLED_BY_AN); } return TRUE; } From aeb0ea65e3ea173ccab744964fa7a0bb8425dc0c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 21 Oct 2020 21:04:03 +0300 Subject: [PATCH 362/708] Mild Zombie Apocalypse When a zombie (or lich) kills a monster in melee without a weapon, the monster can rise few turns later as a zombie. The only creatures that can be zombified are ones that actually have a zombie counterpart monster. A zombie cannot turn a jackal into a zombie, for instance. But it could turn a shopkeeper into a human zombie, or a dwarf king into a dwarf zombie. Zombies will fight with monsters that can be turned into zombies. Originally this was a SliceHack feature, but this is based on xNetHack version of it, with some modifications. --- doc/fixes37.0 | 1 + include/decl.h | 1 + include/extern.h | 4 +++ include/timeout.h | 1 + src/decl.c | 1 + src/do.c | 22 +++++++++++++ src/end.c | 2 ++ src/mhitm.c | 6 ++++ src/mkobj.c | 6 +++- src/mon.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- src/monmove.c | 63 ++++++++++++++++++++++-------------- src/priest.c | 20 ++++++++++-- src/timeout.c | 1 + 13 files changed, 182 insertions(+), 27 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c72819118..163b1c38f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -569,6 +569,7 @@ add section marker [] support to run-time config file; CHOOSE section1,section2 render the color names in the corresponding color when using the pick-a-color menu for adding status highlights or menu colors via 'O' reading blessed scroll of teleportation confers one-shot teleport control +mild zombie apocalypse Platform- and/or Interface-Specific New Features diff --git a/include/decl.h b/include/decl.h index be1d583ac..c72ab57bf 100644 --- a/include/decl.h +++ b/include/decl.h @@ -972,6 +972,7 @@ struct instance_globals { /* mon.c */ boolean vamp_rise_msg; boolean disintegested; + boolean zombify; short *animal_list; /* list of PM values for animal monsters */ int animal_list_count; diff --git a/include/extern.h b/include/extern.h index b743db206..a8151c034 100644 --- a/include/extern.h +++ b/include/extern.h @@ -425,6 +425,7 @@ E void FDECL(schedule_goto, (d_level *, BOOLEAN_P, BOOLEAN_P, int, E void NDECL(deferred_goto); E boolean FDECL(revive_corpse, (struct obj *)); E void FDECL(revive_mon, (ANY_P *, long)); +E void FDECL(zombify_mon, (ANY_P *, long)); E boolean FDECL(cmd_safety_prevention, (const char *, const char *, int *)); E int NDECL(donull); E int NDECL(dowipe); @@ -1454,6 +1455,8 @@ E int FDECL(cmap_to_type, (int)); /* ### mon.c ### */ E void NDECL(mon_sanity_check); +E boolean FDECL(zombie_maker, (struct permonst *)); +E int FDECL(zombie_form, (struct permonst *)); E int FDECL(m_poisongas_ok, (struct monst *)); E int FDECL(undead_to_corpse, (int)); E int FDECL(genus, (int, int)); @@ -1583,6 +1586,7 @@ E void FDECL(mon_yells, (struct monst *, const char *)); E int FDECL(dochug, (struct monst *)); E boolean FDECL(m_digweapon_check, (struct monst *, XCHAR_P, XCHAR_P)); E int FDECL(m_move, (struct monst *, int)); +E int FDECL(m_move_aggress, (struct monst *, XCHAR_P, XCHAR_P)); E void FDECL(dissolve_bars, (int, int)); E boolean FDECL(closed_door, (int, int)); E boolean FDECL(accessible, (int, int)); diff --git a/include/timeout.h b/include/timeout.h index 5cad4388a..3853c80d4 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -29,6 +29,7 @@ enum timeout_types { ROT_ORGANIC = 0, /* for buried organics */ ROT_CORPSE, REVIVE_MON, + ZOMBIFY_MON, BURN_OBJECT, HATCH_EGG, FIG_TRANSFORM, diff --git a/src/decl.c b/src/decl.c index 4c836bbde..5f44d64e1 100644 --- a/src/decl.c +++ b/src/decl.c @@ -498,6 +498,7 @@ const struct instance_globals g_init = { /* mon.c */ UNDEFINED_VALUE, /* vamp_rise_msg */ UNDEFINED_VALUE, /* disintegested */ + UNDEFINED_VALUE, /* zombify */ NULL, /* animal_list */ UNDEFINED_VALUE, /* animal_list_count */ diff --git a/src/do.c b/src/do.c index c891a94d4..ee2c3c141 100644 --- a/src/do.c +++ b/src/do.c @@ -1982,6 +1982,28 @@ long timeout UNUSED; } } +/* Timeout callback. Revive the corpse as a zombie. */ +/*ARGSUSED*/ +void +zombify_mon(arg, timeout) +anything *arg; +long timeout UNUSED; +{ + struct obj *body = arg->a_obj; + int zmon = zombie_form(&mons[body->corpsenm]); + + if (zmon != NON_PM) { + + if (has_omid(body)) + free_omid(body); + if (has_omonst(body)) + free_omonst(body); + + body->corpsenm = zmon; + revive_mon(arg, timeout); + } +} + boolean cmd_safety_prevention(cmddesc, act, flagcounter) const char *cmddesc; diff --git a/src/end.c b/src/end.c index e25657c84..d8187a9e8 100644 --- a/src/end.c +++ b/src/end.c @@ -491,6 +491,8 @@ int how; u.ugrave_arise = PM_WRAITH; else if (mptr->mlet == S_MUMMY && g.urace.mummynum != NON_PM) u.ugrave_arise = g.urace.mummynum; + else if (zombie_maker(mptr) && zombie_form(g.youmonst.data) != NON_PM) + u.ugrave_arise = zombie_form(g.youmonst.data); else if (mptr->mlet == S_VAMPIRE && Race_if(PM_HUMAN)) u.ugrave_arise = PM_VAMPIRE; else if (mptr == &mons[PM_GHOUL]) diff --git a/src/mhitm.c b/src/mhitm.c index e08ce35ba..fba87b7e4 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1485,7 +1485,13 @@ int dieroll; place_monster(mdef, mdef->mx, mdef->my); mdef->mhp = 0; } + g.zombify = !mwep && zombie_maker(magr->data) + && ((mattk->aatyp == AT_TUCH + || mattk->aatyp == AT_CLAW + || mattk->aatyp == AT_BITE) + && zombie_form(mdef->data) != NON_PM); monkilled(mdef, "", (int) mattk->adtyp); + g.zombify = FALSE; /* reset */ if (!DEADMONSTER(mdef)) return res; /* mdef lifesaved */ else if (res == MM_AGR_DIED) diff --git a/src/mkobj.c b/src/mkobj.c index d894ae920..7f97bae96 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1198,6 +1198,10 @@ struct obj *body; when = age; break; } + } else if (!no_revival && g.zombify + && zombie_form(&mons[body->corpsenm]) != NON_PM) { + action = ZOMBIFY_MON; + when = 5 + rn2(15); } (void) start_timer(when, TIMER_OBJECT, action, obj_to_any(body)); @@ -1541,7 +1545,7 @@ unsigned corpstatflags; otmp->corpsenm = monsndx(ptr); otmp->owt = weight(otmp); - if (otmp->otyp == CORPSE && (special_corpse(old_corpsenm) + if (otmp->otyp == CORPSE && (g.zombify || special_corpse(old_corpsenm) || special_corpse(otmp->corpsenm))) { obj_stop_timers(otmp); start_corpse_timeout(otmp); diff --git a/src/mon.c b/src/mon.c index 85279ae2e..d6e9e24a0 100644 --- a/src/mon.c +++ b/src/mon.c @@ -10,6 +10,7 @@ static void FDECL(sanity_check_single_mon, (struct monst *, BOOLEAN_P, const char *)); static boolean FDECL(restrap, (struct monst *)); +static long FDECL(mm_2way_aggression, (struct monst *, struct monst *)); static long FDECL(mm_aggression, (struct monst *, struct monst *)); static long FDECL(mm_displacement, (struct monst *, struct monst *)); static int NDECL(pick_animal); @@ -191,6 +192,59 @@ struct monst *mtmp; return M_POISONGAS_BAD; } +/* Return TRUE if this monster is capable of converting other monsters into + * zombies. */ +boolean +zombie_maker(pm) +struct permonst *pm; +{ + switch(pm->mlet) { + case S_ZOMBIE: + /* Z-class monsters that aren't actually zombies go here */ + if (pm == &mons[PM_GHOUL] || pm == &mons[PM_SKELETON]) + return FALSE; + return TRUE; + case S_LICH: + /* all liches will create zombies as well */ + return TRUE; + } + return FALSE; +} + +/* return the monster index of the zombie monster which this monster could be + * turned into, or NON_PM if it doesn't have a direct counterpart. Sort of the + * zombie-specific inverse of undead_to_corpse. + * If a zombie gets passed to this function, it should return NON_PM, not the + * same monster again. */ +int +zombie_form(pm) +struct permonst *pm; +{ + switch(pm->mlet) { + case S_KOBOLD: + return PM_KOBOLD_ZOMBIE; + case S_ORC: + return PM_ORC_ZOMBIE; + case S_GIANT: + if (pm == &mons[PM_ETTIN]) + return PM_ETTIN_ZOMBIE; + return PM_GIANT_ZOMBIE; + case S_HUMAN: + case S_KOP: + if (is_elf(pm)) + return PM_ELF_ZOMBIE; + return PM_HUMAN_ZOMBIE; + case S_HUMANOID: + if (is_dwarf(pm)) + return PM_DWARF_ZOMBIE; + else + break; + case S_GNOME: + return PM_GNOME_ZOMBIE; + } + return NON_PM; +} + /* convert the monster index of an undead to its living counterpart */ int undead_to_corpse(mndx) @@ -1710,6 +1764,23 @@ long flag; return cnt; } +/* Part of mm_aggression that represents two-way aggression. To avoid having to + * code each case twice, this function contains those cases that ought to + * happen twice, and mm_aggression will call it twice. */ +static long +mm_2way_aggression(magr, mdef) +struct monst *magr, *mdef; +{ + struct permonst *ma = magr->data; + struct permonst *md = mdef->data; + + /* zombies vs things that can be zombified */ + if (zombie_maker(ma) && zombie_form(md) != NON_PM) + return ALLOW_M|ALLOW_TM; + + return 0; +} + /* Monster against monster special attacks; for the specified monster combinations, this allows one monster to attack another adjacent one in the absence of Conflict. There is no provision for targetting @@ -1722,6 +1793,10 @@ struct monst *magr, /* monster that is currently deciding where to move */ { int mndx = monsndx(magr->data); + /* don't allow pets to fight each other */ + if (magr->mtame && mdef->mtame) + return 0; + /* supposedly purple worms are attracted to shrieking because they like to eat shriekers, so attack the latter when feasible */ if ((mndx == PM_PURPLE_WORM || mndx == PM_BABY_PURPLE_WORM) @@ -1730,7 +1805,7 @@ struct monst *magr, /* monster that is currently deciding where to move */ /* Various other combinations such as dog vs cat, cat vs rat, and elf vs orc have been suggested. For the time being we don't support those. */ - return 0L; + return (mm_2way_aggression(magr, mdef) | mm_2way_aggression(mdef, magr)); } /* Monster displacing another monster out of the way */ @@ -2665,8 +2740,12 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */ } /* corpse--none if hero was inside the monster */ if (!wasinside && corpse_chance(mtmp, (struct monst *) 0, FALSE)) { + g.zombify = (!g.thrownobj && !g.stoned && !uwep + && zombie_maker(g.youmonst.data) + && zombie_form(mtmp->data) != NON_PM); cadaver = make_corpse(mtmp, burycorpse ? CORPSTAT_BURIED : CORPSTAT_NONE); + g.zombify = FALSE; /* reset */ if (burycorpse && cadaver && cansee(x, y) && !mtmp->minvis && cadaver->where == OBJ_BURIED && !nomsg) { pline("%s corpse ends up buried.", s_suffix(Monnam(mtmp))); diff --git a/src/monmove.c b/src/monmove.c index a16336ff0..b367096e8 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1293,29 +1293,8 @@ register int after; * Pets get taken care of above and shouldn't reach this code. * Conflict gets handled even farther away (movemon()). */ - if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) { - struct monst *mtmp2; - int mstatus; - - mtmp2 = m_at(nix, niy); - - g.notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my); - /* note: mstatus returns 0 if mtmp2 is nonexistent */ - mstatus = mattackm(mtmp, mtmp2); - - if (mstatus & MM_AGR_DIED) /* aggressor died */ - return 2; - - if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED) && rn2(4) - && mtmp2->movement >= NORMAL_SPEED) { - mtmp2->movement -= NORMAL_SPEED; - g.notonhead = 0; - mstatus = mattackm(mtmp2, mtmp); /* return attack */ - if (mstatus & MM_DEF_DIED) - return 2; - } - return 3; - } + if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) + return m_move_aggress(mtmp, nix, niy); if ((info[chi] & ALLOW_MDISP)) { struct monst *mtmp2; @@ -1607,6 +1586,44 @@ register int after; return mmoved; } +/* The part of m_move that deals with a monster attacking another monster (and + * that monster possibly retaliating). + * Extracted into its own function so that it can be called with monsters that + * have special move patterns (shopkeepers, priests, etc) that want to attack + * other monsters but aren't just roaming freely around the level (so allowing + * m_move to run fully for them could select an invalid move). + * x and y are the coordinates mtmp wants to attack. + * Return values are the same as for m_move, but this function only return 2 + * (mtmp died) or 3 (mtmp made its move). + */ +int +m_move_aggress(mtmp, x, y) +struct monst * mtmp; +xchar x, y; +{ + struct monst *mtmp2; + int mstatus; + + mtmp2 = m_at(x, y); + + g.notonhead = mtmp2 && (x != mtmp2->mx || y != mtmp2->my); + /* note: mstatus returns 0 if mtmp2 is nonexistent */ + mstatus = mattackm(mtmp, mtmp2); + + if (mstatus & MM_AGR_DIED) /* aggressor died */ + return 2; + + if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED) && rn2(4) + && mtmp2->movement >= NORMAL_SPEED) { + mtmp2->movement -= NORMAL_SPEED; + g.notonhead = 0; + mstatus = mattackm(mtmp2, mtmp); /* return attack */ + if (mstatus & MM_DEF_DIED) + return 2; + } + return 3; +} + void dissolve_bars(x, y) register int x, y; diff --git a/src/priest.c b/src/priest.c index 67e8c3114..3f9a1199b 100644 --- a/src/priest.c +++ b/src/priest.c @@ -52,6 +52,7 @@ register xchar omx, omy, gx, gy; schar chcnt, cnt; coord poss[9]; long info[9]; + long ninfo; long allowflags; #if 0 /* dead code; see below */ struct obj *ib = (struct obj *) 0; @@ -100,12 +101,14 @@ pick_move: ny = poss[i].y; if (IS_ROOM(levl[nx][ny].typ) || (mtmp->isshk && (!in_his_shop || ESHK(mtmp)->following))) { - if (avoid && (info[i] & NOTONL)) + if (avoid && (info[i] & NOTONL) && !(info[i] & ALLOW_M)) continue; if ((!appr && !rn2(++chcnt)) - || (appr && GDIST(nx, ny) < GDIST(nix, niy))) { + || (appr && GDIST(nx, ny) < GDIST(nix, niy)) + || (info[i] & ALLOW_M)) { nix = nx; niy = ny; + ninfo = info[i]; } } } @@ -118,6 +121,19 @@ pick_move: } if (nix != omx || niy != omy) { + + if (ninfo & ALLOW_M) { + /* mtmp is deciding it would like to attack this turn. + * Returns from m_move_aggress don't correspond to the same things + * as this function should return, so we need to translate. */ + switch (m_move_aggress(mtmp, nix, niy)) { + case 2: + return -2; /* died making the attack */ + case 3: + return 1; /* attacked and spent this move */ + } + } + if (MON_AT(nix, niy)) return 0; remove_monster(omx, omy); diff --git a/src/timeout.c b/src/timeout.c index ca24e94b9..80e1f10ea 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1745,6 +1745,7 @@ static const ttable timeout_funcs[NUM_TIME_FUNCS] = { TTAB(rot_organic, (timeout_proc) 0, "rot_organic"), TTAB(rot_corpse, (timeout_proc) 0, "rot_corpse"), TTAB(revive_mon, (timeout_proc) 0, "revive_mon"), + TTAB(zombify_mon, (timeout_proc) 0, "zombify_mon"), TTAB(burn_object, cleanup_burn, "burn_object"), TTAB(hatch_egg, (timeout_proc) 0, "hatch_egg"), TTAB(fig_transform, (timeout_proc) 0, "fig_transform"), From 0e713dc4e90eba08ec50c4260a36161d5f3db4d8 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Oct 2020 19:43:10 -0700 Subject: [PATCH 363/708] fix #K2617 - metallivores eating iron bars Monsters with rust attacks (rust monster) and corrosion attacks (black pudding, gray ooze) can eat or otherwise destroy iron bars but xorns could only move through the iron bars spot without being able to eat the metal there. Change xorn to eat bars instead of phazing through them. Lets rock moles eat bars too. Hero polymorphed into a rust monster would eat bars if trying to move to their location but couldn't do so if already there (maybe was in xorn form and now in rust monster form). Xorns could pass through them but not eat them. Allow hero metallivores to eat bars at the current location via 'e', similar to eating food off the floor. Hero as rock mole behaves like rust monster. --- doc/fixes37.0 | 8 +++++++- include/extern.h | 3 ++- src/eat.c | 51 ++++++++++++++++++++++++++++++++++++++++-------- src/hack.c | 36 +++++++++++++++++++++++++++------- src/mondata.c | 7 +++++-- src/monmove.c | 11 ++++++++--- 6 files changed, 94 insertions(+), 22 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 163b1c38f..711d612e7 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.332 $ $NHDT-Date: 1602958104 2020/10/17 18:08:24 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.337 $ $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ General Fixes and Modified Features ----------------------------------- @@ -280,6 +280,12 @@ when reporting that hero can't repair a chest's broken lock with key/pick/card pre-populate teleport destination prompt with travel destination ghosts cannot be renamed tossed upwards objects got two times half physical damage reduction +monster xorns could pass through iron bars but not eat them; monster rock + moles could no neither; now they can eat bars when adjacent and will + do so if the bars are blocking their path +hero poly'd into rust monster could implicitly eat bars when adjacent by + trying to move there, now when in rock mole form too; in xorn form + can explicitly eat them via 'e' after moving onto their spot Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index a8151c034..e24e605b6 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1602270114 2020/10/09 19:01:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.867 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.873 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -874,6 +874,7 @@ E anything *FDECL(long_to_any, (long)); E anything *FDECL(monst_to_any, (struct monst *)); E anything *FDECL(obj_to_any, (struct obj *)); E boolean FDECL(revive_nasty, (int, int, const char *)); +E int FDECL(still_chewing, (XCHAR_P, XCHAR_P)); E void FDECL(movobj, (struct obj *, XCHAR_P, XCHAR_P)); E boolean FDECL(may_dig, (XCHAR_P, XCHAR_P)); E boolean FDECL(may_passwall, (XCHAR_P, XCHAR_P)); diff --git a/src/eat.c b/src/eat.c index ffc36dd25..f73c4d1d5 100644 --- a/src/eat.c +++ b/src/eat.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 eat.c $NHDT-Date: 1599258557 2020/09/04 22:29:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.233 $ */ +/* NetHack 3.7 eat.c $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.235 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1449,7 +1449,8 @@ opentin(VOID_ARGS) { /* perhaps it was stolen (although that should cause interruption) */ if (!carried(g.context.tin.tin) - && (!obj_here(g.context.tin.tin, u.ux, u.uy) || !can_reach_floor(TRUE))) + && (!obj_here(g.context.tin.tin, u.ux, u.uy) + || !can_reach_floor(TRUE))) return 0; /* %% probably we should use tinoid */ if (g.context.tin.usedtime++ >= 50) { You("give up your attempt to open the tin."); @@ -2488,6 +2489,18 @@ doeat() } } + /* from floorfood(), &zeroobj means iron bars at current spot */ + if (otmp == &cg.zeroobj) { + /* hero in metallivore form is eating [diggable] iron bars + at current location so skip the other assorted checks; + operates as if digging rather than via the eat occupation */ + if (still_chewing(u.ux, u.uy) && levl[u.ux][u.uy].typ == IRONBARS) { + /* this is verbose, but player will see the hero rather than the + bars so wouldn't know that more turns of eating are required */ + You("pause to swallow."); + } + return 1; + } /* We have to make non-foods take 1 move to eat, unless we want to * do ridiculous amounts of coding to deal with partly eaten plate * mails, players who polymorph back to human in the middle of their @@ -3156,18 +3169,18 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */ register struct obj *otmp; char qbuf[QBUFSZ]; char c; - boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */ - offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */ + struct permonst *uptr = g.youmonst.data; + boolean feeding = !strcmp(verb, "eat"), /* corpsecheck==0 */ + offering = !strcmp(verb, "sacrifice"); /* corpsecheck==1 */ /* if we can't touch floor objects then use invent food only */ if (iflags.menu_requested /* command was preceded by 'm' prefix */ || !can_reach_floor(TRUE) || (feeding && u.usteed) || (is_pool_or_lava(u.ux, u.uy) - && (Wwalking || is_clinger(g.youmonst.data) - || (Flying && !Breathless)))) + && (Wwalking || is_clinger(uptr) || (Flying && !Breathless)))) goto skipfloor; - if (feeding && metallivorous(g.youmonst.data)) { + if (feeding && metallivorous(uptr)) { struct obj *gold; struct trap *ttmp = t_at(u.ux, u.uy); @@ -3188,8 +3201,30 @@ int corpsecheck; /* 0, no check, 1, corpses, 2, tinnable corpses */ return (struct obj *) 0; } } + if (levl[u.ux][u.uy].typ == IRONBARS) { + /* already verified that hero is metallivorous above */ + boolean nodig = (levl[u.ux][u.uy].wall_info & W_NONDIGGABLE) != 0; - if (g.youmonst.data != &mons[PM_RUST_MONSTER] + c = 'n'; + Strcpy(qbuf, "There are iron bars here"); + if (nodig || u.uhunger > 1500) { + pline("%s but you %s eat them.", qbuf, + nodig ? "cannot" : "are too full to"); + } else { + Strcat(qbuf, ((!g.context.digging.chew + || g.context.digging.pos.x != u.ux + || g.context.digging.pos.y != u.uy + || !on_level(&g.context.digging.level, &u.uz)) + ? "; eat them?" + : "; resume eating them?")); + c = yn_function(qbuf, ynqchars, 'n'); + } + if (c == 'y') + return (struct obj *) &cg.zeroobj; /* csst away 'const' */ + else if (c == 'q') + return (struct obj *) 0; + } + if (uptr != &mons[PM_RUST_MONSTER] && (gold = g_at(u.ux, u.uy)) != 0) { if (gold->quan == 1L) Sprintf(qbuf, "There is 1 gold piece here; eat it?"); diff --git a/src/hack.c b/src/hack.c index 941643a12..0e8efb024 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1600469617 2020/09/18 22:53:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.268 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1603507385 2020/10/24 02:43:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,7 +9,6 @@ static void NDECL(maybe_wail); static int NDECL(moverock); -static int FDECL(still_chewing, (XCHAR_P, XCHAR_P)); static void NDECL(dosinkfall); static boolean FDECL(findtravelpath, (int)); static boolean FDECL(trapmove, (int, int, struct trap *)); @@ -394,7 +393,7 @@ moverock() * Chew on a wall, door, or boulder. [What about statues?] * Returns TRUE if still eating, FALSE when done. */ -static int +int still_chewing(x, y) xchar x, y; { @@ -418,7 +417,15 @@ xchar x, y; : "hard stone"); nomul(0); return 1; - } else if (g.context.digging.pos.x != x || g.context.digging.pos.y != y + } else if (lev->typ == IRONBARS + && metallivorous(g.youmonst.data) && u.uhunger > 1500) { + /* finishing eating via 'morehungry()' doesn't handle choking */ + You("are too full to eat the bars."); + nomul(0); + return 1; + } else if (!g.context.digging.chew + || g.context.digging.pos.x != x + || g.context.digging.pos.y != y || !on_level(&g.context.digging.level, &u.uz)) { g.context.digging.down = FALSE; g.context.digging.chew = TRUE; @@ -504,7 +511,20 @@ xchar x, y; digtxt = "chew through the tree."; lev->typ = ROOM; } else if (lev->typ == IRONBARS) { - digtxt = "eat through the bars."; + if (metallivorous(g.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; + + /* lesshungry() requires that victual be set up, so skip it; + morehungry() of a negative amount will increase nutrition + without any possibility of choking to death on the meal; + updates hunger state and requests status update if changed */ + morehungry(-nut); + } + digtxt = (x == u.ux && y == u.uy) + ? "devour the iron bars." + : "eat through the bars."; dissolve_bars(x, y); } else if (lev->typ == SDOOR) { if (lev->doormask & D_TRAPPED) { @@ -745,8 +765,10 @@ int mode; pline("There is an obstacle there."); return FALSE; } else if (tmpr->typ == IRONBARS) { - if ((dmgtype(g.youmonst.data, AD_RUST) - || dmgtype(g.youmonst.data, AD_CORR)) && mode == DO_MOVE + if (mode == DO_MOVE + && (dmgtype(g.youmonst.data, AD_RUST) + || dmgtype(g.youmonst.data, AD_CORR) + || metallivorous(g.youmonst.data)) && still_chewing(x, y)) { return FALSE; } diff --git a/src/mondata.c b/src/mondata.c index 497beef06..5ccc48bb3 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.c $NHDT-Date: 1596498186 2020/08/03 23:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.83 $ */ +/* NetHack 3.7 mondata.c $NHDT-Date: 1603507386 2020/10/24 02:43:06 $ $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. */ @@ -334,7 +334,10 @@ struct permonst *mptr; { return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr) || is_whirly(mptr) || verysmall(mptr) - || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST) + /* rust monsters and some puddings can destroy bars */ + || dmgtype(mptr, AD_RUST) || dmgtype(mptr, AD_CORR) + /* rock moles can eat bars */ + || metallivorous(mptr) || (slithy(mptr) && !bigmonst(mptr))); } diff --git a/src/monmove.c b/src/monmove.c index b367096e8..00986f4fb 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monmove.c $NHDT-Date: 1600469618 2020/09/18 22:53:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */ +/* NetHack 3.7 monmove.c $NHDT-Date: 1603507386 2020/10/24 02:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.146 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1477,9 +1477,12 @@ register int after; add_damage(mtmp->mx, mtmp->my, 0L); } } else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) { - /* 3.6.2: was using may_dig() but it doesn't handle bars */ + /* 3.6.2: was using may_dig() but that doesn't handle bars; + AD_RUST catches rust monsters but metallivorous() is + needed for xorns and rock moles */ if (!(levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE) - && (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) { + && (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR) + || metallivorous(ptr))) { if (canseemon(mtmp)) pline("%s eats through the iron bars.", Monnam(mtmp)); dissolve_bars(mtmp->mx, mtmp->my); @@ -1631,6 +1634,8 @@ register int x, y; levl[x][y].typ = (Is_special(&u.uz) || *in_rooms(x, y, 0)) ? ROOM : CORR; levl[x][y].flags = 0; newsym(x, y); + if (x == u.ux && y == u.uy) + switch_terrain(); } boolean From 74c2716004952b02af209451fe30e154daec2e92 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 23 Oct 2020 20:15:01 -0700 Subject: [PATCH 364/708] fix #K2622 - fire/frost horn feedback for monster When a monster used a fire horn or frost horn to attack the hero, the feedback claimed that the attack was being directed at itself. The error occurred in code that was added to 3.7 during 3.6 development but wasn't present in 3.6.x so fixes entry is in the "exposed by git" section. --- doc/fixes37.0 | 4 +++- src/muse.c | 21 +++++++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 711d612e7..4e19df77c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.337 $ $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.338 $ $NHDT-Date: 1603509297 2020/10/24 03:14:57 $ General Fixes and Modified Features ----------------------------------- @@ -369,6 +369,8 @@ replace worm tail placement code that reportedly led to a sanity_check warning learn scroll of teleportation after reading even when random destination is right by starting spot fix off-by-one bug in dimensions of theme rooms +fire/frost horn feedback when zapped by monster was inaccurate (falsely + claimed that it was "directed at self" when attacking hero) curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/muse.c b/src/muse.c index 31f88fbd6..360b56482 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 muse.c $NHDT-Date: 1596498190 2020/08/03 23:43:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.129 $ */ +/* NetHack 3.7 muse.c $NHDT-Date: 1603509297 2020/10/24 03:14:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -183,6 +183,8 @@ struct monst *mtmp; struct obj *otmp; boolean self; { + char *objnamp, objbuf[BUFSZ]; + if (!canseemon(mtmp)) { int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */ ? (BOLT_LIM + 1) : (BOLT_LIM - 3); @@ -191,9 +193,7 @@ boolean self; (distu(mtmp->mx, mtmp->my) <= range * range) ? "nearby" : "in the distance"); otmp->known = 0; /* hero doesn't know how many charges are left */ - } else { - char *objnamp, objbuf[BUFSZ]; - + } else if (self) { otmp->dknown = 1; objnamp = xname(otmp); if (strlen(objnamp) >= QBUFSZ) @@ -202,8 +202,17 @@ boolean self; /* " plays a directed at himself!" */ pline("%s!", monverbself(mtmp, Monnam(mtmp), "play", objbuf)); makeknown(otmp->otyp); /* (wands handle this slightly differently) */ - if (!self) - stop_occupation(); + } else { + otmp->dknown = 1; + objnamp = xname(otmp); + if (strlen(objnamp) >= QBUFSZ) + objnamp = simpleonames(otmp); + pline("%s %s %s directed at you!", + /* monverbself() would adjust the verb if hallucination made + subject plural; stick with singular here, at least for now */ + Monnam(mtmp), "plays", an(objnamp)); + makeknown(otmp->otyp); + stop_occupation(); } otmp->spe -= 1; /* use a charge */ } From 8cc75bf583ca2e13d8b37f0d156352e142133913 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Sat, 24 Oct 2020 11:38:22 +0200 Subject: [PATCH 365/708] Fix "may be used uninitialized" warning --- src/priest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/priest.c b/src/priest.c index 3f9a1199b..f7a8b0c49 100644 --- a/src/priest.c +++ b/src/priest.c @@ -52,7 +52,7 @@ register xchar omx, omy, gx, gy; schar chcnt, cnt; coord poss[9]; long info[9]; - long ninfo; + long ninfo = 0; long allowflags; #if 0 /* dead code; see below */ struct obj *ib = (struct obj *) 0; From 1b37ac6280216d059781511a8e2d3c7c949cb85f Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 24 Oct 2020 03:17:19 -0700 Subject: [PATCH 366/708] disclosure prompt phrasing With to-be-3.7, if game ends without any achievements, the conduct disclosure prompt is the same as it has always been Do you want to see your conduct? If it ends after attaining one achievement (probably entering the mines or acquiring the second rank title when gaining Xp level 3) you're asked Do you want to see your conduct and achievement? which looks awkward after the fact if 'y' reveals multiple conducts. Instead of deciding whether to pluralize "conduct(s)", simplify the prompt when one or more achievements have been attained to be Do you want to see your conduct and achievements? That works even when there is only one achievement. --- src/end.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/end.c b/src/end.c index d8187a9e8..bdce05a88 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1597182933 2020/08/11 21:55:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.212 $ */ +/* NetHack 3.7 end.c $NHDT-Date: 1603534633 2020/10/24 10:17:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.214 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -820,9 +820,14 @@ boolean taken; if (should_query_disclose_option('c', &defquery)) { int acnt = count_achievements(); - Sprintf(qbuf, "Do you want to see your conduct%s%s?", - (acnt > 0) ? " and achievement" : "", - (acnt > 1) ? "s" : ""); + Sprintf(qbuf, "Do you want to see your conduct%s?", + /* this was distinguishing between one achievement and + multiple achievements, but "conduct and achievement" + looked strange if multiple conducts got shown (which + is usual for an early game death); we could switch + to plural vs singular for conducts but the less + specific "conduct and achievements" is sufficient */ + (acnt > 0) ? " and achievements" : ""); c = yn_function(qbuf, ynqchars, defquery); } else { c = defquery; From 22ca1ae4da13f6c6d91f0c390d320a4c8f66cdf0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 24 Oct 2020 18:27:34 +0300 Subject: [PATCH 367/708] Fix monster hiding under hatching egg staying hidden --- doc/fixes37.0 | 1 + src/timeout.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4e19df77c..876a2aa12 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -286,6 +286,7 @@ monster xorns could pass through iron bars but not eat them; monster rock hero poly'd into rust monster could implicitly eat bars when adjacent by trying to move there, now when in rock mole form too; in xorn form can explicitly eat them via 'e' after moving onto their spot +monster hiding under an egg that hatched was kept hidden Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/timeout.c b/src/timeout.c index 80e1f10ea..9782401b9 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -985,6 +985,8 @@ long timeout; /* free egg here because we use it above */ obj_extract_self(egg); obfree(egg, (struct obj *) 0); + if ((mon = m_at(x,y)) && !hideunder(mon) && cansee(x, y)) + redraw = TRUE; } if (redraw) newsym(x, y); From 4e1cf071ae26dc7080f6a385c97c9e96ad395f6b Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Mon, 19 Oct 2020 01:52:46 +0200 Subject: [PATCH 368/708] List lamps and lanterns in charging prompt Brass lanterns and oil lamps are always chargeable. Magic lamps are only listed if they are not yet identified. --- doc/fixes37.0 | 1 + src/read.c | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 876a2aa12..c068816be 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -579,6 +579,7 @@ render the color names in the corresponding color when using the pick-a-color menu for adding status highlights or menu colors via 'O' reading blessed scroll of teleportation confers one-shot teleport control mild zombie apocalypse +list lamps and lanterns in charging prompt Platform- and/or Interface-Specific New Features diff --git a/src/read.c b/src/read.c index 42b1040a2..bd208a9d6 100644 --- a/src/read.c +++ b/src/read.c @@ -501,8 +501,16 @@ struct obj *obj; && objects[obj->otyp].oc_name_known))); if (is_weptool(obj)) /* specific check before general tools */ return FALSE; - if (obj->oclass == TOOL_CLASS) + if (obj->oclass == TOOL_CLASS) { + if (obj->otyp == BRASS_LANTERN + || (obj->otyp == OIL_LAMP) + /* only list magic lamps if they are not identified yet */ + || (obj->otyp == MAGIC_LAMP + && !objects[MAGIC_LAMP].oc_name_known)) { + return TRUE; + } return (boolean) objects[obj->otyp].oc_charged; + } return FALSE; /* why are weapons/armor considered charged anyway? */ } From ec5772d6d29a7de46768fa40f2d1e984215256a9 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 25 Oct 2020 15:47:49 -0700 Subject: [PATCH 369/708] Qt hitpointbar Add support for the 'hitpointbar' to the Qt interface. Rather than rendering the status title (name+rank or name+monster_species) using inverse video for leading substring to produce distinct left and right sides, draw a horizontal bar above that field. The left portion (current health) is thicker and uses red for <10% or <5hp, orange for <25% or <10hp, yellow for <50%, green for <75%, blue for <100%, and black for 100%. The right portion (missing maximum health) is thinner and runs from white (paired with red), light gray (paired with orange), dark gray (with yellow), plain gray (which turns out to be darker than dark gray, with green), dark blue (with blue), and black (but black is never shown for injury portion because that's suppressed when at full health). Qt already supports a square frame around the hero's map tile that changes color according to health. Turning the hitpointbar option Off or On has no effect on that. --- doc/fixes37.0 | 3 +- src/options.c | 11 +++- win/Qt/qt_bind.cpp | 11 ++-- win/Qt/qt_stat.cpp | 142 +++++++++++++++++++++++++++++++++++++++++++-- win/Qt/qt_stat.h | 6 ++ 5 files changed, 158 insertions(+), 15 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c068816be..d56d5c7b6 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.338 $ $NHDT-Date: 1603509297 2020/10/24 03:14:57 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ $NHDT-Date: 1603666043 2020/10/25 22:47:23 $ General Fixes and Modified Features ----------------------------------- @@ -600,6 +600,7 @@ Qt: clicking on the paper doll runs the #seeall command (inventory of wielded words, same set of things whose tiles are used to populate the doll) Qt: clicking on the status window runs the #attributes command (^X) Qt: add a Search button to the toolbar +Qt: support the 'hitpointbar' option NetHack Community Patches (or Variation) Included diff --git a/src/options.c b/src/options.c index 39e69c9f1..f00907912 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1599893947 2020/09/12 06:59:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.473 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1603666043 2020/10/25 22:47:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.478 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4607,6 +4607,12 @@ char *op; /* [is reassessment really needed here?] */ status_initialize(REASSESS_ONLY); g.opt_need_redraw = TRUE; +#ifdef QT_GRAPHICS + } else if (WINDOWPORT("Qt")) { + /* Qt doesn't support HILITE_STATUS or FLUSH_STATUS so fails + VIA_WINDOWPORT(), but it does support WC2_HITPOINTBAR */ + g.context.botlx = TRUE; +#endif } break; case opt_color: @@ -7619,7 +7625,8 @@ doset() /* changing options via menu by Per Liboriussen */ check_gold_symbol(); reglyph_darkroom(); (void) doredraw(); - } else if (g.context.botl || g.context.botlx) { + } + if (g.context.botl || g.context.botlx) { bot(); } return 0; diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 5fb65f980..b31465ad5 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -931,12 +931,11 @@ static void Qt_positionbar(char *) {} struct window_procs Qt_procs = { "Qt", - WC_COLOR | WC_HILITE_PET - | WC_ASCII_MAP | WC_TILED_MAP - | WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT - | WC_POPUP_DIALOG - | WC_PLAYER_SELECTION | WC_SPLASH_SCREEN, - 0L, + (WC_COLOR | WC_HILITE_PET + | WC_ASCII_MAP | WC_TILED_MAP + | WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT + | WC_POPUP_DIALOG | WC_PLAYER_SELECTION | WC_SPLASH_SCREEN), + (WC2_HITPOINTBAR), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ nethack_qt_::NetHackQtBind::qt_init_nhwindows, nethack_qt_::NetHackQtBind::qt_player_selection, diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 02fb15772..cfccb439d 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -2,7 +2,7 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// qt_stat.cpp -- bindings between the Qt 4 interface and the main code +// qt_stat.cpp -- status window, upper right portion of the overall window extern "C" { #include "hack.h" @@ -26,10 +26,6 @@ extern const char *hu_stat[]; /* from eat.c */ namespace nethack_qt_ { NetHackQtStatusWindow::NetHackQtStatusWindow() : - // Notes: - // Alignment needs -2 init value, because -1 is an alignment. - // Armor Class is an schar, so 256 is out of range. - // Blank value is 0 and should never change. name(this,"(name)"), dlevel(this,"(dlevel)"), str(this, "Str"), @@ -62,10 +58,14 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : lev(this,"Lev"), fly(this,"Fly"), ride(this,"Ride"), + hpbar_health(this), + hpbar_injury(this), hline1(this), hline2(this), hline3(this), - first_set(true) + cursy(0), + first_set(true), + alreadyfullhp(false) { p_str = QPixmap(str_xpm); p_str = QPixmap(str_xpm); @@ -127,6 +127,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : fly.setIcon(p_fly); ride.setIcon(p_ride); + // separator lines hline1.setFrameStyle(QFrame::HLine|QFrame::Sunken); hline2.setFrameStyle(QFrame::HLine|QFrame::Sunken); hline3.setFrameStyle(QFrame::HLine|QFrame::Sunken); @@ -134,11 +135,14 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : hline2.setLineWidth(1); hline3.setLineWidth(1); + QHBoxLayout *hpbar = InitHitpointBar(); + #if 1 //RLC name.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); dlevel.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QVBoxLayout *vbox = new QVBoxLayout(); vbox->setSpacing(0); + vbox->addLayout(hpbar); vbox->addWidget(&name); vbox->addWidget(&dlevel); vbox->addWidget(&hline1); @@ -390,6 +394,130 @@ void NetHackQtStatusWindow::fadeHighlighting() ride.dissipateHighlight(); } +// hitpointbar: two panels: left==current health, right==missing max health +QHBoxLayout *NetHackQtStatusWindow::InitHitpointBar() +{ + hpbar_health.setFrameStyle(QFrame::NoFrame); + hpbar_health.setMaximumHeight(9); + hpbar_health.setAutoFillBackground(true); + if (!iflags.wc2_hitpointbar) + hpbar_health.hide(); + + hpbar_injury.setFrameStyle(QFrame::NoFrame); + /* health portion has thickness 9, injury portion just 3 */ + hpbar_injury.setMaximumHeight(3); + hpbar_injury.setContentsMargins(0, 3, 0, 3); // left,top,right,bottom + hpbar_injury.setAutoFillBackground(true); + hpbar_injury.hide(); // only shown when hitpointbar is On and uhp < uhpmax + + QHBoxLayout *hpbar = new QHBoxLayout; + hpbar->setSpacing(0); + hpbar->setMargin(0); + hpbar->addWidget(&hpbar_health); + hpbar->setAlignment(&hpbar_health, Qt::AlignLeft); + hpbar->addWidget(&hpbar_injury); + hpbar->setAlignment(&hpbar_injury, Qt::AlignRight); + return hpbar; // caller will add our result to vbox layout +} + +// when hitpoint bar is enabled, calculate and draw it, otherwise remove it +void NetHackQtStatusWindow::HitpointBar() +{ + // a style sheet is used to specify color for otherwise blank labels; + // barcolors[][*]: column [0=left] is current health, [1=right] is injury + static const char + *styleformat = "QLabel { background-color : %s ; color : transparent ;" + " min-width : %d ; max-width %d }", + *barcolors[6][2] = { + { "black", "black" }, // 100% /* second black never shown */ + { "blue", "darkBlue" }, //75..99 + // gray is darker than darkGray for some reason (at least on OSX)... + // green and orange would look better if they were lighter/brighter + { "green", "gray" }, //50..74 + { "yellow", "darkGray" }, //25..49 + { "#ff7f00", "lightGray" }, //10..24 /* #ff7f00=="orange" */ + { "red", "white" }, // 0..9 + }; + + /* + * tty and curses use inverse video characters in the left portion + * of the name+rank string to reflect hero's health. We draw a + * separate line above the name+rank field instead. The left side + * of the line indicates current health. The right side is only + * shown when injured and indicates missing amount of maximum health. + */ + if (iflags.wc2_hitpointbar) { + int colorindx, w, + ihp = Upolyd ? u.mh : u.uhp, + ihpmax = Upolyd ? u.mhmax : u.uhpmax; + ihp = std::max(std::min(ihp, ihpmax), 0); + int pct = 100 * ihp / ihpmax, + lox = hline1.x(), + hix = lox + hline1.width() - 1; + QRect geoH = hpbar_health.geometry(), + geoI = hpbar_injury.geometry(); + QString styleH, styleI; + + if (ihp < ihpmax) { + // health is less than full; + // use red for extreme low health even if the percentage is + // above the usual threshold (which will happen when maximum + // health is very low); do a similar threshold override for + // orange even though it can be distracting for low level hero + colorindx = (pct < 10 || ihp < 5) ? 5 // red | white + : (pct < 25 || ihp < 10 ) ? 4 // orange | lightGray + : (pct < 50) ? 3 // yellow | darkGray* + : (pct < 75) ? 2 // green | gray* + : 1; // blue | darkBlue + + int pxl_health = (hix - lox + 1) * ihp / ihpmax; + geoH.setRight(std::min(lox + pxl_health - 1, hix)); + hpbar_health.setGeometry(geoH); + w = geoH.right() - geoH.left() + 1; // might yield 0 (ie, if dead) + styleH.sprintf(styleformat, barcolors[colorindx][0], w, w); + hpbar_health.setStyleSheet(styleH); + // style sheet should be doing this but width was sticking at full + hpbar_health.setMaximumWidth(w); + hpbar_health.show(); // don't need to hide() if/when width is 0 + + int oldleft = geoI.left(); + geoI.setLeft(geoH.right() + 1); + geoI.setRight(hix); + hpbar_injury.setGeometry(geoI); + w = geoI.right() - geoI.left() + 1; + styleI.sprintf(styleformat, barcolors[colorindx][1], w, w); + hpbar_injury.setStyleSheet(styleI); + if (geoI.left() != oldleft) + hpbar_injury.move(geoI.left(), geoI.top()); + hpbar_injury.show(); + + alreadyfullhp = false; + } else if (!alreadyfullhp) { // skip if unchanged + // health is full + colorindx = 0; // black | (not used) + + hpbar_injury.hide(); + geoI.setLeft(hix); // hix + 1 + hpbar_injury.setGeometry(geoI); + + geoH.setRight(hix); + hpbar_health.setGeometry(geoH); + w = geoH.right() - geoH.left() + 1; + styleH.sprintf(styleformat, barcolors[colorindx][0], w, w); + hpbar_health.setStyleSheet(styleH); + hpbar_health.setMaximumWidth(w); // (see above) + hpbar_health.show(); + + alreadyfullhp = true; + } + } else { + // hitpoint bar is disabled + hpbar_health.hide(); + hpbar_injury.hide(); + alreadyfullhp = false; + } +} + /* * Update the displayed status. The current code in botl.c updates * two lines of information. Both lines are always updated one after @@ -413,6 +541,8 @@ void NetHackQtStatusWindow::updateStats() if (cursy != 0) return; /* do a complete update when line 0 is done */ + HitpointBar(); + int st = ACURR(A_STR); if (st > STR18(100)) { buf.sprintf("Str:%d", st - 100); // 19..25 diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index a8d27cb95..7a3715b3d 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -104,6 +104,9 @@ private: NetHackQtLabelledIcon fly; NetHackQtLabelledIcon ride; + QLabel hpbar_health; // hit point bar, left half + QLabel hpbar_injury; // hit point bar, right half + QFrame hline1; QFrame hline2; QFrame hline3; @@ -111,7 +114,10 @@ private: int cursy; bool first_set; + bool alreadyfullhp; + QHBoxLayout *InitHitpointBar(); + void HitpointBar(); void nullOut(); void updateStats(); void checkTurnEvents(); From 9c384ba867d01f2b1b0cc335b5292b7e300aade2 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 26 Oct 2020 12:44:40 -0700 Subject: [PATCH 370/708] Qt popup dialog input vs '&' I'm not sure whether any yn_function() calls include ampersand in the list of acceptable choices but if any did, the button for that character would have shown up blank. (Clicking on it would have successfully produced '&' as player's input though.) --- doc/fixes37.0 | 3 ++- win/Qt/qt_yndlg.cpp | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d56d5c7b6..38ebeb41a 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.341 $ $NHDT-Date: 1603666043 2020/10/25 22:47:23 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.342 $ $NHDT-Date: 1603741470 2020/10/26 19:44:30 $ General Fixes and Modified Features ----------------------------------- @@ -458,6 +458,7 @@ Qt: rename toolbar button "Get" and action menu choice "Get" to "Pick up" Qt: status icons for alignment|hunger|encumbrance which started out centered relative to the label text below them would shift to being left justified when status got updated +Qt: handle '&' properly if it occurs as part of yn_function popup dialog Qt+OSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index d7b370a32..4ea3688b0 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -246,6 +246,17 @@ char NetHackQtYnDialog::Exec() case '\033': // won't happen; ESC is hidden button_name = "Esc"; break; + case '&': + // ampersand is used as a hidden quote char to flag + // next character as a keyboard shortcut associated + // with the current action--that's inappropriate here; + // two consecutive ampersands are needed to display + // one in a button label; first check whether caller + // has already done that, skip this one if so + if (i > 0 && ch[i - 1].cell() == QChar('&')) + continue; // next i + button_name = "&&"; + break; } } button=new QPushButton(button_name); From 14ec98a241698eb67fa8417cfd426e051aed1bea Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 26 Oct 2020 22:37:40 -0700 Subject: [PATCH 371/708] Qt saved game selection This fixes the Qt popup widget for selecting among saved games. The character name from each applicable save file is shown in a button and clicking on one of those buttons restores corresponding file. Previously all the buttons were written on top of each other so only the final name was visible and the button for the initial name received the click. The widget also has [quit] and [new game] buttons. This fixes restoring an existing save file if no character name is supplied on the command line in the options. It does not fix the problem where picking [new game] remembers the file name of the last saved game in the popup's list and overwrites that file (after requesting confirmation to do so) if/when you eventually save. The resulting file will contain the character just saved but be named for the earlier one. It may not be obvious because on subsequent restores it will list names from inside the files rather than deduce those from file names, so the clobbered/ misnamed file will just show up as the former new character. --- doc/fixes37.0 | 5 +++- win/Qt/qt_svsel.cpp | 70 +++++++++++++++++++++++++++++++-------------- 2 files changed, 52 insertions(+), 23 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 38ebeb41a..489c4ebd1 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.342 $ $NHDT-Date: 1603741470 2020/10/26 19:44:30 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.343 $ $NHDT-Date: 1603777052 2020/10/27 05:37:32 $ General Fixes and Modified Features ----------------------------------- @@ -459,6 +459,9 @@ Qt: status icons for alignment|hunger|encumbrance which started out centered relative to the label text below them would shift to being left justified when status got updated Qt: handle '&' properly if it occurs as part of yn_function popup dialog +Qt: fix the display side of saved game selection; character names for + available save files are shown in a column of push buttons instead + of each button overwriting all the ones before it Qt+OSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/qt_svsel.cpp b/win/Qt/qt_svsel.cpp index 11cec2c61..219fa7d5b 100644 --- a/win/Qt/qt_svsel.cpp +++ b/win/Qt/qt_svsel.cpp @@ -3,6 +3,34 @@ // NetHack may be freely redistributed. See license for details. // qt_svsel.cpp -- saved game selector +// +// Popup's layout: +//---- +// NetHack 3.7.x (literal text w/ dynamic version number) +// /----------------------\ +// | | +// | | +// | splash image | nhsplash.xpm (red dragon w/ rider) +// | | +// | | +// \----------------------/ +// by the NetHack DevTeam (literal text) +// [ Quit ] [New-Game] side-by-side buttons +// Saved characters (literal text in small font) +// [ character one ] button with character name +// [ character two ] button with another character name +// [ character three ] button with yet another character name +// ... as many buttons as needed +//---- +// +// TODO? +// Character names are sorted alphabetically. It would be useful to +// be able to sort by role or by game start date or by save date. +// The core fetches character names from inside the files; it could +// obtain the information needed for alternate sorting. Simpler +// enchancement: instead of just showing the character name, show +// "name-role-race-gender-alignment". +// extern "C" { #include "hack.h" @@ -20,26 +48,29 @@ extern "C" { namespace nethack_qt_ { +// +// popup dialog at start of game to choose between a new game or which save +// file to load if user has at least one saved game and either hasn't supplied +// any character name or has supplied one which doesn't have a save file +// NetHackQtSavedGameSelector::NetHackQtSavedGameSelector(const char** saved) : QDialog(NetHackQtBind::mainWidget()) { QVBoxLayout *vbl = new QVBoxLayout(this); QHBoxLayout* hb; -#if 0 // this works but don't add it until the rest is working as intended char cvers[BUFSZ]; QString qvers = QString("NetHack ") + QString(version_string(cvers)); - QLabel* vers = new QLabel(qvers, this); + QLabel *vers = new QLabel(qvers, this); vers->setAlignment(Qt::AlignCenter); vbl->addWidget(vers); -#endif - QLabel* logo = new QLabel(this); + QLabel *logo = new QLabel(this); logo->setAlignment(Qt::AlignCenter); logo->setPixmap(QPixmap("nhsplash.xpm")); vbl->addWidget(logo); - QLabel* attr = new QLabel("by the NetHack DevTeam",this); + QLabel *attr = new QLabel("by the NetHack DevTeam", this); attr->setAlignment(Qt::AlignCenter); vbl->addWidget(attr); vbl->addStretch(2); @@ -51,30 +82,25 @@ QLayout: Attempting to add QLayout "" to QDialog "", which already has a layout hb = new QHBoxLayout((QWidget *) NULL); vbl->addLayout(hb, Qt::AlignCenter); - QPushButton* q = new QPushButton("Quit",this); + QPushButton *q = new QPushButton("Quit", this); hb->addWidget(q); connect(q, SIGNAL(clicked()), this, SLOT(reject())); - QPushButton* c = new QPushButton("New Game",this); + QPushButton *c = new QPushButton("New Game", this); hb->addWidget(c); connect(c, SIGNAL(clicked()), this, SLOT(accept())); c->setDefault(true); - // - // FIXME! - // The text "Saved Characters" is overwritten by all the - // filename buttons. The last button added is the only one - // visible but clicking on it seems to activate the first - // one instead. - // - QGroupBox* box = new QGroupBox("Saved Characters",this); - QButtonGroup *bg = new QButtonGroup(this); - vbl->addWidget(box); - QVBoxLayout *bgl UNUSED = new QVBoxLayout(box); + QGroupBox *box = new QGroupBox("Saved Characters", this); + QVBoxLayout *bgl = new QVBoxLayout(); + QButtonGroup *bg = new QButtonGroup(); connect(bg, SIGNAL(buttonPressed(int)), this, SLOT(done(int))); - for (int i=0; saved[i]; i++) { - QPushButton* b = new QPushButton(saved[i],box); - bg->addButton(b, i+2); + for (int i = 0; saved[i]; ++i) { + QPushButton *b = new QPushButton(saved[i]); + bgl->addWidget(b); + bg->addButton(b, i + 2); } + box->setLayout(bgl); + vbl->addWidget(box); } int NetHackQtSavedGameSelector::choose() @@ -83,7 +109,7 @@ int NetHackQtSavedGameSelector::choose() if ( qt_compact_mode ) showMaximized(); #endif - return exec()-2; + return exec() - 2; } } // namespace nethack_qt_ From 70e4f5b197205adcea900660d63f089f980fbde9 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 27 Oct 2020 15:10:22 -0700 Subject: [PATCH 372/708] Qt: new game vs saved game selection If player got Qt's saved game selection widget at startup but picked "new game" there, the save file for the last character in the list of saved games would be clobbered with the new character's game if a save was performed. It wasn't necessarily easy to spot because saved game selection shows the character name from inside the file rather than from the file name, so the next restore would look normal except for one older character missing. Noticed while testing: when you used the character selection widget (either by picking "new game" in saved game selection or because there aren't any save files), if you blanked out the name field or it was already blanked because a generic name like "player" had been specified, then clicked on "play", the program would get stuck in a loop somewhere. I didn't try to figure out where, just changed qt_askname() to revert to original name if it ended up with a blank one. --- doc/fixes37.0 | 6 +++++- win/Qt/Qt-issues.txt | 9 --------- win/Qt/qt_bind.cpp | 39 +++++++++++++++++++++++++++++---------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 489c4ebd1..a46b9c1c1 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.343 $ $NHDT-Date: 1603777052 2020/10/27 05:37:32 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ $NHDT-Date: 1603836614 2020/10/27 22:10:14 $ General Fixes and Modified Features ----------------------------------- @@ -462,6 +462,10 @@ Qt: handle '&' properly if it occurs as part of yn_function popup dialog Qt: fix the display side of saved game selection; character names for available save files are shown in a column of push buttons instead of each button overwriting all the ones before it +Qt: don't clobber an existing save file after choosing "new game" in the + saved game selection widget +Qt: don't get stuck in a loop after choosing "play" while the character name + field is empty in the character selection widget Qt+OSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index ba7ad5c95..4ac6fc2e7 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -44,15 +44,6 @@ On the map, ^V is a dead key (at least on OSX; all other ASCII control characters from ^A through ^U, ^W through ^Z, and ^[, ^\, ^], ^^, ^_ work; no attempt to have ^@ generate NUL has been made). -The save file selection widget writes all the file name selection -buttons on top of each other, with the last one added being the only -one visible. Clicking on it seems to be picking the first one instead. -If you pick "new game" and use a different character name then -eventually save, it clobbers the last one in the list (rather, warns -the player that a save file exists and asks whether to overwrite it; -answering yes and then loading the file shows the new character, not -the original one even though the file is still named for that one). - Map column #0, which the core reserves for its own purposes and isn't intended to be displayed, is displayed (as blank terrain). diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index b31465ad5..512ab06af 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -185,38 +185,57 @@ void NetHackQtBind::qt_player_selection() void NetHackQtBind::qt_askname() { - have_asked = true; + char default_plname[PL_NSIZ]; - // We do it all here, and nothing in askname + have_asked = true; + str_copy(default_plname, g.plname, PL_NSIZ); + + // We do it all here (plus qt_plsel.cpp and qt_svsel.cpp), + // nothing in player_selection(). char** saved = get_saved_games(); - int ch = -1; + int ch = -1; // -1 => new game if ( saved && *saved ) { if ( splash ) splash->hide(); NetHackQtSavedGameSelector sgsel((const char**)saved); ch = sgsel.choose(); if ( ch >= 0 ) str_copy(g.plname, saved[ch], SIZE(g.plname)); + // caller needs new lock name even if plname[] hasn't changed + // because successful get_saved_games() clobbers g.SAVEF[] + ::iflags.renameinprogress = TRUE; } free_saved_games(saved); switch (ch) { case -1: + // New Game if (splash) splash->hide(); - if (NetHackQtPlayerSelector(keybuffer).Choose()) - return; + if (NetHackQtPlayerSelector(keybuffer).Choose()) { + // success; handle plname[] verification below prior to returning + break; + } /*FALLTHRU*/ case -2: + // Quit + clearlocks(); + qt_exit_nhwindows(0); + nh_terminate(0); + /*NOTREACHED*/ break; default: - return; + // picked a character from the saved games list + break; } - // Quit - clearlocks(); - qt_exit_nhwindows(0); - nh_terminate(0); + if (!*g.plname) + // in case Choose() returns with plname[] empty + Strcpy(g.plname, default_plname); + else if (strcmp(g.plname, default_plname) != 0) + // caller needs to set new lock file name + ::iflags.renameinprogress = TRUE; + return; } void NetHackQtBind::qt_get_nh_event() From 706977a1e7f31fa90cc9dd8255f23d53396dedbf Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 28 Oct 2020 01:43:53 -0700 Subject: [PATCH 373/708] Qt: character selection For Qt's character selection widget, only allow the [Play] button to be used when the character name field is non-blank. When that field is blank, show "(required)" there. Catch up with SYSCF for checking generic names like "player". Fix up handling for some conditionally unused variables. --- win/Qt/qt_plsel.cpp | 150 ++++++++++++++++++++++++++++++++------------ win/Qt/qt_plsel.h | 6 ++ 2 files changed, 117 insertions(+), 39 deletions(-) diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index d9a2d4337..a0c76ab4c 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -4,6 +4,16 @@ // qt_plsel.cpp -- player selector dialog +// +// TODO: +// increase height so that no scrolling is needed for role list; +// the [Random] button doesn't do anything; +// make race first vs role first dynamically selectable (tty allows +// gender first and alignment first too); +// maybe add a set of radio buttons for normal mode vs explore mode +// [vs wizard mode if eligible] +// + extern "C" { #include "hack.h" } @@ -24,6 +34,29 @@ extern "C" { // Warwick prefers it this way... #define QT_CHOOSE_RACE_FIRST +/* check whether plname[] is among the list of generic user names */ +static bool generic_plname() +{ + if (*g.plname) { + const char *sptr; + const char *genericusers = sysopt.genericusers; + int ln = (int) strlen(g.plname); + + if (!genericusers || !*genericusers) + genericusers = "player games"; + else if (!strcmp(genericusers, "*")) /* "*" => always ask for name */ + return true; + + if ((sptr = strstri(genericusers, g.plname)) != 0 + /* check for full word: start of list or following a space */ + && (sptr == genericusers || sptr[-1] == ' ') + /* and also preceding a space or at end of list */ + && (sptr[ln] == ' ' || sptr[ln] == '\0')) + return true; + } + return false; +} + namespace nethack_qt_ { // temporary @@ -133,14 +166,19 @@ public: NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) : QDialog(NetHackQtBind::mainWidget()), - fully_specified_role(true) + fully_specified_role(true), + chosen_gend(ROLE_NONE), + chosen_align(ROLE_NONE), + rand_btn(new QPushButton("Random")), + play_btn(new QPushButton("Play")), + quit_btn(new QPushButton("Quit")) { /* 0 1 2 + Name ------------------------------------+ 0 | | + ---- ------------------------------------+ - + Role ---+ + Race ---+ + Gender ------+ + + Race ---+ + Role ---+ + Gender ------+ | | | | | * Male | 1 | | | | | * Female | | | | | +--------------+ @@ -165,30 +203,36 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) QVBoxLayout *namelayout = new QVBoxLayout(namebox); QLineEdit* name = new QLineEdit(namebox); namelayout->addWidget(name); - name->setMaxLength(sizeof(g.plname)-1); - if ( strncmp(g.plname,"player",6) && strncmp(g.plname,"games",5) ) - name->setText(g.plname); + name->setMaxLength(PL_NSIZ - 1); + name->setPlaceholderText(QString(" (required)")); // grayed out + + // if plname[] contains a generic user name, clear it + if (generic_plname()) + *g.plname = '\0'; + name->setText(g.plname); connect(name, SIGNAL(textChanged(const QString&)), - this, SLOT(selectName(const QString&)) ); + this, SLOT(selectName(const QString&))); name->setFocus(); + QGroupBox* genderbox = new QGroupBox("Gender",this); QButtonGroup *gendergroup = new QButtonGroup(this); QGroupBox* alignbox = new QGroupBox("Alignment",this); QButtonGroup *aligngroup = new QButtonGroup(this); + // these two QVBoxLayout pointers aren't used, the vertical box layouts + // being assigned to them are... QVBoxLayout* vbgb UNUSED = new QVBoxLayout(genderbox); QVBoxLayout* vbab UNUSED = new QVBoxLayout(alignbox); char versionbuf[QBUFSZ]; - QLabel* logo = new QLabel(QString(nh_attribution).arg(version_string(versionbuf)), this); + QLabel *logo = new QLabel(QString(nh_attribution).arg( + version_string(versionbuf)), this); l->addWidget( namebox, 0,0,1,3 ); -#ifdef QT_CHOOSE_RACE_FIRST - race = new NhPSListView(this); role = new NhPSListView(this); + race = new NhPSListView(this); +#ifdef QT_CHOOSE_RACE_FIRST l->addWidget( race, 1,0,6,1 ); l->addWidget( role, 1,1,6,1 ); #else - role = new NhPSListView(this); - race = new NhPSListView(this); l->addWidget( role, 1,0,6,1 ); l->addWidget( race, 1,1,6,1 ); #endif @@ -215,7 +259,8 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); role->setItem(i, 0, item); } - connect( role, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(selectRole(int, int, int, int)) ); + connect(role, SIGNAL(currentCellChanged(int, int, int, int)), + this, SLOT(selectRole(int, int, int, int))); role->setHorizontalHeaderLabels(QStringList("Role")); role->resizeColumnToContents(0); @@ -230,7 +275,8 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); race->setItem(i, 0, item); } - connect( race, SIGNAL(currentCellChanged(int, int, int, int)), this, SLOT(selectRace(int, int, int, int)) ); + connect(race, SIGNAL(currentCellChanged(int, int, int, int)), + this, SLOT(selectRace(int, int, int, int))); race->setHorizontalHeaderLabels(QStringList("Race")); race->resizeColumnToContents(0); @@ -240,7 +286,8 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) genderbox->layout()->addWidget(gender[i]); gendergroup->addButton(gender[i], i); } - connect( gendergroup, SIGNAL(buttonPressed(int)), this, SLOT(selectGender(int)) ); + connect(gendergroup, SIGNAL(buttonPressed(int)), + this, SLOT(selectGender(int))); alignment = new QRadioButton*[ROLE_ALIGNS]; for (i=0; ilayout()->addWidget(alignment[i]); aligngroup->addButton(alignment[i], i); } - connect( aligngroup, SIGNAL(buttonPressed(int)), this, SLOT(selectAlignment(int)) ); + connect(aligngroup, SIGNAL(buttonPressed(int)), + this, SLOT(selectAlignment(int))); - QPushButton* rnd = new QPushButton("Random",this); - l->addWidget( rnd, 4, 2 ); - rnd->setDefault(false); - connect( rnd, SIGNAL(clicked()), this, SLOT(Randomize()) ); - - QPushButton* ok = new QPushButton("Play",this); - l->addWidget( ok, 5, 2 ); - ok->setDefault(true); - connect( ok, SIGNAL(clicked()), this, SLOT(accept()) ); - - QPushButton* cancel = new QPushButton("Quit",this); - l->addWidget( cancel, 6, 2 ); - connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + l->addWidget(rand_btn, 4, 2); + connect(rand_btn, SIGNAL(clicked()), this, SLOT(Randomize())); + l->addWidget(play_btn, 5, 2); + connect(play_btn, SIGNAL(clicked()), this, SLOT(accept())); + l->addWidget(quit_btn, 6, 2); + connect(quit_btn, SIGNAL(clicked()), this, SLOT(reject())); + // if plname[] is non-empty, the Play button is enabled and the default; + // otherwise, Play is disabled and Quit is the default + plnamePlayVsQuit(); Randomize(); } @@ -307,7 +351,7 @@ void NetHackQtPlayerSelector::Randomize() } // make sure we have a valid combination, honoring - // the users request if possible. + // the user's request if possible. bool choose_race_first; #ifdef QT_CHOOSE_RACE_FIRST choose_race_first = true; @@ -361,12 +405,35 @@ void NetHackQtPlayerSelector::Randomize() race->setCurrentCell(ra, 0); } -void NetHackQtPlayerSelector::selectName(const QString& n) +// if plname[] is empty, disable [Play], otherwise [Play] is the default +void NetHackQtPlayerSelector::plnamePlayVsQuit() { - str_copy(g.plname,n.toLatin1().constData(),SIZE(g.plname)); + if (*g.plname) { + play_btn->setEnabled(true); + play_btn->setDefault(true); + //quit_btn->setDefault(false); + } else { + play_btn->setEnabled(false); // [Play] still visible but grayed out + //play_btn->setDefault(false); + quit_btn->setDefault(true); + } } -void NetHackQtPlayerSelector::selectRole(int crow, int ccol, int prow, int pcol) +// the line edit widget for the name field has received input +void NetHackQtPlayerSelector::selectName(const QString& n) +{ + const char *name_str = n.toLatin1().constData(); + // skip any leading spaces + // (it would be better to set up a validator that rejects leading spaces) + while (*name_str == ' ') + ++name_str; + str_copy(g.plname, name_str, PL_NSIZ); + // possibly enable or disable the [Play] button + plnamePlayVsQuit(); +} + +void NetHackQtPlayerSelector::selectRole(int crow, int ccol, + int prow, int pcol) { int ra = race->currentRow(); int ro = role->currentRow(); @@ -395,17 +462,20 @@ void NetHackQtPlayerSelector::selectRole(int crow, int ccol, int prow, int pcol) item = role->item(j, 0); item->setSelected(item == i); bool v = validrace(j,ra); - item->setFlags( - v ? Qt::ItemIsEnabled|Qt::ItemIsSelectable - : Qt::NoItemFlags); + item->setFlags(v ? Qt::ItemIsEnabled|Qt::ItemIsSelectable + : Qt::NoItemFlags); } + nhUse(crow); + nhUse(ccol); + nhUse(pcol); #endif //flags.initrole = role->currentRow(); setupOthers(); } -void NetHackQtPlayerSelector::selectRace(int crow UNUSED, int ccol UNUSED, int prow, int pcol UNUSED) +void NetHackQtPlayerSelector::selectRace(int crow, int ccol, + int prow, int pcol) { int ra = race->currentRow(); int ro = role->currentRow(); @@ -433,10 +503,12 @@ void NetHackQtPlayerSelector::selectRace(int crow UNUSED, int ccol UNUSED, int p item = race->item(j, 0); item->setSelected(item == i); bool v = validrace(ro,j); - item->setFlags( - v ? Qt::ItemIsEnabled|Qt::ItemIsSelectable - : Qt::NoItemFlags); + item->setFlags(v ? Qt::ItemIsEnabled|Qt::ItemIsSelectable + : Qt::NoItemFlags); } + nhUse(crow); + nhUse(ccol); + nhUse(pcol); #endif //flags.initrace = race->currentRow(); diff --git a/win/Qt/qt_plsel.h b/win/Qt/qt_plsel.h index 5e2f7923e..985b544dc 100644 --- a/win/Qt/qt_plsel.h +++ b/win/Qt/qt_plsel.h @@ -22,6 +22,7 @@ public slots: void Quit(); void Random(); void Randomize(); + void plnamePlayVsQuit(); void selectName(const QString& n); void selectRole(int current, int, int previous, int); @@ -38,9 +39,14 @@ private: QTableWidget* race; QRadioButton **gender; QRadioButton **alignment; + bool fully_specified_role; int chosen_gend; int chosen_align; + + QPushButton *rand_btn; + QPushButton *play_btn; + QPushButton *quit_btn; }; } // namespace nethack_qt_ From f5a6267b3a856cb20b0db41f42806515f723b626 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 28 Oct 2020 18:07:27 -0700 Subject: [PATCH 374/708] Qt character selection hackery Tweak the Qt character selection widget format a bit. Forcing the 'logo' string to be taller has resulted in stretching the window enough to fit all the roles without a scrollbar. (On my monitor on my OSX system, that is. It won't necessarily be an improvement for anybody else but shouldn't break anything.) The TODO item about making it taller so that role list fits is still there. --- win/Qt/qt_plsel.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index a0c76ab4c..85e20ecf6 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -6,7 +6,8 @@ // // TODO: -// increase height so that no scrolling is needed for role list; +// increase height so that no scrolling is needed for role list [needs +// to be done properly instead of forcing logo string to be taller] // the [Random] button doesn't do anything; // make race first vs role first dynamically selectable (tty allows // gender first and alignment first too); @@ -63,8 +64,10 @@ namespace nethack_qt_ { void centerOnMain( QWidget* w ); // end temporary -static const char nh_attribution[] = "
NetHack %1" - "
by the NetHack DevTeam
"; +// hack: padded with blank lines by inserting breaks above and below in +// order to force window to be tall enough to show all the roles at once +static const char nh_attribution[] = "
NetHack %1" + "
by the NetHack DevTeam

"; class NhPSListViewItem : public QTableWidgetItem { public: @@ -214,9 +217,10 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) this, SLOT(selectName(const QString&))); name->setFocus(); - QGroupBox* genderbox = new QGroupBox("Gender",this); + // changed to move gender and alignment labels inside their boxes (below) + QGroupBox *genderbox = new QGroupBox(); QButtonGroup *gendergroup = new QButtonGroup(this); - QGroupBox* alignbox = new QGroupBox("Alignment",this); + QGroupBox *alignbox = new QGroupBox(); QButtonGroup *aligngroup = new QButtonGroup(this); // these two QVBoxLayout pointers aren't used, the vertical box layouts // being assigned to them are... @@ -280,6 +284,12 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) race->setHorizontalHeaderLabels(QStringList("Race")); race->resizeColumnToContents(0); + // TODO: render the alignment and gender labels smaller to match the + // horizontal header labels for role and race; getting the font from + // race table above and setting it for labels below made no difference + + QLabel *gendlabel = new QLabel("Gender"); + genderbox->layout()->addWidget(gendlabel); gender = new QRadioButton*[ROLE_GENDERS]; for (i=0; ilayout()->addWidget(alignlabel); alignment = new QRadioButton*[ROLE_ALIGNS]; for (i=0; i Date: Thu, 29 Oct 2020 19:14:28 +0200 Subject: [PATCH 375/708] Restful sleep regenerates hp When sleeping due to wearing an amulet of restful sleep, hit points will regenerate, one point faster than with normal regeneration. --- doc/fixes37.0 | 1 + src/allmain.c | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a46b9c1c1..8814aa28c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -287,6 +287,7 @@ hero poly'd into rust monster could implicitly eat bars when adjacent by trying to move there, now when in rock mole form too; in xorn form can explicitly eat them via 'e' after moving onto their spot monster hiding under an egg that hatched was kept hidden +restful sleep regenerates hit points Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/allmain.c b/src/allmain.c index eb17b82e0..a11919b85 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -471,6 +471,8 @@ boolean resuming; } } +#define U_CAN_REGEN() (Regeneration || (Sleepy && u.usleep)) + /* maybe recover some lost health (or lose some when an eel out of water) */ static void regen_hp(wtcap) @@ -491,7 +493,7 @@ int wtcap; && (!Half_physical_damage || !(g.moves % 2L))) heal = -1; } else if (u.mh < u.mhmax) { - if (Regeneration || (encumbrance_ok && !(g.moves % 20L))) + if (U_CAN_REGEN() || (encumbrance_ok && !(g.moves % 20L))) heal = 1; } if (heal) { @@ -506,7 +508,7 @@ int wtcap; no !Upolyd check here, so poly'd hero recovered lost u.uhp once u.mh reached u.mhmax; that may have been convenient for the player, but it didn't make sense for gameplay...] */ - if (u.uhp < u.uhpmax && (encumbrance_ok || Regeneration)) { + if (u.uhp < u.uhpmax && (encumbrance_ok || U_CAN_REGEN())) { if (u.ulevel > 9) { if (!(g.moves % 3L)) { int Con = (int) ACURR(A_CON); @@ -523,8 +525,10 @@ int wtcap; if (!(g.moves % (long) ((MAXULEV + 12) / (u.ulevel + 2) + 1))) heal = 1; } - if (Regeneration && !heal) + if (U_CAN_REGEN() && !heal) heal = 1; + if (Sleepy && u.usleep) + heal++; if (heal) { g.context.botl = TRUE; @@ -541,6 +545,8 @@ int wtcap; interrupt_multi("You are in full health."); } +#undef U_CAN_REGEN + void stop_occupation() { From 01c4a50f98cd9505024df635334e105fde9a624d Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 30 Oct 2020 09:08:23 -0400 Subject: [PATCH 376/708] warning and a bit of alignment-related header consolidation --- include/align.h | 12 ++++++++++++ include/dungeon.h | 8 -------- include/rm.h | 5 ----- src/dungeon.c | 4 ++-- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/include/align.h b/include/align.h index 9e3e658ff..45b10d768 100644 --- a/include/align.h +++ b/include/align.h @@ -30,6 +30,8 @@ typedef struct align { /* alignment & record */ #define AM_LAWFUL 4 #define AM_MASK 7 +/* Some altars are considered as shrines, so we need a flag. */ +#define AM_SHRINE 8 #define AM_SPLEV_CO 3 #define AM_SPLEV_NONCO 7 @@ -41,4 +43,14 @@ typedef struct align { /* alignment & record */ #define Align2amask(x) \ (((x) == A_NONE) ? AM_NONE : ((x) == A_LAWFUL) ? AM_LAWFUL : (x) + 2) +/* Because clearly Nethack needs more ways to specify alignment. + The Amask2msa AM_LAWFUL check needs to mask with AM_MASK to + strip off possible AM_SHRINE bit */ +#define Amask2msa(x) (((x) & AM_MASK) == AM_LAWFUL ? 3 : (x) & AM_MASK) +#define Msa2amask(x) ((x) == 3 ? AM_LAWFUL : (x)) +#define MSA_NONE 0 /* unaligned or multiple alignments */ +#define MSA_LAWFUL 1 +#define MSA_NEUTRAL 2 +#define MSA_CHAOTIC 3 + #endif /* ALIGN_H */ diff --git a/include/dungeon.h b/include/dungeon.h index 83ea0015c..2a135c62f 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -182,14 +182,6 @@ struct linfo { * fountains"). This makes it also subject to player conditions (amnesia). */ -/* Because clearly Nethack needs more ways to specify alignment */ -#define Amask2msa(x) ((x) == 4 ? 3 : (x) &AM_MASK) -#define Msa2amask(x) ((x) == 3 ? 4 : (x)) -#define MSA_NONE 0 /* unaligned or multiple alignments */ -#define MSA_LAWFUL 1 -#define MSA_NEUTRAL 2 -#define MSA_CHAOTIC 3 - /* what the player knows about a single dungeon level */ /* initialized in mklev() */ typedef struct mapseen { diff --git a/include/rm.h b/include/rm.h index 761e8b30c..fbaa8a388 100644 --- a/include/rm.h +++ b/include/rm.h @@ -335,11 +335,6 @@ extern const struct symdef def_warnsyms[WARNCOUNT]; #define D_TRAPPED 16 #define D_SECRET 32 /* only used by sp_lev.c, NOT in rm-struct */ -/* - * Some altars are considered as shrines, so we need a flag. - */ -#define AM_SHRINE 8 - /* * Thrones should only be looted once. */ diff --git a/src/dungeon.c b/src/dungeon.c index 935a32088..17a5ba3f1 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -2672,8 +2672,8 @@ recalc_mapseen() struct monst *mtmp; struct cemetery *bp, **bonesaddr; struct trap *t; - unsigned i, ridx; - int x, y, ltyp, count, atmp; + unsigned i, ridx, atmp; + int x, y, ltyp, count; /* Should not happen in general, but possible if in the process * of being booted from the quest. The mapseen object gets From 96ba25241c7ee47e1f830ff041988cf7a4656cdc Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 30 Oct 2020 09:14:23 -0400 Subject: [PATCH 377/708] revert to numeric --- include/align.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/align.h b/include/align.h index 45b10d768..f6539ceed 100644 --- a/include/align.h +++ b/include/align.h @@ -46,8 +46,8 @@ typedef struct align { /* alignment & record */ /* Because clearly Nethack needs more ways to specify alignment. The Amask2msa AM_LAWFUL check needs to mask with AM_MASK to strip off possible AM_SHRINE bit */ -#define Amask2msa(x) (((x) & AM_MASK) == AM_LAWFUL ? 3 : (x) & AM_MASK) -#define Msa2amask(x) ((x) == 3 ? AM_LAWFUL : (x)) +#define Amask2msa(x) (((x) & AM_MASK) == 4 ? 3 : (x) & AM_MASK) +#define Msa2amask(x) ((x) == 3 ? 4 : (x)) #define MSA_NONE 0 /* unaligned or multiple alignments */ #define MSA_LAWFUL 1 #define MSA_NEUTRAL 2 From 7086427aaa135430e10570fd613a77d109347c77 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Fri, 30 Oct 2020 20:30:21 +0100 Subject: [PATCH 378/708] Enable checkpointing again by default This was accidentally changed in the options refactoring in commit 68fdc3bbcb. --- include/optlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/optlist.h b/include/optlist.h index c8d4f28e8..12b9f3a47 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -122,7 +122,7 @@ pfx_##a, NHOPTC(catname, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, "the name of your (first) cat (e.g., catname:Tabby)") #ifdef INSURANCE - NHOPTB(checkpoint, 0, opt_out, set_in_game, Off, Yes, No, No, NoAlias, + NHOPTB(checkpoint, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.ins_chkpt) #else NHOPTB(checkpoint, 0, opt_out, set_in_game, Off, No, No, No, NoAlias, From 05263bc276e5a0f4c3fb97e07ba3103f3ea9dd74 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 30 Oct 2020 23:01:50 +0200 Subject: [PATCH 379/708] Fix memory leak when adding basic color menucolors --- src/options.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/options.c b/src/options.c index f00907912..8172cc398 100644 --- a/src/options.c +++ b/src/options.c @@ -6579,7 +6579,7 @@ boolean load_colors; if (c == CLR_BLACK || c == CLR_WHITE || c == NO_COLOR) continue; /* skip these */ Sprintf(cnm, patternfmt, colornames[i].name); - add_menu_coloring_parsed(dupstr(cnm), c, ATR_NONE); + add_menu_coloring_parsed(cnm, c, ATR_NONE); } /* right now, menu_colorings contains the alternate color list; From 8907a5df9c90bfe17b51a7bcae2e19c29a7a800b Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 30 Oct 2020 17:46:21 -0700 Subject: [PATCH 380/708] more alignment conversion The overview code could reveal the true alignment of an altar if hero saw a mimic pretending to be an altar on that spot, or reveal junk for the alignment when mimicking at altar on some other spot. Avoid passing macros that might evaluate their arguments more than once to other macros which might also do that. The hidden code expansion can easily get out of hand (although in this case it was modest). Also, get rid of the unused MSA_foo alignment values since two of them had the values swapped. Lastly, make Amask2align() more robust in case a value with the shrine bit set gets passed to it. --- include/align.h | 35 +++++++++++++++++++---------------- src/dungeon.c | 13 ++++++++++--- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/include/align.h b/include/align.h index f6539ceed..055fb13ed 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 align.h $NHDT-Date: 1596498525 2020/08/03 23:48:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ */ +/* NetHack 3.7 align.h $NHDT-Date: 1604105154 2020/10/31 00:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ /* Copyright (c) Mike Stephenson, Izchak Miller 1991. */ /* NetHack may be freely redistributed. See license for details. */ @@ -30,27 +30,30 @@ typedef struct align { /* alignment & record */ #define AM_LAWFUL 4 #define AM_MASK 7 -/* Some altars are considered as shrines, so we need a flag. */ +/* Some altars are considered as shrines, so we need a flag for that + for the altarmask field of struct rm. */ #define AM_SHRINE 8 -#define AM_SPLEV_CO 3 -#define AM_SPLEV_NONCO 7 +/* special level flags, gone by the time the level has been loaded */ +#define AM_SPLEV_CO 3 /* co-aligned: force alignment to match hero's */ +#define AM_SPLEV_NONCO 7 /* non-co-aligned: force alignment to not match */ #define AM_SPLEV_RANDOM 8 -#define Amask2align(x) \ - ((aligntyp)((!(x)) ? A_NONE : ((x) == AM_LAWFUL) ? A_LAWFUL \ - : ((int) x) - 2)) +#define Amask2align(x) \ + ((aligntyp) ((((x) & AM_MASK) == 0) ? A_NONE \ + : (((x) & AM_MASK) == AM_LAWFUL) ? A_LAWFUL \ + : ((int) (x) - 2))) /* 2 => 0, 1 => -1 */ #define Align2amask(x) \ - (((x) == A_NONE) ? AM_NONE : ((x) == A_LAWFUL) ? AM_LAWFUL : (x) + 2) + ((unsigned) (((x) == A_NONE) ? AM_NONE \ + : ((x) == A_LAWFUL) ? AM_LAWFUL \ + : ((x) + 2))) /* -1 => 1, 0 => 2 */ -/* Because clearly Nethack needs more ways to specify alignment. - The Amask2msa AM_LAWFUL check needs to mask with AM_MASK to - strip off possible AM_SHRINE bit */ -#define Amask2msa(x) (((x) & AM_MASK) == 4 ? 3 : (x) & AM_MASK) -#define Msa2amask(x) ((x) == 3 ? 4 : (x)) +/* Because clearly Nethack needs more ways to specify alignment... + Amask2msa(): 1, 2, 4 converted to 1, 2, 3 to fit within a width 2 bitfield; + Msa2amask(): 1, 2, 3 converted back to 1, 2, 4; + For Amask2msa(), 'x' might have the shrine bit set so strip that off. */ +#define Amask2msa(x) ((((x) & AM_MASK) == 4) ? 3 : (x) & AM_MASK) +#define Msa2amask(x) (((x) == 3) ? 4 : (x)) #define MSA_NONE 0 /* unaligned or multiple alignments */ -#define MSA_LAWFUL 1 -#define MSA_NEUTRAL 2 -#define MSA_CHAOTIC 3 #endif /* ALIGN_H */ diff --git a/src/dungeon.c b/src/dungeon.c index 17a5ba3f1..e116073b9 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1596498164 2020/08/03 23:42:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.133 $ */ +/* NetHack 3.7 dungeon.c $NHDT-Date: 1604105163 2020/10/31 00:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2842,10 +2842,13 @@ recalc_mapseen() mptr->feat.ngrave = count; break; case ALTAR: + /* get the altarmask for this location; might be a mimic */ + atmp = altarmask_at(x, y); + /* convert to index: 0..3 */ atmp = (Is_astralevel(&u.uz) && (levl[x][y].seenv & SVALL) != SVALL) ? MSA_NONE - : Amask2msa(levl[x][y].altarmask); + : Amask2msa(atmp); if (!mptr->feat.naltar) mptr->feat.msalign = atmp; else if (mptr->feat.msalign != atmp) @@ -3297,6 +3300,8 @@ boolean printdun; an(shop_string(mptr->feat.shoptype))); } if (mptr->feat.naltar > 0) { + unsigned atmp; + /* Temples + non-temple altars get munged into just "altars" */ if (mptr->feat.ntemple != mptr->feat.naltar) ADDNTOBUF("altar", mptr->feat.naltar); @@ -3304,7 +3309,9 @@ boolean printdun; ADDNTOBUF("temple", mptr->feat.ntemple); /* only print out altar's god if they are all to your god */ - if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type) + atmp = mptr->feat.msalign; /* 0, 1, 2, 3 */ + atmp = Msa2amask(atmp); /* 0, 1, 2, 4 */ + if (Amask2align(atmp) == u.ualign.type) /* -127, -1, 0, +1 */ Sprintf(eos(buf), " to %s", align_gname(u.ualign.type)); } ADDNTOBUF("throne", mptr->feat.nthrone); From b37116b0f9a6dac5d9731731f63c4cf6d83009d8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 31 Oct 2020 09:30:38 -0400 Subject: [PATCH 381/708] merge pr #403 wasm fixes Closes #403 --- doc/fixes37.0 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 8814aa28c..b92e07915 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -644,8 +644,8 @@ fix the "stuck pets" issue (github #329) allow themed room subrooms to be filled (github #347) allow rereading spellbooks to refresh memory at any time (github #261) allow themed rooms constrained by level difficulty (github #344) -add a varied form of LIBNH nethack library contribution (github #385) -add cross-compile to WASM (github #385) +add a varied form of LIBNH nethack library contribution (github #385, #403) +add cross-compile to WASM (github #385, #403) Code Cleanup and Reorganization From 750b86f0a85e6d138693cf62c12725dbb0bd17bf Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 31 Oct 2020 12:49:13 -0700 Subject: [PATCH 382/708] comment accuracy --- src/dungeon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dungeon.c b/src/dungeon.c index e116073b9..ec60d7168 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1604105163 2020/10/31 00:46:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ +/* NetHack 3.7 dungeon.c $NHDT-Date: 1604173730 2020/10/31 19:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3311,7 +3311,7 @@ boolean printdun; /* only print out altar's god if they are all to your god */ atmp = mptr->feat.msalign; /* 0, 1, 2, 3 */ atmp = Msa2amask(atmp); /* 0, 1, 2, 4 */ - if (Amask2align(atmp) == u.ualign.type) /* -127, -1, 0, +1 */ + if (Amask2align(atmp) == u.ualign.type) /* -128, -1, 0, +1 */ Sprintf(eos(buf), " to %s", align_gname(u.ualign.type)); } ADDNTOBUF("throne", mptr->feat.nthrone); From 5b0ac4ceacce83a94a9c03a1fe8e14550fce5d39 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 31 Oct 2020 15:34:47 -0700 Subject: [PATCH 383/708] Qt: yn dialog bit Take care of a Qt TODO: when using 'popup_dialog' and entering a count during a yn#aq question, change the default answer button from 'n' to 'y' since ending the count with accepts it. --- win/Qt/qt_yndlg.cpp | 21 +++++++++------------ win/Qt/qt_yndlg.h | 1 + 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 4ea3688b0..4c59c073f 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -37,7 +37,8 @@ NetHackQtYnDialog::NetHackQtYnDialog(QWidget *parent, const QString &q, question(q), choices(ch), def(df), keypress('\033'), allow_count(false), - le((QLineEdit *) NULL) + le((QLineEdit *) NULL), + y_btn((QPushButton *) NULL) { setWindowTitle("NetHack: Question"); @@ -182,6 +183,7 @@ char NetHackQtYnDialog::Exec() QPushButton *button; for (int i = 0; i < nchoices; ++i) { + bool making_y = false; if (ch[i] == '\033') break; // ESC and anything after are hidden if (ch[i] == '#' && allow_count) @@ -193,6 +195,7 @@ char NetHackQtYnDialog::Exec() switch (ch[i].cell()) { case 'y': button_name = "Yes"; + making_y = true; break; case 'n': button_name = "No"; @@ -260,6 +263,8 @@ char NetHackQtYnDialog::Exec() } } button=new QPushButton(button_name); + if (making_y && allow_count) + y_btn = button; // to change default in keyPressEvent() if (!enable.isNull()) { if (!enable.contains(ch[i])) button->setEnabled(false); @@ -394,17 +399,9 @@ void NetHackQtYnDialog::keyPressEvent(QKeyEvent* event) le->setAttribute(Qt::WA_KeyboardFocusChange, true); // this is definitely useful... le->setFocus(Qt::ActiveWindowFocusReason); - // - // TODO: 'No' is highlighted as default for result if player - // types , but once count entry starts that should - // be changed because this LineEdit dialog has now become - // the defacto default. We can't just turn off the default - // setting for the 'No' button because only works - // if there is a default explicitly set. Unfortunately the - // LineEdit widget isn't a viable candidate for that because - // it isn't a button. [Maybe just highlight 'Yes' instead?] - // - + // change default button from 'n' to 'y' + if (y_btn) + y_btn->setDefault(true); } else if (where != -1) { this->done(where + 1000); diff --git a/win/Qt/qt_yndlg.h b/win/Qt/qt_yndlg.h index cdbdc0710..e6c1bcdef 100644 --- a/win/Qt/qt_yndlg.h +++ b/win/Qt/qt_yndlg.h @@ -18,6 +18,7 @@ private: char keypress; bool allow_count; QLineEdit *le; + QPushButton *y_btn; // abritrary size; might need to be more sophisicated someday char alt_answer[26 + 1], alt_result[26 + 1]; From 90790d3aa45f742114877b0f879b491872cff7a8 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 1 Nov 2020 13:46:16 -0800 Subject: [PATCH 384/708] Qt hitpointbar coloring A couple of colors used by the Qt hitpointbar didn't look very good. Switch to lighter green because the named value for that is too dark. It was using the wrong value for orange; the right one isn't too dark after all. --- win/Qt/qt_stat.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index cfccb439d..7b918e070 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -431,11 +431,12 @@ void NetHackQtStatusWindow::HitpointBar() *barcolors[6][2] = { { "black", "black" }, // 100% /* second black never shown */ { "blue", "darkBlue" }, //75..99 - // gray is darker than darkGray for some reason (at least on OSX)... - // green and orange would look better if they were lighter/brighter - { "green", "gray" }, //50..74 + /* gray is darker than darkGray for some reason (at least on OSX); + default green is too dark compared to blue, yellow, orange, + and red so is changed here to green.lighter(150) */ + { "#00c000", "gray" }, //50..74 /* "green"=="#008000" */ { "yellow", "darkGray" }, //25..49 - { "#ff7f00", "lightGray" }, //10..24 /* #ff7f00=="orange" */ + { "orange", "lightGray" }, //10..24 { "red", "white" }, // 0..9 }; From 87b378bb33a1977564616c6b35ab124f3fb83dac Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 1 Nov 2020 14:30:25 -0800 Subject: [PATCH 385/708] more Amask2align() Recent change to Amask2align() was only masking the shrine bit off its argument some of the time. --- include/align.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/align.h b/include/align.h index 055fb13ed..bd7b70cc1 100644 --- a/include/align.h +++ b/include/align.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 align.h $NHDT-Date: 1604105154 2020/10/31 00:45:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.14 $ */ +/* NetHack 3.7 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. */ @@ -42,7 +42,7 @@ typedef struct align { /* alignment & record */ #define Amask2align(x) \ ((aligntyp) ((((x) & AM_MASK) == 0) ? A_NONE \ : (((x) & AM_MASK) == AM_LAWFUL) ? A_LAWFUL \ - : ((int) (x) - 2))) /* 2 => 0, 1 => -1 */ + : ((int) ((x) & AM_MASK)) - 2)) /* 2 => 0, 1 => -1 */ #define Align2amask(x) \ ((unsigned) (((x) == A_NONE) ? AM_NONE \ : ((x) == A_LAWFUL) ? AM_LAWFUL \ From 9275fc24282fd7eec64de08ddb18edf8d3f501f1 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 1 Nov 2020 16:35:44 -0800 Subject: [PATCH 386/708] return string for msg history --- sys/libnh/npm-package/test/test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/libnh/npm-package/test/test.js b/sys/libnh/npm-package/test/test.js index 3032399e3..5ad4e4e62 100644 --- a/sys/libnh/npm-package/test/test.js +++ b/sys/libnh/npm-package/test/test.js @@ -40,6 +40,8 @@ nethackStart(async function (name, ... args) { case "shim_yn_function": case "shim_message_menu": return 121; // 'y' + case "shim_getmsghistory": + return ""; case "shim_nhgetch": case "shim_nh_poskey": return 0; From d6d0e6dc60fad74c12d4bc3c03f22f1a68203779 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 1 Nov 2020 16:36:19 -0800 Subject: [PATCH 387/708] fix bug due to fancy logic --- win/shim/winshim.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 2910f0be6..4fb5f0d22 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -305,7 +305,11 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r // which field is being updated? args[0] = globalThis.nethackGlobal.constants["STATUS_FIELD"][args[0]]; // arg[1] is a string unless it is BL_CONDITION, BL_RESET, BL_FLUSH, BL_CHARACTERISTICS - if(["BL_CONDITION", "BL_RESET", "BL_FLUSH", "BL_CHARACTERISTICS"].indexOf(args[0] && args[1]) < 0) { + if(args[0] !== "BL_CONDITION" && + args[0] !== "BL_RESET" && + args[0] !== "BL_FLUSH" && + args[0] !== "BL_CHARACTERISTICS" && + args[1]) { args[1] = getArg(name, args[1], "s"); } else { args[1] = getArg(name, args[1], "p"); From 9fa0c9cfd2139065656012a485f2c4dafb8e1e5f Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sun, 1 Nov 2020 16:41:38 -0800 Subject: [PATCH 388/708] bump version --- sys/libnh/npm-package/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/libnh/npm-package/package.json b/sys/libnh/npm-package/package.json index 0d2e13937..d7a11e442 100644 --- a/sys/libnh/npm-package/package.json +++ b/sys/libnh/npm-package/package.json @@ -1,6 +1,6 @@ { "name": "@neth4ck/neth4ck", - "version": "1.0.1", + "version": "1.0.2", "description": "The original NetHack rogue-like game built as a WebAssembly module", "main": "src/nethackShim.js", "scripts": { From c8d05ac3528c6c75a6b9cdfa60411d49a56048e3 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 3 Nov 2020 14:25:06 -0800 Subject: [PATCH 389/708] ignitable() macro ignitable() was excluding magic lamp and then every place that used it did so as 'ignitable(obj) || obj->otyp == MAGIC_LAMP' so just include magic lamp. I noticed that while hunting for an explanation for report #K2734 where returning to a previously visited level triggered the warning "begin_burn: unexpected eggs". I've decided that the zombie apocalypse is probably the cause. It inserted a new type of timer in the list of such but it didn't bump EDITLEVEL to invalidate save and bones files which relied on indices into the old list. I'm not sure whether we should bump that now. --- include/obj.h | 18 +++++++++++------- src/apply.c | 6 +++--- src/light.c | 5 ++--- src/trap.c | 10 +++++----- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/include/obj.h b/include/obj.h index 88c4902d0..69ab173f8 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 obj.h $NHDT-Date: 1596498552 2020/08/03 23:49:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 3.7 obj.h $NHDT-Date: 1604442292 2020/11/03 22:24:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -308,22 +308,26 @@ struct obj { (otmp->otyp == TALLOW_CANDLE || otmp->otyp == WAX_CANDLE) #define MAX_OIL_IN_FLASK 400 /* maximum amount of oil in a potion of oil */ -/* MAGIC_LAMP intentionally excluded below */ -/* age field of this is relative age rather than absolute */ -#define age_is_relative(otmp) \ +/* age field of this is relative age rather than absolute; does not include + magic lamp */ +#define age_is_relative(otmp) \ ((otmp)->otyp == BRASS_LANTERN || (otmp)->otyp == OIL_LAMP \ || (otmp)->otyp == CANDELABRUM_OF_INVOCATION \ || (otmp)->otyp == TALLOW_CANDLE || (otmp)->otyp == WAX_CANDLE \ || (otmp)->otyp == POT_OIL) -/* object can be ignited */ -#define ignitable(otmp) \ +/* object can be ignited; magic lamp used to excluded here too but all + usage of this macro ended up testing + (ignitable(obj) || obj->otyp == MAGIC_LAMP) + so include it; brass lantern can be lit but not by fire */ +#define ignitable(otmp) \ ((otmp)->otyp == BRASS_LANTERN || (otmp)->otyp == OIL_LAMP \ + || ((otmp)->otyp == MAGIC_LAMP && (otmp)->spe > 0) \ || (otmp)->otyp == CANDELABRUM_OF_INVOCATION \ || (otmp)->otyp == TALLOW_CANDLE || (otmp)->otyp == WAX_CANDLE \ || (otmp)->otyp == POT_OIL) /* things that can be read */ -#define is_readable(otmp) \ +#define is_readable(otmp) \ ((otmp)->otyp == FORTUNE_COOKIE || (otmp)->otyp == T_SHIRT \ || (otmp)->otyp == ALCHEMY_SMOCK || (otmp)->otyp == CREDIT_CARD \ || (otmp)->otyp == CAN_OF_GREASE || (otmp)->otyp == MAGIC_MARKER \ diff --git a/src/apply.c b/src/apply.c index a43e3b730..9c742959c 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1602270122 2020/10/09 19:02:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.328 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1604442295 2020/11/03 22:24:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.330 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1404,14 +1404,14 @@ struct obj *obj; } /* Called when potentially lightable object is affected by fire_damage(). - Return TRUE if object was lit and FALSE otherwise --ALI */ + Return TRUE if object becomes lit and FALSE otherwise --ALI */ boolean catch_lit(obj) struct obj *obj; { xchar x, y; - if (!obj->lamplit && (obj->otyp == MAGIC_LAMP || ignitable(obj))) { + if (!obj->lamplit && ignitable(obj)) { if ((obj->otyp == MAGIC_LAMP || obj->otyp == CANDELABRUM_OF_INVOCATION) && obj->spe == 0) return FALSE; diff --git a/src/light.c b/src/light.c index d3fce655e..02ddaf03f 100644 --- a/src/light.c +++ b/src/light.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 light.c $NHDT-Date: 1596498173 2020/08/03 23:42:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ +/* NetHack 3.7 light.c $NHDT-Date: 1604442297 2020/11/03 22:24:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.46 $ */ /* Copyright (c) Dean Luick, 1994 */ /* NetHack may be freely redistributed. See license for details. */ @@ -691,8 +691,7 @@ boolean obj_is_burning(obj) struct obj *obj; { - return (boolean) (obj->lamplit && (obj->otyp == MAGIC_LAMP - || ignitable(obj) + return (boolean) (obj->lamplit && (ignitable(obj) || artifact_light(obj))); } diff --git a/src/trap.c b/src/trap.c index 5ba5bdc74..01c7a80fe 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1602270123 2020/10/09 19:02:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.364 $ */ +/* NetHack 3.7 trap.c $NHDT-Date: 1604442297 2020/11/03 22:24:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.365 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5563,9 +5563,9 @@ boolean override; return defsyms[trap_to_defsym(ttyp)].explanation; } -/* Ignite ignitable items in the given object chain, due to some external source - * of fire. The object chain should be somewhere exposed, like someone's open - * inventory or the floor. +/* Ignite ignitable items in the given object chain, due to some external + * source of fire. The object chain should be somewhere exposed, like + * someone's open inventory or the floor. * This is modeled after destroy_item() somewhat and hopefully will be able to * merge into it in the future. */ @@ -5590,7 +5590,7 @@ struct obj *objchn; } for (obj = objchn; obj; obj = obj->nobj) { - if (!(ignitable(obj) || obj->otyp == MAGIC_LAMP) + if (!ignitable(obj) /* The Candelabrum requires intention to be lit */ || obj->otyp == CANDELABRUM_OF_INVOCATION || obj->otyp == BRASS_LANTERN /* doesn't ignite via fire */ From c9ac5bc48a2ea846605b9b31d91aa16f18226d18 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 4 Nov 2020 11:36:49 +0200 Subject: [PATCH 390/708] Increase EDITLEVEL post Zombie Apocalypse I forgot to increase EDITLEVEL, as the Zombie Apocalypse added a timeout routine, messing up saves and bones. --- include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/patchlevel.h b/include/patchlevel.h index 29450b3cf..adf03ba79 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 23 +#define EDITLEVEL 24 /* * Development status possibilities. From bf2094d3dd13e5ed7744f38855b07f661966053f Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 4 Nov 2020 10:17:21 -0800 Subject: [PATCH 391/708] remove obsolete 3.6 compat - Schroedinger's cat Remove unneeded code. Noticed while looking for an explanation of the reported attempt to light eggs. --- src/restore.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/src/restore.c b/src/restore.c index ea75d54da..8df518b45 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 restore.c $NHDT-Date: 1593953357 2020/07/05 12:49:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.166 $ */ +/* NetHack 3.7 restore.c $NHDT-Date: 1604513828 2020/11/04 18:17:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.169 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -294,27 +294,6 @@ boolean frozen; /* restore container back pointers */ for (otmp3 = otmp->cobj; otmp3; otmp3 = otmp3->nobj) otmp3->ocontainer = otmp; - } else if (SchroedingersBox(otmp)) { - struct obj *catcorpse; - - /* - * TODO: Remove this after 3.6.x save compatibility is dropped. - * - * As of 3.6.2, SchroedingersBox() always has a cat corpse in it. - * For 3.6.[01], it was empty and its weight was falsified - * to have the value it would have had if there was one inside. - * Put a non-rotting cat corpse in this box to convert to 3.6.2. - * - * [Note: after this fix up, future save/restore of this object - * will take the Has_contents() code path above.] - */ - if ((catcorpse = mksobj(CORPSE, TRUE, FALSE)) != 0) { - otmp->spe = 1; /* flag for special SchroedingersBox */ - set_corpsenm(catcorpse, PM_HOUSECAT); - (void) stop_timer(ROT_CORPSE, obj_to_any(catcorpse)); - add_to_container(otmp, catcorpse); - otmp->owt = weight(otmp); - } } if (otmp->bypass) otmp->bypass = 0; From 702e52b43112f47413def1408e0d42a72a8302ef Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 5 Nov 2020 14:28:17 -0800 Subject: [PATCH 392/708] Qt str_copy() The Qt interface's routine to perform a bounded string copy ignored the limit when copying and only honored the limit to lie about the return length. --- win/Qt/qt_str.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/win/Qt/qt_str.cpp b/win/Qt/qt_str.cpp index 9450bd895..1a6de3f90 100644 --- a/win/Qt/qt_str.cpp +++ b/win/Qt/qt_str.cpp @@ -13,14 +13,14 @@ namespace nethack_qt_ { // Bounded string copy size_t str_copy(char *dest, const char *src, size_t max) { - size_t len = strlen(src); + size_t len = 0; if (max != 0) { - size_t csize = len; + len = strlen(src); if (len > max - 1) { len = max - 1; } - memcpy(dest, src, csize); - dest[csize] = '\0'; + memcpy(dest, src, len); + dest[len] = '\0'; } return len; } From 24ec7f232cf44d20f4f320182115cdea835c7ffe Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 5 Nov 2020 14:36:13 -0800 Subject: [PATCH 393/708] Qt string requestor Some enhancements to the widget used to get player input for getline() and also menu search and text window search. give caller control of [cancel] and [okay] button names; give caller a say in how wide the string input box should be instead of basing that on the length of the prompt string (needs more work...); use fixed-width font for displaying the user's input; clean up the widget layout a little bit. src/Makefile needs a dependency update for Qt (not included). --- win/Qt/qt_bind.cpp | 2 +- win/Qt/qt_streq.cpp | 58 ++++++++++++++++++++++++++------------------- win/Qt/qt_streq.h | 11 +++++---- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 512ab06af..3a64002ee 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -754,7 +754,7 @@ char NetHackQtBind::qt_yn_function(const char *question_, void NetHackQtBind::qt_getlin(const char *prompt, char *line) { NetHackQtStringRequestor requestor(mainWidget(),prompt); - if (!requestor.Get(line)) { + if (!requestor.Get(line, BUFSZ, 40)) { Strcpy(line, "\033"); // discard any input that Get() might have left pending keybuffer.Drain(); diff --git a/win/Qt/qt_streq.cpp b/win/Qt/qt_streq.cpp index 96133edec..04fed5ca9 100644 --- a/win/Qt/qt_streq.cpp +++ b/win/Qt/qt_streq.cpp @@ -16,6 +16,7 @@ extern "C" { #include "qt_post.h" #include "qt_streq.h" #include "qt_str.h" +#include "qt_set.h" namespace nethack_qt_ { @@ -23,15 +24,19 @@ namespace nethack_qt_ { void centerOnMain(QWidget *); // end temporary -NetHackQtStringRequestor::NetHackQtStringRequestor(QWidget *parent, const char* p, const char* cancelstr) : +NetHackQtStringRequestor::NetHackQtStringRequestor(QWidget *parent, + const char *p, const char *cancelstr, const char *okaystr) : QDialog(parent), prompt(QString::fromLatin1(p),this), input(this,"input") { + if (qt_settings) + input.setFont(qt_settings->normalFixedFont()); + cancel=new QPushButton(cancelstr,this); connect(cancel,SIGNAL(clicked()),this,SLOT(reject())); - okay=new QPushButton("Okay",this); + okay = new QPushButton(okaystr, this); connect(okay,SIGNAL(clicked()),this,SLOT(accept())); connect(&input,SIGNAL(returnPressed()),this,SLOT(accept())); okay->setDefault(true); @@ -44,39 +49,42 @@ void NetHackQtStringRequestor::resizeEvent(QResizeEvent*) const int margin=5; const int gutter=5; - int h=(height()-margin*2-gutter); - + int h = (height() - margin * 2 - gutter); + int w = (width() - margin * 2 - gutter); + int ifw = input.hasFrame() ? 3 : 0; // hack alert for input.frameWidth() if (prompt.text().size() > 16) { - h/=3; - prompt.setGeometry(margin,margin,width()-margin*2,h); - input.setGeometry(width()*1/5,margin+h+gutter, - (width()-margin-2-gutter)*4/5,h); + h /= 3; + prompt.setGeometry(margin + ifw * 2 + 1, margin, w + gutter, h); + input.setGeometry(width() * 1 / 5 - ifw, margin + h + gutter, + w * 4 / 5, h); } else { - h/=2; - prompt.setGeometry(margin,margin,(width()-margin*2-gutter)*2/5,h); - input.setGeometry(prompt.geometry().right()+gutter,margin, - (width()-margin-2-gutter)*3/5,h); + h /= 2; + prompt.setGeometry(margin + ifw * 2 + 1, margin, w * 2 / 5, h); + input.setGeometry(prompt.geometry().right() + gutter + - (ifw * 2 + 1) - ifw * 2, + margin, w * 3 / 5, h); } - cancel->setGeometry(margin,input.geometry().bottom()+gutter, - (width()-margin*2-gutter)/2,h); - okay->setGeometry(cancel->geometry().right()+gutter,cancel->geometry().y(), - cancel->width(),h); + cancel->setGeometry(margin, input.geometry().bottom() + gutter, w / 2, h); + okay->setGeometry(cancel->geometry().right() + gutter, + cancel->geometry().y(), w / 2, h); } -void NetHackQtStringRequestor::SetDefault(const char* d) +void NetHackQtStringRequestor::SetDefault(const char *d) { input.setText(d); } -bool NetHackQtStringRequestor::Get(char* buffer, int maxchar) +bool NetHackQtStringRequestor::Get(char *buffer, int maxchar, int minchar) { - input.setMaxLength(maxchar); - if (prompt.text().size() > 16) { - resize(fontMetrics().width(prompt.text())+50,fontMetrics().height()*6); - } else { - resize(fontMetrics().width(prompt.text())*2+50,fontMetrics().height()*4); - } + input.setMaxLength(maxchar - 1); + + const QString &txt = prompt.text(); + int pw = fontMetrics().width(txt), + ww = minchar * input.fontMetrics().width(QChar('X')); + int heightfactor = ((txt.size() > 16) ? 3 : 2) * 2; // 2 or 3 lines high + int widthfudge = (((txt.size() > 16) ? 1 : 2) * 5) * 2; // 5: margn, guttr + resize(pw + ww + widthfudge, fontMetrics().height() * heightfactor); #ifdef EDIT_GETLIN input.setText(buffer); @@ -94,7 +102,7 @@ bool NetHackQtStringRequestor::Get(char* buffer, int maxchar) exec(); if (result()) { - str_copy(buffer,input.text().toLatin1().constData(),maxchar); + str_copy(buffer, input.text().toLatin1().constData(), maxchar); return true; } else { return false; diff --git a/win/Qt/qt_streq.h b/win/Qt/qt_streq.h index 12fd0a776..89894dc03 100644 --- a/win/Qt/qt_streq.h +++ b/win/Qt/qt_streq.h @@ -19,10 +19,13 @@ private: QPushButton* cancel; public: - NetHackQtStringRequestor(QWidget *parent, const char* p,const char* cancelstr="Cancel"); - void SetDefault(const char*); - bool Get(char* buffer, int maxchar=80); - virtual void resizeEvent(QResizeEvent*); + NetHackQtStringRequestor(QWidget *parent, const char *p, + const char *cancelstr = "Cancel", + const char *okaystr = "Okay"); + void SetDefault(const char *); + // maxchar is size of buffer[], minchar is size of line edit widget + bool Get(char *buffer, int maxchar = 80, int minchar = 20); + virtual void resizeEvent(QResizeEvent *); }; } // namespace nethack_qt_ From e4106bb1613da808ae87780dfeedb4c80e6afc2a Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 5 Nov 2020 15:35:30 -0800 Subject: [PATCH 394/708] Qt text windows Text window search behaved very strangely: at some point after selecting [Search], entering a search string, having the string entry popup go away, and having the search performed, but before the result could be shown, the text window got pushed behind the main window (map+messages+paperdoll+status). Clicking on the main window's minimize button hid the main window and gave access to the text window behind it. That was still functional even after having been inaccessible; another search could be performed and/or it could be dismissed. I still don't know what causes that or how to properly fix it, but using raise() is a workaround to bring it to the front where it belongs. Unfortunately you can see it go away and come back so searching for text is distracting. Allow (when not searching) to dismiss all text windows including RIP. Accept ctrl+[ as ESC. Make text window searching be case-insensitive. Searching wouldn't find a match on the first line of text. Now it will. This also includes an attempt to fix github issue #400 (typing a pickup command while "things that are here" popup text window is displayed seems to hang the program), but since I can't reproduce that, I can't tell whether the fix works. The issue description says that pickup started executing and "things here" couldn't be dismissed which is different from "things here" being behind the map waiting for it to be dismissed. The attempted fix is for text window handling to tell Qt that it wants control of the keyboard, so nethack shouldn't see any attempted pickup command. --- doc/fixes37.0 | 6 +- win/Qt/Qt-issues.txt | 7 ++ win/Qt/qt_menu.cpp | 170 ++++++++++++++++++++++++++++++++++--------- win/Qt/qt_menu.h | 6 ++ 4 files changed, 152 insertions(+), 37 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b92e07915..4eb6b9062 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.344 $ $NHDT-Date: 1603836614 2020/10/27 22:10:14 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ $NHDT-Date: 1604619327 2020/11/05 23:35:27 $ General Fixes and Modified Features ----------------------------------- @@ -467,6 +467,10 @@ Qt: don't clobber an existing save file after choosing "new game" in the saved game selection widget Qt: don't get stuck in a loop after choosing "play" while the character name field is empty in the character selection widget +Qt: {maybe just Qt+OSX:} when viewing a text window ('V' to look at 'history' + for instance), clicking on [Search], entering a search target in the + resulting popup and clicking on [Okay] or typing , the text + window got pushed underneath the main window so seemed to go away Qt+OSX: fix control key Qt+OSX: rename menu entry "nethack->Preferences..." for invoking nethack's 'O' command to "Game->Run-time options" and entry "Game->Qt settings" diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index 4ac6fc2e7..b25adff97 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -52,4 +52,11 @@ intended to be displayed, is displayed (as blank terrain). 3.6 status conditions (Stone, Slime, Strngl, Deaf, Lev, Fly, Ride) have been implemented but need icon artwork (one 40x40 tile for each). +In a menu window, typing ':' (via shift+something) works to initiate +a search without the need to click on the [Search] button. In a text +window, it does not, despite moving the menu key press interpretation +code into its own routine and calling that for both types of windows. +From the text window code, it sees the initial shift but not the ':' +that should follow. + ----- diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 3a6062ee1..4a59f4356 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -55,6 +55,24 @@ namespace nethack_qt_ { void centerOnMain( QWidget* w ); // end temporary +static uchar keyValue(QKeyEvent *key_event) +{ + // key_event manipulation derived from NetHackQtBind::notify() + const int k = key_event->key(); + Qt::KeyboardModifiers mod = key_event->modifiers(); + QChar ch = !key_event->text().isEmpty() ? key_event->text().at(0) : 0; + if (ch >= 128) + ch = 0; + // on OSX, ascii control codes are not sent, force them + if (ch == 0 && (mod & Qt::ControlModifier) != 0) { + if (k >= Qt::Key_A && k <= Qt::Key_Underscore) + ch = QChar((k - (Qt::Key_A - 1))); + } + uchar result = (uchar) ch.cell(); + //raw_printf("kV: k=%d, ch=%d", k, result); + return result; +} + QSize NetHackQtTextListBox::sizeHint() const { QScrollBar *hscroll = horizontalScrollBar(); @@ -697,18 +715,9 @@ void NetHackQtMenuWindow::ClearCount(void) void NetHackQtMenuWindow::keyPressEvent(QKeyEvent *key_event) { - // key_event manipulation derived from NetHackQtBind::notify() - const int k = key_event->key(); - Qt::KeyboardModifiers mod = key_event->modifiers(); - QChar ch = !key_event->text().isEmpty() ? key_event->text().at(0) : 0; - if (ch > 128) - ch = 0; - // on OSX, ascii control codes are not sent, force them - if (ch == 0 && (mod & Qt::ControlModifier) != 0) { - if (k >= Qt::Key_A && k <= Qt::Key_Underscore) - ch = (QChar) (k - (Qt::Key_A - 1)); - } - uchar key = (char) ch.cell(); + uchar key = keyValue(key_event); + if (!key) + return; // only one possible match for key==ch, and if one occurs it takes // precedence over any other match (for instance, some menus might @@ -837,7 +846,7 @@ void NetHackQtMenuWindow::Search() line[0] = '\0'; /* for EDIT_GETLIN */ if (requestor.Get(line)) { for (int i=0; iaddWidget(&rip); @@ -974,6 +995,10 @@ NetHackQtTextWindow::NetHackQtTextWindow(QWidget *parent) : hb->addWidget(&ok); hb->addWidget(&search); vb->addWidget(lines); + + // we don't want keystrokes being sent to the main window for use as + // commands while this text window is popped up + setFocusPolicy(Qt::StrongFocus); } void NetHackQtTextWindow::doUpdate() @@ -984,7 +1009,6 @@ void NetHackQtTextWindow::doUpdate() NetHackQtTextWindow::~NetHackQtTextWindow() { - } QWidget* NetHackQtTextWindow::Widget() @@ -994,7 +1018,16 @@ QWidget* NetHackQtTextWindow::Widget() bool NetHackQtTextWindow::Destroy() { - return !isVisible(); + return true; /*!isVisible();*/ +} + +void NetHackQtTextWindow::doDismiss() +{ + // [Clear() was needed when the search target string was kept in + // a static buffer but is superfluous now that that's part of + // the TextWindow class and initialized in the constructor.] + Clear(); + accept(); } void NetHackQtTextWindow::UseRIP(int how, time_t when) @@ -1083,12 +1116,18 @@ void NetHackQtTextWindow::UseRIP(int how, time_t when) void NetHackQtTextWindow::Clear() { lines->clear(); - use_rip=false; - str_fixed=false; + target[0] = '\0'; // discard search target string + use_rip = false; + str_fixed = false; + textsearching = false; } void NetHackQtTextWindow::Display(bool block UNUSED) { + // make sure window isn't completely empty + if (!lines->count()) + PutStr(ATR_NONE, ""); + if (str_fixed) { lines->setFont(qt_settings->normalFixedFont()); } else { @@ -1117,7 +1156,11 @@ void NetHackQtTextWindow::Display(bool block UNUSED) centerOnMain(this); show(); } + + lines->clearSelection(); // affects [Search] + exec(); + textsearching = false; } void NetHackQtTextWindow::PutStr(int attr UNUSED, const QString& text) @@ -1126,22 +1169,77 @@ void NetHackQtTextWindow::PutStr(int attr UNUSED, const QString& text) lines->addItem(text); } +// prompt for a target string and search current text window for it; +// if found, highlight the next line target occurs on; +// multiple searches with same or different search string are supported void NetHackQtTextWindow::Search() { - NetHackQtStringRequestor requestor(this, "Search for:"); - static char line[256]=""; - requestor.SetDefault(line); - if (requestor.Get(line)) { - int current=lines->currentRow(); - for (int i=1; icount(); i++) { - int lnum=(i+current)%lines->count(); - QString str=lines->item(lnum)->text(); - if (str.contains(line)) { - lines->setCurrentRow(lnum); - return; - } - } - lines->setCurrentItem(NULL); + textsearching = true; + NetHackQtStringRequestor requestor(this, "Search for:", "Done", "Find"); + requestor.SetDefault(target); + boolean get_a_line = requestor.Get(target, (int) sizeof target); + + // FIXME: + // Force text window to be on top. Without this, it moves behind + // the map after the string requestor completes. Then it can't + // be seen or accessed (unless the game window is minimized or + // possibly dragged out of the way). Unfortunately the window + // noticeably vanishes and then immediately gets redrawn. + if (!this->isActiveWindow()) + this->activateWindow(); + this->raise(); + + if (get_a_line) { + int linecount = lines->count(); + int current = lines->currentRow(); + // when no row is highlighted (selected), start the search + // on the current row, otherwise start on the row after it + // [normally means that the very first row is a candidate + // for containgin the target during the very first search] + int startln = lines->selectedItems().count(); + for (int i = startln; i < linecount; ++i) { + int lnum = (i + current) % linecount; + const QString &str = lines->item(lnum)->text(); + // Check whether target occurs on this line. If it does, + // the line is highlighted and this search finishes. + // When not currently within view, highlighting also + // scrolls the view to make it become the bottom line. + // A subsequent search will remember the target string + // and start searching on the line past the highlighted + // one (even if a new target is specified). + if (str.contains(target, Qt::CaseInsensitive)) { + lines->setCurrentRow(lnum); + return; + } + } + lines->setCurrentItem(NULL); + } else { + target[0] = '\0'; + } + textsearching = false; + return; +} + +void NetHackQtTextWindow::keyPressEvent(QKeyEvent *key_event) +{ + uchar key = keyValue(key_event); + + // + // FIXME: + // Typing ':' doesn't produce ':' so key won't match MENU_SEARCH, + // despite the fact that it does produce ':' for menu input and + // we're calling the exact same code for both types of window...? + // + if (key == MENU_SEARCH) { + if (!use_rip) + Search(); + } else if (key == '\n' || key == '\r') { + if (!textsearching) + accept(); + } else if (key == '\033') { + reject(); + } else { + QDialog::keyPressEvent(key_event); } } diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index b61a9305b..e69265a4f 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -155,15 +155,21 @@ public slots: void Search(); private slots: + void doDismiss(); void doUpdate(); +protected: + virtual void keyPressEvent(QKeyEvent *); + private: bool use_rip; bool str_fixed; + bool textsearching; QPushButton ok; QPushButton search; NetHackQtTextListBox* lines; + char target[BUFSZ]; NetHackQtRIP rip; }; From 096511b509a4ebe4ce64997826e77bf627fcb3f7 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 5 Nov 2020 16:03:05 -0800 Subject: [PATCH 395/708] github pull request #406 - polyfodder() macro Some eggs and tins could cause an out of bounds index into the mons[] array. Post-3.6 bug: the faulty part of the test is only relevant for 3.7 genetic engineer monster. Earlier versions just called pm_to_cham() which does it's own index validation. Fixes #406 --- doc/fixes37.0 | 4 +++- include/obj.h | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4eb6b9062..455db9ee2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.347 $ $NHDT-Date: 1604619327 2020/11/05 23:35:27 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ $NHDT-Date: 1604620981 2020/11/06 00:03:01 $ General Fixes and Modified Features ----------------------------------- @@ -373,6 +373,8 @@ learn scroll of teleportation after reading even when random destination is fix off-by-one bug in dimensions of theme rooms fire/frost horn feedback when zapped by monster was inaccurate (falsely claimed that it was "directed at self" when attacking hero) +tins of spinach and 'dead' eggs could cause out of array bounds access + attempting to index into mons[] by polyfodder() macro curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/include/obj.h b/include/obj.h index 69ab173f8..3504992d6 100644 --- a/include/obj.h +++ b/include/obj.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 obj.h $NHDT-Date: 1604442292 2020/11/03 22:24:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ +/* NetHack 3.7 obj.h $NHDT-Date: 1604620981 2020/11/06 00:03:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.79 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -247,13 +247,16 @@ struct obj { #define stale_egg(egg) \ ((g.monstermoves - (egg)->age) > (2 * MAX_EGG_HATCH_TIME)) #define ofood(o) ((o)->otyp == CORPSE || (o)->otyp == EGG || (o)->otyp == TIN) + /* note: sometimes eggs and tins have special corpsenm values that + shouldn't be used as an index into mons[] */ #define polyfodder(obj) \ - (ofood(obj) && (pm_to_cham((obj)->corpsenm) != NON_PM \ + (ofood(obj) && (obj)->corpsenm >= LOW_PM \ + && (pm_to_cham((obj)->corpsenm) != NON_PM \ || dmgtype(&mons[(obj)->corpsenm], AD_POLY))) #define mlevelgain(obj) (ofood(obj) && (obj)->corpsenm == PM_WRAITH) #define mhealup(obj) (ofood(obj) && (obj)->corpsenm == PM_NURSE) -#define Is_pudding(o) \ - (o->otyp == GLOB_OF_GRAY_OOZE || o->otyp == GLOB_OF_BROWN_PUDDING \ +#define Is_pudding(o) \ + (o->otyp == GLOB_OF_GRAY_OOZE || o->otyp == GLOB_OF_BROWN_PUDDING \ || o->otyp == GLOB_OF_GREEN_SLIME || o->otyp == GLOB_OF_BLACK_PUDDING) /* Containers */ From ca5cc4bb4bd26cdf4209cb54085f58797825a90a Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 6 Nov 2020 16:48:35 -0800 Subject: [PATCH 396/708] Qt: update a couple of source comments --- win/Qt/qt_menu.cpp | 2 +- win/Qt/qt_yndlg.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 4a59f4356..731333d99 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -1195,7 +1195,7 @@ void NetHackQtTextWindow::Search() // when no row is highlighted (selected), start the search // on the current row, otherwise start on the row after it // [normally means that the very first row is a candidate - // for containgin the target during the very first search] + // for containing the target during the very first search] int startln = lines->selectedItems().count(); for (int i = startln; i < linecount; ++i) { int lnum = (i + current) % linecount; diff --git a/win/Qt/qt_yndlg.cpp b/win/Qt/qt_yndlg.cpp index 4c59c073f..836e13042 100644 --- a/win/Qt/qt_yndlg.cpp +++ b/win/Qt/qt_yndlg.cpp @@ -154,6 +154,8 @@ char NetHackQtYnDialog::Exec() QButtonGroup *bgroup = new QButtonGroup(group); int nchoices=ch.length(); + // note: is_ynaq covers nyaq too because the choices string is + // "ynaq" for both; only the default differs; likewise for nyNaq bool is_ynaq = (ch == QString("ynaq") // [Yes ][ No ][All ][Stop] || ch == QString("yn#aq") || ch == altchoices), // alternate "yn#aq" @@ -289,11 +291,11 @@ char NetHackQtYnDialog::Exec() QLabel *lb = 0; if (allow_count) { - // put the Count widget in between [y] and [n][a][q] + // insert Count widget in front of [n], between [y] and [n][a][q] lb = new QLabel("Count:"); - groupbox->insertWidget(1, lb); // [n] button is item #1 + groupbox->insertWidget(1, lb); // [y] button is item #0, [n] is #1 le = new QLineEdit(); - groupbox->insertWidget(2, le); // [n] became #2, Count label #1 + groupbox->insertWidget(2, le); // [n] became #2, Count label is #1 le->setPlaceholderText(QString("#")); // grayed out } // add an invisible right-most field to left justify the buttons From 0eee7b7edc579cbf2b9905ee7b06b7afb7583480 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 7 Nov 2020 02:32:50 -0800 Subject: [PATCH 397/708] Qt paper doll comments --- src/objnam.c | 4 ++-- win/Qt/qt_inv.cpp | 34 ++++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index cbc539f20..0d54695a9 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1596162343 2020/07/31 02:25:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.304 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1604745123 2020/11/07 10:32:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.305 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1269,7 +1269,7 @@ unsigned doname_flags; (objects won't normally be formatted during that time, but if 'perm_invent' is enabled then they might be) */ if (iflags.suppress_price || g.restoring) { - ; /* don't attempt to obtain any stop pricing, even if 'with_price' */ + ; /* don't attempt to obtain any shop pricing, even if 'with_price' */ } else if (is_unpaid(obj)) { /* in inventory or in container in invent */ long quotedprice = unpaid_cost(obj, TRUE); diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index a5e9a3c1b..816045446 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -107,23 +107,37 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border); } +// called to update the paper doll inventory subset void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) { - // 0 1 2 two dual - // hander wielding - // 0 b H q b H q b H q - // 1 S " w W " W X " w - // 2 G C x G C x G C . - // 3 = A = = A = = A = - // 4 l U L l U L l U L - // 5 . F . . F . . F . + // Paper doll is a 6 row by 3 column grid of worn and wielded + // equipment showing the map tiles that the inventory objects + // would be displayed as if they were on the floor. // - // 3.7: use a different legend for the layout - // show quiver instead of repeating gloves on both sides; + // 0 1 2 two- dual + // [ old ] normal hander wielding legend + // 0 [x H b] b H q b H q b H q b eyewear H helmet q quiver + // 1 [S " w] S " w W " W X " w S shield " amulet w weapon + // 2 [G C G] G C x G C x G C . G gloves C cloak x alt-weap + // 3 [= A =] = A = = A = = A = = left rg A suit = right ring + // 4 [. U .] l U L l U L l U L l leash U shirt L light + // 5 [. F .] . F . . F . . F . . blank F boots . blank + // W wielded two-handed weapon + // X wielded secondary weapon + // + // 3.7: use a different legend for the layout: + // show gloves in only one slot; + // move alternate weapon to former right hand glove slot; + // move blindfold to former alternate weapon slot; + // add quiver to former blindfold slot; // show secondary weapon in shield slot when two-weapon is active; // show two-handed primary weapon in both shield and uwep slots; // show lit lamp/lantern/candle/candelabrum on lower right side; // show leash-in-use on lower left side + // + // Possible enhancement: for two-handed weapon, show the left hand + // instance as a mirror image of the normal right hand one. + // #ifdef ENHANCED_PAPERDOLL if (iflags.wc_ascii_map) From beb189e6cbb68e9b5f8c56aa60b9a3023653c0d8 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Sat, 7 Nov 2020 16:13:14 -0800 Subject: [PATCH 398/708] delinting --- sys/libnh/npm-package/src/nethackShim.js | 37 +++++++++++++++++------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/sys/libnh/npm-package/src/nethackShim.js b/sys/libnh/npm-package/src/nethackShim.js index e7a802c30..23c58e021 100644 --- a/sys/libnh/npm-package/src/nethackShim.js +++ b/sys/libnh/npm-package/src/nethackShim.js @@ -6,41 +6,56 @@ let savedOnRuntimeInitialized; // starts nethack function nethackStart(cb, inputModule = {}) { - if(typeof cb !== "string" && typeof cb !== "function") throw new TypeError("expected first argument to be 'Function' or 'String' representing global callback function name"); - if(typeof inputModule !== "object") throw new TypeError("expected second argument to be object"); + if (typeof cb !== "string" && typeof cb !== "function") { + throw new TypeError("expected first argument to be 'Function' or 'String' representing global callback function name"); + } + + if (typeof inputModule !== "object") { + throw new TypeError("expected second argument to be object"); + } let cbName; - if(typeof cb === "function") { + if (typeof cb === "function") { cbName = cb.name; - if (cbName === "") cbName = "__anonymousNetHackCallback"; - if (globalThis[cbName] === undefined) globalThis[cbName] = cb; - else if (globalThis[cbName] !== cb) throw new Error (`'globalThis["${cbName}"]' is not the same as specified callback`); + if (cbName === "") { + cbName = "__anonymousNetHackCallback"; + } + + if (globalThis[cbName] === undefined) { + globalThis[cbName] = cb; + } else if (globalThis[cbName] !== cb) { + throw new Error(`'globalThis["${cbName}"]' is not the same as specified callback`); + } } /* global globalThis */ userCallback = globalThis[cbName]; - if(typeof userCallback !== "function") throw new TypeError(`expected 'globalThis["${cbName}"]' to be a function`); + if (typeof userCallback !== "function") { + throw new TypeError(`expected 'globalThis["${cbName}"]' to be a function`); + } // if(userCallback.constructor.name !== "AsyncFunction") throw new TypeError(`expected 'globalThis["${cbName}"]' to be an async function`); // Emscripten Module config Module = inputModule; savedOnRuntimeInitialized = Module.onRuntimeInitialized; - Module.onRuntimeInitialized = function (... args) { + Module.onRuntimeInitialized = function(... args) { // after the WASM is loaded, add the shim graphics callback function Module.ccall( "shim_graphics_set_callback", // C function name null, // return type ["string"], // arg types [cbName], // arg values - {async: true} // options + {async: true}, // options ); // if the user had their own onRuntimeInitialized(), call it now - if (savedOnRuntimeInitialized) savedOnRuntimeInitialized(... args); + if (savedOnRuntimeInitialized) { + savedOnRuntimeInitialized(... args); + } }; // load and run the module - var factory = require(path.join(__dirname, "../build/nethack.js")); + let factory = require(path.join(__dirname, "../build/nethack.js")); factory(Module); } From ea0ef81ecdda7a357823678aa5411f41068bf6f6 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 8 Nov 2020 16:07:42 -0800 Subject: [PATCH 399/708] fix github issue #408 - stuck to distant mimic Attacking a concealed mimic at range by applying a polearm could make the hero be stuck to that mimic in addition to bringing it out of hiding. Only do that when adjacent. This also adds a new sanity check when setting u.ustuck. It may get triggered by other sticking activity since only attacking has been tested. The check must be explicitly enabled by setting the wizard mode 'sanity_check' option. Fixes #408 --- doc/fixes37.0 | 4 +++- src/mon.c | 8 +++++++- src/uhitm.c | 16 +++++++++------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 455db9ee2..9774892e7 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ $NHDT-Date: 1604620981 2020/11/06 00:03:01 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.349 $ $NHDT-Date: 1604880453 2020/11/09 00:07:33 $ General Fixes and Modified Features ----------------------------------- @@ -288,6 +288,8 @@ hero poly'd into rust monster could implicitly eat bars when adjacent by can explicitly eat them via 'e' after moving onto their spot monster hiding under an egg that hatched was kept hidden restful sleep regenerates hit points +attacking non-adjacent concealed mimic by applying a polearm would make the + hero be stuck to that mimic Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index d6e9e24a0..44097e221 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1600933441 2020/09/24 07:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.348 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1604880454 2020/11/09 00:07:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.351 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2575,6 +2575,12 @@ void set_ustuck(mtmp) struct monst *mtmp; { + if (iflags.sanity_check || iflags.debug_fuzzer) { + if (mtmp && distu(mtmp->mx, mtmp->my) > 2) + impossible("Sticking to %s at distu %d?", + mon_nam(mtmp), distu(mtmp->mx, mtmp->my)); + } + g.context.botl = 1; u.ustuck = mtmp; } diff --git a/src/uhitm.c b/src/uhitm.c index 53a82d7d3..7ad48d82e 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1596498221 2020/08/03 23:43:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.240 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1604880456 2020/11/09 00:07:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.242 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -141,10 +141,10 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */ /* if it was an invisible mimic, treat it as if we stumbled * onto a visible mimic */ - if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers - /* applied pole-arm attack is too far to get stuck */ - && distu(mtmp->mx, mtmp->my) <= 2) { - if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)) + if (M_AP_TYPE(mtmp) && !Protection_from_shape_changers) { + if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK) + /* applied pole-arm attack is too far to get stuck */ + && distu(mtmp->mx, mtmp->my) <= 2) set_ustuck(mtmp); } /* #H7329 - if hero is on engraved "Elbereth", this will end up @@ -2007,7 +2007,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ break; } case AD_STCK: - if (!negated && !sticks(pd)) + if (!negated && !sticks(pd) && distu(mdef->mx, mdef->my) <= 2) u.ustuck = mdef; /* it's now stuck to you */ break; case AD_WRAP: @@ -3133,7 +3133,9 @@ struct monst *mtmp; { const char *fmt = "Wait! That's %s!", *generic = "a monster", *what = 0; - if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)) + if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK) + /* must be adjacent; attack via polearm could be from farther away */ + && distu(mtmp->mx, mtmp->my) <= 2) set_ustuck(mtmp); if (Blind) { From 6b37efa9e165053762307f631d61a05266325f1a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 8 Nov 2020 16:38:01 -0800 Subject: [PATCH 400/708] Qt paper doll's depiction of two-handed weapon When wielding a two-handed weapon, Qt's paper doll shows uwep in the shield slot as well as in the weapon slot to reflect that it's occupying both hands. Make the shield slot's copy be a mirror image of the weapon's tile so that it looks less like wielding two weapons. --- win/Qt/qt_glyph.cpp | 50 ++++++++++++++++++++++++++++++++++++--------- win/Qt/qt_glyph.h | 14 ++++++++----- win/Qt/qt_inv.cpp | 25 +++++++++++++---------- win/Qt/qt_inv.h | 5 ++++- 4 files changed, 67 insertions(+), 27 deletions(-) diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index 7edbefa99..bed3bd5a3 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -81,23 +81,31 @@ NetHackQtGlyphs::NetHackQtGlyphs() setSize(tilefile_tile_W, tilefile_tile_H); } -void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y) +void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y, + bool reversed) { - int tile = glyph2tile[glyph]; - int px = (tile % tiles_per_row) * width(); - int py = tile / tiles_per_row * height(); + if (!reversed) { + int tile = glyph2tile[glyph]; + int px = (tile % tiles_per_row) * width(); + int py = tile / tiles_per_row * height(); - painter.drawPixmap(x, y, pm, px, py, width(), height()); + painter.drawPixmap(x, y, pm, px, py, width(), height()); + } else { + // for paper doll; mirrored image for left side of two-handed weapon + painter.drawPixmap(x, y, reversed_pixmap(glyph), + 0, 0, width(), height()); + } } void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, int cellx, int celly) { - drawGlyph(painter, glyph, cellx * width(), celly * height()); + drawGlyph(painter, glyph, cellx * width(), celly * height(), false); } void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, - int cellx, int celly, int border) + int cellx, int celly, int border, + bool reversed) { int wd = width(), ht = height(), @@ -105,7 +113,7 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, lox = cellx * (wd + 2), loy = celly * (ht + 2) + yoffset; - drawGlyph(painter, glyph, lox + 1, loy + 1); + drawGlyph(painter, glyph, lox + 1, loy + 1, reversed); #ifdef TEXTCOLOR if (border != NO_BORDER) { @@ -155,9 +163,10 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, #endif } -QPixmap NetHackQtGlyphs::glyph(int glyph) +// mis-named routine to get the pixmap for a particular glyph +QPixmap NetHackQtGlyphs::glyph(int glyphindx) { - int tile = glyph2tile[glyph]; + int tile = glyph2tile[glyphindx]; int px = (tile % tiles_per_row) * tilefile_tile_W; int py = tile / tiles_per_row * tilefile_tile_H; @@ -165,6 +174,27 @@ QPixmap NetHackQtGlyphs::glyph(int glyph) tilefile_tile_W, tilefile_tile_H)); } +// transpose a glyph's tile horizontally, scaled for use in paper doll +QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx) +{ + QPixmap pxmp = glyph(glyphindx); +#ifdef ENHANCED_PAPERDOLL + qreal wid = (qreal) pxmp.width(), + //hgt = (qreal) pxmp.height(), + xscale = (qreal) qt_settings->dollWidth / (qreal) tilefile_tile_W, + yscale = (qreal) qt_settings->dollHeight / (qreal) tilefile_tile_H; + QTransform *mirrormatrix = new QTransform( + // negate x coordinates to flip the image across the y-axis + -1.0 * xscale, 0.0, 0.0, yscale, + // slide flipped image to the right to make things positive again + wid * xscale, 0.0 + ); + return pxmp.transformed(*mirrormatrix); +#else + return pxmp; +#endif +} + void NetHackQtGlyphs::setSize(int w, int h) { if (size == QSize(w, h)) diff --git a/win/Qt/qt_glyph.h b/win/Qt/qt_glyph.h index 719e5cf17..39b0e3914 100644 --- a/win/Qt/qt_glyph.h +++ b/win/Qt/qt_glyph.h @@ -23,17 +23,21 @@ public: void toggleSize(); void setSize(int w, int h); - void drawGlyph(QPainter&, int glyph, int pixelx, int pixely); - void drawCell(QPainter&, int glyph, int cellx, int celly); - void drawBorderedCell(QPainter&, int glyph, - int cellx, int celly, int bordercode); - QPixmap glyph(int glyph); + void drawGlyph(QPainter &, int glyph, int pixelx, int pixely, + bool reversed = false); + void drawCell(QPainter &, int glyph, int cellx, int celly); + void drawBorderedCell(QPainter &, int glyph, + int cellx, int celly, int bordercode, + bool reversed); + QPixmap glyph(int glyphindx); + QPixmap reversed_pixmap(int glyphindx); private: QImage img; QPixmap pm,pm1, pm2; QSize size; int tiles_per_row; + //QTransform *mirrormatrix; }; } // namespace nethack_qt_ diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 816045446..e32a82522 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -61,10 +61,11 @@ NetHackQtInvUsageWindow::~NetHackQtInvUsageWindow() void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, int x, int y, // cell index, not pixels - const char *alttip, bool canbe) + const char *alttip, int flags) { short int glyph; int border; + bool rev = false; if (nhobj) { border = BORDER_DEFAULT; @@ -86,6 +87,8 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, Strcpy(tips[x][y], itmnam); else tips[x][y] = dupstr(itmnam); + + rev = (flags == dollReverse); #endif glyph = obj_to_glyph(nhobj, rn2_on_display_rng); } else { @@ -102,9 +105,11 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, #else nhUse(alttip); #endif - glyph = canbe ? cmap_to_glyph(S_room) : GLYPH_UNEXPLORED; + // an empty slot is shown as floor tile unless it's always empty + glyph = (flags != dollUnused) ? cmap_to_glyph(S_room) + : GLYPH_UNEXPLORED; } - qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border); + qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border, rev); } // called to update the paper doll inventory subset @@ -135,16 +140,14 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // show lit lamp/lantern/candle/candelabrum on lower right side; // show leash-in-use on lower left side // - // Possible enhancement: for two-handed weapon, show the left hand - // instance as a mirror image of the normal right hand one. - // + // Actually indexed by grid[column][row]. #ifdef ENHANCED_PAPERDOLL if (iflags.wc_ascii_map) qt_settings->doll_is_shown = false; if (!qt_settings->doll_is_shown) return; - // set glyphs() for the paperdoll; might be different size than map's + // set glyphs() for the paper doll; might be different size than map's qt_settings->glyphs().setSize(qt_settings->dollWidth, qt_settings->dollHeight); @@ -165,15 +168,15 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) never be Null when the corresponding tests pass */ if (u.twoweap) drawWorn(painter, uswapwep, 0, 1, NULL); // secondary weapon, in use - else if (uwep && bimanual(uwep)) - drawWorn(painter, uwep, 0, 1, NULL); // two-handed uwep shown twice + else if (uwep && bimanual(uwep)) // show two-handed uwep twice + drawWorn(painter, uwep, 0, 1, NULL, dollReverse); // uwep on left else drawWorn(painter, uarms, 0, 1, "no shield"); drawWorn(painter, uarmg, 0, 2, "no gloves"); drawWorn(painter, uleft, 0, 3, "no left ring"); /* light source and leash aren't unique and don't have pointers defined */ drawWorn(painter, find_tool(LEASH), 0, 4, "no leashes in use"); - drawWorn(painter, NULL, 0, 5, NULL, false); // always blank + drawWorn(painter, NULL, 0, 5, NULL, dollUnused); // always blank // middle column; no unused slots drawWorn(painter, uarmh, 1, 0, "no helmet"); @@ -198,7 +201,7 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) (and might also duplicate Sunsword when it is wielded--hence lit-- depending upon whether another light source precedes it in invent) */ drawWorn(painter, find_tool(OIL_LAMP), 2, 4, "no active light sources"); - drawWorn(painter, NULL, 2, 5, NULL, false); // always blank + drawWorn(painter, NULL, 2, 5, NULL, dollUnused); // always blank painter.end(); diff --git a/win/Qt/qt_inv.h b/win/Qt/qt_inv.h index 2566c8f79..2c1c694e0 100644 --- a/win/Qt/qt_inv.h +++ b/win/Qt/qt_inv.h @@ -10,6 +10,9 @@ namespace nethack_qt_ { +// for calls to drawWorn +enum drawWornFlag { dollNoFlag = 0, dollUnused = 1, dollReverse = 2 }; + class NetHackQtInvUsageWindow : public QWidget { public: NetHackQtInvUsageWindow(QWidget* parent); @@ -23,7 +26,7 @@ protected: private: void drawWorn(QPainter &painter, obj *nhobj, int x, int y, - const char *alttip, bool canbe=true); + const char *alttip, int flags = dollNoFlag); bool tooltip_event(QHelpEvent *tipevent); char *tips[3][6]; // PAPERDOLL is a grid of 3x6 cells for tiles From e23f764d11c7f8faac34d4ee6f22d26b70bea05d Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 12 Nov 2020 04:30:25 -0800 Subject: [PATCH 401/708] fix #K2924 - breaking a wand without free hands Breaking a wand didn't require the hero to have free hands. That's definitely a bug when they're both welded to the same two-handed weapon. It's debatable when welded separately to a one-handed weapon and to a shield but simpler to pretend there's no such distinction. This also makes glass wand join balsa wand as "fragile". Hero doesn't need as much strength to break them as other wands and the wording for breaking them is slightly different. My fixes entry initially had a trailing space. When I took that out, I spotted a couple of others so take those out too. --- doc/fixes37.0 | 9 ++++++--- src/apply.c | 19 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9774892e7..10cead1e5 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.349 $ $NHDT-Date: 1604880453 2020/11/09 00:07:33 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.350 $ $NHDT-Date: 1605184219 2020/11/12 12:30:19 $ General Fixes and Modified Features ----------------------------------- @@ -290,6 +290,9 @@ monster hiding under an egg that hatched was kept hidden restful sleep regenerates hit points attacking non-adjacent concealed mimic by applying a polearm would make the hero be stuck to that mimic +hero could break a wand ("raising the wand high over your head, you break it + in two") even if hands were welded to a two-handed weapon or to a + one-handed weapon and also to a shield Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -644,7 +647,7 @@ always print a message when the hero level teleports (github #265) remove Sokoban luck penalties for actions you can't cheat with (github #260) sounds for minotaurs (github #298) correct the Guidebook descriptions for msdos video_width and video_height to - state that they work with video:vesa; the video:vga setting that was + state that they work with video:vesa; the video:vga setting that was described there forces the 640x480x16 mode where video_width and video_height don't operate (github #294) redo rndmonst() to operate in a single pass (github pull request #286) @@ -690,7 +693,7 @@ resurrect 'makedefs -m' to be able to derive default mons[].diffculty values suitable for assigning to new or changed monsters convert obj->oextra->omid from pointer to scalar get rid of unused obj->oextra->olong -relocated unmaintained code to outdated folder, specifically sys/amiga, +relocated unmaintained code to outdated folder, specifically sys/amiga, sys/atari, sys/be, sys/mac, sys/os2, sys/wince, win/Qt3, win/gem, win/gnome, include/amiconf.h, include/beconf.h, include/def_os2.h, include/os2conf.h, include/macconf.h, include/tosconf.h, diff --git a/src/apply.c b/src/apply.c index 9c742959c..d5f8a1797 100644 --- a/src/apply.c +++ b/src/apply.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 apply.c $NHDT-Date: 1604442295 2020/11/03 22:24:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.330 $ */ +/* NetHack 3.7 apply.c $NHDT-Date: 1605184220 2020/11/12 12:30:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.331 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3406,21 +3406,24 @@ struct obj *obj; boolean fillmsg = FALSE; int expltype = EXPL_MAGICAL; char confirm[QBUFSZ], buf[BUFSZ]; - boolean is_fragile = objdescr_is(obj, "balsa"); - - if (!paranoid_query(ParanoidBreakwand, - safe_qbuf(confirm, - "Are you really sure you want to break ", - "?", obj, yname, ysimple_name, "the wand"))) - return 0; + boolean is_fragile = (objdescr_is(obj, "balsa") + || objdescr_is(obj, "glass")); if (nohands(g.youmonst.data)) { You_cant("break %s without hands!", yname(obj)); return 0; + } else if (!freehand()) { + Your("%s are occupied!", makeplural(body_part(HAND))); + return 0; } else if (ACURR(A_STR) < (is_fragile ? 5 : 10)) { You("don't have the strength to break %s!", yname(obj)); return 0; } + if (!paranoid_query(ParanoidBreakwand, + safe_qbuf(confirm, + "Are you really sure you want to break ", + "?", obj, yname, ysimple_name, "the wand"))) + return 0; pline("Raising %s high above your %s, you %s it in two!", yname(obj), body_part(HEAD), is_fragile ? "snap" : "break"); From 6ec55a36249cf04493c49a87df70ab0b3cceb68b Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 9 Nov 2020 18:50:02 +0200 Subject: [PATCH 402/708] Rework stairs structure Use a linked list to store stair and ladder information, instead of having fixed up/down stairs/ladders and a single "special" (branch) stair. Breaks saves and bones. Adds information to migrating objects and monsters for the dungeon and level where they are migrating from. --- doc/fixes37.0 | 2 +- include/decl.h | 19 +---- include/dungeon.h | 4 +- include/extern.h | 9 ++ include/monst.h | 1 + include/obj.h | 2 + include/patchlevel.h | 2 +- include/rm.h | 2 + src/allmain.c | 46 +++------- src/apply.c | 8 +- src/cmd.c | 11 ++- src/decl.c | 9 +- src/dig.c | 11 +-- src/do.c | 25 +++--- src/dog.c | 31 +++++-- src/dokick.c | 58 ++++++++----- src/dungeon.c | 197 ++++++++++++++++++++++++++++++++++++------- src/invent.c | 11 ++- src/mail.c | 17 ++-- src/makemon.c | 20 ++--- src/mklev.c | 40 ++++----- src/mkmaze.c | 10 ++- src/mkobj.c | 2 + src/mkroom.c | 22 +++-- src/mon.c | 8 +- src/muse.c | 56 +++++++----- src/potion.c | 4 +- src/restore.c | 61 +++++++++++--- src/save.c | 36 ++++++-- src/shk.c | 11 ++- src/sp_lev.c | 105 +++++------------------ src/teleport.c | 31 +++++-- src/wizard.c | 34 ++++---- src/zap.c | 8 +- 34 files changed, 552 insertions(+), 361 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 10cead1e5..34885e5c8 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -706,4 +706,4 @@ get rid of 3.6.1 workaround needed to retain compatibility with 3.6.0 bones add an additional note to mextra.h and obj.h comments that reminds people to appropriately init new fields if they need to initialize to something other than zero - +rework stairs structure into a linked list diff --git a/include/decl.h b/include/decl.h index c72ab57bf..dc1039c22 100644 --- a/include/decl.h +++ b/include/decl.h @@ -75,16 +75,6 @@ struct dgn_topology { /* special dungeon levels for speed */ #define sokoend_level (g.dungeon_topology.d_sokoend_level) /* clang-format on */ -#define xdnstair (g.dnstair.sx) -#define ydnstair (g.dnstair.sy) -#define xupstair (g.upstair.sx) -#define yupstair (g.upstair.sy) - -#define xdnladder (g.dnladder.sx) -#define ydnladder (g.dnladder.sy) -#define xupladder (g.upladder.sx) -#define yupladder (g.upladder.sy) - #define dunlev_reached(x) (g.dungeons[(x)->dnum].dunlev_ureached) #include "quest.h" @@ -726,10 +716,7 @@ struct instance_globals { int y_maze_max; int otg_temp; /* used by object_to_glyph() [otg] */ int in_doagain; - stairway dnstair; /* stairs down */ - stairway upstair; /* stairs up */ - stairway dnladder; /* ladder down */ - stairway upladder; /* ladder up */ + stairway *stairs; int smeq[MAXNROFROOMS + 1]; int doorindex; char *save_cm; @@ -754,7 +741,6 @@ struct instance_globals { number of shots, index of current one, validity check, shoot vs throw */ struct multishot m_shot; dungeon dungeons[MAXDUNGEON]; /* ini'ed by init_dungeon() */ - stairway sstairs; dest_area updest; dest_area dndest; coord inv_pos; @@ -765,9 +751,6 @@ struct instance_globals { boolean mrg_to_wielded; /* weapon picked is merged with wielded one */ struct plinemsg_type *plinemsg_types; char toplines[TBUFSZ]; - struct mkroom *upstairs_room; - struct mkroom *dnstairs_room; - struct mkroom *sstairs_room; coord bhitpos; /* place where throw or zap hits or stops */ boolean in_steed_dismounting; coord doors[DOORMAX]; diff --git a/include/dungeon.h b/include/dungeon.h index 2a135c62f..7a07e58f4 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -34,7 +34,9 @@ typedef struct s_level { /* special dungeon level element */ typedef struct stairway { /* basic stairway identifier */ xchar sx, sy; /* x / y location of the stair */ d_level tolev; /* where does it go */ - char up; /* what type of stairway (up/down) */ + boolean up; /* up or down? */ + boolean isladder; /* ladder or stairway? */ + struct stairway *next; } stairway; /* level region types */ diff --git a/include/extern.h b/include/extern.h index e24e605b6..9280b47b6 100644 --- a/include/extern.h +++ b/include/extern.h @@ -630,6 +630,15 @@ E void FDECL(next_level, (BOOLEAN_P)); E void FDECL(prev_level, (BOOLEAN_P)); E void FDECL(u_on_newpos, (int, int)); E void FDECL(u_on_rndspot, (int)); +E void FDECL(stairway_add, (int,int, BOOLEAN_P, BOOLEAN_P, d_level *)); +E void NDECL(stairway_print); +E void NDECL(stairway_free_all); +E stairway *FDECL(stairway_at, (int, int)); +E stairway *FDECL(stairway_find, (d_level *)); +E stairway *FDECL(stairway_find_from, (d_level *, BOOLEAN_P)); +E stairway *FDECL(stairway_find_dir, (BOOLEAN_P)); +E stairway *FDECL(stairway_find_type_dir, (BOOLEAN_P, BOOLEAN_P)); +E stairway *FDECL(stairway_find_special_dir, (BOOLEAN_P)); E void FDECL(u_on_sstairs, (int)); E void NDECL(u_on_upstairs); E void NDECL(u_on_dnstairs); diff --git a/include/monst.h b/include/monst.h index eaecd34a7..6842162ca 100644 --- a/include/monst.h +++ b/include/monst.h @@ -82,6 +82,7 @@ struct monst { xchar mx, my; xchar mux, muy; /* where the monster thinks you are */ #define MTSZ 4 + /* mtrack[0..2] is used to keep extra data when migrating the monster */ coord mtrack[MTSZ]; /* monster track */ int mhp, mhpmax; unsigned mappearance; /* for undetected mimics and the wiz */ diff --git a/include/obj.h b/include/obj.h index 3504992d6..4b6f6d5c8 100644 --- a/include/obj.h +++ b/include/obj.h @@ -122,6 +122,8 @@ struct obj { long age; /* creation date */ long owornmask; unsigned lua_ref_cnt; /* # of lua script references for this object */ + xchar omigr_from_dnum; /* where obj is migrating from */ + xchar omigr_from_dlevel; /* where obj is migrating from */ struct oextra *oextra; /* pointer to oextra struct */ }; diff --git a/include/patchlevel.h b/include/patchlevel.h index adf03ba79..0ca768ddb 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 24 +#define EDITLEVEL 25 /* * Development status possibilities. diff --git a/include/rm.h b/include/rm.h index fbaa8a388..b55512439 100644 --- a/include/rm.h +++ b/include/rm.h @@ -243,6 +243,8 @@ enum screen_symbols { #define is_cmap_furniture(i) ((i) >= S_upstair && (i) <= S_fountain) #define is_cmap_water(i) ((i) == S_pool || (i) == S_water) #define is_cmap_lava(i) ((i) == S_lava) +#define is_cmap_stairs(i) ((i) == S_upstair || (i) == S_dnstair || \ + (i) == S_upladder || (i) == S_dnladder) struct symdef { diff --git a/src/allmain.c b/src/allmain.c index a11919b85..d015e7621 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -712,43 +712,21 @@ do_positionbar() { static char pbar[COLNO]; char *p; + stairway *stway = g.stairs; p = pbar; - /* up stairway */ - if (g.upstair.sx - && (glyph_to_cmap(g.level.locations[g.upstair.sx][g.upstair.sy].glyph) - == S_upstair - || glyph_to_cmap(g.level.locations[g.upstair.sx][g.upstair.sy].glyph) - == S_upladder)) { - *p++ = '<'; - *p++ = g.upstair.sx; - } - if (g.sstairs.sx - && (glyph_to_cmap(g.level.locations[g.sstairs.sx][g.sstairs.sy].glyph) - == S_upstair - || glyph_to_cmap(g.level.locations[g.sstairs.sx][g.sstairs.sy].glyph) - == S_upladder)) { - *p++ = '<'; - *p++ = g.sstairs.sx; - } + /* TODO: use the same method as getpos() so objects don't cover stairs */ + while (stway) { + int x = stway->sx; + int y = stway->sy; + int glyph = glyph_to_cmap(g.level.locations[x][y].glyph); - /* down stairway */ - if (g.dnstair.sx - && (glyph_to_cmap(g.level.locations[g.dnstair.sx][g.dnstair.sy].glyph) - == S_dnstair - || glyph_to_cmap(g.level.locations[g.dnstair.sx][g.dnstair.sy].glyph) - == S_dnladder)) { - *p++ = '>'; - *p++ = g.dnstair.sx; - } - if (g.sstairs.sx - && (glyph_to_cmap(g.level.locations[g.sstairs.sx][g.sstairs.sy].glyph) - == S_dnstair - || glyph_to_cmap(g.level.locations[g.sstairs.sx][g.sstairs.sy].glyph) - == S_dnladder)) { - *p++ = '>'; - *p++ = g.sstairs.sx; - } + if (is_cmap_stairs(glyph)) { + *p++ = (stway->up ? '<' : '>'); + *p++ = stway->sx; + } + stway = stway->next; + } /* hero location */ if (u.ux) { diff --git a/src/apply.c b/src/apply.c index d5f8a1797..a7cc2d82c 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2556,10 +2556,10 @@ struct obj *otmp; what = "in water"; else if (is_lava(u.ux, u.uy)) what = "in lava"; - else if (On_stairs(u.ux, u.uy)) - what = (u.ux == xdnladder || u.ux == xupladder) ? "on the ladder" - : "on the stairs"; - else if (IS_FURNITURE(levtyp) || IS_ROCK(levtyp) + else if (On_stairs(u.ux, u.uy)) { + stairway *stway = stairway_at(u.ux, u.uy); + what = stway->isladder ? "on the ladder" : "on the stairs"; + } else if (IS_FURNITURE(levtyp) || IS_ROCK(levtyp) || closed_door(u.ux, u.uy) || t_at(u.ux, u.uy)) what = "here"; else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) diff --git a/src/cmd.c b/src/cmd.c index b870f0d46..c6561ee19 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3958,6 +3958,7 @@ boolean doit; schar typ = levl[u.ux][u.uy].typ; int npick; menu_item *picks = (menu_item *) 0; + stairway *stway = stairway_at(u.ux, u.uy); win = create_nhwindow(NHW_MENU); start_menu(win, MENU_BEHAVE_STANDARD); @@ -3974,16 +3975,14 @@ boolean doit; add_herecmd_menuitem(win, dosit, "Sit on the throne"); - if (On_stairs_up(u.ux, u.uy)) { + if (stway && stway->up) { Sprintf(buf, "Go up the %s", - (u.ux == xupladder && u.uy == yupladder) - ? "ladder" : "stairs"); + stway->isladder ? "ladder" : "stairs"); add_herecmd_menuitem(win, doup, buf); } - if (On_stairs_dn(u.ux, u.uy)) { + if (stway && !stway->up) { Sprintf(buf, "Go down the %s", - (u.ux == xupladder && u.uy == yupladder) - ? "ladder" : "stairs"); + stway->isladder ? "ladder" : "stairs"); add_herecmd_menuitem(win, dodown, buf); } if (u.usteed) { /* another movement choice */ diff --git a/src/decl.c b/src/decl.c index 5f44d64e1..54d38ac6d 100644 --- a/src/decl.c +++ b/src/decl.c @@ -270,10 +270,7 @@ const struct instance_globals g_init = { (ROWNO - 1) & ~1, /* y_maze_max */ UNDEFINED_VALUE, /* otg_temp */ 0, /* in_doagain */ - DUMMY, /* dnstair */ - DUMMY, /* upstair */ - DUMMY, /* dnladder */ - DUMMY, /* upladder */ + NULL, /* stairs */ DUMMY, /* smeq */ 0, /* doorindex */ NULL, /* save_cm */ @@ -294,7 +291,6 @@ const struct instance_globals g_init = { UNDEFINED_PTR, /* sp_levchn */ { 0, 0, STRANGE_OBJECT, FALSE }, /* m_shot */ UNDEFINED_VALUES, /* dungeons */ - { 0, 0, { 0, 0 }, 0 }, /* sstairs */ { 0, 0, 0, 0, 0, 0, 0, 0 }, /* updest */ { 0, 0, 0, 0, 0, 0, 0, 0 }, /* dndest */ { 0, 0} , /* inv_pos */ @@ -305,9 +301,6 @@ const struct instance_globals g_init = { FALSE, /* mrg_to_wielded */ NULL, /* plinemsg_types */ UNDEFINED_VALUES, /* toplines */ - UNDEFINED_PTR, /* upstairs_room */ - UNDEFINED_PTR, /* dnstairs_room */ - UNDEFINED_PTR, /* sstairs_room */ DUMMY, /* bhitpos */ FALSE, /* in_steed_dismounting */ DUMMY, /* doors */ diff --git a/src/dig.c b/src/dig.c index 05369498f..7c3e603c2 100644 --- a/src/dig.c +++ b/src/dig.c @@ -188,7 +188,8 @@ int x, y; (madeby == BY_YOU && uwep && is_axe(uwep)) ? "chop" : "dig in"; if (On_stairs(x, y)) { - if (x == xdnladder || x == xupladder) { + stairway *stway = stairway_at(x, y); + if (stway->isladder) { if (verbose) pline_The("ladder resists your effort."); } else if (verbose) @@ -1431,12 +1432,12 @@ zap_dig() if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !Underwater) { if (u.dz < 0 || On_stairs(u.ux, u.uy)) { int dmg; - if (On_stairs(u.ux, u.uy)) + if (On_stairs(u.ux, u.uy)) { + stairway *stway = stairway_at(u.ux, u.uy); pline_The("beam bounces off the %s and hits the %s.", - (u.ux == xdnladder || u.ux == xupladder) - ? "ladder" - : "stairs", + stway->isladder ? "ladder" : "stairs", ceiling(u.ux, u.uy)); + } You("loosen a rock from the %s.", ceiling(u.ux, u.uy)); pline("It falls on your %s!", body_part(HEAD)); dmg = rnd((uarmh && is_metallic(uarmh)) ? 2 : 6); diff --git a/src/do.c b/src/do.c index ee2c3c141..a98417fa3 100644 --- a/src/do.c +++ b/src/do.c @@ -950,10 +950,9 @@ int dodown() { struct trap *trap = 0; - boolean stairs_down = ((u.ux == xdnstair && u.uy == ydnstair) - || (u.ux == g.sstairs.sx && u.uy == g.sstairs.sy - && !g.sstairs.up)), - ladder_down = (u.ux == xdnladder && u.uy == ydnladder); + stairway *stway = stairway_at(u.ux, u.uy); + boolean stairs_down = (stway && !stway->up && !stway->isladder), + ladder_down = (stway && !stway->up && stway->isladder); if (u_rooted()) return 1; @@ -1105,6 +1104,8 @@ dodown() int doup() { + stairway *stway = stairway_at(u.ux,u.uy); + if (u_rooted()) return 1; @@ -1114,10 +1115,7 @@ doup() return 1; } - if ((u.ux != xupstair || u.uy != yupstair) - && (!xupladder || u.ux != xupladder || u.uy != yupladder) - && (!g.sstairs.sx || u.ux != g.sstairs.sx || u.uy != g.sstairs.sy - || !g.sstairs.up)) { + if (!stway || (stway && !stway->up)) { You_cant("go up here."); return 0; } @@ -1458,6 +1456,7 @@ boolean at_stairs, falling, portal; dunlev_reached(&u.uz) = dunlev(&u.uz); } + stairway_free_all(); /* set default level change destination areas */ /* the special level code may override these */ (void) memset((genericptr_t) &g.updest, 0, sizeof g.updest); @@ -1528,8 +1527,9 @@ boolean at_stairs, falling, portal; } } else if (at_stairs && !In_endgame(&u.uz)) { if (up) { - if (g.at_ladder) - u_on_newpos(xdnladder, ydnladder); + stairway *stway = stairway_find_from(&u.uz0, g.at_ladder); + if (stway) + u_on_newpos(stway->sx, stway->sy); else if (newdungeon) u_on_sstairs(1); else @@ -1544,8 +1544,9 @@ boolean at_stairs, falling, portal; (Flying && g.at_ladder) ? " along" : "", g.at_ladder ? "ladder" : "stairs"); } else { /* down */ - if (g.at_ladder) - u_on_newpos(xupladder, yupladder); + stairway *stway = stairway_find_from(&u.uz0, g.at_ladder); + if (stway) + u_on_newpos(stway->sx, stway->sy); else if (newdungeon) u_on_sstairs(0); else diff --git a/src/dog.c b/src/dog.c index 14a6b1992..450996168 100644 --- a/src/dog.c +++ b/src/dog.c @@ -306,6 +306,8 @@ boolean with_you; xchar xlocale, ylocale, xyloc, xyflags, wander; int num_segs; boolean failed_to_place = FALSE; + stairway *stway; + d_level fromdlev; mtmp->nmon = fmon; fmon = mtmp; @@ -331,6 +333,8 @@ boolean with_you; xyflags = mtmp->mtrack[0].y; xlocale = mtmp->mtrack[1].x; ylocale = mtmp->mtrack[1].y; + fromdlev.dnum = mtmp->mtrack[2].x; + fromdlev.dlevel = mtmp->mtrack[2].y; memset(mtmp->mtrack, 0, sizeof mtmp->mtrack); if (mtmp == u.usteed) @@ -376,19 +380,34 @@ boolean with_you; xlocale = u.ux, ylocale = u.uy; break; case MIGR_STAIRS_UP: - xlocale = xupstair, ylocale = yupstair; + if ((stway = stairway_find_from(&fromdlev, FALSE)) != 0) { + xlocale = stway->sx; + ylocale = stway->sy; + } break; case MIGR_STAIRS_DOWN: - xlocale = xdnstair, ylocale = ydnstair; + if ((stway = stairway_find_from(&fromdlev, FALSE)) != 0) { + xlocale = stway->sx; + ylocale = stway->sy; + } break; case MIGR_LADDER_UP: - xlocale = xupladder, ylocale = yupladder; + if ((stway = stairway_find_from(&fromdlev, TRUE)) != 0) { + xlocale = stway->sx; + ylocale = stway->sy; + } break; case MIGR_LADDER_DOWN: - xlocale = xdnladder, ylocale = ydnladder; + if ((stway = stairway_find_from(&fromdlev, TRUE)) != 0) { + xlocale = stway->sx; + ylocale = stway->sy; + } break; case MIGR_SSTAIRS: - xlocale = g.sstairs.sx, ylocale = g.sstairs.sy; + if ((stway = stairway_find(&fromdlev)) != 0) { + xlocale = stway->sx; + ylocale = stway->sy; + } break; case MIGR_PORTAL: if (In_endgame(&u.uz)) { @@ -719,6 +738,8 @@ coord *cc; /* optional destination coordinates */ xyflags |= 2; mtmp->wormno = num_segs; mtmp->mlstmv = g.monstermoves; + mtmp->mtrack[2].x = u.uz.dnum; /* migrating from this dungeon */ + mtmp->mtrack[2].y = u.uz.dlevel; /* migrating from this dungeon level */ mtmp->mtrack[1].x = cc ? cc->x : mtmp->mx; mtmp->mtrack[1].y = cc ? cc->y : mtmp->my; mtmp->mtrack[0].x = xyloc; diff --git a/src/dokick.c b/src/dokick.c index 979f1315c..81ed6c314 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -19,7 +19,7 @@ static int FDECL(kick_object, (XCHAR_P, XCHAR_P, char *)); static int FDECL(really_kick_object, (XCHAR_P, XCHAR_P)); static char *FDECL(kickstr, (char *, const char *)); static void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long)); -static void FDECL(drop_to, (coord *, SCHAR_P)); +static void FDECL(drop_to, (coord *, SCHAR_P, XCHAR_P, XCHAR_P)); static const char kick_passes_thru[] = "kick passes harmlessly through"; @@ -1322,10 +1322,13 @@ dokick() } static void -drop_to(cc, loc) +drop_to(cc, loc, x,y) coord *cc; schar loc; +xchar x,y; { + stairway *stway = stairway_at(x, y); + /* cover all the MIGR_xxx choices generated by down_gate() */ switch (loc) { case MIGR_RANDOM: /* trap door or hole */ @@ -1340,12 +1343,14 @@ schar loc; /*FALLTHRU*/ case MIGR_STAIRS_UP: case MIGR_LADDER_UP: - cc->x = u.uz.dnum; - cc->y = u.uz.dlevel + 1; - break; case MIGR_SSTAIRS: - cc->x = g.sstairs.tolev.dnum; - cc->y = g.sstairs.tolev.dlevel; + if (stway) { + cc->x = stway->tolev.dnum; + cc->y = stway->tolev.dlevel; + } else { + cc->x = u.uz.dnum; + cc->y = u.uz.dlevel + 1; + } break; default: case MIGR_NOWHERE: @@ -1373,7 +1378,7 @@ xchar dlev; /* if !0 send to dlev near player */ return; toloc = down_gate(x, y); - drop_to(&cc, toloc); + drop_to(&cc, toloc, x, y); if (!cc.y) return; @@ -1502,7 +1507,7 @@ boolean shop_floor_obj; return FALSE; if ((toloc = down_gate(x, y)) == MIGR_NOWHERE) return FALSE; - drop_to(&cc, toloc); + drop_to(&cc, toloc, x, y); if (!cc.y) return FALSE; @@ -1586,6 +1591,7 @@ boolean shop_floor_obj; otmp->ox = cc.x; otmp->oy = cc.y; otmp->owornmask = (long) toloc; + /* boulder from rolling boulder trap, no longer part of the trap */ if (otmp->otyp == BOULDER) otmp->otrapped = 0; @@ -1614,6 +1620,9 @@ boolean near_hero; register int nx, ny; int where; boolean nobreak, noscatter; + stairway *stway; + d_level fromdlev; + boolean isladder; for (otmp = g.migrating_objs; otmp; otmp = otmp2) { otmp2 = otmp->nobj; @@ -1633,16 +1642,21 @@ boolean near_hero; obj_extract_self(otmp); otmp->owornmask = 0L; + fromdlev.dnum = otmp->omigr_from_dnum; + fromdlev.dlevel = otmp->omigr_from_dlevel; + + isladder = FALSE; switch (where) { - case MIGR_STAIRS_UP: - nx = xupstair, ny = yupstair; - break; case MIGR_LADDER_UP: - nx = xupladder, ny = yupladder; - break; + isladder = TRUE; + case MIGR_STAIRS_UP: case MIGR_SSTAIRS: - nx = g.sstairs.sx, ny = g.sstairs.sy; + if ((stway = stairway_find_from(&fromdlev, isladder)) != 0) { + nx = stway->sx; + nx = stway->sy; + } + break; break; case MIGR_WITH_HERO: nx = u.ux, ny = u.uy; @@ -1652,6 +1666,8 @@ boolean near_hero; nx = ny = 0; break; } + otmp->omigr_from_dnum = 0; + otmp->omigr_from_dlevel = 0; if (nx > 0) { place_object(otmp, nx, ny); if (!nobreak && !IS_SOFT(levl[nx][ny].typ)) { @@ -1727,6 +1743,8 @@ unsigned long deliverflags; free_oname(otmp); } otmp->migr_species = NON_PM; + otmp->omigr_from_dnum = 0; + otmp->omigr_from_dlevel = 0; (void) add_to_minv(mtmp, otmp); cnt++; if (maxobj && cnt >= maxobj) @@ -1773,19 +1791,19 @@ down_gate(x, y) xchar x, y; { struct trap *ttmp; + stairway *stway = stairway_at(x, y); g.gate_str = 0; /* this matches the player restriction in goto_level() */ if (on_level(&u.uz, &qstart_level) && !ok_to_quest()) return MIGR_NOWHERE; - if ((xdnstair == x && ydnstair == y) - || (g.sstairs.sx == x && g.sstairs.sy == y && !g.sstairs.up)) { + if (stway && !stway->up && !stway->isladder) { g.gate_str = "down the stairs"; - return (xdnstair == x && ydnstair == y) ? MIGR_STAIRS_UP - : MIGR_SSTAIRS; + return (stway->tolev.dnum == u.uz.dnum) ? MIGR_STAIRS_UP + : MIGR_SSTAIRS; } - if (xdnladder == x && ydnladder == y) { + if (stway && !stway->up && stway->isladder) { g.gate_str = "down the ladder"; return MIGR_LADDER_UP; } diff --git a/src/dungeon.c b/src/dungeon.c index ec60d7168..32e1ea4c6 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1398,13 +1398,14 @@ void next_level(at_stairs) boolean at_stairs; { - if (at_stairs && u.ux == g.sstairs.sx && u.uy == g.sstairs.sy) { - /* Taking a down dungeon branch. */ - goto_level(&g.sstairs.tolev, at_stairs, FALSE, FALSE); - } else { - /* Going down a stairs or jump in a trap door. */ - d_level newlevel; + stairway *stway = stairway_at(u.ux, u.uy); + d_level newlevel; + if (at_stairs && stway) { + newlevel.dnum = stway->tolev.dnum; + newlevel.dlevel = stway->tolev.dlevel; + goto_level(&newlevel, at_stairs, FALSE, FALSE); + } else { newlevel.dnum = u.uz.dnum; newlevel.dlevel = u.uz.dlevel + 1; goto_level(&newlevel, at_stairs, !at_stairs, FALSE); @@ -1416,17 +1417,22 @@ void prev_level(at_stairs) boolean at_stairs; { - if (at_stairs && u.ux == g.sstairs.sx && u.uy == g.sstairs.sy) { + stairway *stway = stairway_at(u.ux, u.uy); + d_level newlevel; + + if (at_stairs && stway && stway->tolev.dnum != u.uz.dnum) { /* Taking an up dungeon branch. */ /* KMH -- Upwards branches are okay if not level 1 */ /* (Just make sure it doesn't go above depth 1) */ if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet) done(ESCAPED); - else - goto_level(&g.sstairs.tolev, at_stairs, FALSE, FALSE); + else { + newlevel.dnum = stway->tolev.dnum; + newlevel.dlevel = stway->tolev.dlevel; + goto_level(&newlevel, at_stairs, FALSE, FALSE); + } } else { /* Going up a stairs or rising through the ceiling. */ - d_level newlevel; newlevel.dnum = u.uz.dnum; newlevel.dlevel = u.uz.dlevel - 1; goto_level(&newlevel, at_stairs, FALSE, FALSE); @@ -1492,13 +1498,141 @@ int upflag; switch_terrain(); } +void +stairway_add(x,y, up, ladder, dest) +int x,y; +boolean up, ladder; +d_level *dest; +{ + stairway *tmp = (stairway *)alloc(sizeof(stairway)); + + tmp->sx = x; + tmp->sy = y; + tmp->up = up; + tmp->isladder = ladder; + assign_level(&(tmp->tolev), dest); + tmp->next = g.stairs; + g.stairs = tmp; +} + +void +stairway_free_all() +{ + stairway *tmp = g.stairs; + + while (tmp) { + stairway *tmp2 = tmp->next; + free(tmp); + tmp = tmp2; + } + g.stairs = NULL; +} + +stairway * +stairway_at(x,y) +int x,y; +{ + stairway *tmp = g.stairs; + + while (tmp && !(tmp->sx == x && tmp->sy == y)) + tmp = tmp->next; + + return tmp; +} + +stairway * +stairway_find(fromdlev) +d_level *fromdlev; +{ + stairway *tmp = g.stairs; + + while (tmp) { + if (tmp->tolev.dnum == fromdlev->dnum + && tmp->tolev.dlevel == fromdlev->dlevel) + return tmp; + tmp = tmp->next; + } + + return tmp; +} + +stairway * +stairway_find_from(fromdlev, ladder) +d_level *fromdlev; +boolean ladder; +{ + stairway *tmp = g.stairs; + + while (tmp) { + if (tmp->tolev.dnum == fromdlev->dnum + && tmp->tolev.dlevel == fromdlev->dlevel + && tmp->isladder == ladder) + return tmp; + tmp = tmp->next; + } + + return tmp; +} + +stairway * +stairway_find_dir(up) +boolean up; +{ + stairway *tmp = g.stairs; + + while (tmp && !(tmp->up == up)) + tmp = tmp->next; + + return tmp; +} + +stairway * +stairway_find_ladder() +{ + stairway *tmp = g.stairs; + + while (tmp && !tmp->isladder) + tmp = tmp->next; + + return tmp; +} + +stairway * +stairway_find_type_dir(ladder,up) +boolean ladder, up; +{ + stairway *tmp = g.stairs; + + while (tmp && !(tmp->isladder == ladder && tmp->up == up)) + tmp = tmp->next; + + return tmp; +} + +stairway * +stairway_find_special_dir(up) +boolean up; +{ + stairway *tmp = g.stairs; + + while (tmp) { + if (tmp->tolev.dnum != u.uz.dnum && tmp->up != up) + return tmp; + tmp = tmp->next; + } + + return tmp; +} + /* place you on the special staircase */ void u_on_sstairs(upflag) int upflag; { - if (g.sstairs.sx) - u_on_newpos(g.sstairs.sx, g.sstairs.sy); + stairway *stway = stairway_find_special_dir(upflag); + + if (stway) + u_on_newpos(stway->sx, stway->sy); else u_on_rndspot(upflag); } @@ -1507,8 +1641,10 @@ int upflag; void u_on_upstairs() { - if (xupstair) - u_on_newpos(xupstair, yupstair); + stairway *stway = stairway_find_dir(TRUE); + + if (stway) + u_on_newpos(stway->sx, stway->sy); else u_on_sstairs(0); /* destination upstairs implies moving down */ } @@ -1517,8 +1653,10 @@ u_on_upstairs() void u_on_dnstairs() { - if (xdnstair) - u_on_newpos(xdnstair, ydnstair); + stairway *stway = stairway_find_dir(FALSE); + + if (stway) + u_on_newpos(stway->sx, stway->sy); else u_on_sstairs(1); /* destination dnstairs implies moving up */ } @@ -1527,37 +1665,34 @@ boolean On_stairs(x, y) xchar x, y; { - return (boolean) ((x == xupstair && y == yupstair) - || (x == xdnstair && y == ydnstair) - || (x == xdnladder && y == ydnladder) - || (x == xupladder && y == yupladder) - || (x == g.sstairs.sx && y == g.sstairs.sy)); + return (stairway_at(x,y) != NULL); } boolean On_ladder(x, y) xchar x, y; { - return (boolean) ((x == xdnladder && y == ydnladder) - || (x == xupladder && y == yupladder)); + stairway *stway = stairway_at(x,y); + + return (boolean) (stway && stway->isladder); } boolean On_stairs_up(x, y) xchar x, y; { - return ((x == xupstair && y == yupstair) - || (x == g.sstairs.sx && y == g.sstairs.sy && g.sstairs.up) - || (x == xupladder && y == yupladder)); + stairway *stway = stairway_at(x,y); + + return (boolean) (stway && stway->up); } boolean On_stairs_dn(x, y) xchar x, y; { - return ((x == xdnstair && y == ydnstair) - || (x == g.sstairs.sx && y == g.sstairs.sy && !g.sstairs.up) - || (x == xdnladder && y == ydnladder)); + stairway *stway = stairway_at(x,y); + + return (boolean) (stway && !stway->up); } boolean @@ -1599,6 +1734,8 @@ Can_rise_up(x, y, lev) int x, y; d_level *lev; { + stairway *stway = stairway_find_special_dir(FALSE); + /* can't rise up from inside the top of the Wizard's tower */ /* KMH -- or in sokoban */ if (In_endgame(lev) || In_sokoban(lev) @@ -1607,7 +1744,7 @@ d_level *lev; return (boolean) (lev->dlevel > 1 || (g.dungeons[lev->dnum].entry_lev == 1 && ledger_no(lev) != 1 - && g.sstairs.sx && g.sstairs.up)); + && stway && stway->up)); } boolean diff --git a/src/invent.c b/src/invent.c index cfc80f5eb..7c1393d2d 100644 --- a/src/invent.c +++ b/src/invent.c @@ -3362,6 +3362,7 @@ char *buf; int ltyp = lev->typ, cmap = -1; const char *dfeature = 0; static char altbuf[BUFSZ]; + stairway *stway = stairway_at(x,y); if (IS_DOOR(ltyp)) { switch (lev->doormask) { @@ -3402,15 +3403,13 @@ char *buf; a_gname(), align_str(Amask2align(lev->altarmask & ~AM_SHRINE))); dfeature = altbuf; - } else if ((x == xupstair && y == yupstair) - || (x == g.sstairs.sx && y == g.sstairs.sy && g.sstairs.up)) + } else if (stway && !stway->isladder && stway->up) cmap = S_upstair; /* "staircase up" */ - else if ((x == xdnstair && y == ydnstair) - || (x == g.sstairs.sx && y == g.sstairs.sy && !g.sstairs.up)) + else if (stway && !stway->isladder && !stway->up) cmap = S_dnstair; /* "staircase down" */ - else if (x == xupladder && y == yupladder) + else if (stway && stway->isladder && stway->up) cmap = S_upladder; /* "ladder up" */ - else if (x == xdnladder && y == ydnladder) + else if (stway && stway->isladder && !stway->up) cmap = S_dnladder; /* "ladder down" */ else if (ltyp == DRAWBRIDGE_DOWN) cmap = S_vodbridge; /* "lowered drawbridge" */ diff --git a/src/mail.c b/src/mail.c index 423673420..1eeae3118 100644 --- a/src/mail.c +++ b/src/mail.c @@ -151,6 +151,7 @@ coord *startp; int lax; /* if TRUE, pick a position in sight. */ int dd; /* distance to current point */ int max_distance; /* max distance found so far */ + stairway *stway = g.stairs; /* * If blind and not telepathic, then it doesn't matter what we pick --- @@ -166,15 +167,13 @@ coord *startp; * Arrive at an up or down stairwell if it is in line of sight from the * hero. */ - if (couldsee(g.upstair.sx, g.upstair.sy)) { - startp->x = g.upstair.sx; - startp->y = g.upstair.sy; - return TRUE; - } - if (couldsee(g.dnstair.sx, g.dnstair.sy)) { - startp->x = g.dnstair.sx; - startp->y = g.dnstair.sy; - return TRUE; + while (stway) { + if (stway->tolev.dnum == u.uz.dnum && couldsee(stway->sx, stway->sy)) { + startp->x = stway->sx; + startp->y = stway->sy; + return TRUE; + } + stway = stway->next; } /* diff --git a/src/makemon.c b/src/makemon.c index 3af9524ba..abf074fd5 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1095,20 +1095,16 @@ coord *cc; goto gotgood; } if (bl == 0 && (!mon || mon->data->mmove)) { + stairway *stway = g.stairs; /* all map positions are visible (or not good), try to pick something logical */ - if (g.dnstair.sx && !rn2(2)) { - nx = g.dnstair.sx; - ny = g.dnstair.sy; - } else if (g.upstair.sx && !rn2(2)) { - nx = g.upstair.sx; - ny = g.upstair.sy; - } else if (g.dnladder.sx && !rn2(2)) { - nx = g.dnladder.sx; - ny = g.dnladder.sy; - } else if (g.upladder.sx && !rn2(2)) { - nx = g.upladder.sx; - ny = g.upladder.sy; + while (stway) { + if (stway->tolev.dnum == u.uz.dnum && !rn2(2)) { + nx = stway->sx; + ny = stway->sy; + break; + } + stway = stway->next; } if (goodpos(nx, ny, mon, gpflags)) goto gotgood; diff --git a/src/mklev.c b/src/mklev.c index 07feca909..0a030dc4a 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -719,10 +719,7 @@ clear_level_structures() g.doorindex = 0; init_rect(); init_vault(); - xdnstair = ydnstair = xupstair = yupstair = 0; - g.sstairs.sx = g.sstairs.sy = 0; - xdnladder = ydnladder = xupladder = yupladder = 0; - g.dnstairs_room = g.upstairs_room = g.sstairs_room = (struct mkroom *) 0; + stairway_free_all(); g.made_branch = FALSE; clear_regions(); g.xstart = 1; @@ -1112,13 +1109,6 @@ mklev() for (ridx = 0; ridx < SIZE(g.rooms); ridx++) g.rooms[ridx].orig_rtype = g.rooms[ridx].rtype; - /* something like this usually belongs in clear_level_structures() - but these aren't saved and restored so might not retain their - values for the life of the current level; reset them to default - now so that they never do and no one will be tempted to introduce - a new use of them for anything on this level */ - g.dnstairs_room = g.upstairs_room = g.sstairs_room = (struct mkroom *) 0; - reseed_random(rn2); reseed_random(rn2_on_display_rng); } @@ -1262,14 +1252,10 @@ xchar x, y; /* location */ if (br->type == BR_PORTAL) { mkportal(x, y, dest->dnum, dest->dlevel); } else if (make_stairs) { - g.sstairs.sx = x; - g.sstairs.sy = y; - g.sstairs.up = - (char) on_level(&br->end1, &u.uz) ? br->end1_up : !br->end1_up; - assign_level(&g.sstairs.tolev, dest); - g.sstairs_room = br_room; + boolean goes_up = on_level(&br->end1, &u.uz) ? br->end1_up : !br->end1_up; - levl[x][y].ladder = g.sstairs.up ? LA_UP : LA_DOWN; + stairway_add(x,y, goes_up, FALSE, dest); + levl[x][y].ladder = goes_up ? LA_UP : LA_DOWN; levl[x][y].typ = STAIRS; } /* @@ -1633,13 +1619,17 @@ struct mkroom *croom; return; if (up) { - xupstair = x; - yupstair = y; - g.upstairs_room = croom; + d_level dest; + + dest.dnum = u.uz.dnum; + dest.dlevel = u.uz.dlevel - 1; + stairway_add(x,y, TRUE, FALSE, &dest); } else { - xdnstair = x; - ydnstair = y; - g.dnstairs_room = croom; + d_level dest; + + dest.dnum = u.uz.dnum; + dest.dlevel = u.uz.dlevel + 1; + stairway_add(x,y, FALSE, FALSE, &dest); } levl[x][y].typ = STAIRS; @@ -1659,7 +1649,7 @@ struct mkroom *croom; int phase; { return (croom && (croom->needjoining || (phase < 0)) - && ((croom != g.dnstairs_room && croom != g.upstairs_room) + && ((!has_dnstairs(croom) && !has_upstairs(croom)) || phase < 1) && (croom->rtype == OROOM || ((phase < 2) && croom->rtype == THEMEROOM))); diff --git a/src/mkmaze.c b/src/mkmaze.c index 16c92a8e3..4b3e7c588 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -1015,6 +1015,7 @@ const char *s; mazexy(&mm); mkstairs(mm.x, mm.y, 0, (struct mkroom *) 0); /* down */ } else { /* choose "vibrating square" location */ + stairway *stway; int trycnt = 0; #define x_maze_min 2 #define y_maze_min 2 @@ -1047,10 +1048,11 @@ const char *s; to be on a spot that's already in use (wall|trap) */ if (++trycnt > 1000) break; - } while (x == xupstair || y == yupstair /*(direct line)*/ - || abs(x - xupstair) == abs(y - yupstair) - || distmin(x, y, xupstair, yupstair) <= INVPOS_DISTANCE - || !SPACE_POS(levl[x][y].typ) || occupied(x, y)); + } while (((stway = stairway_find_dir(TRUE)) != 0) + && (x == stway->sx || y == stway->sy /*(direct line)*/ + || abs(x - stway->sx) == abs(y - stway->sy) + || distmin(x, y, stway->sx, stway->sy) <= INVPOS_DISTANCE + || !SPACE_POS(levl[x][y].typ) || occupied(x, y))); g.inv_pos.x = x; g.inv_pos.y = y; maketrap(g.inv_pos.x, g.inv_pos.y, VIBRATING_SQUARE); diff --git a/src/mkobj.c b/src/mkobj.c index 7f97bae96..f4960008b 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2130,6 +2130,8 @@ struct obj *obj; obj->where = OBJ_MIGRATING; obj->nobj = g.migrating_objs; + obj->omigr_from_dnum = u.uz.dnum; + obj->omigr_from_dlevel = u.uz.dlevel; g.migrating_objs = obj; } diff --git a/src/mkroom.c b/src/mkroom.c index b8df0ffa5..d1e7c7cbb 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -622,10 +622,13 @@ boolean has_dnstairs(sroom) register struct mkroom *sroom; { - if (sroom == g.dnstairs_room) - return TRUE; - if (g.sstairs.sx && !g.sstairs.up) - return (boolean) (sroom == g.sstairs_room); + stairway *stway = g.stairs; + + while (stway) { + if (!stway->up && inside_room(sroom, stway->sx, stway->sy)) + return TRUE; + stway = stway->next; + } return FALSE; } @@ -633,10 +636,13 @@ boolean has_upstairs(sroom) register struct mkroom *sroom; { - if (sroom == g.upstairs_room) - return TRUE; - if (g.sstairs.sx && g.sstairs.up) - return (boolean) (sroom == g.sstairs_room); + stairway *stway = g.stairs; + + while (stway) { + if (stway->up && inside_room(sroom, stway->sx, stway->sy)) + return TRUE; + stway = stway->next; + } return FALSE; } diff --git a/src/mon.c b/src/mon.c index 44097e221..6ae225d44 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2327,11 +2327,15 @@ register struct monst *mtmp; #endif if (mtmp->data->mlet == S_KOP) { + stairway *stway = stairway_find_type_dir(FALSE, FALSE); + /* Dead Kops may come back. */ switch (rnd(5)) { case 1: /* returns near the stairs */ - (void) makemon(mtmp->data, xdnstair, ydnstair, NO_MM_FLAGS); - break; + if (stway) { + (void) makemon(mtmp->data, stway->sx, stway->sy, NO_MM_FLAGS); + break; + } case 2: /* randomly */ (void) makemon(mtmp->data, 0, 0, NO_MM_FLAGS); break; diff --git a/src/muse.c b/src/muse.c index 360b56482..12e2cb6d6 100644 --- a/src/muse.c +++ b/src/muse.c @@ -336,6 +336,7 @@ struct monst *mtmp; int fraction, x = mtmp->mx, y = mtmp->my; boolean stuck = (mtmp == u.ustuck), immobile = (mtmp->data->mmove == 0); + stairway *stway; if (is_animal(mtmp->data) || mindless(mtmp->data)) return FALSE; @@ -432,23 +433,25 @@ struct monst *mtmp; if (stuck || immobile) { ; /* fleeing by stairs or traps is not possible */ } else if (levl[x][y].typ == STAIRS) { - if (x == xdnstair && y == ydnstair) { + stway = stairway_at(x,y); + if (stway && !stway->up && stway->tolev.dnum == u.uz.dnum) { if (!is_floater(mtmp->data)) g.m.has_defense = MUSE_DOWNSTAIRS; - } else if (x == xupstair && y == yupstair) { + } else if (stway && stway->up && stway->tolev.dnum == u.uz.dnum) { g.m.has_defense = MUSE_UPSTAIRS; - } else if (g.sstairs.sx && x == g.sstairs.sx && y == g.sstairs.sy) { - if (g.sstairs.up || !is_floater(mtmp->data)) + } else if (stway && stway->tolev.dnum != u.uz.dnum) { + if (stway->up || !is_floater(mtmp->data)) g.m.has_defense = MUSE_SSTAIRS; } } else if (levl[x][y].typ == LADDER) { - if (x == xupladder && y == yupladder) { + stway = stairway_at(x,y); + if (stway && stway->up && stway->tolev.dnum == u.uz.dnum) { g.m.has_defense = MUSE_UP_LADDER; - } else if (x == xdnladder && y == ydnladder) { + } else if (stway && !stway->up && stway->tolev.dnum == u.uz.dnum) { if (!is_floater(mtmp->data)) g.m.has_defense = MUSE_DN_LADDER; - } else if (g.sstairs.sx && x == g.sstairs.sx && y == g.sstairs.sy) { - if (g.sstairs.up || !is_floater(mtmp->data)) + } else if (stway && stway->tolev.dnum != u.uz.dnum) { + if (stway->up || !is_floater(mtmp->data)) g.m.has_defense = MUSE_SSTAIRS; } } else { @@ -653,6 +656,7 @@ struct monst *mtmp; struct obj *otmp = g.m.defensive; boolean vis, vismon, oseen; const char *Mnam; + stairway *stway; if ((i = precheck(mtmp, otmp)) != 0) return i; @@ -770,8 +774,7 @@ struct monst *mtmp; if (IS_FURNITURE(levl[mtmp->mx][mtmp->my].typ) || IS_DRAWBRIDGE(levl[mtmp->mx][mtmp->my].typ) || (is_drawbridge_wall(mtmp->mx, mtmp->my) >= 0) - || (g.sstairs.sx && g.sstairs.sx == mtmp->mx - && g.sstairs.sy == mtmp->my)) { + || stairway_at(mtmp->mx, mtmp->my)) { pline_The("digging ray is ineffective."); return 2; } @@ -893,6 +896,9 @@ struct monst *mtmp; return 2; case MUSE_UPSTAIRS: m_flee(mtmp); + stway = stairway_at(mtmp->mx, mtmp->my); + if (!stway) + return 0; if (ledger_no(&u.uz) == 1) goto escape; /* impossible; level 1 upstairs are SSTAIRS */ if (Inhell && mon_has_amulet(mtmp) && !rn2(4) @@ -910,33 +916,45 @@ struct monst *mtmp; } else { if (vismon) pline("%s escapes upstairs!", Monnam(mtmp)); - migrate_to_level(mtmp, ledger_no(&u.uz) - 1, MIGR_STAIRS_DOWN, + migrate_to_level(mtmp, ledger_no(&(stway->tolev)), MIGR_STAIRS_DOWN, (coord *) 0); } return 2; case MUSE_DOWNSTAIRS: m_flee(mtmp); + stway = stairway_at(mtmp->mx, mtmp->my); + if (!stway) + return 0; if (vismon) pline("%s escapes downstairs!", Monnam(mtmp)); - migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_STAIRS_UP, + migrate_to_level(mtmp, ledger_no(&(stway->tolev)), MIGR_STAIRS_UP, (coord *) 0); return 2; case MUSE_UP_LADDER: m_flee(mtmp); + stway = stairway_at(mtmp->mx, mtmp->my); + if (!stway) + return 0; if (vismon) pline("%s escapes up the ladder!", Monnam(mtmp)); - migrate_to_level(mtmp, ledger_no(&u.uz) - 1, MIGR_LADDER_DOWN, + migrate_to_level(mtmp, ledger_no(&(stway->tolev)), MIGR_LADDER_DOWN, (coord *) 0); return 2; case MUSE_DN_LADDER: m_flee(mtmp); + stway = stairway_at(mtmp->mx, mtmp->my); + if (!stway) + return 0; if (vismon) pline("%s escapes down the ladder!", Monnam(mtmp)); - migrate_to_level(mtmp, ledger_no(&u.uz) + 1, MIGR_LADDER_UP, + migrate_to_level(mtmp, ledger_no(&(stway->tolev)), MIGR_LADDER_UP, (coord *) 0); return 2; case MUSE_SSTAIRS: m_flee(mtmp); + stway = stairway_at(mtmp->mx, mtmp->my); + if (!stway) + return 0; if (ledger_no(&u.uz) == 1) { escape: /* Monsters without the Amulet escape the dungeon and @@ -959,12 +977,12 @@ struct monst *mtmp; } if (vismon) pline("%s escapes %sstairs!", Monnam(mtmp), - g.sstairs.up ? "up" : "down"); + stway->up ? "up" : "down"); /* going from the Valley to Castle (Stronghold) has no sstairs to target, but having g.sstairs. == <0,0> will work the same as specifying MIGR_RANDOM when mon_arrive() eventually places the monster, so we can use MIGR_SSTAIRS unconditionally */ - migrate_to_level(mtmp, ledger_no(&g.sstairs.tolev), MIGR_SSTAIRS, + migrate_to_level(mtmp, ledger_no(&(stway->tolev)), MIGR_SSTAIRS, (coord *) 0); return 2; case MUSE_TELEPORT_TRAP: @@ -1223,11 +1241,7 @@ struct monst *mtmp; && !Teleport_control /* do try to move hero to a more vulnerable spot */ && (onscary(u.ux, u.uy, mtmp) - || (u.ux == xupstair && u.uy == yupstair) - || (u.ux == xdnstair && u.uy == ydnstair) - || (u.ux == g.sstairs.sx && u.uy == g.sstairs.sy) - || (u.ux == xupladder && u.uy == yupladder) - || (u.ux == xdnladder && u.uy == ydnladder))) { + || (stairway_at(u.ux, u.uy))) { g.m.offensive = obj; g.m.has_offense = MUSE_WAN_TELEPORTATION; } diff --git a/src/potion.c b/src/potion.c index 4b12acb32..02484db07 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1051,9 +1051,7 @@ register struct obj *otmp; HLevitation &= ~I_SPECIAL; /* can't descend upon demand */ if (BLevitation) { ; /* rising via levitation is blocked */ - } else if ((u.ux == xupstair && u.uy == yupstair) - || (g.sstairs.up && u.ux == g.sstairs.sx && u.uy == g.sstairs.sy) - || (xupladder && u.ux == xupladder && u.uy == yupladder)) { + } else if (stairway_find_dir(TRUE)) { (void) doup(); /* in case we're already Levitating, which would have resulted in incrementing 'nothing' */ diff --git a/src/restore.c b/src/restore.c index 8df518b45..5b933ae19 100644 --- a/src/restore.c +++ b/src/restore.c @@ -905,6 +905,33 @@ NHFILE *nhfp; return 1; } +void +rest_stairs(nhfp) +NHFILE *nhfp; +{ + int buflen = 0; + stairway stway; + int len = 0; + + stairway_free_all(); + while (1) { + if (nhfp->structlevel) { + len += sizeof(buflen); + mread(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); + } + + if (buflen == -1) + break; + + if (nhfp->structlevel) { + len += sizeof(stairway); + mread(nhfp->fd, (genericptr_t) &stway, sizeof(stairway)); + } + + stairway_add(stway.sx, stway.sy, stway.up, stway.isladder, &(stway.tolev)); + } +} + void restcemetery(nhfp, cemeteryaddr) NHFILE *nhfp; @@ -1050,11 +1077,7 @@ xchar lev; elapsed = g.monstermoves - g.omoves; if (nhfp->structlevel) { - mread(nhfp->fd, (genericptr_t)&g.upstair, sizeof(stairway)); - mread(nhfp->fd, (genericptr_t)&g.dnstair, sizeof(stairway)); - mread(nhfp->fd, (genericptr_t)&g.upladder, sizeof(stairway)); - mread(nhfp->fd, (genericptr_t)&g.dnladder, sizeof(stairway)); - mread(nhfp->fd, (genericptr_t)&g.sstairs, sizeof(stairway)); + rest_stairs(nhfp); mread(nhfp->fd, (genericptr_t)&g.updest, sizeof(dest_area)); mread(nhfp->fd, (genericptr_t)&g.dndest, sizeof(dest_area)); mread(nhfp->fd, (genericptr_t)&g.level.flags, sizeof(g.level.flags)); @@ -1132,22 +1155,33 @@ xchar lev; rest_regions(nhfp); if (ghostly) { + stairway *stway = g.stairs; + while (stway) { + if (!stway->isladder && !stway->up && stway->tolev.dnum == u.uz.dnum) + break; + stway = stway->next; + } + /* Now get rid of all the temp fruits... */ freefruitchn(g.oldfruit), g.oldfruit = 0; if (lev > ledger_no(&medusa_level) - && lev < ledger_no(&stronghold_level) && xdnstair == 0) { + && lev < ledger_no(&stronghold_level) && !stway) { coord cc; + d_level dest; + + dest.dnum = u.uz.dnum; + dest.dlevel = u.uz.dlevel + 1; mazexy(&cc); - xdnstair = cc.x; - ydnstair = cc.y; + stairway_add(cc.x, cc.y, FALSE, FALSE, &dest); levl[cc.x][cc.y].typ = STAIRS; } br = Is_branchlev(&u.uz); if (br && u.uz.dlevel == 1) { d_level ltmp; + stairway *stway; if (on_level(&u.uz, &br->end1)) assign_level(<mp, &br->end2); @@ -1157,8 +1191,15 @@ xchar lev; switch (br->type) { case BR_STAIR: case BR_NO_END1: - case BR_NO_END2: /* OK to assign to g.sstairs if it's not used */ - assign_level(&g.sstairs.tolev, <mp); + case BR_NO_END2: + stway = g.stairs; + while (stway) { + if (stway->tolev.dnum != u.uz.dnum) + break; + stway = stway->next; + } + if (stway) + assign_level(&(stway->tolev), <mp); break; case BR_PORTAL: /* max of 1 portal per level */ for (trap = g.ftrap; trap; trap = trap->ntrap) diff --git a/src/save.c b/src/save.c index a15ce5860..586ae177d 100644 --- a/src/save.c +++ b/src/save.c @@ -28,6 +28,7 @@ static void FDECL(savedamage, (NHFILE *)); static void FDECL(saveobj, (NHFILE *,struct obj *)); static void FDECL(savemon, (NHFILE *,struct monst *)); static void FDECL(savelevl, (NHFILE *,BOOLEAN_P)); +static void FDECL(save_stairs, (NHFILE *)); static void FDECL(saveobjchn, (NHFILE *,struct obj *)); static void FDECL(savemonchn, (NHFILE *,struct monst *)); static void FDECL(savetrapchn, (NHFILE *,struct trap *)); @@ -457,11 +458,7 @@ xchar lev; if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) g.lastseentyp, sizeof g.lastseentyp); bwrite(nhfp->fd, (genericptr_t) &g.monstermoves, sizeof g.monstermoves); - bwrite(nhfp->fd, (genericptr_t) &g.upstair, sizeof (stairway)); - bwrite(nhfp->fd, (genericptr_t) &g.dnstair, sizeof (stairway)); - bwrite(nhfp->fd, (genericptr_t) &g.upladder, sizeof (stairway)); - bwrite(nhfp->fd, (genericptr_t) &g.dnladder, sizeof (stairway)); - bwrite(nhfp->fd, (genericptr_t) &g.sstairs, sizeof (stairway)); + save_stairs(nhfp); bwrite(nhfp->fd, (genericptr_t) &g.updest, sizeof (dest_area)); bwrite(nhfp->fd, (genericptr_t) &g.dndest, sizeof (dest_area)); bwrite(nhfp->fd, (genericptr_t) &g.level.flags, sizeof g.level.flags); @@ -496,6 +493,7 @@ xchar lev; fobj = 0; g.level.buriedobjlist = 0; g.billobjs = 0; + stairway_free_all(); /* level.bonesinfo = 0; -- handled by savecemetery() */ } save_engravings(nhfp); @@ -668,6 +666,34 @@ struct obj *otmp; } } +static void +save_stairs(nhfp) +NHFILE *nhfp; +{ + stairway *stway = g.stairs; + int buflen = (int) sizeof (stairway); + int len = 0; + + while (stway) { + if (perform_bwrite(nhfp)) { + if (nhfp->structlevel) { + len += sizeof(buflen); + bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); + len += sizeof(stairway); + bwrite(nhfp->fd, (genericptr_t) stway, sizeof(stairway)); + } + } + stway = stway->next; + } + if (perform_bwrite(nhfp)) { + if (nhfp->structlevel) { + buflen = -1; + len += sizeof(buflen); + bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); + } + } +} + static void saveobjchn(nhfp, otmp) NHFILE *nhfp; diff --git a/src/shk.c b/src/shk.c index 2c7852d10..f393daab9 100644 --- a/src/shk.c +++ b/src/shk.c @@ -362,6 +362,13 @@ register boolean nearshop; { coord mm; + stairway *stway = g.stairs; + + while (stway) { + if (!stway->isladder && !stway->up && stway->tolev.dnum == u.uz.dnum) + break; + stway = stway->next; + } if (nearshop) { /* Create swarm around you, if you merely "stepped out" */ @@ -375,8 +382,8 @@ register boolean nearshop; if (flags.verbose) pline_The("Keystone Kops are after you!"); /* Create swarm near down staircase (hinders return to level) */ - mm.x = xdnstair; - mm.y = ydnstair; + mm.x = stway->sx; + mm.y = stway->sy; makekops(&mm); /* Create swarm near shopkeeper (hinders return to shop) */ mm.x = shkp->mx; diff --git a/src/sp_lev.c b/src/sp_lev.c index f3e2fe1a3..5767744c9 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -60,7 +60,6 @@ static void FDECL(create_object, (object *, struct mkroom *)); static void FDECL(create_altar, (altar *, struct mkroom *)); static boolean FDECL(search_door, (struct mkroom *, xchar *, xchar *, XCHAR_P, int)); -static void NDECL(fix_stair_rooms); static void FDECL(create_corridor, (corridor *)); static struct mkroom *FDECL(build_room, (room *, struct mkroom *)); static void FDECL(light_region, (region *)); @@ -500,6 +499,7 @@ boolean extras; struct mkroom *sroom; timer_element *timer; boolean ball_active = FALSE, ball_fliparea = FALSE; + stairway *stway; /* nothing to do unless (flp & 1) or (flp & 2) or both */ if ((flp & 3) == 0) @@ -537,29 +537,11 @@ boolean extras; } /* stairs and ladders */ - if (flp & 1) { - if (xupstair) - yupstair = FlipY(yupstair); - if (xdnstair) - ydnstair = FlipY(ydnstair); - if (xupladder) - yupladder = FlipY(yupladder); - if (xdnladder) - ydnladder = FlipY(ydnladder); - if (g.sstairs.sx) - g.sstairs.sy = FlipY(g.sstairs.sy); - } - if (flp & 2) { - if (xupstair) - xupstair = FlipX(xupstair); - if (xdnstair) - xdnstair = FlipX(xdnstair); - if (xupladder) - xupladder = FlipX(xupladder); - if (xdnladder) - xdnladder = FlipX(xdnladder); - if (g.sstairs.sx) - g.sstairs.sx = FlipX(g.sstairs.sx); + for (stway = g.stairs; stway; stway = stway->next) { + if (flp & 1) + stway->sy = FlipY(stway->sy); + if (flp & 2) + stway->sx = FlipX(stway->sx); } /* traps */ @@ -2564,52 +2546,6 @@ schar ftyp, btyp; return TRUE; } -/* - * Disgusting hack: since special levels have their rooms filled before - * sorting the rooms, we have to re-arrange the speed values g.upstairs_room - * and g.dnstairs_room after the rooms have been sorted. On normal levels, - * stairs don't get created until _after_ sorting takes place. - */ -static void -fix_stair_rooms() -{ - int i; - struct mkroom *croom; - - if (xdnstair - && !((g.dnstairs_room->lx <= xdnstair - && xdnstair <= g.dnstairs_room->hx) - && (g.dnstairs_room->ly <= ydnstair - && ydnstair <= g.dnstairs_room->hy))) { - for (i = 0; i < g.nroom; i++) { - croom = &g.rooms[i]; - if ((croom->lx <= xdnstair && xdnstair <= croom->hx) - && (croom->ly <= ydnstair && ydnstair <= croom->hy)) { - g.dnstairs_room = croom; - break; - } - } - if (i == g.nroom) - panic("Couldn't find dnstair room in fix_stair_rooms!"); - } - if (xupstair - && !((g.upstairs_room->lx <= xupstair - && xupstair <= g.upstairs_room->hx) - && (g.upstairs_room->ly <= yupstair - && yupstair <= g.upstairs_room->hy))) { - for (i = 0; i < g.nroom; i++) { - croom = &g.rooms[i]; - if ((croom->lx <= xupstair && xupstair <= croom->hx) - && (croom->ly <= yupstair && yupstair <= croom->hy)) { - g.upstairs_room = croom; - break; - } - } - if (i == g.nroom) - panic("Couldn't find upstair room in fix_stair_rooms!"); - } -} - /* * Corridors always start from a door. But it can end anywhere... * Basically we search for door coordinates or for endpoints coordinates @@ -2622,7 +2558,6 @@ corridor *c; coord org, dest; if (c->src.room == -1) { - fix_stair_rooms(); makecorridors(); /*makecorridors(c->src.door);*/ return; } @@ -3933,12 +3868,18 @@ boolean using_ladder; if (using_ladder) { levl[x][y].typ = LADDER; if (up) { - xupladder = x; - yupladder = y; + d_level dest; + + dest.dnum = u.uz.dnum; + dest.dlevel = u.uz.dlevel - 1; + stairway_add(x, y, TRUE, TRUE, &dest); levl[x][y].ladder = LA_UP; } else { - xdnladder = x; - ydnladder = y; + d_level dest; + + dest.dnum = u.uz.dnum; + dest.dlevel = u.uz.dlevel + 1; + stairway_add(x, y, FALSE, TRUE, &dest); levl[x][y].ladder = LA_DOWN; } } else { @@ -5334,17 +5275,15 @@ ensure_way_out() struct trap *ttmp = g.ftrap; int x,y; boolean ret = TRUE; + stairway *stway = g.stairs; set_selection_floodfillchk(floodfillchk_match_accessible); - if (xupstair && !selection_getpoint(xupstair, yupstair, ov)) - selection_floodfill(ov, xupstair, yupstair, TRUE); - if (xdnstair && !selection_getpoint(xdnstair, ydnstair, ov)) - selection_floodfill(ov, xdnstair, ydnstair, TRUE); - if (xupladder && !selection_getpoint(xupladder, yupladder, ov)) - selection_floodfill(ov, xupladder, yupladder, TRUE); - if (xdnladder && !selection_getpoint(xdnladder, ydnladder, ov)) - selection_floodfill(ov, xdnladder, ydnladder, TRUE); + while (stway) { + if (stway->tolev.dnum == u.uz.dnum) + selection_floodfill(ov, stway->sx, stway->sy, TRUE); + stway = stway->next; + } while (ttmp) { if ((ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE diff --git a/src/teleport.c b/src/teleport.c index cb8bb4f40..396ae3b56 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1260,6 +1260,17 @@ register int x, y; make_angry_shk(mtmp, oldx, oldy); } +static stairway * +stairway_find_forwiz(ladder, up) +boolean ladder, up; +{ + stairway *stway = g.stairs; + + while (stway && !(stway->isladder == ladder && stway->up == up && stway->tolev.dnum == u.uz.dnum)) + stway = stway->next; + return stway; +} + /* place a monster at a random location, typically due to teleport */ /* return TRUE if successful, FALSE if not */ boolean @@ -1268,6 +1279,7 @@ struct monst *mtmp; /* mx==0 implies migrating monster arrival */ boolean suppress_impossible; { register int x, y, trycount; + stairway *stway; if (mtmp == u.usteed) { tele(); @@ -1275,12 +1287,19 @@ boolean suppress_impossible; } if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */ - if (!In_W_tower(u.ux, u.uy, &u.uz)) - x = xupstair, y = yupstair; - else if (!xdnladder) /* bottom level of tower */ - x = xupladder, y = yupladder; - else - x = xdnladder, y = ydnladder; + if (!In_W_tower(u.ux, u.uy, &u.uz)) { + stway = stairway_find_forwiz(FALSE, TRUE); + x = stway->sx; + y = stway->sy; + } else if (!stairway_find_forwiz(TRUE, FALSE)) { /* bottom level of tower */ + stway = stairway_find_forwiz(TRUE, TRUE); + x = stway->sx; + y = stway->sy; + } else { + stway = stairway_find_forwiz(TRUE, FALSE); + x = stway->sx; + y = stway->sy; + } /* if the wiz teleports away to heal, try the up staircase, to block the player's escaping before he's healed (deliberately use `goodpos' rather than `rloc_pos_ok' here) */ diff --git a/src/wizard.c b/src/wizard.c index a0b267682..0c6462888 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -329,30 +329,26 @@ xchar *sx; xchar *sy; { xchar x = 0, y = 0; + stairway *stway = g.stairs; + boolean stdir = !builds_up(&u.uz); - if (builds_up(&u.uz)) { - if (xdnstair) { - x = xdnstair; - y = ydnstair; - } else if (xdnladder) { - x = xdnladder; - y = ydnladder; - } + if ((stway = stairway_find_type_dir(FALSE, stdir)) != 0) { + x = stway->sx; + y = stway->sy; + } else if ((stway = stairway_find_type_dir(TRUE, stdir)) != 0) { + x = stway->sx; + y = stway->sy; } else { - if (xupstair) { - x = xupstair; - y = yupstair; - } else if (xupladder) { - x = xupladder; - y = yupladder; + while (stway) { + if (stway->tolev.dnum != u.uz.dnum) { + x = stway->sx; + y = stway->sy; + break; + } + stway = stway->next; } } - if (!x && g.sstairs.sx) { - x = g.sstairs.sx; - y = g.sstairs.sy; - } - if (x && y) { *sx = x; *sy = y; diff --git a/src/zap.c b/src/zap.c index 3910b909a..0494a9fb0 100644 --- a/src/zap.c +++ b/src/zap.c @@ -2891,6 +2891,7 @@ struct obj *obj; /* wand or spell */ struct engr *e; struct trap *ttmp; char buf[BUFSZ]; + stairway *stway = g.stairs; /* some wands have special effects other than normal bhitpile */ /* drawbridge might change */ @@ -2913,11 +2914,16 @@ struct obj *obj; /* wand or spell */ return TRUE; /* we've done our own bhitpile */ case WAN_OPENING: case SPE_KNOCK: + while (stway) { + if (!stway->isladder && !stway->up && stway->tolev.dnum == u.uz.dnum) + break; + stway = stway->next; + } /* up or down, but at closed portcullis only */ if (is_db_wall(x, y) && find_drawbridge(&xx, &yy)) { open_drawbridge(xx, yy); disclose = TRUE; - } else if (u.dz > 0 && (x == xdnstair && y == ydnstair) + } else if (u.dz > 0 && stway && stway->sx == x && stway->sy == y /* can't use the stairs down to quest level 2 until leader "unlocks" them; give feedback if you try */ && on_level(&u.uz, &qstart_level) && !ok_to_quest()) { From 6cbd2c5d85da9630c431da8c9fa390dd5d800ab6 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 13 Nov 2020 14:11:54 -0800 Subject: [PATCH 403/708] warning fixes Using 'ladder' as a variable conflicts with 'struct flag flags' because of a macro in rm.h. Also remove or hide a couple of unused variables. The hack.c diff is unrelated; just a reformatting bit that I had laying around. --- src/dungeon.c | 33 +++++++++++++-------------------- src/hack.c | 7 ++++--- src/mklev.c | 27 ++++++++++----------------- src/restore.c | 15 ++++++++------- src/teleport.c | 9 +++++---- 5 files changed, 40 insertions(+), 51 deletions(-) diff --git a/src/dungeon.c b/src/dungeon.c index 32e1ea4c6..f27f0cae2 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dungeon.c $NHDT-Date: 1604173730 2020/10/31 19:48:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ +/* NetHack 3.7 dungeon.c $NHDT-Date: 1605305480 2020/11/13 22:11:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1499,9 +1499,9 @@ int upflag; } void -stairway_add(x,y, up, ladder, dest) -int x,y; -boolean up, ladder; +stairway_add(x, y, up, isladder, dest) +int x, y; +boolean up, isladder; d_level *dest; { stairway *tmp = (stairway *)alloc(sizeof(stairway)); @@ -1509,7 +1509,7 @@ d_level *dest; tmp->sx = x; tmp->sy = y; tmp->up = up; - tmp->isladder = ladder; + tmp->isladder = isladder; assign_level(&(tmp->tolev), dest); tmp->next = g.stairs; g.stairs = tmp; @@ -1536,7 +1536,6 @@ int x,y; while (tmp && !(tmp->sx == x && tmp->sy == y)) tmp = tmp->next; - return tmp; } @@ -1549,28 +1548,26 @@ d_level *fromdlev; while (tmp) { if (tmp->tolev.dnum == fromdlev->dnum && tmp->tolev.dlevel == fromdlev->dlevel) - return tmp; + break; /* return */ tmp = tmp->next; } - return tmp; } stairway * -stairway_find_from(fromdlev, ladder) +stairway_find_from(fromdlev, isladder) d_level *fromdlev; -boolean ladder; +boolean isladder; { stairway *tmp = g.stairs; while (tmp) { if (tmp->tolev.dnum == fromdlev->dnum && tmp->tolev.dlevel == fromdlev->dlevel - && tmp->isladder == ladder) - return tmp; + && tmp->isladder == isladder) + break; /* return */ tmp = tmp->next; } - return tmp; } @@ -1582,7 +1579,6 @@ boolean up; while (tmp && !(tmp->up == up)) tmp = tmp->next; - return tmp; } @@ -1593,19 +1589,17 @@ stairway_find_ladder() while (tmp && !tmp->isladder) tmp = tmp->next; - return tmp; } stairway * -stairway_find_type_dir(ladder,up) -boolean ladder, up; +stairway_find_type_dir(isladder, up) +boolean isladder, up; { stairway *tmp = g.stairs; - while (tmp && !(tmp->isladder == ladder && tmp->up == up)) + while (tmp && !(tmp->isladder == isladder && tmp->up == up)) tmp = tmp->next; - return tmp; } @@ -1620,7 +1614,6 @@ boolean up; return tmp; tmp = tmp->next; } - return tmp; } diff --git a/src/hack.c b/src/hack.c index 0e8efb024..f50538ada 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1603507385 2020/10/24 02:43:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.269 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1605305491 2020/11/13 22:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2991,12 +2991,13 @@ monster_nearby() for (y = u.uy - 1; y <= u.uy + 1; y++) { if (!isok(x, y) || (x == u.ux && y == u.uy)) continue; - if ((mtmp = m_at(x, y)) && M_AP_TYPE(mtmp) != M_AP_FURNITURE + if ((mtmp = m_at(x, y)) != 0 + && M_AP_TYPE(mtmp) != M_AP_FURNITURE && M_AP_TYPE(mtmp) != M_AP_OBJECT && (Hallucination || (!mtmp->mpeaceful && !noattacks(mtmp->data))) && (!is_hider(mtmp->data) || !mtmp->mundetected) - && mtmp->mcanmove && !mtmp->msleeping /* aplvax!jcn */ + && mtmp->mcanmove && !mtmp->msleeping && !onscary(u.ux, u.uy, mtmp) && canspotmon(mtmp)) return 1; } diff --git a/src/mklev.c b/src/mklev.c index 0a030dc4a..bfb0c085c 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mklev.c $NHDT-Date: 1596498181 2020/08/03 23:43:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 3.7 mklev.c $NHDT-Date: 1605305491 2020/11/13 22:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.96 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Alex Smith, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1252,7 +1252,8 @@ xchar x, y; /* location */ if (br->type == BR_PORTAL) { mkportal(x, y, dest->dnum, dest->dlevel); } else if (make_stairs) { - boolean goes_up = on_level(&br->end1, &u.uz) ? br->end1_up : !br->end1_up; + boolean goes_up = on_level(&br->end1, &u.uz) ? br->end1_up + : !br->end1_up; stairway_add(x,y, goes_up, FALSE, dest); levl[x][y].ladder = goes_up ? LA_UP : LA_DOWN; @@ -1601,9 +1602,11 @@ coord *tm; void mkstairs(x, y, up, croom) xchar x, y; -char up; -struct mkroom *croom; +char up; /* [why 'char' when usage is boolean?] */ +struct mkroom *croom UNUSED; { + d_level dest; + if (!x) { impossible("mkstairs: bogus stair attempt at <%d,%d>", x, y); return; @@ -1618,19 +1621,9 @@ struct mkroom *croom; || (dunlev(&u.uz) == dunlevs_in_dungeon(&u.uz) && !up)) return; - if (up) { - d_level dest; - - dest.dnum = u.uz.dnum; - dest.dlevel = u.uz.dlevel - 1; - stairway_add(x,y, TRUE, FALSE, &dest); - } else { - d_level dest; - - dest.dnum = u.uz.dnum; - dest.dlevel = u.uz.dlevel + 1; - stairway_add(x,y, FALSE, FALSE, &dest); - } + dest.dnum = u.uz.dnum; + dest.dlevel = u.uz.dlevel + (up ? -1 : 1); + stairway_add(x, y, up ? TRUE : FALSE, FALSE, &dest); levl[x][y].typ = STAIRS; levl[x][y].ladder = up ? LA_UP : LA_DOWN; diff --git a/src/restore.c b/src/restore.c index 5b933ae19..3ca9c0e2a 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 restore.c $NHDT-Date: 1604513828 2020/11/04 18:17:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.169 $ */ +/* NetHack 3.7 restore.c $NHDT-Date: 1605305492 2020/11/13 22:11:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.171 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -916,7 +916,7 @@ NHFILE *nhfp; stairway_free_all(); while (1) { if (nhfp->structlevel) { - len += sizeof(buflen); + len += (int) sizeof(buflen); mread(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); } @@ -924,11 +924,12 @@ NHFILE *nhfp; break; if (nhfp->structlevel) { - len += sizeof(stairway); - mread(nhfp->fd, (genericptr_t) &stway, sizeof(stairway)); + len += (int) sizeof (stairway); + mread(nhfp->fd, (genericptr_t) &stway, sizeof (stairway)); } - stairway_add(stway.sx, stway.sy, stway.up, stway.isladder, &(stway.tolev)); + stairway_add(stway.sx, stway.sy, stway.up, stway.isladder, + &(stway.tolev)); } } @@ -1157,7 +1158,8 @@ xchar lev; if (ghostly) { stairway *stway = g.stairs; while (stway) { - if (!stway->isladder && !stway->up && stway->tolev.dnum == u.uz.dnum) + if (!stway->isladder && !stway->up + && stway->tolev.dnum == u.uz.dnum) break; stway = stway->next; } @@ -1181,7 +1183,6 @@ xchar lev; br = Is_branchlev(&u.uz); if (br && u.uz.dlevel == 1) { d_level ltmp; - stairway *stway; if (on_level(&u.uz, &br->end1)) assign_level(<mp, &br->end2); diff --git a/src/teleport.c b/src/teleport.c index 396ae3b56..48a720296 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 teleport.c $NHDT-Date: 1600468454 2020/09/18 22:34:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */ +/* NetHack 3.7 teleport.c $NHDT-Date: 1605305493 2020/11/13 22:11:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1261,12 +1261,13 @@ register int x, y; } static stairway * -stairway_find_forwiz(ladder, up) -boolean ladder, up; +stairway_find_forwiz(isladder, up) +boolean isladder, up; { stairway *stway = g.stairs; - while (stway && !(stway->isladder == ladder && stway->up == up && stway->tolev.dnum == u.uz.dnum)) + while (stway && !(stway->isladder == isladder + && stway->up == up && stway->tolev.dnum == u.uz.dnum)) stway = stway->next; return stway; } From e647eab6dc898e9d7cde1534c362e7d0d1b8d6d2 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 13 Nov 2020 16:52:45 -0800 Subject: [PATCH 404/708] fix github issue #410 - mon throwing c'trice egg If a monster threw a cocktrice egg that hit and petrified another monster, the hero would credit (experience) and blame (possible alignment penalty, &c) for it. Fixes #410 --- doc/fixes37.0 | 4 +++- src/mthrowu.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 34885e5c8..390364630 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.350 $ $NHDT-Date: 1605184219 2020/11/12 12:30:19 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.352 $ $NHDT-Date: 1605315160 2020/11/14 00:52:40 $ General Fixes and Modified Features ----------------------------------- @@ -293,6 +293,8 @@ attacking non-adjacent concealed mimic by applying a polearm would make the hero could break a wand ("raising the wand high over your head, you break it in two") even if hands were welded to a two-handed weapon or to a one-handed weapon and also to a shield +if a monster threw a cocktrice egg at the hero but hit and petrified another + monster, the hero would get credit/blame for killing it Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mthrowu.c b/src/mthrowu.c index 4bae7d788..66ef9d949 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mthrowu.c $NHDT-Date: 1596498189 2020/08/03 23:43:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.102 $ */ +/* NetHack 3.7 mthrowu.c $NHDT-Date: 1605315160 2020/11/14 00:52:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.103 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -395,8 +395,8 @@ boolean verbose; /* give message(s) even when you can't see what happened */ } } if (otmp->otyp == EGG && touch_petrifies(&mons[otmp->corpsenm])) { - if (!munstone(mtmp, TRUE)) - minstapetrify(mtmp, TRUE); + if (!munstone(mtmp, FALSE)) + minstapetrify(mtmp, FALSE); if (resists_ston(mtmp)) damage = 0; } From 08310c8a71a1002057bf3cdea72241c5cd083a8d Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 13 Nov 2020 17:15:04 -0800 Subject: [PATCH 405/708] Qt status Try to set the initial window sizes to be big enough to show the full welcome line in the message window when the Qt settings (Preferences on OSX) specify Large font (Huge/Medium/Small/Tiny seemed ok but I wasn't systematic about checking them). While at it, I added a long comment about the status window format and noticed a bug with experience formatting there. Again only seemed to matter for Large font but the change to fix ignores font size. Plus add a couple of Qt "issues", one old and one just discovered. --- doc/fixes37.0 | 4 +++- win/Qt/Qt-issues.txt | 11 ++++++++++ win/Qt/qt_main.cpp | 14 +++++++++++-- win/Qt/qt_stat.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 390364630..52d629f10 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.352 $ $NHDT-Date: 1605315160 2020/11/14 00:52:40 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.353 $ $NHDT-Date: 1605316497 2020/11/14 01:14:57 $ General Fixes and Modified Features ----------------------------------- @@ -385,6 +385,8 @@ tins of spinach and 'dead' eggs could cause out of array bounds access curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support +Qt: at Xp levels above 20 with 'showexp' On, the combined status field + "Level:NN/nnnnnnnn" was too big and truncated by a char at each end tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display tty: previous change resulted in remnants of previous level being shown on diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index b25adff97..c38fca661 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -59,4 +59,15 @@ code into its own routine and calling that for both types of windows. From the text window code, it sees the initial shift but not the ':' that should follow. +Clicking on window close button pops up a confirmation dialog with + [ Save and exit ] [__Quit_without_saving__] +with the second one highlighted. Internally they're specified as +"&Save" and "&Quit". Typing or picks Quit, but +typing 'Q' or 'q' picks Save-and-exit because Alt+Q is expected for +the keyboard shortcut. + +The status window can't be resized while hitpointbar is active. +Toggling it off, resizing as desired, then toggling it back on is a +viable workaround. + ----- diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 00765d8a9..69a2729dc 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1138,6 +1138,16 @@ void NetHackQtMainWindow::layout() // call resizePaperDoll() indirectly... qt_settings->resizeDoll(); #endif + // reset widths + int w = width(); /* of main window */ + // 10: approximate size of resizing hotspots + int d = qt_settings->doll_is_shown ? 10 + invusage->width() + 10 : 10; + if (d % 4) + d += 4 - d % 4; + splittersizes[2] = w / 2 - (d * 1 / 4); // status + splittersizes[1] = d - 10; // invusage + splittersizes[0] = w / 2 - (d * 3 / 4); // messages + hsplitter->setSizes(splittersizes); } } @@ -1162,8 +1172,8 @@ void NetHackQtMainWindow::resizePaperDoll(bool showdoll) hsplitter->setSizes(hsplittersizes); } - // Height limit is 48 pixels per doll cell; - // values greater than 44 need taller window which pushes the map down. + // Height limit is 48+2 pixels per doll cell plus 1 pixel margin at top; + // values greater than 42+2 need taller window which pushes the map down. // FIXME: this doesn't shrink the window back if size is reduced from 45+ int oldheight = vsplittersizes[0], newheight = w->height(); diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 7b918e070..deadd798f 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -3,6 +3,43 @@ // NetHack may be freely redistributed. See license for details. // qt_stat.cpp -- status window, upper right portion of the overall window +// +// The Qt status window consists of many lines: +// +// hitpoint bar (when enabled) +// Title (plname the Rank or plname the MonsterSpecies) +// Dungeon location (branch and level) +// separator line +// six icons (special 40x40 tiles, paired with...) +// six characteristic texts ("Str:18/03", "Dex:15", &c) +// separator line +// five status fields without icons (some containing two values: +// Gold, HP/HPmax, Energy/Enmax, AC, XpLevel/ExpPoints or HD) +// optional line with two text fields (Time:1234, Score:89) +// separator line +// varying number of icons (one or more, each paired with...) +// corresponding text (Alignment plus zero or more status conditions +// including Hunger if not "normal" and encumbrance if not "normal") +// +// The hitpoint bar spans the width of the status window when enabled. +// Title and location are centered. +// The icons and text for the size characteristics are evenly spaced. +// The five main stats are padded with an empty sixth and spaced to +// match the characteristics. +// Time and Score are spaced as if each were three fields wide. +// Icons and texts for alignment and conditions are left justified. +// The separator lines are thin and don't take up much vertical space. +// The hitpoint bar line and the Time+Score line are omitted when the +// corresponding items are disabled. +// +// FIXME: +// When hitpoint bar is shown, attempting to resize horizontally won't +// do anything. Toggling it off, then resizing, and back On works. +// +// TODO: +// If/when status conditions become too wide for the status window, scale +// down their icons and switch their text to a smaller font to match. +// extern "C" { #include "hack.h" @@ -23,6 +60,8 @@ extern "C" { extern const char *enc_stat[]; /* from botl.c */ extern const char *hu_stat[]; /* from eat.c */ +extern int qt_compact_mode; + namespace nethack_qt_ { NetHackQtStatusWindow::NetHackQtStatusWindow() : @@ -67,6 +106,11 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : first_set(true), alreadyfullhp(false) { + if (!qt_compact_mode) { + int w = NetHackQtBind::mainWidget()->width(); + setMaximumWidth(w / 2); + } + p_str = QPixmap(str_xpm); p_str = QPixmap(str_xpm); p_dex = QPixmap(dex_xpm); @@ -648,7 +692,11 @@ void NetHackQtStatusWindow::updateStats() // up/down highlighting becomes tricky--don't try very hard if (::flags.showexp) { buf.sprintf("%ld/%ld", (long) u.ulevel, (long) u.uexp); - level.setLabel("Level:" + buf, + // at levels above 20, "Level:NN/nnnnnnnn" doesn't fit so + // shorten "Level" to "Lvl" at that stage; + // at level 30, a few pixels are truncated from the start + // and end of "Lvl:30/nnnnnnnnn" but the result is ledgible + level.setLabel(((u.ulevel <= 20) ? "Level:" : "Lvl:") + buf, NetHackQtLabelledIcon::NoNum, (long) u.uexp); } else { level.setLabel("Level:", (long) u.ulevel); From 289c8d654d9fddcc922aa1cb73b07e635ed3e9be Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 14 Nov 2020 13:41:31 +0200 Subject: [PATCH 406/708] Futureproofing hypothetical type mismatches If we ever want huge maps with COLNO or ROWNO larger than signed char, this will at least allow the game to compile and start when typedef'ing xchar to int. Trying to use huge maps exposes more bugs. --- include/decl.h | 12 ++--- include/extern.h | 4 +- include/mkroom.h | 2 +- include/patchlevel.h | 2 +- src/light.c | 10 ++--- src/nhlsel.c | 101 ++++++++++++++++++++----------------------- src/sp_lev.c | 37 ++++++++-------- src/vision.c | 100 +++++++++++++++++++++--------------------- 8 files changed, 130 insertions(+), 138 deletions(-) diff --git a/include/decl.h b/include/decl.h index dc1039c22..87000f88c 100644 --- a/include/decl.h +++ b/include/decl.h @@ -803,8 +803,8 @@ struct instance_globals { /* display.c */ gbuf_entry gbuf[ROWNO][COLNO]; - char gbuf_start[ROWNO]; - char gbuf_stop[ROWNO]; + xchar gbuf_start[ROWNO]; + xchar gbuf_stop[ROWNO]; /* do.c */ @@ -828,7 +828,7 @@ struct instance_globals { int petname_used; /* user preferred pet name has been used */ xchar gtyp; /* type of dog's current goal */ xchar gx; /* x position of dog's current goal */ - char gy; /* y position of dog's current goal */ + xchar gy; /* y position of dog's current goal */ char dogname[PL_PSIZ]; char catname[PL_PSIZ]; char horsename[PL_PSIZ]; @@ -1169,9 +1169,9 @@ struct instance_globals { Stormbringer's maliciousness. */ /* vision.c */ - char **viz_array; /* used in cansee() and couldsee() macros */ - char *viz_rmin; /* min could see indices */ - char *viz_rmax; /* max could see indices */ + xchar **viz_array; /* used in cansee() and couldsee() macros */ + xchar *viz_rmin; /* min could see indices */ + xchar *viz_rmax; /* max could see indices */ boolean vision_full_recalc; /* weapon.c */ diff --git a/include/extern.h b/include/extern.h index 9280b47b6..74de4f1e7 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1119,7 +1119,7 @@ E int NDECL(dosuspend); E void FDECL(new_light_source, (XCHAR_P, XCHAR_P, int, int, ANY_P *)); E void FDECL(del_light_source, (int, ANY_P *)); -E void FDECL(do_light_sources, (char **)); +E void FDECL(do_light_sources, (xchar **)); E void FDECL(show_transient_light, (struct obj *, int, int)); E void NDECL(transient_light_cleanup); E struct monst *FDECL(find_mid, (unsigned, unsigned)); @@ -2497,7 +2497,7 @@ E void FDECL(set_selection_floodfillchk, (int FDECL((*), (int,int)))); E void FDECL(selection_floodfill, (struct selectionvar *, int, int, BOOLEAN_P)); E boolean FDECL(pm_good_location, (int, int, struct permonst *)); -E void FDECL(get_location_coord, (schar *, schar *, int, struct mkroom *, +E void FDECL(get_location_coord, (xchar *, xchar *, int, struct mkroom *, long)); E void FDECL(selection_setpoint, (int, int, struct selectionvar *, XCHAR_P)); E struct selectionvar * FDECL(selection_not, (struct selectionvar *)); diff --git a/include/mkroom.h b/include/mkroom.h index e707aa695..07d2318aa 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -9,7 +9,7 @@ /* mkroom.h - types and structures for room and shop initialization */ struct mkroom { - schar lx, hx, ly, hy; /* usually xchar, but hx may be -1 */ + xchar lx, hx, ly, hy; /* usually xchar, but hx may be -1 */ schar rtype; /* type of room (zoo, throne, etc...) */ schar orig_rtype; /* same as rtype, but not zeroed later */ schar rlit; /* is the room lit ? */ diff --git a/include/patchlevel.h b/include/patchlevel.h index 0ca768ddb..5e1557d79 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 25 +#define EDITLEVEL 26 /* * Development status possibilities. diff --git a/src/light.c b/src/light.c index 02ddaf03f..26f832777 100644 --- a/src/light.c +++ b/src/light.c @@ -48,8 +48,8 @@ static void FDECL(write_ls, (NHFILE *, light_source *)); static int FDECL(maybe_write_ls, (NHFILE *, int, BOOLEAN_P)); /* imported from vision.c, for small circles */ -extern char circle_data[]; -extern char circle_start[]; +extern xchar circle_data[]; +extern xchar circle_start[]; /* Create a new light source. Caller (and extern.h) doesn't need to know @@ -144,13 +144,13 @@ anything *id; /* Mark locations that are temporarily lit via mobile light sources. */ void do_light_sources(cs_rows) -char **cs_rows; +xchar **cs_rows; { int x, y, min_x, max_x, max_y, offset; - char *limits; + xchar *limits; short at_hero_range = 0; light_source *ls; - char *row; + xchar *row; for (ls = g.light_base; ls; ls = ls->next) { ls->flags &= ~LSF_SHOW; diff --git a/src/nhlsel.c b/src/nhlsel.c index 26edad483..953b7c241 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -14,7 +14,7 @@ static int FDECL(l_selection_not, (lua_State *)); static int FDECL(l_selection_filter_percent, (lua_State *)); static int FDECL(l_selection_rndcoord, (lua_State *)); static boolean FDECL(params_sel_2coords, (lua_State *, struct selectionvar **, - schar *, schar *, schar *, schar *)); + xchar *, xchar *, xchar *, xchar *)); static int FDECL(l_selection_line, (lua_State *)); static int FDECL(l_selection_randline, (lua_State *)); static int FDECL(l_selection_rect, (lua_State *)); @@ -143,7 +143,7 @@ l_selection_setpoint(L) lua_State *L; { struct selectionvar *sel = (struct selectionvar *) 0; - schar x = -1, y = -1; + xchar x = -1, y = -1; int val = 1; int argc = lua_gettop(L); long crd = 0L; @@ -153,15 +153,15 @@ lua_State *L; } else if (argc == 1) { sel = l_selection_check(L, 1); } else if (argc == 2) { - x = (schar) luaL_checkinteger(L, 1); - y = (schar) luaL_checkinteger(L, 2); + x = (xchar) luaL_checkinteger(L, 1); + y = (xchar) luaL_checkinteger(L, 2); lua_pop(L, 2); (void) l_selection_new(L); sel = l_selection_check(L, 1); } else { sel = l_selection_check(L, 1); - x = (schar) luaL_checkinteger(L, 2); - y = (schar) luaL_checkinteger(L, 3); + x = (xchar) luaL_checkinteger(L, 2); + y = (xchar) luaL_checkinteger(L, 3); val = (int) luaL_optinteger(L, 4, 1); } @@ -188,8 +188,8 @@ l_selection_getpoint(L) lua_State *L; { struct selectionvar *sel = l_selection_check(L, 1); - schar x = (schar) luaL_checkinteger(L, 2); - schar y = (schar) luaL_checkinteger(L, 3); + xchar x = (xchar) luaL_checkinteger(L, 2); + xchar y = (xchar) luaL_checkinteger(L, 3); int val; long crd; @@ -344,16 +344,16 @@ static boolean params_sel_2coords(L, sel, x1,y1, x2,y2) lua_State *L; struct selectionvar **sel; -schar *x1, *y1, *x2, *y2; +xchar *x1, *y1, *x2, *y2; { int argc = lua_gettop(L); if (argc == 4) { (void) l_selection_new(L); - *x1 = (schar) luaL_checkinteger(L, 1); - *y1 = (schar) luaL_checkinteger(L, 2); - *x2 = (schar) luaL_checkinteger(L, 3); - *y2 = (schar) luaL_checkinteger(L, 4); + *x1 = (xchar) luaL_checkinteger(L, 1); + *y1 = (xchar) luaL_checkinteger(L, 2); + *x2 = (xchar) luaL_checkinteger(L, 3); + *y2 = (xchar) luaL_checkinteger(L, 4); *sel = l_selection_check(L, 5); lua_remove(L, 1); lua_remove(L, 1); @@ -362,10 +362,10 @@ schar *x1, *y1, *x2, *y2; return TRUE; } else if (argc == 5) { *sel = l_selection_check(L, 1); - *x1 = (schar) luaL_checkinteger(L, 2); - *y1 = (schar) luaL_checkinteger(L, 3); - *x2 = (schar) luaL_checkinteger(L, 4); - *y2 = (schar) luaL_checkinteger(L, 5); + *x1 = (xchar) luaL_checkinteger(L, 2); + *y1 = (xchar) luaL_checkinteger(L, 3); + *x2 = (xchar) luaL_checkinteger(L, 4); + *y2 = (xchar) luaL_checkinteger(L, 5); lua_pop(L, 4); return TRUE; } @@ -380,10 +380,7 @@ l_selection_line(L) lua_State *L; { struct selectionvar *sel = NULL; - schar x1; - schar y1; - schar x2; - schar y2; + xchar x1, y1, x2, y2; if (!params_sel_2coords(L, &sel, &x1, &y1, &x2, &y2)) { nhl_error(L, "selection.line: illegal arguments"); @@ -404,10 +401,7 @@ l_selection_rect(L) lua_State *L; { struct selectionvar *sel = NULL; - schar x1; - schar y1; - schar x2; - schar y2; + xchar x1, y1, x2, y2; if (!params_sel_2coords(L, &sel, &x1, &y1, &x2, &y2)) { nhl_error(L, "selection.rect: illegal arguments"); @@ -437,10 +431,7 @@ lua_State *L; { struct selectionvar *sel = NULL; int y; - schar x1; - schar y1; - schar x2; - schar y2; + xchar x1, y1, x2, y2; if (!params_sel_2coords(L, &sel, &x1, &y1, &x2, &y2)) { nhl_error(L, "selection.fillrect: illegal arguments"); @@ -473,22 +464,22 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - schar x1, y1, x2, y2; + xchar x1, y1, x2, y2; int roughness = 7; if (argc == 6) { sel = l_selection_check(L, 1); - x1 = (schar) luaL_checkinteger(L, 2); - y1 = (schar) luaL_checkinteger(L, 3); - x2 = (schar) luaL_checkinteger(L, 4); - y2 = (schar) luaL_checkinteger(L, 5); + x1 = (xchar) luaL_checkinteger(L, 2); + y1 = (xchar) luaL_checkinteger(L, 3); + x2 = (xchar) luaL_checkinteger(L, 4); + y2 = (xchar) luaL_checkinteger(L, 5); roughness = (int) luaL_checkinteger(L, 6); lua_pop(L, 5); } else if (argc == 5 && lua_type(L, 1) == LUA_TNUMBER) { - x1 = (schar) luaL_checkinteger(L, 1); - y1 = (schar) luaL_checkinteger(L, 2); - x2 = (schar) luaL_checkinteger(L, 3); - y2 = (schar) luaL_checkinteger(L, 4); + x1 = (xchar) luaL_checkinteger(L, 1); + y1 = (xchar) luaL_checkinteger(L, 2); + x2 = (xchar) luaL_checkinteger(L, 3); + y2 = (xchar) luaL_checkinteger(L, 4); roughness = (int) luaL_checkinteger(L, 5); lua_pop(L, 5); (void) l_selection_new(L); @@ -610,11 +601,11 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - schar x, y; + xchar x, y; if (argc == 2) { - x = (schar) luaL_checkinteger(L, 1); - y = (schar) luaL_checkinteger(L, 2); + x = (xchar) luaL_checkinteger(L, 1); + y = (xchar) luaL_checkinteger(L, 2); lua_pop(L, 2); (void) l_selection_new(L); sel = l_selection_check(L, 1); @@ -644,20 +635,20 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - schar x = 0, y = 0; + xchar x = 0, y = 0; int r = 0, filled = 0; if (argc == 3) { - x = (schar) luaL_checkinteger(L, 1); - y = (schar) luaL_checkinteger(L, 2); + x = (xchar) luaL_checkinteger(L, 1); + y = (xchar) luaL_checkinteger(L, 2); r = (int) luaL_checkinteger(L, 3); lua_pop(L, 3); (void) l_selection_new(L); sel = l_selection_check(L, 1); filled = 0; } else if (argc == 4 && lua_type(L, 1) == LUA_TNUMBER) { - x = (schar) luaL_checkinteger(L, 1); - y = (schar) luaL_checkinteger(L, 2); + x = (xchar) luaL_checkinteger(L, 1); + y = (xchar) luaL_checkinteger(L, 2); r = (int) luaL_checkinteger(L, 3); filled = (int) luaL_checkinteger(L, 4); /* TODO: boolean*/ lua_pop(L, 4); @@ -665,8 +656,8 @@ lua_State *L; sel = l_selection_check(L, 1); } else if (argc == 4 || argc == 5) { sel = l_selection_check(L, 1); - x = (schar) luaL_checkinteger(L, 2); - y = (schar) luaL_checkinteger(L, 3); + x = (xchar) luaL_checkinteger(L, 2); + y = (xchar) luaL_checkinteger(L, 3); r = (int) luaL_checkinteger(L, 4); filled = (int) luaL_optinteger(L, 5, 0); /* TODO: boolean */ } else { @@ -693,12 +684,12 @@ lua_State *L; { int argc = lua_gettop(L); struct selectionvar *sel = (struct selectionvar *) 0; - schar x = 0, y = 0; + xchar x = 0, y = 0; int r1 = 0, r2 = 0, filled = 0; if (argc == 4) { - x = (schar) luaL_checkinteger(L, 1); - y = (schar) luaL_checkinteger(L, 2); + x = (xchar) luaL_checkinteger(L, 1); + y = (xchar) luaL_checkinteger(L, 2); r1 = (int) luaL_checkinteger(L, 3); r2 = (int) luaL_checkinteger(L, 4); lua_pop(L, 4); @@ -706,8 +697,8 @@ lua_State *L; sel = l_selection_check(L, 1); filled = 0; } else if (argc == 5 && lua_type(L, 1) == LUA_TNUMBER) { - x = (schar) luaL_checkinteger(L, 1); - y = (schar) luaL_checkinteger(L, 2); + x = (xchar) luaL_checkinteger(L, 1); + y = (xchar) luaL_checkinteger(L, 2); r1 = (int) luaL_checkinteger(L, 3); r2 = (int) luaL_checkinteger(L, 4); filled = (int) luaL_optinteger(L, 5, 0); /* TODO: boolean */ @@ -716,8 +707,8 @@ lua_State *L; sel = l_selection_check(L, 1); } else if (argc == 5 || argc == 6) { sel = l_selection_check(L, 1); - x = (schar) luaL_checkinteger(L, 2); - y = (schar) luaL_checkinteger(L, 3); + x = (xchar) luaL_checkinteger(L, 2); + y = (xchar) luaL_checkinteger(L, 3); r1 = (int) luaL_checkinteger(L, 4); r2 = (int) luaL_checkinteger(L, 5); filled = (int) luaL_optinteger(L, 6, 0); /* TODO: boolean */ diff --git a/src/sp_lev.c b/src/sp_lev.c index 5767744c9..c03d08f26 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -42,11 +42,11 @@ static void FDECL(maybe_add_door, (int, int, struct mkroom *)); static void NDECL(link_doors_rooms); static int NDECL(rnddoor); static int NDECL(rndtrap); -static void FDECL(get_location, (schar *, schar *, int, struct mkroom *)); +static void FDECL(get_location, (xchar *, xchar *, int, struct mkroom *)); static boolean FDECL(is_ok_location, (SCHAR_P, SCHAR_P, int)); static unpacked_coord FDECL(get_unpacked_coord, (long, int)); -static void FDECL(get_room_loc, (schar *, schar *, struct mkroom *)); -static void FDECL(get_free_room_loc, (schar *, schar *, +static void FDECL(get_room_loc, (xchar *, xchar *, struct mkroom *)); +static void FDECL(get_free_room_loc, (xchar *, xchar *, struct mkroom *, packed_coord)); static boolean FDECL(create_subroom, (struct mkroom *, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); @@ -1075,7 +1075,7 @@ rndtrap() */ static void get_location(x, y, humidity, croom) -schar *x, *y; +xchar *x, *y; int humidity; struct mkroom *croom; { @@ -1207,7 +1207,7 @@ int defhumidity; void get_location_coord(x, y, humidity, croom, crd) -schar *x, *y; +xchar *x, *y; int humidity; struct mkroom *croom; long crd; @@ -1230,7 +1230,7 @@ long crd; static void get_room_loc(x, y, croom) -schar *x, *y; +xchar *x, *y; struct mkroom *croom; { coord c; @@ -1257,11 +1257,11 @@ struct mkroom *croom; */ static void get_free_room_loc(x, y, croom, pos) -schar *x, *y; +xchar *x, *y; struct mkroom *croom; packed_coord pos; { - schar try_x, try_y; + xchar try_x, try_y; register int trycnt = 0; get_location_coord(&try_x, &try_y, DRY, croom, pos); @@ -1741,7 +1741,7 @@ create_trap(t, croom) spltrap *t; struct mkroom *croom; { - schar x = -1, y = -1; + xchar x = -1, y = -1; coord tm; if (croom) { @@ -1825,7 +1825,7 @@ monster *m; struct mkroom *croom; { struct monst *mtmp; - schar x, y; + xchar x, y; char class; aligntyp amask; coord cc; @@ -2088,7 +2088,7 @@ object *o; struct mkroom *croom; { struct obj *otmp; - schar x, y; + xchar x, y; char c; boolean named; /* has a name been supplied in level description? */ @@ -2324,7 +2324,8 @@ create_altar(a, croom) altar *a; struct mkroom *croom; { - schar sproom, x = -1, y = -1; + schar sproom; + xchar x = -1, y = -1; aligntyp amask; boolean croom_is_temple = TRUE; int oldtyp; @@ -3922,7 +3923,7 @@ lspo_grave(L) lua_State *L; { int argc = lua_gettop(L); - schar x, y; + xchar x, y; long scoord; int ax,ay; char *txt; @@ -4134,7 +4135,7 @@ lspo_gold(L) lua_State *L; { int argc = lua_gettop(L); - schar x, y; + xchar x, y; long amount; long gcoord; int gx, gy; @@ -4885,7 +4886,7 @@ lua_State *L; -1, D_ISOPEN, D_CLOSED, D_LOCKED, D_NODOOR, D_BROKEN, D_SECRET }; int msk; - schar x,y; + xchar x,y; xchar typ; int argc = lua_gettop(L); @@ -4966,7 +4967,7 @@ lua_State *L; "throne", "tree", NULL }; static const int features2i[] = { FOUNTAIN, SINK, POOL, THRONE, TREE, STONE }; - schar x,y; + xchar x,y; int typ; int argc = lua_gettop(L); boolean can_have_flags = FALSE; @@ -5167,7 +5168,7 @@ lua_State *L; if (x1 == -1 && y1 == -1 && x2 == -1 && y2 == -1) { (void) selection_not(sel); } else { - schar rx1, ry1, rx2, ry2; + xchar rx1, ry1, rx2, ry2; rx1 = x1, ry1 = y1, rx2 = x2, ry2 = x2; get_location(&rx1, &ry1, ANY_LOC, g.coder->croom); get_location(&rx2, &ry2, ANY_LOC, g.coder->croom); @@ -5825,7 +5826,7 @@ lua_State *L; { static const char *const wprops[] = { "nondiggable", "nonpasswall", NULL }; static const int wprop2i[] = { W_NONDIGGABLE, W_NONPASSWALL, -1 }; - schar dx1 = -1, dy1 = -1, dx2 = -1, dy2 = -1; + xchar dx1 = -1, dy1 = -1, dx2 = -1, dy2 = -1; int wprop; create_des_coder(); diff --git a/src/vision.c b/src/vision.c index 45cd1fe9b..3136cf0e3 100644 --- a/src/vision.c +++ b/src/vision.c @@ -23,7 +23,7 @@ * @...X +4 * */ -const char circle_data[] = { +const xchar circle_data[] = { /* 0*/ 0, /* 1*/ 1, 1, /* 3*/ 2, 2, 1, @@ -49,7 +49,7 @@ const char circle_data[] = { * used for a single point: temporary light source of a camera flash * as it traverses its path. */ -const char circle_start[] = { +const xchar circle_start[] = { /* 0*/ 0, /* 1*/ 1, /* 2*/ 3, @@ -74,26 +74,26 @@ const char circle_start[] = { /*------ local variables ------*/ -static char could_see[2][ROWNO][COLNO]; /* vision work space */ -static char *cs_rows0[ROWNO], *cs_rows1[ROWNO]; -static char cs_rmin0[ROWNO], cs_rmax0[ROWNO]; -static char cs_rmin1[ROWNO], cs_rmax1[ROWNO]; +static xchar could_see[2][ROWNO][COLNO]; /* vision work space */ +static xchar *cs_rows0[ROWNO], *cs_rows1[ROWNO]; +static xchar cs_rmin0[ROWNO], cs_rmax0[ROWNO]; +static xchar cs_rmin1[ROWNO], cs_rmax1[ROWNO]; static char viz_clear[ROWNO][COLNO]; /* vision clear/blocked map */ static char *viz_clear_rows[ROWNO]; -static char left_ptrs[ROWNO][COLNO]; /* LOS algorithm helpers */ -static char right_ptrs[ROWNO][COLNO]; +static xchar left_ptrs[ROWNO][COLNO]; /* LOS algorithm helpers */ +static xchar right_ptrs[ROWNO][COLNO]; /* Forward declarations. */ static void FDECL(fill_point, (int, int)); static void FDECL(dig_point, (int, int)); static void NDECL(view_init); -static void FDECL(view_from, (int, int, char **, char *, char *, int, +static void FDECL(view_from, (int, int, xchar **, xchar *, xchar *, int, void (*)(int, int, genericptr_t), genericptr_t)); -static void FDECL(get_unused_cs, (char ***, char **, char **)); -static void FDECL(rogue_vision, (char **, char *, char *)); +static void FDECL(get_unused_cs, (xchar ***, xchar **, xchar **)); +static void FDECL(rogue_vision, (xchar **, xchar *, xchar *)); /* Macro definitions that I can't find anywhere. */ #define sign(z) ((z) < 0 ? -1 : ((z) ? 1 : 0)) @@ -246,11 +246,11 @@ vision_reset() */ static void get_unused_cs(rows, rmin, rmax) -char ***rows; -char **rmin, **rmax; +xchar ***rows; +xchar **rmin, **rmax; { register int row; - register char *nrmin, *nrmax; + register xchar *nrmin, *nrmax; if (g.viz_array == cs_rows0) { *rows = cs_rows1; @@ -287,8 +287,8 @@ char **rmin, **rmax; */ static void rogue_vision(next, rmin, rmax) -char **next; /* could_see array pointers */ -char *rmin, *rmax; +xchar **next; /* could_see array pointers */ +xchar *rmin, *rmax; { int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET; /* no SHARED... */ int start, stop, in_door, xhi, xlo, yhi, ylo; @@ -494,13 +494,13 @@ int control; { extern unsigned char seenv_matrix[3][3]; /* from display.c */ static unsigned char colbump[COLNO + 1]; /* cols to bump sv */ - char **temp_array; /* points to the old vision array */ - char **next_array; /* points to the new vision array */ - char *next_row; /* row pointer for the new array */ - char *old_row; /* row pointer for the old array */ - char *next_rmin; /* min pointer for the new array */ - char *next_rmax; /* max pointer for the new array */ - const char *ranges; /* circle ranges -- used for xray & night vision */ + xchar **temp_array; /* points to the old vision array */ + xchar **next_array; /* points to the new vision array */ + xchar *next_row; /* row pointer for the new array */ + xchar *old_row; /* row pointer for the old array */ + xchar *next_rmin; /* min pointer for the new array */ + xchar *next_rmax; /* max pointer for the new array */ + const xchar *ranges; /* circle ranges -- used for xray & night vision */ int row = 0; /* row counter (outer loop) */ int start, stop; /* inner loop starting/stopping index */ int dx, dy; /* one step from a lit door or lit wall (see below) */ @@ -1092,9 +1092,9 @@ int row, col; static int start_row; static int start_col; static int step; -static char **cs_rows; -static char *cs_left; -static char *cs_right; +static xchar **cs_rows; +static xchar *cs_left; +static xchar *cs_right; static void FDECL((*vis_func), (int, int, genericptr_t)); static genericptr_t varg; @@ -1605,9 +1605,9 @@ static close2d *close_dy[CLOSE_MAX_BC_DY]; static far2d *far_dy[FAR_MAX_BC_DY]; static void FDECL(right_side, (int, int, int, int, int, - int, int, const char *)); + int, int, const xchar *)); static void FDECL(left_side, (int, int, int, int, int, int, int, - const char *)); + const xchar *)); static int FDECL(close_shadow, (int, int, int, int)); static int FDECL(far_shadow, (int, int, int, int)); @@ -1720,7 +1720,7 @@ int cb_row, cb_col; /* close block row and col */ int fb_row, fb_col; /* far block row and col */ int left; /* left mark of the previous row */ int right_mark; /* right mark of previous row */ -char *limits; /* points at range limit for current row, or NULL */ +xchar *limits; /* points at range limit for current row, or NULL */ { register int i; register char *rowp = NULL; @@ -1998,7 +1998,7 @@ int cb_row, cb_col; /* close block row and col */ int fb_row, fb_col; /* far block row and col */ int left_mark; /* left mark of previous row */ int right; /* right mark of the previous row */ -const char *limits; +const xchar *limits; { register int i; register char *rowp = NULL; @@ -2196,8 +2196,8 @@ const char *limits; static void view_from(srow, scol, loc_cs_rows, left_most, right_most, range, func, arg) int srow, scol; /* source row and column */ -char **loc_cs_rows; /* could_see array (row pointers) */ -char *left_most, *right_most; /* limits of what could be seen */ +xchar **loc_cs_rows; /* could_see array (row pointers) */ +xchar *left_most, *right_most; /* limits of what could be seen */ int range; /* 0 if unlimited */ void FDECL((*func), (int, int, genericptr_t)); genericptr_t arg; @@ -2289,8 +2289,8 @@ genericptr_t arg; /* * Defines local to Algorithm C. */ -static void FDECL(right_side, (int, int, int, const char *)); -static void FDECL(left_side, (int, int, int, const char *)); +static void FDECL(right_side, (int, int, int, const xchar *)); +static void FDECL(left_side, (int, int, int, const xchar *)); /* Initialize algorithm C (nothing). */ static void @@ -2307,7 +2307,7 @@ right_side(row, left, right_mark, limits) int row; /* current row */ int left; /* first (left side) visible spot on prev row */ int right_mark; /* last (right side) visible spot on prev row */ -const char *limits; /* points at range limit for current row, or NULL */ +const xchar *limits; /* points at range limit for current row, or NULL */ { int right; /* right limit of "could see" */ int right_edge; /* right edge of an opening */ @@ -2315,9 +2315,9 @@ const char *limits; /* points at range limit for current row, or NULL */ int deeper; /* if TRUE, call self as needed */ int result; /* set by q?_path() */ register int i; /* loop counter */ - register char *rowp = NULL; /* row optimization */ - char *row_min = NULL; /* left most [used by macro set_min()] */ - char *row_max = NULL; /* right most [used by macro set_max()] */ + register xchar *rowp = NULL; /* row optimization */ + xchar *row_min = NULL; /* left most [used by macro set_min()] */ + xchar *row_max = NULL; /* right most [used by macro set_max()] */ int lim_max; /* right most limit of circle */ nrow = row + step; @@ -2497,13 +2497,13 @@ const char *limits; /* points at range limit for current row, or NULL */ static void left_side(row, left_mark, right, limits) int row, left_mark, right; -const char *limits; +const xchar *limits; { int left, left_edge, nrow, deeper, result; register int i; - register char *rowp = NULL; - char *row_min = NULL; - char *row_max = NULL; + register xchar *rowp = NULL; + xchar *row_min = NULL; + xchar *row_max = NULL; int lim_min; #ifdef GCC_WARN @@ -2633,19 +2633,19 @@ const char *limits; static void view_from(srow, scol, loc_cs_rows, left_most, right_most, range, func, arg) int srow, scol; /* starting row and column */ -char **loc_cs_rows; /* pointers to the rows of the could_see array */ -char *left_most; /* min mark on each row */ -char *right_most; /* max mark on each row */ +xchar **loc_cs_rows; /* pointers to the rows of the could_see array */ +xchar *left_most; /* min mark on each row */ +xchar *right_most; /* max mark on each row */ int range; /* 0 if unlimited */ void FDECL((*func), (int, int, genericptr_t)); genericptr_t arg; { register int i; /* loop counter */ - char *rowp; /* optimization for setting could_see */ + xchar *rowp; /* optimization for setting could_see */ int nrow; /* the next row */ int left; /* the left-most visible column */ int right; /* the right-most visible column */ - const char *limits; /* range limit for next row */ + const xchar *limits; /* range limit for next row */ /* Set globals for q?_path(), left_side(), and right_side() to use. */ start_col = scol; @@ -2685,7 +2685,7 @@ genericptr_t arg; if (right > scol + range) right = scol + range; } else - limits = (char *) 0; + limits = (xchar *) 0; if (func) { for (i = left; i <= right; i++) @@ -2744,12 +2744,12 @@ genericptr_t arg; { /* If not centered on hero, do the hard work of figuring the area */ if (scol != u.ux || srow != u.uy) { - view_from(srow, scol, (char **) 0, (char *) 0, (char *) 0, range, + view_from(srow, scol, (xchar **) 0, (xchar *) 0, (xchar *) 0, range, func, arg); } else { register int x; int y, min_x, max_x, max_y, offset; - const char *limits; + const xchar *limits; boolean override_vision; /* vision doesn't pass through water or clouds, detection should From 7cfc5a7142d06bd0ca71e9422e88bbaeba6835fd Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 15 Nov 2020 13:22:45 +0200 Subject: [PATCH 407/708] Fix buffer underrun in curses --- win/curses/cursmisc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 825df06a7..0914400ea 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -691,7 +691,8 @@ curses_rtrim(char *str) char *s; for (s = str; *s != '\0'; ++s); - for (--s; isspace(*s) && s > str; --s); + if (s > str) + for (--s; isspace(*s) && s > str; --s); if (s == str) *s = '\0'; else From deb730d9b5160fc03e3679431ea38f9297a2c428 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 15 Nov 2020 13:51:47 +0200 Subject: [PATCH 408/708] More hypothetical type mismatches --- include/extern.h | 6 +++--- include/patchlevel.h | 2 +- include/rm.h | 2 +- src/nhlsel.c | 12 ++++++------ src/sp_lev.c | 15 ++++++++------- 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/include/extern.h b/include/extern.h index 74de4f1e7..43e81cf25 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2502,12 +2502,12 @@ E void FDECL(get_location_coord, (xchar *, xchar *, int, struct mkroom *, E void FDECL(selection_setpoint, (int, int, struct selectionvar *, XCHAR_P)); E struct selectionvar * FDECL(selection_not, (struct selectionvar *)); E void FDECL(selection_filter_percent, (struct selectionvar *, int)); -E int FDECL(selection_rndcoord, (struct selectionvar *, schar *, schar *, +E int FDECL(selection_rndcoord, (struct selectionvar *, xchar *, xchar *, BOOLEAN_P)); E void FDECL(selection_do_grow, (struct selectionvar *, int)); -E void FDECL(selection_do_line, (SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P, +E void FDECL(selection_do_line, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, struct selectionvar *)); -E void FDECL(selection_do_randline, (SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P, +E void FDECL(selection_do_randline, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, SCHAR_P, SCHAR_P, struct selectionvar *)); E struct selectionvar *FDECL(selection_filter_mapchar, (struct selectionvar *, XCHAR_P, int)); diff --git a/include/patchlevel.h b/include/patchlevel.h index 5e1557d79..a6d3fba00 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 26 +#define EDITLEVEL 27 /* * Development status possibilities. diff --git a/include/rm.h b/include/rm.h index b55512439..3d303a5c4 100644 --- a/include/rm.h +++ b/include/rm.h @@ -544,7 +544,7 @@ struct cemetery { /* date+time in string of digits rather than binary */ char when[4 + 2 + 2 + 2 + 2 + 2 + 1]; /* "YYYYMMDDhhmmss\0" */ /* final resting place spot */ - schar frpx, frpy; + xchar frpx, frpy; boolean bonesknown; }; diff --git a/src/nhlsel.c b/src/nhlsel.c index 953b7c241..bfe09db3e 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -318,7 +318,7 @@ lua_State *L; { struct selectionvar *sel = l_selection_check(L, 1); int removeit = (int) luaL_optinteger(L, 2, 0); - schar x, y; + xchar x, y; selection_rndcoord(sel, &x, &y, removeit); update_croom(); if (g.coder && g.coder->croom) { @@ -739,7 +739,7 @@ lua_State *L; struct selectionvar *sel = (struct selectionvar *) 0; /* if x2 and y2 aren't set, the gradient has a single center point of x,y; * if they are set, the gradient is centered on a (x,y) to (x2,y2) line */ - schar x = 0, y = 0, x2 = -1, y2 = -1; + xchar x = 0, y = 0, x2 = -1, y2 = -1; /* points will not be added within mindist of the center; the chance for a * point between mindist and maxdist to be added to the selection starts at * 0% at mindist and increases linearly to 100% at maxdist */ @@ -758,10 +758,10 @@ lua_State *L; if (argc == 1 && lua_type(L, 1) == LUA_TTABLE) { lcheck_param_table(L); type = gradtypes2i[get_table_option(L, "type", "radial", gradtypes)]; - x = (schar) get_table_int(L, "x"); - y = (schar) get_table_int(L, "y"); - x2 = (schar) get_table_int_opt(L, "x2", -1); - y2 = (schar) get_table_int_opt(L, "y2", -1); + x = (xchar) get_table_int(L, "x"); + y = (xchar) get_table_int(L, "y"); + x2 = (xchar) get_table_int_opt(L, "x2", -1); + y2 = (xchar) get_table_int_opt(L, "y2", -1); /* maxdist is required because there's no obvious default value for it, * whereas mindist has an obvious defalt of 0 */ maxdist = get_table_int(L, "maxdist"); diff --git a/src/sp_lev.c b/src/sp_lev.c index c03d08f26..cb81076c6 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -43,7 +43,7 @@ static void NDECL(link_doors_rooms); static int NDECL(rnddoor); static int NDECL(rndtrap); static void FDECL(get_location, (xchar *, xchar *, int, struct mkroom *)); -static boolean FDECL(is_ok_location, (SCHAR_P, SCHAR_P, int)); +static boolean FDECL(is_ok_location, (XCHAR_P, XCHAR_P, int)); static unpacked_coord FDECL(get_unpacked_coord, (long, int)); static void FDECL(get_room_loc, (xchar *, xchar *, struct mkroom *)); static void FDECL(get_free_room_loc, (xchar *, xchar *, @@ -1145,7 +1145,7 @@ struct mkroom *croom; static boolean is_ok_location(x, y, humidity) -register schar x, y; +register xchar x, y; register int humidity; { register int typ; @@ -2793,7 +2793,7 @@ int humidity; if (--tryct < 0) break; /* give up */ } while (!(x % 2) || !(y % 2) || SpLev_Map[x][y] - || !is_ok_location((schar) x, (schar) y, humidity)); + || !is_ok_location((xchar) x, (xchar) y, humidity)); m->x = (xchar) x, m->y = (xchar) y; } @@ -4361,7 +4361,7 @@ int percent; int selection_rndcoord(ov, x, y, removeit) struct selectionvar *ov; -schar *x, *y; +xchar *x, *y; boolean removeit; { int idx = 0; @@ -4712,7 +4712,7 @@ long x, y, x2, y2, gtyp, mind, maxd, limit; /* bresenham line algo */ void selection_do_line(x1, y1, x2, y2, ov) -schar x1, y1, x2, y2; +xchar x1, y1, x2, y2; struct selectionvar *ov; { int d0, dx, dy, ai, bi, xi, yi; @@ -4766,7 +4766,8 @@ struct selectionvar *ov; void selection_do_randline(x1, y1, x2, y2, rough, rec, ov) -schar x1, y1, x2, y2, rough, rec; +xchar x1, y1, x2, y2; +schar rough, rec; struct selectionvar *ov; { int mx, my; @@ -5208,7 +5209,7 @@ struct selectionvar *ov; WAN_TELEPORTATION, SCR_TELEPORTATION, RIN_TELEPORTATION }; struct selectionvar *ov2 = selection_new(), *ov3; - schar x, y; + xchar x, y; boolean res = TRUE; selection_floodfill(ov2, nx, ny, TRUE); From 0dc44ad2103dcac54c57b606ec7d7ec9d7594238 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 15 Nov 2020 14:25:40 +0200 Subject: [PATCH 409/708] Update comment about xchar --- include/global.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/global.h b/include/global.h index 23350a12c..1cdc6a168 100644 --- a/include/global.h +++ b/include/global.h @@ -49,9 +49,8 @@ #endif /* DUMB */ /* - * type xchar: small integers in the range 0 - 127, usually coordinates - * although they are nonnegative they must not be declared unsigned - * since otherwise comparisons with signed quantities are done incorrectly + * type xchar: small integers (typedef'd as signed char, + * so in the range -127 - 127), usually coordinates. */ typedef schar xchar; From 56494d3479f6d36fc00772a0eedfb5bd1d177216 Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Sun, 15 Nov 2020 16:07:43 +0100 Subject: [PATCH 410/708] Fix an implicit-fallthrough and maybe-uninitialized warning --- src/dokick.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dokick.c b/src/dokick.c index 81ed6c314..80cdcaa50 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1617,7 +1617,7 @@ obj_delivery(near_hero) boolean near_hero; { register struct obj *otmp, *otmp2; - register int nx, ny; + int nx = 0, ny = 0; int where; boolean nobreak, noscatter; stairway *stway; @@ -1650,6 +1650,7 @@ boolean near_hero; switch (where) { case MIGR_LADDER_UP: isladder = TRUE; + /*FALLTHRU*/ case MIGR_STAIRS_UP: case MIGR_SSTAIRS: if ((stway = stairway_find_from(&fromdlev, isladder)) != 0) { @@ -1657,7 +1658,6 @@ boolean near_hero; nx = stway->sy; } break; - break; case MIGR_WITH_HERO: nx = u.ux, ny = u.uy; break; From f965d187b8f2bddc68e0bfb11ae4a12fc4c17fed Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 15 Nov 2020 11:08:10 -0500 Subject: [PATCH 411/708] support for build with current Lua version 5.4.1 This may require make spotless make fetch-lua for some platforms. --- .travis.yml | 16 ++++++++-------- Porting | 2 +- sys/msdos/Makefile.GCC | 6 +++--- sys/msdos/fetch-cross-compiler.sh | 2 +- sys/unix/Makefile.top | 2 +- sys/unix/NetHack.xcodeproj/project.pbxproj | 4 ++-- sys/unix/hints/include/cross-pre.2020 | 6 +++--- sys/vms/Makefile.src | 2 +- sys/winnt/Install.nt | 12 ++++++------ sys/winnt/Makefile.gcc | 10 +++++----- sys/winnt/Makefile.msc | 13 ++++++++----- sys/winnt/travis-gcc.sh | 4 ++-- win/win32/vs/NetHack.vcxproj | 1 + win/win32/vs/NetHackProperties.props | 2 +- win/win32/vs/NetHackW.vcxproj | 3 ++- win/win32/vs/travisci.sh | 2 +- 16 files changed, 46 insertions(+), 41 deletions(-) diff --git a/.travis.yml b/.travis.yml index ceba99f72..81bb145b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ matrix: include: - name: linux-xenial-gcc-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.1 compiler: gcc addons: apt: @@ -21,7 +21,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-bionic-gcc-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.1 dist: bionic compiler: gcc addons: @@ -40,7 +40,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-focal-clang-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.1 dist: focal compiler: clang addons: @@ -59,7 +59,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-xenial-gcc-nocommon os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.1 dist: xenial compiler: gcc script: @@ -70,7 +70,7 @@ matrix: - make install - name: linux-focal-gcc9-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.1 dist: focal compiler: gcc addons: @@ -91,7 +91,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-xenial-gcc-minimal os: linux - env: HINTS=linux-minimal LUA_VERSION=5.4.0 + env: HINTS=linux-minimal LUA_VERSION=5.4.1 compiler: gcc script: | cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ @@ -129,7 +129,7 @@ matrix: script: - export ADD_CURSES=Y - export PDCURSES_TOP=../lib/pdcurses - - export LUA_VERSION=5.4.0 + - export LUA_VERSION=5.4.1 - sh sys/winnt/travis-gcc.sh - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - test -d "lib/pdcurses" || exit 0 @@ -138,7 +138,7 @@ matrix: - mingw32-make LUA_VERSION=$LUA_VERSION install - name: msdos-linux-focal-djgpp-crosscompile os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.0 + env: HINTS=linux.2020 LUA_VERSION=5.4.1 dist: focal compiler: gcc script: diff --git a/Porting b/Porting index 3f5a99d8e..70c8ccd1f 100644 --- a/Porting +++ b/Porting @@ -207,7 +207,7 @@ need to be included in the packaging of the game. 4.3. Lua Compile and link into a library, or obtain a prebuilt Lua library for -your platform. Place the Lua source into lib/lua-5.4.0 (or other folder +your platform. Place the Lua source into lib/lua-5.4.1 (or other folder representing an appropriate Lua version); place the compiled Lua library into lib. diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index bd04dc986..abe561180 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -42,13 +42,13 @@ PDCURSES_TOP=../../pdcurses ifeq "$(LUA_VERSION)" "5.3.5" LUAVER=5.3.5 else -LUAVER=5.4.0 +LUAVER=5.4.1 endif #--------------------------------------------------------------- # Location of LUA # # Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.0.tar.gz +# http://www.lua.org/ftp/lua-5.4.1.tar.gz # # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere @@ -305,7 +305,7 @@ ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ) #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz #================================================================= LUASRC = $(LUATOP)/src diff --git a/sys/msdos/fetch-cross-compiler.sh b/sys/msdos/fetch-cross-compiler.sh index 12d861fd3..b5267b590 100644 --- a/sys/msdos/fetch-cross-compiler.sh +++ b/sys/msdos/fetch-cross-compiler.sh @@ -12,7 +12,7 @@ if [ -z "$GCCVER" ]; then fi if [ -z "$LUA_VERSION" ]; then - export LUA_VERSION=5.4.0 + export LUA_VERSION=5.4.1 fi if [ ! -d "$(pwd)/lib" ]; then diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 740c8b979..4860b56dd 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -75,7 +75,7 @@ VARDAT = $(VARDATD) $(VARDATND) #CHGRP = chgrp # Lua version -LUA_VERSION = 5.4.0 +LUA_VERSION = 5.4.1 # # end of configuration diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index 78a8a4b3b..a22cb1e31 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -1381,7 +1381,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_INC_DIR}\necho '/* nhlua.h - generated by Xcode script */' > nhlua.h\necho '#include \"../lib/lua-5.4.0/src/lua.h\"' >> nhlua.h\nsed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' < ${NH_LIB_DIR}/lua-5.4.0/src/lua.h >> nhlua.h\necho '#include \"../lib/lua-5.4.0/src/lualib.h\"' >> nhlua.h\necho '#include \"../lib/lua-5.4.0/src/lauxlib.h\"' >> nhlua.h\necho '/*nhlua.h*/' >> nhlua.h\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_INC_DIR}\necho '/* nhlua.h - generated by Xcode script */' > nhlua.h\necho '#include \"../lib/lua-5.4.1/src/lua.h\"' >> nhlua.h\nsed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' < ${NH_LIB_DIR}/lua-5.4.1/src/lua.h >> nhlua.h\necho '#include \"../lib/lua-5.4.1/src/lualib.h\"' >> nhlua.h\necho '#include \"../lib/lua-5.4.1/src/lauxlib.h\"' >> nhlua.h\necho '/*nhlua.h*/' >> nhlua.h\n"; }; 544768B8239954B9004B9739 /* Build Lua library */ = { isa = PBXShellScriptBuildPhase; @@ -1400,7 +1400,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_LIB_DIR}\nmkdir -p lua\ncd ${NH_LIB_DIR}/lua-5.4.0/src\nmake a\ncp liblua.a ../../lua\ncd ../../..\n\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_LIB_DIR}\nmkdir -p lua\ncd ${NH_LIB_DIR}/lua-5.4.1/src\nmake a\ncp liblua.a ../../lua\ncd ../../..\n\n"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 562a1934d..e61d4191e 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -47,9 +47,9 @@ endif ifdef BUILD_TARGET_LUA #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz #================================================================= -LUA_VERSION ?=5.4.0 +LUA_VERSION ?=5.4.1 LUATOP ?= ../lib/lua-$(LUA_VERSION) LUASRCDIR ?= $(LUATOP)/src LUAOBJFILES1 = $(TARGETPFX)lapi.o $(TARGETPFX)lauxlib.o \ @@ -148,7 +148,7 @@ ifdef CROSS_TO_MSDOS # 2. Then # make CROSS_TO_MSDOS=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 all # -# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz #================================================================= CFLAGS += -DCROSSCOMPILE diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 9149a985f..8e5ac62cf 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -215,7 +215,7 @@ HOBJ = $(FIRSTOBJ) $(SYSOBJ) $(WINOBJ) $(RANDOBJ) \ LUAOBJ = nhlua.o,nhlsel.o -# 5.4.0 adds header files ljumptab.h and lopnames.h and removes lbitlib.c +# 5.4.0 added header files ljumptab.h and lopnames.h and removes lbitlib.c # so comment top two and uncomment bottom two for the previous version (5.3.5) LUA535SRCFILES = LUA535OBJFILES = diff --git a/sys/winnt/Install.nt b/sys/winnt/Install.nt index 5deb4dccb..a226fe50d 100644 --- a/sys/winnt/Install.nt +++ b/sys/winnt/Install.nt @@ -47,7 +47,7 @@ version. You can use one of the following build environments: | | | +----+ +------+ +-----------+ | | | | | | - share winnt tty win32 Lua-5.4.0 pdcurses + share winnt tty win32 Lua-5.4.1 pdcurses | vs @@ -55,11 +55,11 @@ version. You can use one of the following build environments: | Building And Running Using Visual Studio 2017 or 2019 | \--------------------------------------------------------/ -Before proceeding, please obtain the lua-5.4.0 sources and copy them to -the new directory lib\lua-5.4.0\src. This source can be obtain either from -http://www.lua.org/ftp/lua-5.4.0.tar.gz or from the git hub mirror -https://github.com/lua/lua.git using the tag 'v5.4.0'. The build expects -to find lua files such as 'lua.h' at 'lib\lua-5.4.0\src\lua.h'. +Before proceeding, please obtain the lua-5.4.1 sources and copy them to +the new directory lib\lua-5.4.1\src. This source can be obtain either from +http://www.lua.org/ftp/lua-5.4.1.tar.gz or from the git hub mirror +https://github.com/lua/lua.git using the tag 'v5.4.1'. The build expects +to find lua files such as 'lua.h' at 'lib\lua-5.4.1\src\lua.h'. If you are NOT using Visual Studio 2017 or 2019 IDE, or you prefer to build using a Make utility and a Makefile proceed to "Building Using Make". diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 996c73e6d..b8acaf51f 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -127,7 +127,7 @@ TARGET_CPU=x86 # #--------------------------------------------------------------- ifndef LUA_VERSION -LUAVER=5.4.0 +LUAVER=5.4.1 else LUAVER=$(LUA_VERSION) endif @@ -135,7 +135,7 @@ endif # Location of LUA # # Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.0.tar.gz +# http://www.lua.org/ftp/lua-5.4.1.tar.gz # # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere @@ -416,11 +416,11 @@ OPTIONS_FILE = $(DAT)\options #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz #================================================================= ifndef LUAVER -LUAVER = 5.4.0 +LUAVER = 5.4.1 endif LUASRC = $(LUATOP)/src LUALIB = $(O)lua-$(LUAVER).static.a @@ -446,7 +446,7 @@ LUAOBJFILES = $(O)lapi.o $(O)lauxlib.o $(O)lbaselib.o \ $(O)lstring.o $(O)lstrlib.o $(O)ltable.o $(O)ltablib.o \ $(O)ltm.o $(O)lundump.o $(O)lutf8lib.o $(O)lvm.o $(O)lzio.o ifeq "$(LUAVER)" "5.3.5" -# 5.4.0 adds header files ljumptab.h and lopnames.h and removes lbitlib.c +# 5.4.0 added header files ljumptab.h and lopnames.h and removes lbitlib.c # so we have to tack those on for the previous version (5.3.5) LUASRCFILES = $(LUASRCFILES) lbitlib.c LUAOBJFILES = $(LUAOBJFILES) lbitlib.o diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 28322938f..b1c0cc7ca 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -131,7 +131,7 @@ DEBUGINFO = Y # This marks the end of the BUILD DECISIONS section. #============================================================================== !IFNDEF LUA_VERSION -LUAVER=5.4.0 +LUAVER=5.4.1 !ELSE LUAVER=$(LUA_VERSION) !ENDIF @@ -140,7 +140,7 @@ LUAVER=$(LUA_VERSION) # Location of LUA # # Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.0.tar.gz +# http://www.lua.org/ftp/lua-5.4.1.tar.gz # # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere @@ -385,7 +385,7 @@ OPTIONS_FILE = $(DAT)\options #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.0.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz #================================================================= !IFNDEF LUAVER @@ -395,6 +395,9 @@ LUATMP = $(LUATMP:-beta=) #strip suffix if exists "-beta" !IF "$(LUATMP)" == "5.4.0" LUAVER = 5.4.0 !ENDIF +!IF "$(LUATMP)" == "5.4.1" +LUAVER = 5.4.1 +!ENDIF !ELSE !ERROR NetHack 3.7 requires LUA so LUATOP must be defined !ENDIF @@ -405,7 +408,7 @@ LUATMP = $(LUATMP:-BETA=) #strip suffix if exists "-BETA" !IF "$(LUATMP)" == "5.3.5" LUAVER = 5.3.5 !ELSE -LUAVER = 5.4.0 +LUAVER = 5.4.1 !ENDIF !ENDIF !ENDIF @@ -437,7 +440,7 @@ LUAOBJFILES = $(O)lapi.o $(O)lauxlib.o $(O)lbaselib.o \ LUASRCFILES = $(LUASRCFILES) lbitlib.c LUAOBJFILES = $(LUAOBJFILES) $(O)lbitlib.o !ELSE -# 5.4.0 adds header files ljumptab.h and lopnames.h +# 5.4.0 added header files ljumptab.h and lopnames.h # and removes lbitlib.c !ENDIF diff --git a/sys/winnt/travis-gcc.sh b/sys/winnt/travis-gcc.sh index bcf44b5b8..ecdb79a9e 100644 --- a/sys/winnt/travis-gcc.sh +++ b/sys/winnt/travis-gcc.sh @@ -3,6 +3,6 @@ mkdir -p lib cd lib git clone --depth 1 https://github.com/wmcbrine/PDCurses.git pdcurses #git clone --depth 1 https://github.com/universal-ctags/ctags.git ctags -curl -R -O http://www.lua.org/ftp/lua-5.4.0.tar.gz -tar zxf lua-5.4.0.tar.gz +curl -R -O http://www.lua.org/ftp/lua-5.4.1.tar.gz +tar zxf lua-5.4.1.tar.gz cd ../ diff --git a/win/win32/vs/NetHack.vcxproj b/win/win32/vs/NetHack.vcxproj index 3905afd7b..992ae9534 100644 --- a/win/win32/vs/NetHack.vcxproj +++ b/win/win32/vs/NetHack.vcxproj @@ -58,6 +58,7 @@ true + true false diff --git a/win/win32/vs/NetHackProperties.props b/win/win32/vs/NetHackProperties.props index 8c3665ce3..c9a904613 100644 --- a/win/win32/vs/NetHackProperties.props +++ b/win/win32/vs/NetHackProperties.props @@ -5,7 +5,7 @@ 3 7 0 - 5.4.0 + 5.4.1 true
diff --git a/win/win32/vs/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj index afc39bbcc..61026d3a0 100644 --- a/win/win32/vs/NetHackW.vcxproj +++ b/win/win32/vs/NetHackW.vcxproj @@ -52,6 +52,7 @@ true + true false @@ -354,4 +355,4 @@ - \ No newline at end of file + diff --git a/win/win32/vs/travisci.sh b/win/win32/vs/travisci.sh index 6eb4fa64a..0a8f9a01c 100644 --- a/win/win32/vs/travisci.sh +++ b/win/win32/vs/travisci.sh @@ -24,7 +24,7 @@ export LIB=/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/$VSVER/$TOOLSVER export LIB=/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/$VSVER/$TOOLSVER/VC/Tools/MSVC/$MSVER/lib/x86:$LIB export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/10/lib/$WKITVER/ucrt/x86:$LIB export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/10/lib/$WKITVER/um/x86:$LIB -export LUA_VERSION=5.4.0 +export LUA_VERSION=5.4.1 mkdir -p lib cd lib git clone --depth 1 https://github.com/wmcbrine/PDCurses.git pdcurses From 0f6b3fb6eb9e1c44a338c455b0e4ea3287befb14 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 15 Nov 2020 08:34:19 -0800 Subject: [PATCH 412/708] Qt hitpointbar tweak When the hitpointbar is showing thick blue + thin dark blue (75% or better health but less than 100%) and partial healing occurs, the dark blue portion was momentarily visible pushed off the right edge of the bar, resulting in slight flicker as the right half of the bar got redrawn. I haven't noticed anything similar for the paler injured-side colors, nor any temporary gap between the two sides when losing health. Also, remove a workaround that was needed at one point but isn't needed anymore. (I don't remember the circumstances.) --- win/Qt/qt_stat.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index deadd798f..3ed390442 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -521,8 +521,10 @@ void NetHackQtStatusWindow::HitpointBar() w = geoH.right() - geoH.left() + 1; // might yield 0 (ie, if dead) styleH.sprintf(styleformat, barcolors[colorindx][0], w, w); hpbar_health.setStyleSheet(styleH); - // style sheet should be doing this but width was sticking at full - hpbar_health.setMaximumWidth(w); + // when healing, having the old injury-side shown while the new + // health-side expands pushes the injury farther right and it's + // momentarily visible there before it gets recalculated+redrawn + hpbar_injury.hide(); // will re-show below hpbar_health.show(); // don't need to hide() if/when width is 0 int oldleft = geoI.left(); @@ -550,7 +552,6 @@ void NetHackQtStatusWindow::HitpointBar() w = geoH.right() - geoH.left() + 1; styleH.sprintf(styleformat, barcolors[colorindx][0], w, w); hpbar_health.setStyleSheet(styleH); - hpbar_health.setMaximumWidth(w); // (see above) hpbar_health.show(); alreadyfullhp = true; From 560d324a2f562346173bcf05d19ee3391de9ec4d Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 15 Nov 2020 08:59:08 -0800 Subject: [PATCH 413/708] Qt screen layout Simplify a recent change to the screen layout. Qt can calculate the details and the recent code resulted in a slight amount of blank space between the paperdoll and its resize hotspot. Fix an off-by-one bug in the paperdoll resize routine. (The one pixel margin at the top was being overlooked.) --- win/Qt/qt_inv.cpp | 8 ++++---- win/Qt/qt_main.cpp | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index e32a82522..da2469ed4 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -222,13 +222,13 @@ QSize NetHackQtInvUsageWindow::sizeHint(void) const if (iflags.wc_ascii_map) qt_settings->doll_is_shown = false; if (qt_settings->doll_is_shown) { - w = (1 + qt_settings->dollWidth + 1) * 3; - h = (1 + qt_settings->dollHeight + 1) * 6; + w += (1 + qt_settings->dollWidth + 1) * 3; + h += (1 + qt_settings->dollHeight + 1) * 6; } #else if (iflags.wc_tiled_map) { - w = (1 + qt_settings->glyphs().width() + 1) * 3; - h = (1 + qt_settings->glyphs().height() + 1) * 6; + w += (1 + qt_settings->glyphs().width() + 1) * 3; + h += (1 + qt_settings->glyphs().height() + 1) * 6; } #endif return QSize(w, h); diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 69a2729dc..3920a610f 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1140,12 +1140,9 @@ void NetHackQtMainWindow::layout() #endif // reset widths int w = width(); /* of main window */ - // 10: approximate size of resizing hotspots - int d = qt_settings->doll_is_shown ? 10 + invusage->width() + 10 : 10; - if (d % 4) - d += 4 - d % 4; + int d = invusage->width(); splittersizes[2] = w / 2 - (d * 1 / 4); // status - splittersizes[1] = d - 10; // invusage + splittersizes[1] = d; // invusage splittersizes[0] = w / 2 - (d * 3 / 4); // messages hsplitter->setSizes(splittersizes); } @@ -1173,7 +1170,9 @@ void NetHackQtMainWindow::resizePaperDoll(bool showdoll) } // Height limit is 48+2 pixels per doll cell plus 1 pixel margin at top; - // values greater than 42+2 need taller window which pushes the map down. + // values greater than 44+2 need taller window which pushes the map down + // (when font size 'Large' is used for messages and status; threshold + // may vary by 1 or 2 for other sizes). // FIXME: this doesn't shrink the window back if size is reduced from 45+ int oldheight = vsplittersizes[0], newheight = w->height(); From d6384f4061e2cc55d44ebc7bb86004e28f981dc3 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 15 Nov 2020 19:31:22 +0200 Subject: [PATCH 414/708] Use enums instead of magic values --- include/extern.h | 2 +- include/you.h | 9 +++++++++ src/do.c | 29 ++++++++++------------------- src/quest.c | 8 ++++---- src/teleport.c | 6 +++--- src/trap.c | 2 +- src/u_init.c | 2 +- 7 files changed, 29 insertions(+), 29 deletions(-) diff --git a/include/extern.h b/include/extern.h index 43e81cf25..d03b6df89 100644 --- a/include/extern.h +++ b/include/extern.h @@ -420,7 +420,7 @@ E void NDECL(save_currentstate); E void FDECL(u_collide_m, (struct monst *)); E void FDECL(goto_level, (d_level *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); E void NDECL(maybe_lvltport_feedback); -E void FDECL(schedule_goto, (d_level *, BOOLEAN_P, BOOLEAN_P, int, +E void FDECL(schedule_goto, (d_level *, int, const char *, const char *)); E void NDECL(deferred_goto); E boolean FDECL(revive_corpse, (struct obj *)); diff --git a/include/you.h b/include/you.h index 0d1761a19..738fb61e9 100644 --- a/include/you.h +++ b/include/you.h @@ -334,6 +334,15 @@ enum utraptypes { TT_BURIEDBALL = 5 }; +enum utotypes { + UTOTYPE_NONE = 0x00, + UTOTYPE_ATSTAIRS = 0x01, + UTOTYPE_FALLING = 0x02, + UTOTYPE_PORTAL = 0x04, + UTOTYPE_RMPORTAL = 0x10, /* remove portal */ + UTOTYPE_DEFERRED = 0x20, /* deferred_goto */ +}; + /*** Information about the player ***/ struct you { xchar ux, uy; /* current map coordinates */ diff --git a/src/do.c b/src/do.c index a98417fa3..f1330eeb0 100644 --- a/src/do.c +++ b/src/do.c @@ -1446,7 +1446,7 @@ boolean at_stairs, falling, portal; assign_level(&u.uz0, &u.uz); assign_level(&u.uz, newlevel); assign_level(&u.utolev, newlevel); - u.utotype = 0; + u.utotype = UTOTYPE_NONE; if (!builds_up(&u.uz)) { /* usual case */ if (dunlev(&u.uz) > dunlev_reached(&u.uz)) dunlev_reached(&u.uz) = dunlev(&u.uz); @@ -1784,24 +1784,13 @@ final_level() /* change levels at the end of this turn, after monsters finish moving */ void -schedule_goto(tolev, at_stairs, falling, portal_flag, pre_msg, post_msg) +schedule_goto(tolev, utotype_flags, pre_msg, post_msg) d_level *tolev; -boolean at_stairs, falling; -int portal_flag; +int utotype_flags; const char *pre_msg, *post_msg; { - int typmask = 0100; /* non-zero triggers `deferred_goto' */ - - /* destination flags (`goto_level' args) */ - if (at_stairs) - typmask |= 1; - if (falling) - typmask |= 2; - if (portal_flag) - typmask |= 4; - if (portal_flag < 0) - typmask |= 0200; /* flag for portal removal */ - u.utotype = typmask; + /* UTOTYPE_DEFERRED is used, so UTOTYPE_NONE can trigger deferred_goto() */ + u.utotype = utotype_flags | UTOTYPE_DEFERRED; /* destination level */ assign_level(&u.utolev, tolev); @@ -1823,8 +1812,10 @@ deferred_goto() assign_level(&oldlev, &u.uz); if (g.dfr_pre_msg) pline1(g.dfr_pre_msg); - goto_level(&dest, !!(typmask & 1), !!(typmask & 2), !!(typmask & 4)); - if (typmask & 0200) { /* remove portal */ + goto_level(&dest, !!(typmask & UTOTYPE_ATSTAIRS), + !!(typmask & UTOTYPE_FALLING), + !!(typmask & UTOTYPE_PORTAL)); + if (typmask & UTOTYPE_RMPORTAL) { /* remove portal */ struct trap *t = t_at(u.ux, u.uy); if (t) { @@ -1835,7 +1826,7 @@ deferred_goto() if (g.dfr_post_msg && !on_level(&u.uz, &oldlev)) pline1(g.dfr_post_msg); } - u.utotype = 0; /* our caller keys off of this */ + u.utotype = UTOTYPE_NONE; /* our caller keys off of this */ if (g.dfr_pre_msg) free((genericptr_t) g.dfr_pre_msg), g.dfr_pre_msg = 0; if (g.dfr_post_msg) diff --git a/src/quest.c b/src/quest.c index 5ca4ec0d7..e1d4dfdbd 100644 --- a/src/quest.c +++ b/src/quest.c @@ -182,13 +182,13 @@ boolean seal; branch *br; d_level *dest; struct trap *t; - int portal_flag; + int portal_flag = u.uevent.qexpelled ? UTOTYPE_NONE : UTOTYPE_PORTAL; br = dungeon_branch("The Quest"); dest = (br->end1.dnum == u.uz.dnum) ? &br->end2 : &br->end1; - portal_flag = u.uevent.qexpelled ? 0 /* returned via artifact? */ - : !seal ? 1 : -1; - schedule_goto(dest, FALSE, FALSE, portal_flag, (char *) 0, (char *) 0); + if (seal) + portal_flag |= UTOTYPE_RMPORTAL; + schedule_goto(dest, portal_flag, (char *) 0, (char *) 0); if (seal) { /* remove the portal to the quest - sealing it off */ int reexpelled = u.uevent.qexpelled; diff --git a/src/teleport.c b/src/teleport.c index 48a720296..b46a9b56d 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -941,7 +941,7 @@ level_tele() } newlevel.dnum = u.uz.dnum; newlevel.dlevel = llimit + newlev; - schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, (char *) 0); + schedule_goto(&newlevel, UTOTYPE_NONE, (char *) 0, (char *) 0); return; } @@ -1049,7 +1049,7 @@ level_tele() } } - schedule_goto(&newlevel, FALSE, FALSE, 0, (char *) 0, + schedule_goto(&newlevel, UTOTYPE_NONE, (char *) 0, flags.verbose ? "You materialize on a different level!" : (char *) 0); @@ -1090,7 +1090,7 @@ register struct trap *ttmp; } target_level = ttmp->dst; - schedule_goto(&target_level, FALSE, FALSE, 1, + schedule_goto(&target_level, UTOTYPE_PORTAL, "You feel dizzy for a moment, but the sensation passes.", (char *) 0); } diff --git a/src/trap.c b/src/trap.c index 01c7a80fe..d8b19b3d4 100644 --- a/src/trap.c +++ b/src/trap.c @@ -536,7 +536,7 @@ unsigned ftflags; Sprintf(msgbuf, "The hole in the %s above you closes up.", ceiling(u.ux, u.uy)); - schedule_goto(&dtmp, FALSE, TRUE, 0, (char *) 0, + schedule_goto(&dtmp, UTOTYPE_FALLING, (char *) 0, !td ? msgbuf : (char *) 0); } diff --git a/src/u_init.c b/src/u_init.c index de375a308..a0cb5bb68 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -614,7 +614,7 @@ u_init() u.udg_cnt = 0; u.mh = u.mhmax = u.mtimedone = 0; u.uz.dnum = u.uz0.dnum = 0; - u.utotype = 0; + u.utotype = UTOTYPE_NONE; #endif /* 0 */ u.uz.dlevel = 1; From ccb5bc4b55343f0f5e5f5a4a3bcba9b8afbae02c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 15 Nov 2020 19:56:35 +0200 Subject: [PATCH 415/708] Avoid hard-coded bit twiddling --- src/sp_lev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sp_lev.c b/src/sp_lev.c index cb81076c6..348f023e0 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1025,10 +1025,9 @@ link_doors_rooms() static int rnddoor() { - int i = 1 << rn2(5); + static int state[] = { D_NODOOR, D_BROKEN, D_ISOPEN, D_CLOSED, D_LOCKED }; - i >>= 1; - return i; + return state[rn2(SIZE(state))]; } /* From 126d1f6bb66aaa659262a962b6898b7486a11ab8 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 15 Nov 2020 18:19:53 -0800 Subject: [PATCH 416/708] Qt character selection buglet Testing for generic character name wasn't robust enough. Looking for whether "game" is a generic name would work when compared with the list "game games" but falsely report 'no' for the list "games game". The first matching substring isn't followed by a space and the routine wasn't checking for other matches in the rest of the list. Check again with a subset list starting after the next space beyond the false hit; repeat as needed. --- win/Qt/qt_plsel.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index 85e20ecf6..bbc3132fa 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -39,7 +39,7 @@ extern "C" { static bool generic_plname() { if (*g.plname) { - const char *sptr; + const char *sptr, *p; const char *genericusers = sysopt.genericusers; int ln = (int) strlen(g.plname); @@ -48,12 +48,18 @@ static bool generic_plname() else if (!strcmp(genericusers, "*")) /* "*" => always ask for name */ return true; - if ((sptr = strstri(genericusers, g.plname)) != 0 + while ((sptr = strstri(genericusers, g.plname)) != NULL) { /* check for full word: start of list or following a space */ - && (sptr == genericusers || sptr[-1] == ' ') - /* and also preceding a space or at end of list */ - && (sptr[ln] == ' ' || sptr[ln] == '\0')) - return true; + if ((sptr == genericusers || sptr[-1] == ' ') + /* and also preceding a space or at end of list */ + && (sptr[ln] == ' ' || sptr[ln] == '\0')) + return true; + /* doesn't match full word, but maybe we got a false hit when + looking for "play" in list "player play" so keep going */ + if ((p = strchr(sptr + 1, ' ')) == NULL) + break; + genericusers = p + 1; + } } return false; } From 5c291bc54022f74a17985b6a54ac2174bba18700 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 15 Nov 2020 18:28:20 -0800 Subject: [PATCH 417/708] honor sysconf SHELLERS on VMS I was looking into adding a confirmation prompt for '!' and it isn't very promising due to sequencing issues. (The check for whether '!' is allowed should happen before the prompt about running it but the latter should take place in the core rather than in the port code.) In the mean time, I noticed that VMS was ignoring the SHELLERS value from SYSCF. Untested implementation of a SHELLERS check on VMS. Even if it works, it should not be using $USER as the user name to verify. Tweaks the Unix implementation of check_user_string() but doesn't switch the testing loop to the simpler version used by VMS which is derived from the generic users test used by Qt. --- include/extern.h | 7 ++++-- sys/unix/unixmain.c | 8 +++--- sys/unix/unixunix.c | 7 +++--- sys/vms/vmsunix.c | 59 ++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/include/extern.h b/include/extern.h index d03b6df89..7b4600174 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1603507384 2020/10/24 02:43:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.873 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1605493683 2020/11/16 02:28:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.878 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2768,7 +2768,7 @@ E void NDECL(port_help); E void FDECL(sethanguphandler, (void (*)(int))); E boolean NDECL(authorize_wizard_mode); E void FDECL(append_slash, (char *)); -E boolean FDECL(check_user_string, (char *)); +E boolean FDECL(check_user_string, (const char *)); E char *NDECL(get_login_name); E unsigned long NDECL(sys_random_seed); #endif /* UNIX */ @@ -2952,6 +2952,9 @@ E char *NDECL(verify_termcap); E void NDECL(privoff); E void NDECL(privon); #endif +#ifdef SYSCF +E boolean FDECL(check_user_string, (const char *)); +#endif #ifdef SHELL E int NDECL(dosh); #endif diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 87e255064..c6fea0d3b 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixmain.c $NHDT-Date: 1596498297 2020/08/03 23:44:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 3.7 unixmain.c $NHDT-Date: 1605493691 2020/11/16 02:28:11 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -647,11 +647,11 @@ char *name; boolean check_user_string(optstr) -char *optstr; +const char *optstr; { struct passwd *pw; int pwlen; - char *eop, *w; + const char *eop, *w; char *pwname = 0; if (optstr[0] == '*') @@ -663,7 +663,7 @@ char *optstr; if (!pwname || !*pwname) return FALSE; pwlen = (int) strlen(pwname); - eop = eos(optstr); + eop = eos((char *) optstr); /* temporarily cast away 'const' */ w = optstr; while (w + pwlen <= eop) { if (!*w) diff --git a/sys/unix/unixunix.c b/sys/unix/unixunix.c index 9364200f5..77d3527db 100644 --- a/sys/unix/unixunix.c +++ b/sys/unix/unixunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixunix.c $NHDT-Date: 1596498298 2020/08/03 23:44:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.31 $ */ +/* NetHack 3.7 unixunix.c $NHDT-Date: 1605493693 2020/11/16 02:28:13 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -271,9 +271,8 @@ dosh() #ifdef SYSCF if (!sysopt.shellers || !sysopt.shellers[0] || !check_user_string(sysopt.shellers)) { - /* FIXME: should no longer assume a particular command keystroke, - and perhaps ought to say "unavailable" rather than "unknown" */ - Norep("Unknown command '!'."); + /* FIXME: should no longer assume a particular command keystroke */ + Norep("Unavailable command '!'."); return 0; } #endif diff --git a/sys/vms/vmsunix.c b/sys/vms/vmsunix.c index e6f2fca07..66afa88a2 100644 --- a/sys/vms/vmsunix.c +++ b/sys/vms/vmsunix.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vmsunix.c $NHDT-Date: 1596498310 2020/08/03 23:45:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ +/* NetHack 3.7 vmsunix.c $NHDT-Date: 1605493693 2020/11/16 02:28:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -54,7 +54,7 @@ int fd; if (fstat(fd, &buf)) return 0; /* cannot get status */ #ifndef INSURANCE - if (buf.st_size != sizeof(int)) + if (buf.st_size != sizeof (int)) return 0; /* not an xlock file */ #endif (void) time(&date); @@ -62,7 +62,7 @@ int fd; int lockedpid; /* should be the same size as hackpid */ unsigned long status, dummy, code = JPI$_PID; - if (read(fd, (genericptr_t) &lockedpid, sizeof(lockedpid)) + if (read(fd, (genericptr_t) &lockedpid, sizeof lockedpid) != sizeof(lockedpid)) /* strange ... */ return 0; status = lib$getjpi(&code, &lockedpid, 0, &dummy); @@ -138,7 +138,7 @@ getlock() error(g.locknum ? "Too many hacks running now." : "There is a game in progress under your name."); -gotlock: + gotlock: fd = creat(g.lock, FCMASK); unlock_file(HLOCK); if (fd == -1) { @@ -373,6 +373,45 @@ privon() } #endif /* CHDIR || SHELL || SECURE */ +#ifdef SYSCF +boolean +check_user_string(userlist) +const char *userlist; +{ + char usrnambuf[BUFSZ]; + const char *sptr, *p, *q; + int ln; + + if (!strcmp(userlist, "*")) + return TRUE; + + /* FIXME: ought to use $getjpi or $getuai to retrieve user name here... */ + Strcpy(usrnambuf, nh_getenv("USER")); + ln = (int) strlen(usrnambuf); + if (!ln) + return FALSE; + + while ((sptr = strstri(userlist, usrnambuf)) != 0) { + /* check for full word: start of list or following a space or comma */ + if ((sptr == userlist || sptr[-1] == ' ' || sptr[-1] == ',') + /* and also preceding a space or comma or at end of list */ + && (sptr[ln] == ' ' || sptr[ln] == ',' || sptr[ln] == '\0')) + return TRUE; + /* doesn't match full word, but maybe we got a false hit when + looking for "jane" in the list "janedoe jane" so keep going */ + p = index(sptr + 1, ' '); + q = index(sptr + 1, ','); + if (!p || (q && q < p)) + p = q; + if (!p) + break; + userlist = p + 1; + } + + return FALSE; +} +#endif /* SYSCF */ + #if defined(SHELL) || defined(SUSPEND) static void hack_escape(screen_manip, msg_str) @@ -406,6 +445,14 @@ unsigned long dosh_pid = 0, /* this should cover any interactive escape */ int dosh() { +#ifdef SYSCF + if (!sysopt.shellers || !sysopt.shellers[0] + || !check_user_string(sysopt.shellers)) { + /* FIXME: should no longer assume a particular command keystroke */ + Norep("Unavailable command '!'."); + return 0; + } +#endif return vms_doshell("", TRUE); /* call for interactive child process */ } @@ -617,7 +664,7 @@ int how; /* 1: exit after traceback; 2: stay in debugger */ in a last-gasp environment so apply the KISS principle...) */ DBGCMD("set Module/Calls ; show Calls 18"), /* epilogue; "exit" ends the sequence it's part of, but it doesn't - seem able to cause program termination end when used separately; + seem able to cause program termination when used separately; instead of relying on it, we'll redirect debugger input to come from the null device so that it'll get an end-of-input condition when it tries to get a command from the user */ @@ -844,7 +891,7 @@ const unsigned long lib$initialize[] = { (unsigned long) (void *) vmsexeini }; #endif /* We also need to link against a linker options file containing: sys$library:starlet.olb/Include=(lib$initialize) -psect_attr=lib$initialize, Con,Usr,noPic,Rel,Gbl,noShr,noExe,Rd,noWrt,Long +psect_attr=lib$initialize, Con,Rel,Gbl,noShr,noExe,Rd,noWrt */ #endif /* C_LIB$INITIALIZE */ /* End of debugger hackery. */ From 7395d1eda187313bfc773878e1b569e0a4989eea Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 16 Nov 2020 03:06:39 -0800 Subject: [PATCH 418/708] Qt status display Move gold from in front of HP to the end of the line they're on, and change its label from "Au:" to "Gold:". That makes both HP and gold easier to see, by having HP first and by having gold be shown after a blank column (where 'Exp' was once displayed separately from 'Xp'). Get rid of the obsolete 'exp' widget, replacing it with 'blank1'. Used to force 6 columns for HP, Energy, AC, Xp+Exp, blank, Gold so that the row lines up with the six characteristics above it. Handle Blind the same way as all the other On/Off conditions instead of setting its label dynamically every time status gets updated. The Qt3 code in outdated/ used to do things that way and there doesn't seem to be any reason to have changed it. Maybe someone (Ray?) had planned to show "Blindfolded" instead of "Blind" when that's the only reason for being blind. Reorder the widget declarations and initializations to match their display order, and add a lot of comments. --- win/Qt/qt_stat.cpp | 94 +++++++++++++++++++++++++++------------------- win/Qt/qt_stat.h | 61 +++++++++++++++++++----------- 2 files changed, 95 insertions(+), 60 deletions(-) diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 3ed390442..79b83c486 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -14,9 +14,9 @@ // six characteristic texts ("Str:18/03", "Dex:15", &c) // separator line // five status fields without icons (some containing two values: -// Gold, HP/HPmax, Energy/Enmax, AC, XpLevel/ExpPoints or HD) -// optional line with two text fields (Time:1234, Score:89) +// HP/HPmax, Energy/Enmax, AC, XpLevel/ExpPoints or HD, [blank], Gold) // separator line +// optional line with two text fields (Time:1234, Score:89) // varying number of icons (one or more, each paired with...) // corresponding text (Alignment plus zero or more status conditions // including Hunger if not "normal" and encumbrance if not "normal") @@ -29,16 +29,38 @@ // Time and Score are spaced as if each were three fields wide. // Icons and texts for alignment and conditions are left justified. // The separator lines are thin and don't take up much vertical space. -// The hitpoint bar line and the Time+Score line are omitted when the -// corresponding items are disabled. +// When enabled, the hitpoint bar bisects the margin above Title, +// increasing the overall status height by 9 pixels; when disabled, +// the status shifts up by those 9 pixels. +// When Time+Score line is empty, it still takes up the vertical space +// that would be used to show those values. // // FIXME: // When hitpoint bar is shown, attempting to resize horizontally won't // do anything. Toggling it off, then resizing, and back On works. +// (Caused by specifying min-width and max-width constraints in the +// style sheets used to control color, but removing those constraints +// causes the bar display to get screwed up.) // // TODO: // If/when status conditions become too wide for the status window, scale // down their icons and switch their text to a smaller font to match. +// Title and Location are explicitly rendered with a bigger font than +// the rest of status. That takes up more space, which is ok, but it +// also increases the vertical margin in between them by more than is +// necessary. Should squeeze some of that excess blank space out. +// Changed values are highlighted as "gone Up" (green) or "gone Down" (red) +// with NetHackQtLabelledIcon::setLabel() taking an optional boolean +// argument indicating "lower is better" (for AC). That flag should +// have other choices: "changed" (third color with no better or worse +// judgement, for alignment and dungeon location) and "ignore" (don't +// highlight, to suppress the bogus highlighting that currently happens +// when toggling 'showexp' or 'showscore'). +// Maybe: if Alignment was moved to the characteristics line, giving that +// seven columns, then Time and Score could replace the one blank field +// on the HP line, giving it seven fields too and eliminating a whole +// line. [Maybe handle this dynamically, controlled via existing +// 'statuslines' 2 vs 3 that's currently a no-op for Qt?] // extern "C" { @@ -65,43 +87,49 @@ extern int qt_compact_mode; namespace nethack_qt_ { NetHackQtStatusWindow::NetHackQtStatusWindow() : + /* first three rows: hitpoint bar, title (plname the Rank), location */ + hpbar_health(this), + hpbar_injury(this), name(this,"(name)"), dlevel(this,"(dlevel)"), + /* next two rows: icon over text label for the six characteristics */ str(this, "Str"), dex(this, "Dex"), con(this, "Con"), intel(this, "Int"), wis(this, "Wis"), cha(this, "Cha"), - gold(this,"Gold"), + /* sixth row, text only: some contain two slash-separated values */ hp(this,"Hit Points"), power(this,"Power"), - ac(this,"Armour Class"), - level(this,"Level"), - exp(this, "_"), // exp displayed as Xp/Exp but exp widget used for padding + ac(this,"Armor Class"), + level(this,"Level"), // Xp level, with "/"+Exp points optionally appended + blank1(this, ""), // used for padding to align columns (was once 'exp') + gold(this,"Gold"), // gold used to be this row's first column, now last + /* seventh row: two optionally displayed values (just text, no icons) */ + time(this,"Time"), // if 'time' option On + score(this,"Score"), // if SCORE_ON_BOTL defined and 'showscore' option On + /* last two rows: alignment followed by conditions (icons over text) */ align(this,"Alignment"), - time(this,"Time"), - score(this,"Score"), hunger(this,""), encumber(this,""), - stoned(this,"Stone"), + stoned(this,"Stone"), // major conditions slimed(this,"Slime"), strngld(this,"Strngl"), sick_fp(this,"FoodPois"), sick_il(this,"TermIll"), - stunned(this,"Stun"), + stunned(this,"Stun"), // minor conditions confused(this,"Conf"), hallu(this,"Hallu"), - blind(this,""), + blind(this,"Blind"), deaf(this,"Deaf"), - lev(this,"Lev"), + lev(this,"Lev"), // 'other' conditions fly(this,"Fly"), ride(this,"Ride"), - hpbar_health(this), - hpbar_injury(this), - hline1(this), + hline1(this), // separators hline2(this), hline3(this), + /* miscellaneous; not display fields */ cursy(0), first_set(true), alreadyfullhp(false) @@ -179,6 +207,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : hline2.setLineWidth(1); hline3.setLineWidth(1); + // set up last but shown first (above name) via layout below */ QHBoxLayout *hpbar = InitHitpointBar(); #if 1 //RLC @@ -200,12 +229,12 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : vbox->addLayout(atr1box); vbox->addWidget(&hline2); QHBoxLayout *atr2box = new QHBoxLayout(); - atr2box->addWidget(&gold); atr2box->addWidget(&hp); atr2box->addWidget(&power); atr2box->addWidget(&ac); atr2box->addWidget(&level); - atr2box->addWidget(&exp); + atr2box->addWidget(&blank1); // empty column #5 + atr2box->addWidget(&gold); vbox->addLayout(atr2box); vbox->addWidget(&hline3); QHBoxLayout *timebox = new QHBoxLayout(); @@ -251,15 +280,14 @@ void NetHackQtStatusWindow::doUpdate() intel.setFont(normal); wis.setFont(normal); cha.setFont(normal); - gold.setFont(normal); hp.setFont(normal); power.setFont(normal); ac.setFont(normal); level.setFont(normal); - //exp.setFont(normal); - align.setFont(normal); + gold.setFont(normal); time.setFont(normal); score.setFont(normal); + align.setFont(normal); hunger.setFont(normal); encumber.setFont(normal); stoned.setFont(normal); @@ -415,7 +443,6 @@ void NetHackQtStatusWindow::fadeHighlighting() power.dissipateHighlight(); ac.dissipateHighlight(); level.dissipateHighlight(); - //exp.dissipateHighlight(); align.dissipateHighlight(); time.dissipateHighlight(); @@ -646,14 +673,9 @@ void NetHackQtStatusWindow::updateStats() if (Stunned) stunned.show(); else stunned.hide(); if (Confusion) confused.show(); else confused.hide(); if (Hallucination) hallu.show(); else hallu.hide(); - // [pr - Why is blind handled differently from other on/off conditions?] - if (Blind) { - blind.setLabel("Blind"); - blind.show(); - } else { - blind.hide(); - } + if (Blind) blind.show(); else blind.hide(); if (Deaf) deaf.show(); else deaf.hide(); + // flying is blocked when levitating, so Lev and Fly are mutually exclusive if (Levitation) lev.show(); else lev.hide(); if (Flying) fly.show(); else fly.hide(); @@ -677,8 +699,6 @@ void NetHackQtStatusWindow::updateStats() // new depth compared to old dlevel.setLabel(buf3, false); - gold.setLabel("Au:", money_cnt(g.invent)); - if (Upolyd) { // You're a monster! buf.sprintf("/%d", u.mhmax); @@ -706,12 +726,9 @@ void NetHackQtStatusWindow::updateStats() buf.sprintf("/%d", u.uenmax); power.setLabel("Pow:", u.uen, buf); ac.setLabel("AC:", (long) u.uac); - //if (::flags.showexp) { - // exp.setLabel("Exp:", (long) u.uexp); - //} else { - // 'exp' is now only used to pad the line that Xp/Exp is displayed on - exp.setLabel(""); - //} + // label prefix used to be "Au:", tty uses "$:" + gold.setLabel("Gold:", money_cnt(g.invent)); + text = NULL; if (u.ualign.type==A_CHAOTIC) { align.setIcon(p_chaotic); @@ -763,7 +780,6 @@ void NetHackQtStatusWindow::updateStats() power.highlightWhenChanging(); ac.highlightWhenChanging(); ac.lowIsGood(); level.highlightWhenChanging(); - //exp.highlightWhenChanging(); -- 'exp' is just padding align.highlightWhenChanging(); // don't highlight 'time' because it changes almost continuously diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index 7a3715b3d..ccc1df7f1 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -65,9 +65,18 @@ private: QPixmap p_fly; QPixmap p_ride; - NetHackQtLabelledIcon name; - NetHackQtLabelledIcon dlevel; + /* + * Status fields, in display order (the three separator lines + * are exceptions). Hitpoint bar is optionally displayed and + * contains two side-by-side parts; neither part is labelled. + */ + QLabel hpbar_health; // hit point bar, left half + QLabel hpbar_injury; // hit point bar, right half + NetHackQtLabelledIcon name; // (aka title) centered on its own row + NetHackQtLabelledIcon dlevel; // (aka location) likewise + /* the six characteristics; each is shown with a 40x40 icon above + and a text label below, so implicitly two rows */ NetHackQtLabelledIcon str; NetHackQtLabelledIcon dex; NetHackQtLabelledIcon con; @@ -75,21 +84,34 @@ private: NetHackQtLabelledIcon wis; NetHackQtLabelledIcon cha; - NetHackQtLabelledIcon gold; - NetHackQtLabelledIcon hp; - NetHackQtLabelledIcon power; - NetHackQtLabelledIcon ac; - NetHackQtLabelledIcon level; // Xp level - NetHackQtLabelledIcon exp; // appended to Xp rather than separate - // but still used to pad their line - NetHackQtLabelledIcon align; // alignment is on Conditions line - // because it has an icon above it - NetHackQtLabelledIcon time; - NetHackQtLabelledIcon score; + /* five various status fields, some showing two values, shown as + a row of text only; 'exp' used to be a separate field but is + now displayed with 'level', with a blank field where it was so + that there continue to be six columns which line up beneath the + characteristics; gold used to be left-most but doesn't warrant + that position; Xp or Xp/Exp is replaced by HD when polymorphed */ + NetHackQtLabelledIcon hp; // current HP / maximum HP + NetHackQtLabelledIcon power; // current energy / maximum energy + NetHackQtLabelledIcon ac; // armor class + NetHackQtLabelledIcon level; // Xp level / Exp points (if 'showexp') + NetHackQtLabelledIcon blank1; // pads the line to six columns + NetHackQtLabelledIcon gold; // used to come before HP - NetHackQtLabelledIcon hunger; - NetHackQtLabelledIcon encumber; + /* next row: two more fields, possibly blank; when present, each + is sized as if for three fields, so their centered values line + up with 2nd and 5th columns of the rows above */ + NetHackQtLabelledIcon time; // moves counter (if 'time' is set) + NetHackQtLabelledIcon score; // tentative score (if compiled with + // SCORE_ON_BOTL and 'showscore' is set) + /* last rows: alignment and zero or more status conditions; + like the characteristics, they are shown as if in two rows with + a 40x40 icon above and text lebel below; blank values are omitted + and non-blank values are left justified */ + NetHackQtLabelledIcon align; // w/ alignment-specific ankh icon + NetHackQtLabelledIcon hunger; // blank if 'normal' + NetHackQtLabelledIcon encumber; // blank if 'unencumbered' ('normal') + /* zero or more status conditions; in major, minor, 'other' order */ NetHackQtLabelledIcon stoned; NetHackQtLabelledIcon slimed; NetHackQtLabelledIcon strngld; @@ -104,12 +126,9 @@ private: NetHackQtLabelledIcon fly; NetHackQtLabelledIcon ride; - QLabel hpbar_health; // hit point bar, left half - QLabel hpbar_injury; // hit point bar, right half - - QFrame hline1; - QFrame hline2; - QFrame hline3; + QFrame hline1; // between dlevel and characteristics + QFrame hline2; // between characteristics and regular status fields + QFrame hline3; // between regular fields and time,score or conditions int cursy; From d81e1672aa2c40fdcf5f81f92094329ef59462fd Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 16 Nov 2020 18:42:12 +0200 Subject: [PATCH 419/708] Unify unpolyable objects to single define --- include/obj.h | 4 ++++ src/potion.c | 2 +- src/zap.c | 3 +-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/obj.h b/include/obj.h index 4b6f6d5c8..89d932251 100644 --- a/include/obj.h +++ b/include/obj.h @@ -356,6 +356,10 @@ struct obj { && !undiscovered_artifact(ART_EYES_OF_THE_OVERWORLD))) #define pair_of(o) ((o)->otyp == LENSES || is_gloves(o) || is_boots(o)) +#define unpolyable(o) ((o)->otyp == WAN_POLYMORPH \ + || (o)->otyp == SPE_POLYMORPH \ + || (o)->otyp == POT_POLYMORPH) + /* achievement tracking; 3.6.x did this differently */ #define is_mines_prize(o) ((o)->o_id == g.context.achieveo.mines_prize_oid) #define is_soko_prize(o) ((o)->o_id == g.context.achieveo.soko_prize_oid) diff --git a/src/potion.c b/src/potion.c index 02484db07..a0e2256ed 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1978,7 +1978,7 @@ dodip() } else if (obj->otyp == POT_POLYMORPH || potion->otyp == POT_POLYMORPH) { /* some objects can't be polymorphed */ if (obj->otyp == potion->otyp /* both POT_POLY */ - || obj->otyp == WAN_POLYMORPH || obj->otyp == SPE_POLYMORPH + || unpolyable(obj) || obj == uball || obj == uskin || obj_resists(obj->otyp == POT_POLYMORPH ? potion : obj, 5, 95)) { diff --git a/src/zap.c b/src/zap.c index 0494a9fb0..b8fd955ae 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1964,8 +1964,7 @@ struct obj *obj, *otmp; switch (otmp->otyp) { case WAN_POLYMORPH: case SPE_POLYMORPH: - if (obj->otyp == WAN_POLYMORPH || obj->otyp == SPE_POLYMORPH - || obj->otyp == POT_POLYMORPH || obj_resists(obj, 5, 95)) { + if (unpolyable(obj) || obj_resists(obj, 5, 95)) { res = 0; break; } From 98075ebfe8ae6077e7f33b027aa3788ad88608d7 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 16 Nov 2020 18:08:02 -0800 Subject: [PATCH 420/708] auto-cursing helmet vs perm_invent I though that I noticed a problem but later couldn't reproduce it, so this might not be redundant. Update persistent inventory when putting on a helmet causes it to become cursed. Minor change: if blind at the time, hero loses knowledge of BUC state. --- doc/fixes37.0 | 3 ++- src/do_wear.c | 10 +++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 52d629f10..973f98992 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.353 $ $NHDT-Date: 1605316497 2020/11/14 01:14:57 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.354 $ $NHDT-Date: 1605578879 2020/11/17 02:07:59 $ General Fixes and Modified Features ----------------------------------- @@ -295,6 +295,7 @@ hero could break a wand ("raising the wand high over your head, you break it one-handed weapon and also to a shield if a monster threw a cocktrice egg at the hero but hit and petrified another monster, the hero would get credit/blame for killing it +update persistent inventory when putting on a helmet causes it to auto-curse Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/do_wear.c b/src/do_wear.c index 3d20fe61f..77e7251ae 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_wear.c $NHDT-Date: 1598958650 2020/09/01 11:10:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ +/* NetHack 3.7 do_wear.c $NHDT-Date: 1605578866 2020/11/17 02:07:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -424,6 +424,14 @@ Helmet_on(VOID_ARGS) pline("%s %s for a moment.", Tobjnam(uarmh, "glow"), hcolor(NH_BLACK)); curse(uarmh); + /* curse() doesn't touch bknown so doesn't update persistent + inventory; do so now [set_bknown() calls update_inventory()] */ + if (Blind) + set_bknown(uarmh, 0); /* lose bknown if previously set */ + else if (Role_if(PM_PRIEST)) + set_bknown(uarmh, 1); /* (bknown should already be set) */ + else if (uarmh->bknown) + update_inventory(); /* keep bknown as-is; display the curse */ } g.context.botl = 1; /* reveal new alignment or INT & WIS */ if (Hallucination) { From cb8baa1d1c6facf4e761cce6ec96932eafc880e1 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 17 Nov 2020 05:07:09 -0800 Subject: [PATCH 421/708] Qt status overhaul: add support for 'statuslines' Condense the Qt status slightly, moving Alignment field from the Conditons line to the Characteristics line and the Time and Score fields from their own possibly blank line to the HP,&c,Gold line. That's for statuslines:2, which is the default. statuslines:3 restores the previous layout. I tried to make that become the default for Qt but it got messy fast and I gave up. I also tried to make changing 'statuslines' back and forth on the fly work but failed. I left the code in as #if DYNAMIC_STATUSLINES but that isn't defined anywhere. For the time being at least, 'statuslines' is config file or NETHACKOPTIONS only for Qt, not changeable via 'O' like for curses and tty. Change the option description for 'statuslines'. That depended upon whether curses was compiled in when it should depend on which interface is active. This moves the alternate info to Guidebook. --- doc/Guidebook.mn | 33 +++++++-- doc/Guidebook.tex | 34 ++++++++- include/optlist.h | 5 -- src/options.c | 16 ++--- win/Qt/qt_bind.cpp | 24 +++++-- win/Qt/qt_bind.h | 1 + win/Qt/qt_main.cpp | 18 +++++ win/Qt/qt_main.h | 4 ++ win/Qt/qt_stat.cpp | 176 +++++++++++++++++++++++++++++---------------- win/Qt/qt_stat.h | 2 + win/Qt/qt_xpms.h | 7 +- 11 files changed, 231 insertions(+), 89 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 49eea8730..bf4b30385 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.395 $ $NHDT-Date: 1596785362 2020/08/07 07:29:22 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.398 $ $NHDT-Date: 1605618309 2020/11/17 13:05:09 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "October 2, 2020 +.ds f2 "November 16, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4241,8 +4241,33 @@ If NetHack can, it should display an opening splash screen when it starts up (default yes). .lp statuslines Number of lines for traditional below-the-map status display. -Acceptable values are 2 and 3 (default is 2). -Curses and tty interfaces only. +Acceptable values are \f(CR2\fP and \f(CR3\fP (default is \f(CR2\fP). +.lp "" +For \f(CR3\fP, the \f(CRtty\fP 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 back and forth during the game with the \(oqO\(cq +command. +.lp "" +The \f(CRcurses\fP interface does likewise if the +.op align_status +option is set to \fItop\fP or \fIbottom\fP but ignores +.op statuslines +when set to \fIleft\fP or \fIright\fP. +.lp "" +The \f(CRQt\fP interface already displays more than 3 lines for status +so uses the +.op statuslines +value differently. +A value of \f(CR3\fP renders status in the \f(CRQt\fP interface's +original format, with the status window spread out vertically. +A value of \f(CR2\fP makes status be slightly condensed, moving some +fields to different lines to eliminate one whole line, reducing the +height needed. +For \f(CRQt\fP, +.op statuslines +can only be set in the configuration file or via NETHACKOPTIONS, not +with the \(oqO\(cq command. .lp "term_cols\ \ \fIand\fP" .lp term_rows Curses interface only. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 00154f042..df603a3ae 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{October 2, 2020} +\date{November 16, 2020} \maketitle @@ -4621,8 +4621,36 @@ it starts up (default yes). %.lp \item[\ib{statuslines}] Number of lines for traditional below-the-map status display. -Acceptable values are 2 and 3 (default is 2). -Curses and tty interfaces only. +Acceptable values are {\tt 2} and {\tt 3} (default is {\tt 2}). + +%.lp "" +For {\tt 3}, the {\tt 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 back and forth during the game with the `O' +command. + +%.lp "" +The {\tt curses} interface does likewise if the +{\it align\verb+_+status\/} +option is set to {\it top\/} or {\it bottom\/} but ignores +{\it statuslines\/} +when set to {\it left\/} or {\it right}. + +%.lp "" +The {\tt Qt} interface already displays more than 3 lines for status +so uses the +{\it statuslines\/} +value differently. +A value of {\tt 3} renders status in the {\tt Qt} interface's +original format, with the status window spread out vertically. +A value of {\tt 2} makes status be slightly condensed, moving some +fields to different lines to eliminate one whole line, reducing the +height needed. +For {\tt Qt}, +{\it statuslines\/} +can only be set in the configuration file or via NETHACKOPTIONS, not +with the `O' command. %.lp \item[\ib{term\verb+_+cols} {\normalfont and}] %.lp diff --git a/include/optlist.h b/include/optlist.h index 12b9f3a47..5bc7ec31e 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -425,13 +425,8 @@ pfx_##a, NHOPTC(statushilites, 20, opt_in, set_in_config, Yes, Yes, Yes, No, NoAlias, "highlight control") #endif -#ifdef CURSES_GRAPHICS NHOPTC(statuslines, 20, opt_in, set_in_game, No, Yes, No, No, NoAlias, - "2 or 3 lines for horizontal (bottom or top) status display") -#else - NHOPTC(statuslines, 20, opt_in, set_in_config, No, Yes, No, No, NoAlias, "2 or 3 lines for status display") -#endif #ifdef WIN32 NHOPTC(subkeyvalue, 7, opt_in, set_in_config, No, Yes, Yes, No, NoAlias, "override keystroke value") diff --git a/src/options.c b/src/options.c index 8172cc398..1b946f29d 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1603666043 2020/10/25 22:47:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.478 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1605618310 2020/11/17 13:05:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.480 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3381,9 +3381,9 @@ char *op; itmp = atoi(op); } if (itmp < 2 || itmp > 3) { - config_error_add("'%s' requires a value of 2 or 3", - allopt[optidx].name); - retval = optn_err; + config_error_add("'%s:%s' is invalid; must be 2 or 3", + allopt[optidx].name, op); + retval = optn_silenterr; } else { iflags.wc2_statuslines = itmp; if (!g.opt_initial) @@ -4212,13 +4212,9 @@ char *op; if ((op = string_for_env_opt(allopt[optidx].name, opts, FALSE)) != empty_optstr) { + nmcpy(g.chosen_windowtype, op, WINTYPELEN); if (!iflags.windowtype_deferred) { - char buf[WINTYPELEN]; - - nmcpy(buf, op, WINTYPELEN); - choose_windows(buf); - } else { - nmcpy(g.chosen_windowtype, op, WINTYPELEN); + choose_windows(g.chosen_windowtype); } } else return optn_err; diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 3a64002ee..7969fa5e8 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -167,6 +167,11 @@ void NetHackQtBind::qt_init_nhwindows(int* argc, char** argv) // This nethack engine feature should be moved into windowport API nt_kbhit = NetHackQtBind::qt_kbhit; #endif + +#ifndef DYNAMIC_STATUSLINES + // 'statuslines' option can be set in config file but not via 'O' + set_wc2_option_mod_status(WC2_STATUSLINES, set_gameview); +#endif } int NetHackQtBind::qt_kbhit() @@ -443,7 +448,7 @@ int NetHackQtBind::qt_select_menu(winid wid, int how, MENU_ITEM_P **menu_list) void NetHackQtBind::qt_update_inventory() { if (main) - main->updateInventory(); + main->updateInventory(); // update the paper doll inventory subset /* doesn't work yet if (g.program_state.something_worth_saving && iflags.perm_invent) display_inventory(NULL, false); @@ -820,6 +825,18 @@ void NetHackQtBind::qt_outrip(winid wid, int how, time_t when) window->UseRIP(how, when); } +void NetHackQtBind::qt_preference_update(const char *optname) +{ +#ifdef DYNAMIC_STATUSLINES // leave disabled; redoStatus() doesn't work + if (!strcmp(optname, "statuslines")) { + // delete and recreate status window + main->redoStatus(); + } +#else + nhUse(optname); +#endif +} + char *NetHackQtBind::qt_getmsghistory(BOOLEAN_P init) { NetHackQtMessageWindow *window = main->GetMessageWindow(); @@ -954,7 +971,7 @@ struct window_procs Qt_procs = { | WC_ASCII_MAP | WC_TILED_MAP | WC_FONT_MAP | WC_TILE_FILE | WC_TILE_WIDTH | WC_TILE_HEIGHT | WC_POPUP_DIALOG | WC_PLAYER_SELECTION | WC_SPLASH_SCREEN), - (WC2_HITPOINTBAR), + (WC2_HITPOINTBAR | WC2_STATUSLINES), {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* color availability */ nethack_qt_::NetHackQtBind::qt_init_nhwindows, nethack_qt_::NetHackQtBind::qt_player_selection, @@ -1012,8 +1029,7 @@ struct window_procs Qt_procs = { #else genl_outrip, #endif - genl_preference_update, - + nethack_qt_::NetHackQtBind::qt_preference_update, nethack_qt_::NetHackQtBind::qt_getmsghistory, nethack_qt_::NetHackQtBind::qt_putmsghistory, genl_status_init, diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index 295fafc57..bc3f2d647 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -81,6 +81,7 @@ public: static void qt_start_screen(); static void qt_end_screen(); + static void qt_preference_update(const char *optname); static char *qt_getmsghistory(BOOLEAN_P init); static void qt_putmsghistory(const char *msg, BOOLEAN_P is_restoring); diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 3920a610f..b4f3822f9 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1148,6 +1148,24 @@ void NetHackQtMainWindow::layout() } } +#ifdef DYNAMIC_STATUSLINES // leave disabled; this doesn't work as intended +// called when 'statuslines' changes from 2 to 3 or vice versa; simpler to +// destroy and recreate the status window than to adjust existing fields +void NetHackQtMainWindow::redoStatus() +{ + NetHackQtStatusWindow *oldstatus = this->status; + if (!oldstatus) + return; // not ready yet? + this->status = new NetHackQtStatusWindow; + + if (!qt_compact_mode) + hsplitter->replaceWidget(2, this->status->Widget()); + + delete oldstatus; + ShowIfReady(); +} +#endif + void NetHackQtMainWindow::resizePaperDoll(bool showdoll) { #ifdef ENHANCED_PAPERDOLL diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index e998e63dd..d01d09558 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -52,6 +52,10 @@ public: void FuncAsCommand(int NDECL((*func))); // this is unconditional in case qt_main.h comes before qt_set.h void resizePaperDoll(bool); // ENHANCED_PAPERDOLL +#ifdef DYNAMIC_STATUSLINES + // called when 'statuslines' option has been changed + void redoStatus(); +#endif public slots: void doMenuItem(QAction *); diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 79b83c486..6c6bf9ce9 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -41,6 +41,8 @@ // (Caused by specifying min-width and max-width constraints in the // style sheets used to control color, but removing those constraints // causes the bar display to get screwed up.) +// There are separate icons for Satiated and Hungry, but Weak, Fainting, +// and Fainted all share the Hungry one when they should be different. // // TODO: // If/when status conditions become too wide for the status window, scale @@ -56,11 +58,12 @@ // judgement, for alignment and dungeon location) and "ignore" (don't // highlight, to suppress the bogus highlighting that currently happens // when toggling 'showexp' or 'showscore'). -// Maybe: if Alignment was moved to the characteristics line, giving that -// seven columns, then Time and Score could replace the one blank field -// on the HP line, giving it seven fields too and eliminating a whole -// line. [Maybe handle this dynamically, controlled via existing -// 'statuslines' 2 vs 3 that's currently a no-op for Qt?] +// The condensed display (statuslines:2; Alignment with Characteristics +// instead of with Conditions and Time,Score on HP,...,Gold row) has +// vertical padding when the Conditions row is empty, but having the +// first Cond come On or the last one go Off still makes the rest of +// status shift a little as if the padding (same size icon plus empty +// text label) was slightly taller than a regular Cond. // extern "C" { @@ -111,6 +114,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : score(this,"Score"), // if SCORE_ON_BOTL defined and 'showscore' option On /* last two rows: alignment followed by conditions (icons over text) */ align(this,"Alignment"), + blank2(this, ""), // used to prevent Conditions row from being empty hunger(this,""), encumber(this,""), stoned(this,"Stone"), // major conditions @@ -150,6 +154,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : p_chaotic = QPixmap(chaotic_xpm); p_neutral = QPixmap(neutral_xpm); p_lawful = QPixmap(lawful_xpm); + p_blank2 = QPixmap(blank_xpm); p_satiated = QPixmap(satiated_xpm); p_hungry = QPixmap(hungry_xpm); @@ -182,6 +187,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : cha.setIcon(p_cha); align.setIcon(p_neutral); + blank2.setIcon(p_blank2); // used for spacing when Conditions row is empty hunger.setIcon(p_hungry); encumber.setIcon(p_encumber[0]); @@ -210,60 +216,98 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : // set up last but shown first (above name) via layout below */ QHBoxLayout *hpbar = InitHitpointBar(); + // 'statuslines' takes a value of 2 or 3; we use 3 as a request to put + // Alignment in front of status conditions so that line is never empty + // and to show Time and/or Score on their own line which might be empty + boolean spreadout = (::iflags.wc2_statuslines != 2); + #if 1 //RLC name.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); dlevel.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); QVBoxLayout *vbox = new QVBoxLayout(); vbox->setSpacing(0); - vbox->addLayout(hpbar); + vbox->addLayout(hpbar); // when 'hitpointbar' is enabled, it comes first vbox->addWidget(&name); vbox->addWidget(&dlevel); vbox->addWidget(&hline1); - QHBoxLayout *atr1box = new QHBoxLayout(); - atr1box->addWidget(&str); - atr1box->addWidget(&dex); - atr1box->addWidget(&con); - atr1box->addWidget(&intel); - atr1box->addWidget(&wis); - atr1box->addWidget(&cha); - vbox->addLayout(atr1box); + QHBoxLayout *charbox = new QHBoxLayout(); // Characteristics + charbox->addWidget(&str); + charbox->addWidget(&dex); + charbox->addWidget(&con); + charbox->addWidget(&intel); + charbox->addWidget(&wis); + charbox->addWidget(&cha); + if (!spreadout) { + // when condensed, include Alignment with Characteristics + charbox->addWidget(&align); + } + vbox->addLayout(charbox); vbox->addWidget(&hline2); - QHBoxLayout *atr2box = new QHBoxLayout(); - atr2box->addWidget(&hp); - atr2box->addWidget(&power); - atr2box->addWidget(&ac); - atr2box->addWidget(&level); - atr2box->addWidget(&blank1); // empty column #5 - atr2box->addWidget(&gold); - vbox->addLayout(atr2box); - vbox->addWidget(&hline3); - QHBoxLayout *timebox = new QHBoxLayout(); - timebox->addWidget(&time); - timebox->addWidget(&score); - vbox->addLayout(timebox); - QHBoxLayout *statbox = new QHBoxLayout(); - statbox->addWidget(&align); - statbox->addWidget(&hunger); - statbox->addWidget(&encumber); - statbox->addWidget(&stoned); - statbox->addWidget(&slimed); - statbox->addWidget(&strngld); - statbox->addWidget(&sick_fp); - statbox->addWidget(&sick_il); - statbox->addWidget(&stunned); - statbox->addWidget(&confused); - statbox->addWidget(&hallu); - statbox->addWidget(&blind); - statbox->addWidget(&deaf); - statbox->addWidget(&lev); - statbox->addWidget(&fly); - statbox->addWidget(&ride); - statbox->setAlignment(Qt::AlignLeft|Qt::AlignVCenter); + QHBoxLayout *statbox = new QHBoxLayout(); // core status fields + statbox->addWidget(&hp); + statbox->addWidget(&power); + statbox->addWidget(&ac); + statbox->addWidget(&level); + if (spreadout) { + // when not condensed, put a blank field in front of Gold; + // Time and Score will be shown on their own separate line + statbox->addWidget(&blank1); // empty column #5 of 6 + statbox->addWidget(&gold); + } else { + // when condensed, display Time and Score on HP,...,Gold row +#ifndef SCORE_ON_BOTL + statbox->addWidget(&blank1); // empty column #5 of 7 +#else + statbox->addWidget(&score); // usually empty column #5 +#endif + statbox->addWidget(&gold); // columns 6 and maybe empty 7 + statbox->addWidget(&time); + } vbox->addLayout(statbox); + vbox->addWidget(&hline3); // separtor before Time+Score or Conditions + if (spreadout) { + // when not condensed, put Time and Score on an extra row; since + // they're both optionally displayed, their row might be empty + // TODO? when neither will be shown, set their heights smaller + // and if either gets toggled On, set height back to normal + QHBoxLayout *timebox = new QHBoxLayout(); + timebox->addWidget(&time); + timebox->addWidget(&score); + vbox->addLayout(timebox); + } + QHBoxLayout *condbox = new QHBoxLayout(); // Conditions + if (spreadout) { + // when not condensed, include Alignment with Conditions to + // spread things out and also so that their row is never empty + condbox->addWidget(&align); + } else { + // otherwise place a padding widget on this row; it will be + // hidden if any Conditions are shown, or shown (with blank + // icon and empty text) when there aren't any, reserving + // space (the height of the row) for later conditions + condbox->addWidget(&blank2); + } + condbox->addWidget(&hunger); + condbox->addWidget(&encumber); + condbox->addWidget(&stoned); + condbox->addWidget(&slimed); + condbox->addWidget(&strngld); + condbox->addWidget(&sick_fp); + condbox->addWidget(&sick_il); + condbox->addWidget(&stunned); + condbox->addWidget(&confused); + condbox->addWidget(&hallu); + condbox->addWidget(&blind); + condbox->addWidget(&deaf); + condbox->addWidget(&lev); + condbox->addWidget(&fly); + condbox->addWidget(&ride); + condbox->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + vbox->addLayout(condbox); setLayout(vbox); #endif - connect(qt_settings,SIGNAL(fontChanged()),this,SLOT(doUpdate())); + connect(qt_settings, SIGNAL(fontChanged()), this, SLOT(doUpdate())); doUpdate(); } @@ -633,6 +677,9 @@ void NetHackQtStatusWindow::updateStats() wis.setLabel("Wis:", (long) ACURR(A_WIS)); cha.setLabel("Cha:", (long) ACURR(A_CHA)); + boolean spreadout = (::iflags.wc2_statuslines != 2); + int k = 0; // number of conditions shown + const char* hung=hu_stat[u.uhs]; if (hung[0]==' ') { hunger.hide(); @@ -640,7 +687,7 @@ void NetHackQtStatusWindow::updateStats() hunger.setIcon(u.uhs ? p_hungry : p_satiated); hunger.setLabel(hung); hunger.ForceResize(); - hunger.show(); + ++k, hunger.show(); } const char *enc = enc_stat[near_capacity()]; if (enc[0]==' ' || !enc[0]) { @@ -649,20 +696,20 @@ void NetHackQtStatusWindow::updateStats() encumber.setIcon(p_encumber[near_capacity() - 1]); encumber.setLabel(enc); encumber.ForceResize(); - encumber.show(); + ++k, encumber.show(); } - if (Stoned) stoned.show(); else stoned.hide(); - if (Slimed) slimed.show(); else slimed.hide(); - if (Strangled) strngld.show(); else strngld.hide(); + if (Stoned) ++k, stoned.show(); else stoned.hide(); + if (Slimed) ++k, slimed.show(); else slimed.hide(); + if (Strangled) ++k, strngld.show(); else strngld.hide(); if (Sick) { /* FoodPois or TermIll or both */ if (u.usick_type & SICK_VOMITABLE) { /* food poisoning */ - sick_fp.show(); + ++k, sick_fp.show(); } else { sick_fp.hide(); } if (u.usick_type & SICK_NONVOMITABLE) { /* terminally ill */ - sick_il.show(); + ++k, sick_il.show(); } else { sick_il.hide(); } @@ -670,16 +717,16 @@ void NetHackQtStatusWindow::updateStats() sick_fp.hide(); sick_il.hide(); } - if (Stunned) stunned.show(); else stunned.hide(); - if (Confusion) confused.show(); else confused.hide(); - if (Hallucination) hallu.show(); else hallu.hide(); - if (Blind) blind.show(); else blind.hide(); - if (Deaf) deaf.show(); else deaf.hide(); + if (Stunned) ++k, stunned.show(); else stunned.hide(); + if (Confusion) ++k, confused.show(); else confused.hide(); + if (Hallucination) ++k, hallu.show(); else hallu.hide(); + if (Blind) ++k, blind.show(); else blind.hide(); + if (Deaf) ++k, deaf.show(); else deaf.hide(); // flying is blocked when levitating, so Lev and Fly are mutually exclusive - if (Levitation) lev.show(); else lev.hide(); - if (Flying) fly.show(); else fly.hide(); - if (u.usteed) ride.show(); else ride.hide(); + if (Levitation) ++k, lev.show(); else lev.hide(); + if (Flying) ++k, fly.show(); else fly.hide(); + if (u.usteed) ++k, ride.show(); else ride.hide(); if (Upolyd) { buf = nh_capitalize_words(mons[u.umonnum].mname); @@ -748,6 +795,13 @@ void NetHackQtStatusWindow::updateStats() // justified relative to the label text for some unknown reason... align.ForceResize(); } + if (spreadout) + ++k; // when not condensed, Alignment is shown on the Conditions row + + if (!k) { + blank2.show(); // for vertical spacing: force the row to be non-empty + } else + blank2.hide(); if (::flags.time) time.setLabel("Time:", (long) g.moves); diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index ccc1df7f1..6464be047 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -46,6 +46,7 @@ private: QPixmap p_chaotic; QPixmap p_neutral; QPixmap p_lawful; + QPixmap p_blank2; // conditionally used for vertical spacing QPixmap p_satiated; QPixmap p_hungry; @@ -109,6 +110,7 @@ private: a 40x40 icon above and text lebel below; blank values are omitted and non-blank values are left justified */ NetHackQtLabelledIcon align; // w/ alignment-specific ankh icon + NetHackQtLabelledIcon blank2; // used for spacing if Align is moved NetHackQtLabelledIcon hunger; // blank if 'normal' NetHackQtLabelledIcon encumber; // blank if 'unencumbered' ('normal') /* zero or more status conditions; in major, minor, 'other' order */ diff --git a/win/Qt/qt_xpms.h b/win/Qt/qt_xpms.h index df0540ad9..43b055e34 100644 --- a/win/Qt/qt_xpms.h +++ b/win/Qt/qt_xpms.h @@ -3,7 +3,8 @@ // In alhpabetical order by array name. Probably not the best ordering... /* clang-format off */ -#if 0 // blank icon for use as placeholder + +// blank icon for use as placeholder /* XPM */ static const char *blank_xpm[] = { /* width height ncolors chars_per_pixel */ @@ -57,7 +58,8 @@ static const char *blank_xpm[] = { "........................................", "........................................" }; -#endif + +// Characteristics, Alignment, and Conditions static const char *blind_xpm[] = { /* width height ncolors chars_per_pixel */ "40 40 5 1", @@ -1821,4 +1823,5 @@ static const char *wis_xpm[] = { "oooooooooooooooooooooooooooooooooooooooo", "oooooooooooooooooooooooooooooooooooooooo" }; + /* clang-format on */ From 03d1eed0b5c902589de3f7a0a21a69291aee44d7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 17 Nov 2020 09:14:47 -0500 Subject: [PATCH 422/708] daily cron doc/Guidebook.txt update --- doc/Guidebook.txt | 1518 ++++++++++++++++++++++----------------------- 1 file changed, 759 insertions(+), 759 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index e4873f630..dfe138943 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - October 2, 2020 + November 16, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1182,7 +1182,7 @@ other stacks with the same name or with no name will merge - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1248,7 +1248,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1314,7 +1314,7 @@ Show your inventory. Default key is `i'. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1380,7 +1380,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1446,7 +1446,7 @@ it. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1512,7 +1512,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1578,7 +1578,7 @@ Show bare map without displaying monsters, objects, or - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1644,7 +1644,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1710,7 +1710,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1776,7 +1776,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1842,7 +1842,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1908,7 +1908,7 @@ attempt is made to open (when unlocked) or unlock (when locked) - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -1974,7 +1974,7 @@ send you to a different level but behave differently. Some - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2040,7 +2040,7 @@ scribed below). Monsters are only active on the current level; - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2106,7 +2106,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2172,7 +2172,7 @@ on the map. Setting this option to true will describe such - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2238,7 +2238,7 @@ when angered. Remember: discretion is the better part of valor. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2304,7 +2304,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2370,7 +2370,7 @@ pends on your strength and your constitution. The stronger and - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2436,7 +2436,7 @@ as uncursed. They could just as easily have been described as - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2502,7 +2502,7 @@ encumbrance, and proficiency (see below). The monster's armor - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2568,7 +2568,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2634,7 +2634,7 @@ boost your training towards the next skill level (unless you've - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2700,7 +2700,7 @@ protection in NetHack. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2766,7 +2766,7 @@ protected. Food stored in ice boxes or tins ("cans") will - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2832,7 +2832,7 @@ is the bane of the undead, so potions of holy water are good - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2898,7 +2898,7 @@ ing a ring and then re-wear them after. That's done implicitly - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -2964,7 +2964,7 @@ mand casts a spell. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3030,7 +3030,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3096,7 +3096,7 @@ map. That remains the case even if it is not actually there any - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3162,7 +3162,7 @@ and candy bars), and lumps of royal jelly. Monks are expected to - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3228,7 +3228,7 @@ The identity of scrolls and spellbooks (and knowledge of spells) - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3294,7 +3294,7 @@ - Attained rank title . - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3360,7 +3360,7 @@ abled by setting the correspondingly named option in - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3426,7 +3426,7 @@ a CHOOSE directive has selected that section. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3492,7 +3492,7 @@ extended command. Prefix the command with "!" to disable the - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3558,7 +3558,7 @@ Define a sound mapping. See the "Configuring User Sounds" - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3624,7 +3624,7 @@ option to the list, and turn it off by typing a `!' or "no" - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3690,7 +3690,7 @@ command. Persistent. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3756,7 +3756,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3822,7 +3822,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3888,7 +3888,7 @@ Your starting gender (gender:male or gender:female). You may - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -3954,7 +3954,7 @@ Name your starting horse (for example "horsename:Trigger"). - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4020,7 +4020,7 @@ consists of a prompt for object class characters, followed by - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4086,7 +4086,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4152,7 +4152,7 @@ can also set your character's role by appending a dash and one - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4218,7 +4218,7 @@ the game or switching into non-scoring explore - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4284,7 +4284,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4350,7 +4350,7 @@ Using the `w' (wield) command when already wielding something - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4416,7 +4416,7 @@ This option only affects the game's screen display, not the - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4482,7 +4482,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4548,7 +4548,7 @@ ed moves if you make inadvertent mouse clicks on the map - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4614,7 +4614,7 @@ select which one to use, such as "tty" or "X11" (default - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4680,7 +4680,7 @@ your terminal (default off). - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4746,7 +4746,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4794,25 +4794,25 @@ statuslines Number of lines for traditional below-the-map status display. - Acceptable values are 2 and 3 (default is 2). Curses and tty - interfaces only. + Acceptable values are 2 and 3 (default is 2). - term_cols and + For 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 back and forth during the game with the `O' command. - term_rows - Curses interface only. Number of columns and rows to use for - the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. - Default is the current window size. + 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. - tiled_map - If NetHack can, it should display a tiled map if it can. - - tile_file - Specify the name of an alternative tile file to override the + The Qt interface already displays more than 3 lines for status + so uses the statuslines value differently. A value of 3 ren- + ders 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 - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4822,10 +4822,27 @@ + eliminate one whole line, reducing the height needed. For Qt, + statuslines can only be set in the configuration file or via + NETHACKOPTIONS, not 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 spec- + ified but will settle for smaller sizes if they are too big. + Default is the current window size. + + tiled_map + If NetHack can, it should display a tiled map if it can. + + tile_file + Specify the name of an alternative tile file to override the default. tile_height - Specify the preferred height of each tile in a tile capable + Specify the preferred height of each tile in a tile capable port. tile_width @@ -4835,50 +4852,33 @@ Use bold black instead of blue for black glyphs (TTY only). use_inverse - If NetHack can, it should display inverse when the game speci- + If NetHack can, it should display inverse when the game speci- fies it. vary_msgcount - If NetHack can, it should display this number of messages at a + 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 in- + Whether to draw boxes around the map, status area, message + area, and persistent inventory window if enabled. Curses in- terface only. Acceptable values are 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) (default) - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns + (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 for align_status set to left or right.) windowcolors - If NetHack can, it should display windows with the specified + If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is - OPTION=windowcolors:wintype foreground/background - - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- - text). - - wraptext - If NetHack can, it should wrap long lines of text if they don't - fit in the visible area of the window. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -4888,14 +4888,32 @@ + OPTION=windowcolors:wintype foreground/background + + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- + text). + + 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. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be set with the `O' command. @@ -4905,25 +4923,37 @@ altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). + + + NetHack 3.7 November 16, 2020 + + + + + + NetHack Guidebook 76 + + + flush (default off, Amiga NetHack only). @@ -4934,83 +4964,53 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of - - - NetHack 3.7 October 2, 2020 - - - - - - NetHack Guidebook 76 - - - + (Win32 tty NetHack only). May be used to alter the value of keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assign- - ments in the configuration file if needed. Cannot be set with + ments in the configuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause + tect", "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA - hardware. Setting "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 of those modes works. Cannot be set + hardware. Setting "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 of those modes works. Cannot be set with the `O' command. video_height - Set the VGA mode resolution height (MS-DOS only, with + Set the VGA mode resolution height (MS-DOS only, with video:vesa) video_width - Set the VGA mode resolution width (MS-DOS only, with + 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 bright.cyan. Cannot be set with the `O' + 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 (de- - fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the - `O' command. - - 9.7. Regular Expressions - - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- - terns. This applies to Autopickup exceptions, Message types, Menu - colors, and User sounds. + Set the intensity level of the three gray scales available - - - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5020,34 +5020,49 @@ + (default dark normal light, PC NetHack only). If the game dis- + play is difficult to read, try adjusting these scales; if this + does not correct the problem, try !color. Cannot be set with + the `O' command. + + 9.7. Regular Expressions + + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- + terns. This applies to Autopickup exceptions, Message types, Menu + colors, and User sounds. + 9.8. Configuring Autopickup Exceptions 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 + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as 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 oc- + In addition, some characters are treated specially if they oc- cur 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 + 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 save and then restore your game. autopickup_ex- + 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 save and then restore your game. autopickup_ex- ception rules and not saved with the game. Here are some examples: @@ -5056,27 +5071,12 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - 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 ex- - clusion of items known to be cursed from autopickup. - - 9.9. 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"), or a three-digit decimal ASCII code. - - For example: + 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 - - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5086,30 +5086,43 @@ + exclusion of items known to be cursed from autopickup. + + 9.9. 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"), or a three-digit decimal ASCII code. + + For example: + BIND=^X:getpos.autodescribe BIND={:menu_first_page BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a key by using "nothing" as the extended command to bind - to. You can also bind the "", "", and "" + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- + The menu control or accelerator keys can also be rebound via + OPTIONS lines in the configuration file. You cannot bind ob- ject symbols into menu accelerators. 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 "context", and if bound to same keys, only one of those - commands will be available. Special command can only be bound + 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 "context", 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 + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. doinv @@ -5119,30 +5132,17 @@ Prefix key to force fight a direction. Default is `F'. fight.numpad - Prefix key to force fight a direction. With number_pad only. + Prefix key to force fight a direction. With number_pad only. Default is `-'. getdir.help - When asked for a direction, the key to show the help. Default + When asked for a direction, the key to show the help. Default is `?'. - getdir.self - When asked for a direction, the key to target yourself. De- - fault is `.'. - - getdir.self2 - When asked for a direction, the key to target yourself. De- - fault is `s'. - - getpos.autodescribe - When asked for a location, the key to toggle autodescribe. De- - fault is `#'. - - getpos.all.next - When asked for a location, the key to go to next closest - NetHack 3.7 October 2, 2020 + + NetHack 3.7 November 16, 2020 @@ -5152,63 +5152,63 @@ - interesting thing. Default is `a'. + getdir.self + When asked for a direction, the key to target yourself. De- + fault is `.'. + + getdir.self2 + When asked for a direction, the key to target yourself. De- + fault is `s'. + + getpos.autodescribe + When asked for a location, the key to toggle autodescribe. De- + fault is `#'. + + getpos.all.next + When asked for a location, the key to go to next closest inter- + esting thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest interesting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door + When asked for a location, the key to go to next closest door or doorway. Default is `d'. getpos.door.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest door or doorway. Default is `D'. getpos.help - When asked for a location, the key to show help. Default is + 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 mon- + When asked for a location, the key to go to next closest mon- ster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest monster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest ob- + When asked for a location, the key to go to next closest ob- ject. Default is `o'. getpos.obj.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest object. Default is `O'. getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- stead. 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 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. Default is `"'. - - getpos.pick - When asked for a location, the key to choose the location, and - possibly ask for more info. Default is `.'. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5218,17 +5218,32 @@ - getpos.pick.once + 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 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. Default is `"'. + + getpos.pick When asked for a location, the key to choose the location, and + possibly ask for more info. Default is `.'. + + getpos.pick.once + When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. getpos.pick.quick When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- + asking for more info, and exit the location asking loop. De- fault is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self @@ -5236,45 +5251,30 @@ fault is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unex- + When asked for a location, the key to go to next closest unex- plored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest unexplored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target + When asked for a location, the key to go to show valid target locations. Default is `$'. getpos.valid.next - When asked for a location, the key to go to next closest valid + When asked for a location, the key to go to next closest valid location. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest valid location. Default is `Z'. nopickup Prefix key to move without picking up items. Default is `m'. - redraw - Key to redraw the screen. Default is `^R'. - redraw.numpad - Key to redraw the screen. With number_pad only. Default is - `^L'. - - repeat - Key to repeat previous command. Default is `^A'. - - reqmenu - Prefix key to request menu from some commands. Default is `m'. - - - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5284,15 +5284,28 @@ + redraw + Key to redraw the screen. Default is `^R'. + + redraw.numpad + Key to redraw the screen. With number_pad only. Default is + `^L'. + + repeat + Key to repeat previous command. Default is `^A'. + + reqmenu + Prefix key to request menu from some commands. Default is `m'. + run Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad - Prefix key to run towards a direction. With number_pad only. + Prefix key to run towards a direction. With number_pad only. Default is `5'. rush @@ -5303,7 +5316,7 @@ 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 + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5316,31 +5329,18 @@ 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 mes- + norep - show the message once, but not again if no other mes- sage is shown in between. - Here's an example of message types using NetHack's internal + 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 displaced ." is not shown at all. - - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions - below them. - - 9.11. 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, curses, win32tty and win32gui interfaces support this. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5350,63 +5350,63 @@ - In general, the configuration file entries to describe the + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching + "You displaced ." is not shown at all. + + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions + below them. + + 9.11. 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, curses, win32tty and win32gui interfaces support this. + + 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 pat- + color - the color to use for lines matching the pat- tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- - genta, light-cyan, and white. And no-color, the default fore- - ground color, which isn't necessarily the same as any of the + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- + 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 line will be shown in red color and under- lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu + uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. - Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- - plicit_uncursed option off so that all items known to be uncursed - are actually displayed with the "uncursed" description. - 9.12. Configuring User Sounds - - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered - to the message window. At this time the Qt port and the win32tty - and win32gui ports support the use of user sounds. - - - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5416,24 +5416,36 @@ - The following configuration file entries are relevant to + Note that if you intend to have one or more color specifica- + tions match " uncursed ", you will probably want to turn the im- + plicit_uncursed option off so that all items known to be uncursed + are actually displayed with the "uncursed" description. + + 9.12. Configuring User Sounds + + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered + to the message 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 user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + 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 3.6); pattern - the pattern to match; sound file - the sound file to play; - volume - the volume to be set while playing the sound + volume - the volume to be set while playing the sound file; - sound index - optional; the index corresponding to a sound + sound index - optional; the index corresponding to a sound file. The pattern should be a POSIX extended regular expression. @@ -5441,7 +5453,7 @@ 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5449,8 +5461,8 @@ 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 + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -5458,21 +5470,9 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configura- - tion 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-magen- - ta, light-cyan, and white. And "no-color", the default fore- - ground color on the display, which is not necessarily the same as - black or white or any of the other colors. - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5482,26 +5482,38 @@ - Allowed attributes are none, bold, dim, underline, blink, - and inverse. "Normal" is a synonym for "none"; they should not + For another example, the following line in your configura- + tion 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-magen- + ta, light-cyan, and white. And "no-color", the default fore- + ground 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, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5512,33 +5524,21 @@ 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 condition- + 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 condition- ally displayed depending upon your other option settings. - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. - Allowed behaviors are "always", "up", "down", "changed", a per- - centage or absolute number threshold, or text to match against. - * "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 statushilites turns. - - * "changed" sets the field attribute for when the field val- - ue changes. This attribute times out after statushilites - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5548,63 +5548,63 @@ - turns. (If a field has both a "changed" rule and an "up" - or "down" rule which matches a change in the field's val- + Allowed behaviors are "always", "up", "down", "changed", a per- + centage or absolute number threshold, or text to match against. + + * "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 statushilites turns. + + * "changed" sets the field attribute for when the field val- + ue 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 val- ue, 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 be- - tween 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 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 corresponding maxi- - mum field. Percentage highlight rules are also allowed + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- perience level to the start of the next level. So if lev- - el 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 + el 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 + a rule for =100% is allowed and matches the special case of being exactly 1 experience point short of the next lev- el. - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only match when strictly above or below. * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". For title, only the role's rank title is tested; + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- - tushilites to 0. - Example hilites: - - - - - - - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5614,6 +5614,11 @@ + The whole feature can be disabled by setting option sta- + tushilites to 0. + + Example hilites: + OPTION=hilite_status: gold/up/yellow/down/brown OPTION=hilite_status: characteristics/up/green/down/red OPTION=hilite_status: hitpoints/100%/gray&normal @@ -5629,23 +5634,23 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols @@ -5662,15 +5667,10 @@ ^ S_arrow_trap (arrow trap) 0 S_ball (iron ball) # S_bars (iron bars) - B S_bat (bat or bird) - ^ S_bear_trap (bear trap) - - S_blcorn (bottom left corner) - b S_blob (blob) - + S_book (spellbook) - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5680,6 +5680,11 @@ + B S_bat (bat or bird) + ^ S_bear_trap (bear trap) + - S_blcorn (bottom left corner) + b S_blob (blob) + + S_book (spellbook) ) S_boomleft (boomerang open left) ( S_boomright (boomerang open right) ` S_boulder (boulder) @@ -5728,15 +5733,10 @@ - S_hbeam (horizontal beam [zap animation]) # S_hcdbridge (horizontal raised drawbridge) + S_hcdoor (closed door in horizontal wall) - . S_hodbridge (horizontal lowered drawbridge) - | S_hodoor (open door in horizontal wall) - ^ S_hole (hole) - @ S_human (human or elf) - h S_humanoid (humanoid) - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5746,6 +5746,11 @@ + . S_hodbridge (horizontal lowered drawbridge) + | S_hodoor (open door in horizontal wall) + ^ S_hole (hole) + @ S_human (human or elf) + h S_humanoid (humanoid) - S_hwall (horizontal wall) . S_ice (ice) i S_imp (imp or minor demon) @@ -5794,15 +5799,10 @@ # S_sink (sink) ^ S_sleeping_gas_trap (sleeping gas trap) S S_snake (snake) - s S_spider (arachnid or centipede) - ^ S_spiked_pit (spiked pit) - ^ S_squeaky_board (squeaky board) - 0 S_ss1 (magic shield 1 of 4) - # S_ss2 (magic shield 2 of 4) - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5812,6 +5812,11 @@ + s S_spider (arachnid or centipede) + ^ S_spiked_pit (spiked pit) + ^ S_squeaky_board (squeaky board) + 0 S_ss1 (magic shield 1 of 4) + # S_ss2 (magic shield 2 of 4) @ S_ss3 (magic shield 3 of 4) * S_ss4 (magic shield 4 of 4) ^ S_statue_trap (statue trap) @@ -5860,15 +5865,10 @@ w S_worm (worm) ~ S_worm_tail (long worm tail) W S_wraith (wraith) - x S_xan (xan or other extraordinary insect) - X S_xorn (xorn) - Y S_yeti (apelike creature) - Z S_zombie (zombie) - z S_zruty (zruty) - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5878,63 +5878,63 @@ + x S_xan (xan or other extraordinary insect) + X S_xorn (xorn) + Y S_yeti (apelike creature) + Z S_zombie (zombie) + z S_zruty (zruty) S_pet_override (any pet if ACCESSIBILITY=1 is set) S_hero_override (hero if ACCESSIBILITY=1 is set) Notes: * 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 en- + space character, except for S_pet_override and S_hero_override + which don't have any default value and can only be used if en- abled 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 de- - pict. So S_rock is only used for boulders and not used at all + * 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 de- + pict. So S_rock is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. 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 charac- + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- ter 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 + 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 location of items on the screen. - 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 message handler", your NetHack has been compiled + 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 message 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 environment variable NETHACK_MSGHANDLER + and other POSIX systems, define MSGHANDLER to enable it. To use + the capability, set the environment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the "symbols" file of all of- - ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you - may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task + somewhat daunting. Included within the "symbols" file of all - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -5944,20 +5944,25 @@ + official distributions of NetHack is a symset called NHAccess. + Selecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you + may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- abled in the sysconf file. - The most crucial settings to make the game more accessible + The most crucial settings to make the game more accessible are: symset:NHAccess Load a symbol set appropriate for use by blind players. roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional @@ -5967,40 +5972,35 @@ 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 + 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. autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip - When targeting with cursor and using fast-move, skip the same + When targeting with cursor and using fast-move, skip the same glyphs 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 in- - formation can be seen via the "#attributes" command. - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6010,18 +6010,23 @@ + nostatus_updates + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- + formation can be seen via the "#attributes" command. + 9.16. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed + 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. @@ -6029,44 +6034,39 @@ SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS = A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- + SUPPORT = A string explaining how to get local support (no de- fault value). - RECOVER = A string explaining how to recover a game on this + 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, WIZ- - ARDS, and SHELLERS check for the player name instead of the us- - er's login name. - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6076,9 +6076,13 @@ + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- + ARDS, and SHELLERS check for the player name instead of the us- + er's login name. + 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6087,26 +6091,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6122,17 +6126,13 @@ 10. Scoring - NetHack maintains a list of the top scores or scorers on + 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. + each account on the machine can post only one non-winning score + on this list. If you score higher than someone else on this - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6142,63 +6142,63 @@ - Your score is chiefly based upon how much experience you + 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, 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 + 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 all your gold, but if + 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 + 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 + 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 paltry cost of not getting on the high score + "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 game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - other benefits of explore mode are left for the trepid reader to + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 + vide god-like powers 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 par- - ticular 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 + For some systems, the player must be logged in under a par- + ticular 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. - - - - - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6210,61 +6210,61 @@ 12. Credits - 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 + 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 Dungeons of Doom, by Ken Arromdee. NetHack is the product of literally scores of people's work. - Main events in the course of the game development are described + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting + Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming Hack into a very different game. He published the Hack - source code for use on UNIX systems by posting that to Usenet + forming 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 ver- sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 1.0.3 in July of 1985. Usenet newsgroup net.games.hack - (later renamed rec.games.hack, eventually replaced by + nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6274,63 +6274,63 @@ - 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 + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 + Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor and so forth, not separate images for beetles and ants or for cloaks and boots). - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6340,63 +6340,63 @@ - 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 ob- + 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6406,63 +6406,63 @@ - (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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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 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 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 plat- + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows CE port for 3.4.1. - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6473,12 +6473,12 @@ 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 + 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 + 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 af- @@ -6487,48 +6487,48 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 + velopment 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 Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6540,49 +6540,49 @@ restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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 en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6594,7 +6594,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6607,19 +6607,19 @@ 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6660,7 +6660,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 @@ -6677,7 +6677,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6726,7 +6726,7 @@ - NetHack 3.7 October 2, 2020 + NetHack 3.7 November 16, 2020 From e100d1a1372c95445a0bd7dce2165db9a6248646 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 17 Nov 2020 18:00:40 +0200 Subject: [PATCH 423/708] More unpolyable unifying ... and fix the potion dipping case. --- include/extern.h | 1 + src/potion.c | 6 +----- src/zap.c | 12 +++++++++++- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/extern.h b/include/extern.h index 7b4600174..843cb73eb 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3154,6 +3154,7 @@ E int FDECL(unturn_dead, (struct monst *)); E void NDECL(unturn_you); E void FDECL(cancel_item, (struct obj *)); E boolean FDECL(drain_item, (struct obj *, BOOLEAN_P)); +E boolean FDECL(obj_unpolyable, (struct obj *)); E struct obj *FDECL(poly_obj, (struct obj *, int)); E boolean FDECL(obj_resists, (struct obj *, int, int)); E boolean FDECL(obj_shudders, (struct obj *)); diff --git a/src/potion.c b/src/potion.c index a0e2256ed..34ff6de8e 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1977,11 +1977,7 @@ dodip() goto poof; } else if (obj->otyp == POT_POLYMORPH || potion->otyp == POT_POLYMORPH) { /* some objects can't be polymorphed */ - if (obj->otyp == potion->otyp /* both POT_POLY */ - || unpolyable(obj) - || obj == uball || obj == uskin - || obj_resists(obj->otyp == POT_POLYMORPH ? potion : obj, - 5, 95)) { + if (obj_unpolyable(obj->otyp == POT_POLYMORPH ? potion : obj)) { pline1(nothing_happens); } else { short save_otyp = obj->otyp; diff --git a/src/zap.c b/src/zap.c index b8fd955ae..edb4943d2 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1476,6 +1476,16 @@ struct obj *obj; delobj(obj); } +/* Returns TRUE if obj resists polymorphing */ +boolean +obj_unpolyable(obj) +struct obj *obj; +{ + return (unpolyable(obj) + || obj == uball || obj == uskin + || obj_resists(obj, 5, 95)); +} + /* classes of items whose current charge count carries over across polymorph */ static const char charged_objs[] = { WAND_CLASS, WEAPON_CLASS, ARMOR_CLASS, @@ -1964,7 +1974,7 @@ struct obj *obj, *otmp; switch (otmp->otyp) { case WAN_POLYMORPH: case SPE_POLYMORPH: - if (unpolyable(obj) || obj_resists(obj, 5, 95)) { + if (obj_unpolyable(obj)) { res = 0; break; } From 87a6616998d4a4345bd9a7920b07eac1cc42f476 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 17 Nov 2020 18:55:16 -0800 Subject: [PATCH 424/708] more Qt status The slightly condensed (statuslines:2) status layout puts additional width pressure on "Level:NN/nnnnnnnn" and "Score:nnnnnnnn" so add some code to conditionally shorten the field prefix if the value of the field is wider than the widget it's displayed in. --- win/Qt/qt_icon.cpp | 37 ++++++++++++++++++++------- win/Qt/qt_icon.h | 23 +++++++++-------- win/Qt/qt_stat.cpp | 62 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 89 insertions(+), 33 deletions(-) diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 2e027b3f5..388a1e500 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -2,7 +2,24 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// qt_icon.cpp -- a labelled icon +// qt_icon.cpp -- a labelled icon for display in the status window +// +// TODO? +// When the label specifies two values separated by a slash (curHP/maxHP, +// curEn/maxEn, XpLevel/ExpPoints when 'showexp' is On), highlighting +// for changes is all or nothing. curHP and curEn go up and down +// without any change to the corresponding maximum all the time. Much +// rarer, but when maxHP and maxEn go up with level gain, the hero +// could be injured by a passive counterattack or collateral damage +// from an area effect--or much simpler, the casting cost of a spell +// that killed a monster and produced the level gain--so the current +// value could stay the same or even go down at same time max goes up. +// Likewise, Exp goes up a lot but Xp relatively rarely. (On the very +// rare occasions where either goes down, they'll both do so.) +// Highlighting two slash-separated values independently would be +// worthwhile but with the 'single label using a style sheet for color' +// approach it isn't going to happen. +// extern "C" { #include "hack.h" @@ -18,24 +35,25 @@ extern "C" { namespace nethack_qt_ { -NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget* parent, const char* l) : +NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l) : QWidget(parent), + label(new QLabel(l,this)), + icon(NULL), low_is_good(false), prev_value(-123), - turn_count(-1), - label(new QLabel(l,this)), - icon(0) + turn_count(-1) { initHighlight(); } -NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget* parent, const char* l, const QPixmap& i) : +NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l, + const QPixmap &i) : QWidget(parent), + label(new QLabel(l,this)), + icon(new QLabel(this)), low_is_good(false), prev_value(-123), - turn_count(-1), - label(new QLabel(l,this)), - icon(new QLabel(this)) + turn_count(-1) { setIcon(i); initHighlight(); @@ -43,6 +61,7 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget* parent, const char* l, con void NetHackQtLabelledIcon::initHighlight() { + // note: named 'green' is much darker than Qt::green hl_good = "QLabel { background-color : green; color : white }"; hl_bad = "QLabel { background-color : red ; color : white }"; } diff --git a/win/Qt/qt_icon.h b/win/Qt/qt_icon.h index eda5c5689..56a24f0e1 100644 --- a/win/Qt/qt_icon.h +++ b/win/Qt/qt_icon.h @@ -11,15 +11,18 @@ namespace nethack_qt_ { class NetHackQtLabelledIcon : public QWidget { public: - NetHackQtLabelledIcon(QWidget* parent, const char* label); - NetHackQtLabelledIcon(QWidget* parent, const char* label, const QPixmap& icon); + NetHackQtLabelledIcon(QWidget *parent, const char *label); + NetHackQtLabelledIcon(QWidget *parent, const char *label, + const QPixmap &icon); enum { NoNum=-99999 }; - void setLabel(const QString&, bool lower=true); // a string - void setLabel(const QString&, long, const QString& tail=""); // a number - void setLabel(const QString&, long show_value, long comparative_value, const QString& tail=""); - void setIcon(const QPixmap&); - virtual void setFont(const QFont&); + void setLabel(const QString &, bool lower=true); // string + void setLabel(const QString &, long, const QString &tail=""); // number + void setLabel(const QString &, long show_value, + long comparative_value, const QString &tail=""); + void setIcon(const QPixmap &); + virtual void setFont(const QFont &); + //QString labelText() { return QString(this->label->text()); } void highlightWhenChanging(); void lowIsGood(); @@ -30,6 +33,9 @@ public: virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; + QLabel *label; + QLabel *icon; + protected: void resizeEvent(QResizeEvent*); @@ -44,9 +50,6 @@ private: int turn_count; /* last time the value changed */ QString hl_good; QString hl_bad; - - QLabel* label; - QLabel* icon; }; } // namespace nethack_qt_ diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 6c6bf9ce9..a3bed62c6 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -757,17 +757,27 @@ void NetHackQtStatusWindow::updateStats() buf.sprintf("/%d", u.uhpmax); hp.setLabel("HP:", std::max((long) u.uhp, 0L), buf); // if Exp points are to be displayed, append them to Xp level; - // up/down highlighting becomes tricky--don't try very hard - if (::flags.showexp) { - buf.sprintf("%ld/%ld", (long) u.ulevel, (long) u.uexp); - // at levels above 20, "Level:NN/nnnnnnnn" doesn't fit so - // shorten "Level" to "Lvl" at that stage; - // at level 30, a few pixels are truncated from the start - // and end of "Lvl:30/nnnnnnnnn" but the result is ledgible - level.setLabel(((u.ulevel <= 20) ? "Level:" : "Lvl:") + buf, - NetHackQtLabelledIcon::NoNum, (long) u.uexp); - } else { - level.setLabel("Level:", (long) u.ulevel); + // up/down highlighting becomes tricky--don't try very hard; + // depending upon font size and status layout, "Level:NN/nnnnnnnn" + // might be too wide to fit + static const char *const lvllbl[3] = { "Level:", "Lvl:", "L:" }; + QFontMetrics fm(level.label->font()); + int startingpass = ::flags.showexp ? 0 : 3; + for (int i = startingpass; i < 6; ++i) { + // passes 0,1,2 are with Exp, 3,4,5 without (3 should always fit) + if (i < 3) { + buf.sprintf("%s%ld/%ld", lvllbl[i], + (long) u.ulevel, (long) u.uexp); + level.setLabel(buf, NetHackQtLabelledIcon::NoNum, + (long) u.uexp); + } else { + buf.sprintf("%s%ld", lvllbl[i - 3], (long) u.ulevel); + level.setLabel(buf, NetHackQtLabelledIcon::NoNum, + (long) u.ulevel); + } + // 2: allow a couple of pixels at either end to be clipped off + if (fm.size(0, buf).width() <= (2 + level.width() + 2)) + break; } } buf.sprintf("/%d", u.uenmax); @@ -803,13 +813,37 @@ void NetHackQtStatusWindow::updateStats() } else blank2.hide(); - if (::flags.time) + if (::flags.time) { + // hypothetically Time could grow to enough digits to have trouble + // fitting, but it's not worth worrying about time.setLabel("Time:", (long) g.moves); - else + } else { time.setLabel(""); + } #ifdef SCORE_ON_BOTL if (::flags.showscore) { - score.setLabel("Score:", (long) botl_score()); + long pts = botl_score(); + if (spreadout) { + // plenty of room; Time and Score both have the width of 3 fields + score.setLabel("Score:", pts); + } else { + // depending upon font size and status layout, "Score:nnnnnnnn" + // might be too wide to fit (simpler version of Level:NN/nnnnnnnn) + static const char *const scrlbl[3] = { "Score:", "Scr:", "S:" }; + QFontMetrics fm(score.label->font()); + for (int i = 0; i < 3; ++i) { + buf.sprintf("%s%ld", scrlbl[i], pts); + score.setLabel(buf, NetHackQtLabelledIcon::NoNum, pts); + // 2: allow a couple of pixels at either end to be clipped off + if (fm.size(0, buf).width() <= (2 + score.width() + 2)) + break; + } + // with Xp/Exp, we fallback to Xp if the shortest label prefix + // is still too long; here we just show a clipped value and + // let user either live with it or turn 'showscore' off (or + // set statuslines:3 to take advantage of the extra room that + // the spread out status layout provides) + } } else #endif { From 8c06dccd9200d88c567c276943f5419d23b571ac Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Tue, 17 Nov 2020 21:06:58 -0800 Subject: [PATCH 425/708] allow repeated running --- sys/unix/hints/include/cross-pre.2020 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 562a1934d..126572dda 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -334,7 +334,7 @@ EMCC_DEBUG_CFLAGS += -s SAFE_HEAP=1 EMCC_DEBUG_CFLAGS += -s LLD_REPORT_UNDEFINED=1 EMCC_DEBUG_CFLAGS += -s EXCEPTION_DEBUG=1 #EMCC_DEBUG_CFLAGS += -fsanitize=undefined -fsanitize=address -fsanitize=leak -EMCC_DEBUG_CFLAGS += -s EXIT_RUNTIME=1 +EMCC_DEBUG_CFLAGS += -s NO_EXIT_RUNTIME # XXX: if --profiling isn't included then any error dumps 10MB of WASM to the screen rather than a useful message EMCC_DEBUG_CFLAGS += --profiling EMCC_PROD_CFLAGS += -O3 From c021293983de667a928b5cc30c73a16219e06e63 Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Tue, 17 Nov 2020 21:10:27 -0800 Subject: [PATCH 426/708] remove unnecesssary JavaScript code --- sys/libnh/npm-package/LICENSE.md | 95 ------------------- sys/libnh/npm-package/README.md | 52 ---------- sys/libnh/npm-package/package-lock.json | 5 - sys/libnh/npm-package/package.json | 25 ----- sys/libnh/npm-package/src/nethackShim.js | 64 ------------- sys/libnh/npm-package/test/test.js | 57 ----------- win/shim/winshim.c | 115 ++--------------------- 7 files changed, 7 insertions(+), 406 deletions(-) delete mode 100644 sys/libnh/npm-package/LICENSE.md delete mode 100644 sys/libnh/npm-package/README.md delete mode 100644 sys/libnh/npm-package/package-lock.json delete mode 100644 sys/libnh/npm-package/package.json delete mode 100644 sys/libnh/npm-package/src/nethackShim.js delete mode 100644 sys/libnh/npm-package/test/test.js diff --git a/sys/libnh/npm-package/LICENSE.md b/sys/libnh/npm-package/LICENSE.md deleted file mode 100644 index 5ad7e3417..000000000 --- a/sys/libnh/npm-package/LICENSE.md +++ /dev/null @@ -1,95 +0,0 @@ - NETHACK GENERAL PUBLIC LICENSE - (Copyright 1989 M. Stephenson) - - (Based on the BISON general public license, - copyright 1988 Richard M. Stallman) - - Everyone is permitted to copy and distribute verbatim copies of this - license, but changing it is not allowed. You can also use this wording to - make the terms for other programs. - - The license agreements of most software companies keep you at the mercy of -those companies. By contrast, our general public license is intended to give -everyone the right to share NetHack. To make sure that you get the rights we -want you to have, we need to make restrictions that forbid anyone to deny you -these rights or to ask you to surrender the rights. Hence this license -agreement. - - Specifically, we want to make sure that you have the right to give away -copies of NetHack, that you receive source code or else can get it if you -want it, that you can change NetHack or use pieces of it in new free -programs, and that you know you can do these things. - - To make sure that everyone has such rights, we have to forbid you to -deprive anyone else of these rights. For example, if you distribute copies -of NetHack, you must give the recipients all the rights that you have. You -must make sure that they, too, receive or can get the source code. And you -must tell them their rights. - - Also, for our own protection, we must make certain that everyone finds out -that there is no warranty for NetHack. If NetHack is modified by someone -else and passed on, we want its recipients to know that what they have is -not what we distributed. - - Therefore we (Mike Stephenson and other holders of NetHack copyrights) make -the following terms which say what you must do to be allowed to distribute or -change NetHack. - - - COPYING POLICIES - - 1. You may copy and distribute verbatim copies of NetHack source code as -you receive it, in any medium, provided that you keep intact the notices on -all files that refer to copyrights, to this License Agreement, and to the -absence of any warranty; and give any other recipients of the NetHack -program a copy of this License Agreement along with the program. - - 2. You may modify your copy or copies of NetHack or any portion of it, and -copy and distribute such modifications under the terms of Paragraph 1 above -(including distributing this License Agreement), provided that you also do the -following: - - a) cause the modified files to carry prominent notices stating that you - changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, that in - whole or in part contains or is a derivative of NetHack or any part - thereof, to be licensed at no charge to all third parties on terms - identical to those contained in this License Agreement (except that you - may choose to grant more extensive warranty protection to some or all - third parties, at your option) - - c) You may charge a distribution fee for the physical act of - transferring a copy, and you may at your option offer warranty protection - in exchange for a fee. - - 3. You may copy and distribute NetHack (or a portion or derivative of it, -under Paragraph 2) in object code or executable form under the terms of -Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete machine-readable source code, which - must be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) accompany it with full information as to how to obtain the complete - machine-readable source code from an appropriate archive site. (This - alternative is allowed only for noncommercial distribution.) - -For these purposes, complete source code means either the full source -distribution as originally released over Usenet or updated copies of the -files in this distribution used to create the object code or executable. - - 4. You may not copy, sublicense, distribute or transfer NetHack except as -expressly provided under this License Agreement. Any attempt otherwise to -copy, sublicense, distribute or transfer NetHack is void and your rights to -use the program under this License agreement shall be automatically -terminated. However, parties who have received computer software programs -from you with this License Agreement will not have their licenses terminated -so long as such parties remain in full compliance. - - -Stated plainly: You are permitted to modify NetHack, or otherwise use parts -of NetHack, provided that you comply with the conditions specified above; -in particular, your modified NetHack or program containing parts of NetHack -must remain freely available as provided in this License Agreement. In -other words, go ahead and share NetHack, but don't try to stop anyone else -from sharing it farther. diff --git a/sys/libnh/npm-package/README.md b/sys/libnh/npm-package/README.md deleted file mode 100644 index 2c9b96938..000000000 --- a/sys/libnh/npm-package/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# NetHack -This is the ACTUAL NetHack game, originally written in 1982 and one of the longest-standing open source collaborations. This isn't a wrapper around the binary NetHack, but the game itself compiled into [WebAssembly](https://webassembly.org/) (WASM) using [emscripten](https://emscripten.org/). This module should run [anywhere WebAssembly is supported](https://developer.mozilla.org/en-US/docs/WebAssembly#Browser_compatibility) including node.js and modern browsers. - -Since NetHack typically uses the [TTY](https://en.wikipedia.org/wiki/Computer_terminal#Text_terminals) to show depictions of the game and that won't work for WebAssembly, you are required to implement the graphics portion of NetHack to make this work. This allows a wide variety of UIs to be created, both text and graphics based as well as using keyboard and mouse to control the game. The API for implementing graphics is described below. - -## Install - -``` sh -npm install nethack -``` - -## API -The main module returns a setup function: `startNethack(uiCallback, moduleOptions)`. -* `uiCallback(name, ... args)` - Your callback function that will handle rendering NetHack on the screen of your choice. The `name` argument is one of the UI functions of the [NetHack Window Interface](https://github.com/NetHack/NetHack/blob/NetHack-3.7/doc/window.doc) and the `args` are corresponding to the window interface function that is being called. You are required to return the correct type of data for the function that is implemented. The `uiCallback` may be an `async` function. -* `moduleOptions` - An optional [emscripten Module object](https://emscripten.org/docs/api_reference/module.html) for configuring the WASM that will be run. - * `Module.arguments` - Of note is the [arguments property](https://emscripten.org/docs/api_reference/module.html#Module.arguments) which gets passed to NetHack as its [command line parameters](https://nethackwiki.com/wiki/Options). - -There are a number of auxilary functions and variables that may help with building your applications. All of these are under `globalThis.nethackOptions`. Use `console.log(globalThis.nethackOptions)` for a full list of options. Some worth mentioning are: -* `globalThis.nethackOptions.helpers` - Helper functions that are useful for NetHack windowing ports - * `globalThis.nethackOptions.mapglyphHelper` - Converts an integer glyph into a character to be displayed. Useful if you are using ASCII characters for representing NetHack (as opposed to tiles). Interface is `mapglyphHelper(glyph, x, y, mgflags)` and will typically be called as part of the `shim_print_glyph` function. -* `globalThis.nethackOptions.constants` - A Object full of constants that are `#define`'d in NetHack's C code. Useful for translating to / from numbers in the APIs and return values. - -## Example -``` js -let nethackStart = require("nethack"); - -nethackStart(doGraphics); - -let winCount = 0; -async function doGraphics(name, ... args) { - console.log(`shim graphics: ${name} [${args}]`); - - switch(name) { - case "shim_create_nhwindow": - winCount++; - console.log("creating window", args, "returning", winCount); - return winCount; - case "shim_yn_function": - case "shim_message_menu": - return 121; // return 'y' to all questions - case "shim_nhgetch": - case "shim_nh_poskey": - return 0; // simulates a mouse click on "exit up the stairs" - default: - return 0; - } -} -``` - -## Other Notes -* This module isn't small -- the WASM code is about 10MB. It may be slow to load over non-broadband connections. There are some emscripten build optimizations that may help with browser builds (such as dynamic loading), but those aren't currently part of this package. Pull requests are always welcome. :) -* This hasn't been tested on browsers. If you get this to work on a browser, please let me know and I will add notes. Or if anyone wants to help setup automated browser testing, that would be supremely appreciated. \ No newline at end of file diff --git a/sys/libnh/npm-package/package-lock.json b/sys/libnh/npm-package/package-lock.json deleted file mode 100644 index fb5f7b7e1..000000000 --- a/sys/libnh/npm-package/package-lock.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "@neth4ck/neth4ck", - "version": "1.0.0", - "lockfileVersion": 1 -} diff --git a/sys/libnh/npm-package/package.json b/sys/libnh/npm-package/package.json deleted file mode 100644 index d7a11e442..000000000 --- a/sys/libnh/npm-package/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "@neth4ck/neth4ck", - "version": "1.0.2", - "description": "The original NetHack rogue-like game built as a WebAssembly module", - "main": "src/nethackShim.js", - "scripts": { - "test": "npm run build && node test/test.js", - "clean": "rm ./build/nethack.js; rm ./build/nethack.wasm; true", - "build": "mkdir build; cp ../../../targets/wasm/nethack.js ../../../targets/wasm/nethack.wasm ./build", - "prepack": "npm run build" - }, - "keywords": [ - "nethack", - "rogue", - "rogue-like", - "roguelike", - "dungeon", - "dungeons", - "game", - "rpg", - "dnd" - ], - "author": "Adam Powers ", - "license": "SEE LICENSE IN LICENSE.md" -} diff --git a/sys/libnh/npm-package/src/nethackShim.js b/sys/libnh/npm-package/src/nethackShim.js deleted file mode 100644 index 23c58e021..000000000 --- a/sys/libnh/npm-package/src/nethackShim.js +++ /dev/null @@ -1,64 +0,0 @@ -const path = require("path"); - -let Module; -let userCallback; -let savedOnRuntimeInitialized; - -// starts nethack -function nethackStart(cb, inputModule = {}) { - if (typeof cb !== "string" && typeof cb !== "function") { - throw new TypeError("expected first argument to be 'Function' or 'String' representing global callback function name"); - } - - if (typeof inputModule !== "object") { - throw new TypeError("expected second argument to be object"); - } - - let cbName; - if (typeof cb === "function") { - cbName = cb.name; - if (cbName === "") { - cbName = "__anonymousNetHackCallback"; - } - - if (globalThis[cbName] === undefined) { - globalThis[cbName] = cb; - } else if (globalThis[cbName] !== cb) { - throw new Error(`'globalThis["${cbName}"]' is not the same as specified callback`); - } - } - - /* global globalThis */ - userCallback = globalThis[cbName]; - if (typeof userCallback !== "function") { - throw new TypeError(`expected 'globalThis["${cbName}"]' to be a function`); - } - // if(userCallback.constructor.name !== "AsyncFunction") throw new TypeError(`expected 'globalThis["${cbName}"]' to be an async function`); - - // Emscripten Module config - Module = inputModule; - savedOnRuntimeInitialized = Module.onRuntimeInitialized; - Module.onRuntimeInitialized = function(... args) { - // after the WASM is loaded, add the shim graphics callback function - Module.ccall( - "shim_graphics_set_callback", // C function name - null, // return type - ["string"], // arg types - [cbName], // arg values - {async: true}, // options - ); - - // if the user had their own onRuntimeInitialized(), call it now - if (savedOnRuntimeInitialized) { - savedOnRuntimeInitialized(... args); - } - }; - - // load and run the module - let factory = require(path.join(__dirname, "../build/nethack.js")); - factory(Module); -} - -// TODO: ES6 'import' style module -module.exports = nethackStart; - diff --git a/sys/libnh/npm-package/test/test.js b/sys/libnh/npm-package/test/test.js deleted file mode 100644 index 5ad4e4e62..000000000 --- a/sys/libnh/npm-package/test/test.js +++ /dev/null @@ -1,57 +0,0 @@ -let nethackStart = require("../src/nethackShim.js"); -Error.stackTraceLimit = 20; - -// debugging to make sure the JavaScript event loop isn't blocked -// const {performance} = require("perf_hooks"); -// let currentTime = 0; -// let lastTime = 0; -// setInterval(() => { -// lastTime = currentTime; -// currentTime = performance.now(); -// console.log("Time since last JavaScript loop:", currentTime-lastTime); -// }, 10); - -let Module = {}; -let winCount = 0; - -/* global globalThis */ -nethackStart(async function (name, ... args) { - switch(name) { - case "shim_init_nhwindows": - console.log("globalThis.nethackGlobal", globalThis.nethackGlobal); - break; - case "shim_create_nhwindow": - winCount++; - console.log("creating window", args, "returning", winCount); - return winCount; - case "shim_print_glyph": - var x = args[1]; - var y = args[2]; - var glyph = args[3]; - - var ret = globalThis.nethackGlobal.helpers.mapglyphHelper(glyph, x, y, 0); - console.log(`GLYPH (${x},${y}): ${String.fromCharCode(ret.ch)}`); - return; - // case "shim_update_inventory": - // globalThis.nethackGlobal.helpers.displayInventory(); - // return; - case "shim_select_menu": - return await selectMenu(...args); - case "shim_yn_function": - case "shim_message_menu": - return 121; // 'y' - case "shim_getmsghistory": - return ""; - case "shim_nhgetch": - case "shim_nh_poskey": - return 0; - default: - console.log(`called doGraphics: ${name} [${args}]`); - return 0; - } -}, Module); - -async function selectMenu(window, how, selected) { - Module.setValue(selected, 0, "*"); - return -1; -} \ No newline at end of file diff --git a/win/shim/winshim.c b/win/shim/winshim.c index 4fb5f0d22..b37da9b11 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -35,7 +35,13 @@ EMSCRIPTEN_KEEPALIVE static char *shim_callback_name = NULL; void shim_graphics_set_callback(char *cbName) { if (shim_callback_name != NULL) free(shim_callback_name); - shim_callback_name = strdup(cbName); + if(cbName && strlen(cbName) > 0) { + debugf("setting shim_callback_name: %s\n", cbName); + shim_callback_name = strdup(cbName); + } else { + debugf("un-setting shim_callback_name\n"); + shim_callback_name = NULL; + } /* TODO: free(shim_callback_name) during shutdown? */ } void local_callback (const char *cb_name, const char *shim_name, void *ret_ptr, const char *fmt_str, void *args); @@ -96,27 +102,6 @@ void name fn_args { \ } #endif /* __EMSCRIPTEN__ */ -enum win_types { - WINSHIM_MESSAGE = 1, - WINSHIM_MAP, - WINSHIM_MENU, - WINSHIM_EXT -}; - -#define VSTUB(name, args) \ -void name args { \ - printf ("Running " #name "...\n"); \ -} - -#define STUB(name, retval, args) \ -name args { \ - printf ("Running " #name "...\n"); \ - return retval; \ -} - -#define DECL(name, args) \ -void name args; - VDECLCB(shim_init_nhwindows,(int *argcp, char **argv), "vpp", P2V argcp, P2V argv) VDECLCB(shim_player_selection,(void), "v") VDECLCB(shim_askname,(void), "v") @@ -279,8 +264,6 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r jsArgs.push(val); } - decodeArgs(name, jsArgs); - // do the callback let userCallback = globalThis[cbName]; runJsEventLoop(() => userCallback.call(this, name, ... jsArgs)).then((retVal) => { @@ -293,90 +276,6 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r }, 0); }); - // make callback arguments friendly: convert numbers to strings where possible - function decodeArgs(name, args) { - // if (!globalThis.nethackGlobal.makeArgsFriendly) return; - - switch(name) { - case "shim_create_nhwindow": - args[0] = globalThis.nethackGlobal.constants["WIN_TYPE"][args[0]]; - break; - case "shim_status_update": - // which field is being updated? - args[0] = globalThis.nethackGlobal.constants["STATUS_FIELD"][args[0]]; - // arg[1] is a string unless it is BL_CONDITION, BL_RESET, BL_FLUSH, BL_CHARACTERISTICS - if(args[0] !== "BL_CONDITION" && - args[0] !== "BL_RESET" && - args[0] !== "BL_FLUSH" && - args[0] !== "BL_CHARACTERISTICS" && - args[1]) { - args[1] = getArg(name, args[1], "s"); - } else { - args[1] = getArg(name, args[1], "p"); - } - break; - case "shim_display_file": - args[1] = !!args[1]; - case "shim_display_nhwindow": - args[0] = decodeWindow(args[0]); - args[1] = !!args[1]; - break; - case "shim_getmsghistory": - args[0] = !!args[0]; - break; - case "shim_putmsghistory": - args[1] = !!args[1]; - break; - case "shim_status_enablefield": - console.log("shim_status_enablefield arg 1:", args[1]); - args[3] = !!args[3]; - break; - case "shim_add_menu": - args[0] = decodeWindow(args[0]); - // args[1] = mapglyphHelper(args[1]); - // args[5] = decodeAttr(args[5]); - break; - case "shim_putstr": - args[0] = decodeWindow(args[0]); - break; - case "shim_select_menu": - args[0] = decodeWindow(args[0]); - args[1] = decodeSelected(args[1]); - break; - case "shim_clear_nhwindow": - case "shim_destroy_nhwindow": - case "shim_curs": - case "shim_start_menu": - case "shim_end_menu": - case "shim_print_glyph": - args[0] = decodeWindow(args[0]); - break; - } - } - - function decodeWindow(winid) { - let { WIN_MAP, WIN_INVEN, WIN_STATUS, WIN_MESSAGE } = globalThis.nethackGlobal.globals; - switch(winid) { - case WIN_MAP: return "WIN_MAP"; - case WIN_MESSAGE: return "WIN_MESSAGE"; - case WIN_STATUS: return "WIN_STATUS"; - case WIN_INVEN: return "WIN_INVEN"; - default: return winid; - } - // return winid; - } - - function decodeSelected(how) { - let { PICK_NONE, PICK_ONE, PICK_ANY } = globalThis.nethackGlobal.constants.MENU_SELECT; - switch(how) { - case PICK_NONE: return "PICK_NONE"; - case PICK_ONE: return "PICK_ONE"; - case PICK_ANY: return "PICK_ANY"; - default: return how; - } - - } - function getArg(name, ptr, type) { return (type === "o")?ptr:getPointerValue(name, getValue(ptr, "*"), type); } From 37361001f46cde0dfe0e9f64c03093ae67a4426f Mon Sep 17 00:00:00 2001 From: Adam Powers Date: Tue, 17 Nov 2020 23:58:12 -0800 Subject: [PATCH 427/708] pre-fix @PatR 'SHELLERS on VMS' change --- sys/libnh/libnhmain.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/libnh/libnhmain.c b/sys/libnh/libnhmain.c index 844f385d0..bbd16482f 100644 --- a/sys/libnh/libnhmain.c +++ b/sys/libnh/libnhmain.c @@ -648,11 +648,11 @@ char *name; boolean check_user_string(optstr) -char *optstr; +const char *optstr; { struct passwd *pw; int pwlen; - char *eop, *w; + const char *eop, *w; char *pwname = 0; if (optstr[0] == '*') @@ -664,7 +664,7 @@ char *optstr; if (!pwname || !*pwname) return FALSE; pwlen = (int) strlen(pwname); - eop = eos(optstr); + eop = eos((char *)optstr); w = optstr; while (w + pwlen <= eop) { if (!*w) From 9aeb4db3b24466d22104f3549286ffc13666609d Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 18 Nov 2020 08:21:07 -0500 Subject: [PATCH 428/708] wasm-bug-fixes-2 github PR #412 --- doc/fixes37.0 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 973f98992..ac28534c6 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -661,7 +661,7 @@ allow themed room subrooms to be filled (github #347) allow rereading spellbooks to refresh memory at any time (github #261) allow themed rooms constrained by level difficulty (github #344) add a varied form of LIBNH nethack library contribution (github #385, #403) -add cross-compile to WASM (github #385, #403) +add cross-compile to WASM (github #385, #403, #412) Code Cleanup and Reorganization From 55d2e359f513c7b0f4a0730c2b75e71516790fc9 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Wed, 18 Nov 2020 08:24:07 -0500 Subject: [PATCH 429/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/Files b/Files index 511936008..c1adc3fc9 100644 --- a/Files +++ b/Files @@ -222,18 +222,6 @@ sys/libnh: (files in top directory) README.md libnhmain.c sysconf -sys/libnh/npm-package: -(files in top directory) -LICENSE.md README.md package-lock.json package.json - -sys/libnh/npm-package/src: -(file in top directory) -nethackShim.js - -sys/libnh/npm-package/test: -(file in top directory) -test.js - sys/libnh/test: (files in top directory) README.md libtest.c run.sh From db90e7907c0ac01bfa2ec6f83797e6bc3ded781a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 18 Nov 2020 08:56:20 -0800 Subject: [PATCH 430/708] Qt: yet more status... Fix the minor problem of the status lines moving up or down a tiny amount when using the condensed (statuslines:2) layout and the condition line changed from empty to non-empty or vice versa. The widget used as filler when no conditions are shown needed to have non-empty label text (single space suffices) and also has to have its font set to the same value as the rest of status. (I previously tried a label of " " and also "_" but had left the font with its default value.) The adjustments to the prefix string when the value of Xp/Exp ("Level" -> "Lvl" -> "L") or Score ("Score" -> "Scr" -> "S") was too wide needed some fixing up. If shrinkage was needed, it was setting the value multiple times and any extra times confused field highlighting because it seemed to be assigning same value rather than a changed one. For condensed layout that moves Alignment to the Characteristics line, add a vertical separator line between Charisma and Alignment. --- win/Qt/qt_stat.cpp | 92 ++++++++++++++++++++++++++++------------------ win/Qt/qt_stat.h | 2 + 2 files changed, 58 insertions(+), 36 deletions(-) diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index a3bed62c6..133655e86 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -58,12 +58,6 @@ // judgement, for alignment and dungeon location) and "ignore" (don't // highlight, to suppress the bogus highlighting that currently happens // when toggling 'showexp' or 'showscore'). -// The condensed display (statuslines:2; Alignment with Characteristics -// instead of with Conditions and Time,Score on HP,...,Gold row) has -// vertical padding when the Conditions row is empty, but having the -// first Cond come On or the last one go Off still makes the rest of -// status shift a little as if the padding (same size icon plus empty -// text label) was slightly taller than a regular Cond. // extern "C" { @@ -114,7 +108,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : score(this,"Score"), // if SCORE_ON_BOTL defined and 'showscore' option On /* last two rows: alignment followed by conditions (icons over text) */ align(this,"Alignment"), - blank2(this, ""), // used to prevent Conditions row from being empty + blank2(this, " "), // used to prevent Conditions row from being empty hunger(this,""), encumber(this,""), stoned(this,"Stone"), // major conditions @@ -133,6 +127,8 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : hline1(this), // separators hline2(this), hline3(this), + vline1(this), // vertical separator between Characteristics and Alignment + vline2(this), // padding for row 2 to match row 1's separator; not shown /* miscellaneous; not display fields */ cursy(0), first_set(true), @@ -206,12 +202,18 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : ride.setIcon(p_ride); // separator lines - hline1.setFrameStyle(QFrame::HLine|QFrame::Sunken); - hline2.setFrameStyle(QFrame::HLine|QFrame::Sunken); - hline3.setFrameStyle(QFrame::HLine|QFrame::Sunken); + hline1.setFrameStyle(QFrame::HLine | QFrame::Sunken); + hline2.setFrameStyle(QFrame::HLine | QFrame::Sunken); + hline3.setFrameStyle(QFrame::HLine | QFrame::Sunken); hline1.setLineWidth(1); hline2.setLineWidth(1); hline3.setLineWidth(1); + // vertical separators for condensed layout (statuslines:2) + vline1.setFrameStyle(QFrame::VLine | QFrame::Sunken); + vline2.setFrameStyle(QFrame::VLine | QFrame::Sunken); + vline1.setLineWidth(1); // separates Alignment from Charisma + vline2.setLineWidth(1); + vline2.hide(); // padding to keep row 2 aligned with row 1, never shown // set up last but shown first (above name) via layout below */ QHBoxLayout *hpbar = InitHitpointBar(); @@ -239,6 +241,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : charbox->addWidget(&cha); if (!spreadout) { // when condensed, include Alignment with Characteristics + charbox->addWidget(&vline1); // show a short vertical separator charbox->addWidget(&align); } vbox->addLayout(charbox); @@ -261,6 +264,7 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : statbox->addWidget(&score); // usually empty column #5 #endif statbox->addWidget(&gold); // columns 6 and maybe empty 7 + statbox->addWidget(&vline2); // padding between 6 and 7; not shown statbox->addWidget(&time); } vbox->addLayout(statbox); @@ -328,10 +332,19 @@ void NetHackQtStatusWindow::doUpdate() power.setFont(normal); ac.setFont(normal); level.setFont(normal); + blank1.setFont(normal); // padding gold.setFont(normal); time.setFont(normal); score.setFont(normal); align.setFont(normal); + // blank2 is used as a dummy condition when Alignment has been moved + // elsewhere (statuslines:2) and no other conditions currently apply; + // it has a blank icon with a label of a single space (if the label + // is completely empty, the rest of status shifts down a little when + // one or more real conditions replace it and shifts up again when + // all conditions are removed and this one is reinstated--as if "" is + // slightly taller than " ") + blank2.setFont(normal); hunger.setFont(normal); encumber.setFont(normal); stoned.setFont(normal); @@ -762,40 +775,46 @@ void NetHackQtStatusWindow::updateStats() // might be too wide to fit static const char *const lvllbl[3] = { "Level:", "Lvl:", "L:" }; QFontMetrics fm(level.label->font()); - int startingpass = ::flags.showexp ? 0 : 3; - for (int i = startingpass; i < 6; ++i) { - // passes 0,1,2 are with Exp, 3,4,5 without (3 should always fit) + for (int i = ::flags.showexp ? 0 : 3; i < 4; ++i) { + // passes 0,1,2 are with Exp, 3 is without Exp and always fits if (i < 3) { - buf.sprintf("%s%ld/%ld", lvllbl[i], - (long) u.ulevel, (long) u.uexp); - level.setLabel(buf, NetHackQtLabelledIcon::NoNum, - (long) u.uexp); + buf.sprintf("%s%ld/%ld", lvllbl[i], (long) u.ulevel, u.uexp); } else { buf.sprintf("%s%ld", lvllbl[i - 3], (long) u.ulevel); - level.setLabel(buf, NetHackQtLabelledIcon::NoNum, - (long) u.ulevel); } - // 2: allow a couple of pixels at either end to be clipped off - if (fm.size(0, buf).width() <= (2 + level.width() + 2)) + // +2: allow a couple of pixels at either end to be clipped off + if (fm.size(0, buf).width() <= (2 + level.label->width() + 2)) break; } + level.setLabel(buf, NetHackQtLabelledIcon::NoNum, + // if we intended to show Exp but must settle + // for Xp due to width, we still want to use + // Exp for setLabel()'s Up|Down highlighting + ::flags.showexp ? u.uexp : (long) u.ulevel); } buf.sprintf("/%d", u.uenmax); - power.setLabel("Pow:", u.uen, buf); + power.setLabel("Pow:", (long) u.uen, buf); ac.setLabel("AC:", (long) u.uac); - // label prefix used to be "Au:", tty uses "$:" - gold.setLabel("Gold:", money_cnt(g.invent)); + // gold prefix used to be "Au:", tty uses "$:"; never too wide to fit; + // practical limit due to carrying capacity limit is less than 300K + long goldamt = money_cnt(g.invent); + goldamt = std::max(goldamt, 0L); // sanity; core's botl() does likewise + goldamt = std::min(goldamt, 99999999L); // ditto + gold.setLabel("Gold:", goldamt); text = NULL; - if (u.ualign.type==A_CHAOTIC) { - align.setIcon(p_chaotic); - text = "Chaotic"; - } else if (u.ualign.type==A_NEUTRAL) { - align.setIcon(p_neutral); - text = "Neutral"; + if (u.ualign.type == A_LAWFUL) { + align.setIcon(p_lawful); + text = "Lawful"; + } else if (u.ualign.type == A_NEUTRAL) { + align.setIcon(p_neutral); + text = "Neutral"; } else { - align.setIcon(p_lawful); - text = "Lawful"; + // Unaligned should never happen but handle it sanely if it does + align.setIcon(p_chaotic); + text = (u.ualign.type == A_CHAOTIC) ? "Chaotic" + : (u.ualign.type == A_NONE) ? "unaligned" + : "other?"; } if (text) { // false: don't highlight as 'became lower' even if the internal @@ -833,11 +852,11 @@ void NetHackQtStatusWindow::updateStats() QFontMetrics fm(score.label->font()); for (int i = 0; i < 3; ++i) { buf.sprintf("%s%ld", scrlbl[i], pts); - score.setLabel(buf, NetHackQtLabelledIcon::NoNum, pts); - // 2: allow a couple of pixels at either end to be clipped off + // +2: allow couple of pixels at either end to be clipped off if (fm.size(0, buf).width() <= (2 + score.width() + 2)) break; } + score.setLabel(buf, NetHackQtLabelledIcon::NoNum, pts); // with Xp/Exp, we fallback to Xp if the shortest label prefix // is still too long; here we just show a clipped value and // let user either live with it or turn 'showscore' off (or @@ -863,17 +882,18 @@ void NetHackQtStatusWindow::updateStats() wis.highlightWhenChanging(); cha.highlightWhenChanging(); - gold.highlightWhenChanging(); hp.highlightWhenChanging(); power.highlightWhenChanging(); ac.highlightWhenChanging(); ac.lowIsGood(); level.highlightWhenChanging(); - align.highlightWhenChanging(); + gold.highlightWhenChanging(); // don't highlight 'time' because it changes almost continuously //time.highlightWhenChanging(); score.highlightWhenChanging(); + align.highlightWhenChanging(); + hunger.highlightWhenChanging(); encumber.highlightWhenChanging(); stoned.highlightWhenChanging(); diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index 6464be047..4f24c7027 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -131,6 +131,8 @@ private: QFrame hline1; // between dlevel and characteristics QFrame hline2; // between characteristics and regular status fields QFrame hline3; // between regular fields and time,score or conditions + QFrame vline1; // for statuslines:2, between Cha and Alignment + QFrame vline2; // for statuslines:2, padding between Gold and Time int cursy; From 27b93148c0b9ff8d905e79d023bf908f921d6cc3 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 18 Nov 2020 11:16:21 -0800 Subject: [PATCH 431/708] ki-rin's horn Let ki-rin cure themselves (of being stunned, confused, or blinded) with their own horn, and make them be poison resistant. They aren't unicorns but their horn is very much like a unicorn horn. They're flagged no-corpse so this hasn't changed them to leave behind a horn upon death. They were flagged as animals who neighed but they are also spell casters. I took the animal flag off (they're still no-hands so shouldn't be able to use items; also, unicorns aren't flagged as animals either) and changed sound to 'ms_spell'. --- dat/data.base | 11 ++++++----- doc/fixes37.0 | 6 +++++- src/monst.c | 8 +++++--- src/muse.c | 30 ++++++++++++++++++++---------- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/dat/data.base b/dat/data.base index 66f32e68a..117d28fe3 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1,5 +1,5 @@ # NetHack 3.7 data.base -# $NHDT-Date: 1596498239 2020/08/03 23:43:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.97 $ +# $NHDT-Date: 1605726848 2020/11/18 19:14:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ # Copyright (c) 1994, 1995, 1996 by the NetHack Development Team # Copyright (c) 1994 by Boudewijn Wayers # NetHack may be freely redistributed. See license for details. @@ -2699,10 +2699,11 @@ kelp* specimens in their native setting. [ 20,000 Leagues Under the Sea, by Jules Verne ] ki-rin - The ki-rin is a strange-looking flying creature. It has - scales, a mane like a lion, a tail, hooves, and a horn. It - is brightly colored, and can usually be found flying in the - sky looking for good deeds to reward. + The ki-rin is a strange-looking wingless flying creature. + It has scales, a mane like a lion, a tail, four legs with + hooves, and a horn like a unicorn's. It is brightly colored, + and can usually be found flying in the sky looking for good + deeds to reward. king arthur *arthur Ector took both his sons to the church before which the diff --git a/doc/fixes37.0 b/doc/fixes37.0 index ac28534c6..caaf3fa64 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.354 $ $NHDT-Date: 1605578879 2020/11/17 02:07:59 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.356 $ $NHDT-Date: 1605726848 2020/11/18 19:14:08 $ General Fixes and Modified Features ----------------------------------- @@ -296,6 +296,10 @@ hero could break a wand ("raising the wand high over your head, you break it if a monster threw a cocktrice egg at the hero but hit and petrified another monster, the hero would get credit/blame for killing it update persistent inventory when putting on a helmet causes it to auto-curse +since ki-rin look quite a bit like unicorns, make them be more like one: + allow them to use their own horn to cure themselves; remove M1_ANIMAL, + change MS_NEIGH to MS_SPELL, add MR_POISON; they're still 'A' rather + than 'u' and don't care about gems Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/monst.c b/src/monst.c index 9bbce0a27..1955f37a0 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 monst.c $NHDT-Date: 1596498187 2020/08/03 23:43:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 3.7 monst.c $NHDT-Date: 1605726850 2020/11/18 19:14:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1020,13 +1020,15 @@ NEARDATA struct permonst mons_init[] = { M1_FLY | M1_HUMANOID | M1_SEE_INVIS, M2_NOPOLY | M2_MINION | M2_STALK | M2_STRONG | M2_NASTY | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 19, CLR_WHITE), + /* the AD&D Monster Manual depicts ki-rin as very similar to unicorns + except that they fly (without wings) and can cast spells */ MON("ki-rin", S_ANGEL, LVL(16, 18, -5, 90, 15), (G_NOHELL | G_NOCORPSE | 1), A(ATTK(AT_KICK, AD_PHYS, 2, 4), ATTK(AT_KICK, AD_PHYS, 2, 4), ATTK(AT_BUTT, AD_PHYS, 3, 6), ATTK(AT_MAGC, AD_SPEL, 2, 6), NO_ATTK, NO_ATTK), - SIZ(WT_HUMAN, 400, MS_NEIGH, MZ_LARGE), 0, 0, - M1_FLY | M1_ANIMAL | M1_NOHANDS | M1_SEE_INVIS, + SIZ(WT_HUMAN, 400, MS_SPELL, MZ_LARGE), MR_POISON, 0, + M1_FLY | M1_NOHANDS | M1_SEE_INVIS, M2_NOPOLY | M2_MINION | M2_STALK | M2_STRONG | M2_NASTY | M2_LORD, M3_INFRAVISIBLE | M3_INFRAVISION, 21, HI_GOLD), MON("Archon", S_ANGEL, LVL(19, 16, -6, 80, 15), diff --git a/src/muse.c b/src/muse.c index 12e2cb6d6..d82792d4a 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 muse.c $NHDT-Date: 1603509297 2020/10/24 03:14:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */ +/* NetHack 3.7 muse.c $NHDT-Date: 1605726852 2020/11/18 19:14:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -331,13 +331,16 @@ boolean find_defensive(mtmp) struct monst *mtmp; { - register struct obj *obj = 0; + struct obj *obj; struct trap *t; int fraction, x = mtmp->mx, y = mtmp->my; boolean stuck = (mtmp == u.ustuck), immobile = (mtmp->data->mmove == 0); stairway *stway; + g.m.defensive = (struct obj *) 0; + g.m.has_defense = 0; + if (is_animal(mtmp->data) || mindless(mtmp->data)) return FALSE; if (dist2(x, y, mtmp->mux, mtmp->muy) > 25) @@ -345,19 +348,25 @@ struct monst *mtmp; if (u.uswallow && stuck) return FALSE; - g.m.defensive = (struct obj *) 0; - g.m.has_defense = 0; - - /* since unicorn horns don't get used up, the monster would look - * silly trying to use the same cursed horn round after round + /* + * Since unicorn horns don't get used up, the monster would look + * silly trying to use the same cursed horn round after round, + * so skip cursed unicorn horns. + * + * Unicorns use their own horns; they're excluded from inventory + * scanning by nohands(). Ki-rin is depicted in the AD&D Monster + * Manual with same horn as a unicorn, so let it use its horn too. + * is_unicorn() doesn't include it; the class differs and it has + * no interest in gems. */ if (mtmp->mconf || mtmp->mstun || !mtmp->mcansee) { - if (!is_unicorn(mtmp->data) && !nohands(mtmp->data)) { + obj = 0; + if (!nohands(mtmp->data)) { for (obj = mtmp->minvent; obj; obj = obj->nobj) if (obj->otyp == UNICORN_HORN && !obj->cursed) break; } - if (obj || is_unicorn(mtmp->data)) { + if (obj || is_unicorn(mtmp->data) || mtmp->data == &mons[PM_KI_RIN]) { g.m.defensive = obj; g.m.has_defense = MUSE_UNICORN_HORN; return TRUE; @@ -2363,7 +2372,8 @@ struct obj *obj; if (typ == PICK_AXE) return (boolean) needspick(mon->data); if (typ == UNICORN_HORN) - return (boolean) (!obj->cursed && !is_unicorn(mon->data)); + return (boolean) (!obj->cursed && !is_unicorn(mon->data) + && mon->data != &mons[PM_KI_RIN]); if (typ == FROST_HORN || typ == FIRE_HORN) return (obj->spe > 0 && can_blow(mon)); if (Is_container(obj) && !(Is_mbag(obj) && obj->cursed)) From 7b5059065497ff7de93fabbb714f6484718f6ec6 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 19 Nov 2020 01:57:13 -0800 Subject: [PATCH 432/708] rename #wizlevelflip to #wizfliplevel Since ^V is dead key for me with Qt on OSX, I use #wizlevelport instead. It's annoying to have to type all the way up to the 'p' for it to become distinct. Rename the biggest conflict, \#wizlevelflip to #wizfliplevel. I still have to type as far as the first 'e' for #wizlevelport but 6 characters are easier to type than 10. It wasn't in the Guidebook so I've left things that way. I am adding it to 'wizhelp' though. --- dat/wizhelp | 3 ++- src/cmd.c | 12 ++++++------ src/sp_lev.c | 8 ++++---- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/dat/wizhelp b/dat/wizhelp index 4e68fef66..46b46dd52 100644 --- a/dat/wizhelp +++ b/dat/wizhelp @@ -20,9 +20,10 @@ Debug-Mode Quick Reference: #vanquished == disclose counts of dead monsters sorted in various ways #vision == show vision array #wizborn == show monster birth/death/geno/extinct stats +#wizfliplevel == transpose the current dungeon level #wizintrinsic == set selected intrinsic timeouts #wizmakemap == recreate the current dungeon level -#wizrumorcheck == validate rumor indexing and show first, second, and last +#wizrumorcheck == validate rumor indexing; also show first, second, and last random engravings, epitaphs, and hallucinatory monsters #wizsmell == smell a monster #wizwhere == show dungeon placement of all special levels diff --git a/src/cmd.c b/src/cmd.c index c6561ee19..ac1f1e21a 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1602621705 2020/10/13 20:41:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.423 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1605779800 2020/11/19 09:56:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.425 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -141,7 +141,7 @@ static int NDECL(wiz_polyself); static int NDECL(wiz_load_lua); static int NDECL(wiz_level_tele); static int NDECL(wiz_level_change); -static int NDECL(wiz_level_flip); +static int NDECL(wiz_flip_level); static int NDECL(wiz_show_seenv); static int NDECL(wiz_show_vision); static int NDECL(wiz_smell); @@ -1061,9 +1061,9 @@ wiz_level_tele(VOID_ARGS) return 0; } -/* #wizlevelflip - transpose the current level */ +/* #wizfliplevel - transpose the current level */ static int -wiz_level_flip(VOID_ARGS) +wiz_flip_level(VOID_ARGS) { static const char choices[] = "0123", prmpt[] = "Flip 0=randomly, 1=vertically, 2=horizonally, 3=both:"; @@ -1943,14 +1943,14 @@ struct ext_func_tab extcmdlist[] = { #endif { C('e'), "wizdetect", "reveal hidden things within a small radius", wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, + { '\0', "wizfliplevel", "flip the level", + wiz_flip_level, IFBURIED | WIZMODECMD }, { C('g'), "wizgenesis", "create a monster", wiz_genesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { C('i'), "wizidentify", "identify all items in inventory", wiz_identify, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '\0', "wizintrinsic", "set an intrinsic", wiz_intrinsic, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, - { '\0', "wizlevelflip", "flip the level", - wiz_level_flip, IFBURIED | WIZMODECMD }, { C('v'), "wizlevelport", "teleport to another level", wiz_level_tele, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '\0', "wizloaddes", "load and execute a des-file lua script", diff --git a/src/sp_lev.c b/src/sp_lev.c index 348f023e0..a21fc72ab 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sp_lev.c $NHDT-Date: 1600909016 2020/09/24 00:56:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.203 $ */ +/* NetHack 3.7 sp_lev.c $NHDT-Date: 1605779812 2020/11/19 09:56:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.216 $ */ /* Copyright (c) 1989 by Jean-Christophe Collet */ /* NetHack may be freely redistributed. See license for details. */ @@ -406,7 +406,7 @@ struct rm *lev; } } -/* for #wizlevelflip; not needed when flipping during level creation; +/* for #wizfliplevel; not needed when flipping during level creation; update seen vector for whole flip area and glyph for known walls */ static void flip_visuals(flp, minx, miny, maxx, maxy) @@ -483,7 +483,7 @@ flip_encoded_direction_bits(int flp, int val) } while (0) /* transpose top with bottom or left with right or both; sometimes called - for new special levels, or for any level via the #wizlevelflip command */ + for new special levels, or for any level via the #wizfliplevel command */ void flip_level(flp, extras) int flp; @@ -808,7 +808,7 @@ boolean extras; } } - if (extras) { /* for #wizlevelflip rather than during level creation */ + if (extras) { /* for #wizfliplevel rather than during level creation */ /* flip hero location only if inside the flippable area */ if (inFlipArea(u.ux, u.uy)) { if (flp & 1) From f7a3e7884cfbbf2b298512aa6d18a04a9c3004d0 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 19 Nov 2020 04:48:15 -0800 Subject: [PATCH 433/708] daily Qt status window update... Highlight changes to dungeon location or alignment in blue instead of green or red since neither the old value nor the new can be classified as better than the other. Likewise when changing between regular Hp and Xp (or Xp/Exp) to or from you-as-mon Hp and HD when polymorph or rehumanization takes place. When toggling Score On, start out highlighted in blue instead of green. When toggling it Off, don't highlight the blank space where it had been in red. At the moment there's a quirk here; if it is highlighted in green (from recent change) or blue (from having just been toggled on) at the time it gets toggled off, the space stays green or blue until that highlight times out. (It has occurred to me that the bogus red highlight might have been added to deliberately overwrite stale green highlights. If so, a better fix should be achievable.) For the title (plname and rank or plname and monster-species), capitalize the player name since core's botl() and at least some other interfaces do that. TODO: toggling Exp needs work. The field used for deciding up/down changes gets swapped and the update in progress compares apples and oranges. [This wasn't an issue in the original Qt implementation where Xp and Exp were two separate fields.] --- win/Qt/qt_icon.cpp | 99 +++++++++++++++++-------------- win/Qt/qt_icon.h | 21 ++++--- win/Qt/qt_stat.cpp | 142 +++++++++++++++++++++++++++++++-------------- win/Qt/qt_stat.h | 6 ++ 4 files changed, 177 insertions(+), 91 deletions(-) diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 388a1e500..19763cffb 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -7,7 +7,8 @@ // TODO? // When the label specifies two values separated by a slash (curHP/maxHP, // curEn/maxEn, XpLevel/ExpPoints when 'showexp' is On), highlighting -// for changes is all or nothing. curHP and curEn go up and down +// for changes is all or nothing based on which field caller passes +// as the value to use for comparison. curHP and curEn go up and down // without any change to the corresponding maximum all the time. Much // rarer, but when maxHP and maxEn go up with level gain, the hero // could be injured by a passive counterattack or collateral damage @@ -19,6 +20,8 @@ // Highlighting two slash-separated values independently would be // worthwhile but with the 'single label using a style sheet for color' // approach it isn't going to happen. +// FIXME: +// Every LabelledIcon duplicates hl_better, hl_worse, hl_changd. // extern "C" { @@ -39,9 +42,9 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l) : QWidget(parent), label(new QLabel(l,this)), icon(NULL), - low_is_good(false), - prev_value(-123), - turn_count(-1) + comp_mode(BiggerIsBetter), + prev_value(NoNum), + turn_count(-1L) { initHighlight(); } @@ -51,9 +54,9 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l, QWidget(parent), label(new QLabel(l,this)), icon(new QLabel(this)), - low_is_good(false), - prev_value(-123), - turn_count(-1) + comp_mode(BiggerIsBetter), + prev_value(NoNum), + turn_count(-1L) { setIcon(i); initHighlight(); @@ -61,12 +64,13 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l, void NetHackQtLabelledIcon::initHighlight() { - // note: named 'green' is much darker than Qt::green - hl_good = "QLabel { background-color : green; color : white }"; - hl_bad = "QLabel { background-color : red ; color : white }"; + // note: string "green" is much darker than Qt::green + hl_better = "QLabel { background-color : green ; color : white }"; + hl_worse = "QLabel { background-color : red ; color : white }"; + hl_changd = "QLabel { background-color : blue ; color : white }"; } -void NetHackQtLabelledIcon::setLabel(const QString& t, bool lower) +void NetHackQtLabelledIcon::setLabel(const QString &t, bool lower) { if (!label) { label=new QLabel(this); @@ -75,7 +79,12 @@ void NetHackQtLabelledIcon::setLabel(const QString& t, bool lower) if (label->text() != t) { label->setText(t); ForceResize(); - highlight((lower == low_is_good) ? hl_good : hl_bad); + if (comp_mode != NoCompare) { + highlight((comp_mode == NeitherIsBetter) ? hl_changd + : (comp_mode == (lower ? SmallerIsBetter + : BiggerIsBetter)) ? hl_better + : hl_worse); + } } } @@ -113,14 +122,19 @@ void NetHackQtLabelledIcon::setFont(const QFont& f) if (label) label->setFont(f); } +// [pr] this might no longer be needed; it seems to have been responsible +// for highlighting the blank space where an optional field like Score +// was just toggled off; we don't need or want that anymore... void NetHackQtLabelledIcon::show() { + if ( #if QT_VERSION >= 300 - if (isHidden()) + isHidden() #else - if (!isVisible()) + !isVisible() #endif - highlight(hl_bad); + && comp_mode != NoCompare) + highlight(hl_worse); QWidget::show(); } @@ -156,41 +170,42 @@ QSize NetHackQtLabelledIcon::minimumSizeHint() const void NetHackQtLabelledIcon::highlightWhenChanging() { - turn_count=0; + turn_count = 0; // turn_count starts negative (as flag to not highlight) } -void NetHackQtLabelledIcon::lowIsGood() +// set comp_mode to one of NoCompare or {Bigger,Smaller,Neither}IsBetter +void NetHackQtLabelledIcon::setCompareMode(int newmode) { - low_is_good=true; -} - -void NetHackQtLabelledIcon::dissipateHighlight() -{ - if (turn_count>0) { - turn_count--; - if (!turn_count) - unhighlight(); - } -} - -void NetHackQtLabelledIcon::highlight(const QString& hl) -{ - if (label) { // Surely it is?! - if (turn_count>=0) { - label->setStyleSheet(hl); - turn_count=4; - // `4' includes this turn, so dissipates after - // 3 more keypresses. - } else { - label->setStyleSheet(""); - } - } + comp_mode = newmode; } void NetHackQtLabelledIcon::unhighlight() { if (label) { // Surely it is?! - label->setStyleSheet(""); + label->setStyleSheet(""); + } + if (turn_count > 0) + turn_count = 0; +} + +void NetHackQtLabelledIcon::highlight(const QString& hl) +{ + if (label) { // Surely it is?! + if (turn_count >= 0) { + label->setStyleSheet(hl); + turn_count = 4; + // 4 includes this turn, so dissipates after 3 more keypresses. + } else { + unhighlight(); + } + } +} + +void NetHackQtLabelledIcon::dissipateHighlight() +{ + if (turn_count > 0) { + if (!--turn_count) + unhighlight(); } } diff --git a/win/Qt/qt_icon.h b/win/Qt/qt_icon.h index 56a24f0e1..454236896 100644 --- a/win/Qt/qt_icon.h +++ b/win/Qt/qt_icon.h @@ -9,13 +9,18 @@ namespace nethack_qt_ { +enum CompareMode { + NoCompare = -1, BiggerIsBetter = 0, + SmallerIsBetter = 1, NeitherIsBetter = 2 +}; + class NetHackQtLabelledIcon : public QWidget { public: NetHackQtLabelledIcon(QWidget *parent, const char *label); NetHackQtLabelledIcon(QWidget *parent, const char *label, const QPixmap &icon); - enum { NoNum=-99999 }; + enum { NoNum = -99999L }; void setLabel(const QString &, bool lower=true); // string void setLabel(const QString &, long, const QString &tail=""); // number void setLabel(const QString &, long show_value, @@ -25,7 +30,7 @@ public: //QString labelText() { return QString(this->label->text()); } void highlightWhenChanging(); - void lowIsGood(); + void setCompareMode(int newmode); void dissipateHighlight(); void ForceResize(); @@ -45,11 +50,13 @@ private: void highlight(const QString& highlight); void unhighlight(); - bool low_is_good; - int prev_value; - int turn_count; /* last time the value changed */ - QString hl_good; - QString hl_bad; + int comp_mode; /* compareMode; default is BiggerIsBetter */ + long prev_value; + long turn_count; /* last time the value changed */ + + QString hl_better; + QString hl_worse; + QString hl_changd; }; } // namespace nethack_qt_ diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 133655e86..f76612b22 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -16,24 +16,39 @@ // five status fields without icons (some containing two values: // HP/HPmax, Energy/Enmax, AC, XpLevel/ExpPoints or HD, [blank], Gold) // separator line -// optional line with two text fields (Time:1234, Score:89) +// line with two optional text fields (Time:1234, Score:89), maybe blank // varying number of icons (one or more, each paired with...) // corresponding text (Alignment plus zero or more status conditions // including Hunger if not "normal" and encumbrance if not "normal") // // The hitpoint bar spans the width of the status window when enabled. // Title and location are centered. -// The icons and text for the size characteristics are evenly spaced. -// The five main stats are padded with an empty sixth and spaced to -// match the characteristics. -// Time and Score are spaced as if each were three fields wide. +// The icons and text for the six characteristics are evenly spaced; +// this pair of lines is sometimes referred to as "row 1" below. +// The five main stats or slash-separated stat pairs are padded with an +// empty slot between Xp and Gold; adding the sixth makes that row +// line up with the characteristics; this line is sometimes referred +// to as "row 2". +// Time and Score are spaced as if each were three fields wide; their +// line is "row 3" relative to statuslines:2 vs statuslines:3. // Icons and texts for alignment and conditions are left justified. // The separator lines are thin and don't take up much vertical space. // When enabled, the hitpoint bar bisects the margin above Title, // increasing the overall status height by 9 pixels; when disabled, // the status shifts up by those 9 pixels. -// When Time+Score line is empty, it still takes up the vertical space -// that would be used to show those values. +// When row 3 (Time, Score) is blank, it still takes up the vertical +// space that would be used to show those values. +// +// The above is for statuslines:3, which used to be the default. For +// statuslines:2, rows 1 and 2 are extended from six to seven fields +// and row 3 (optional Time, Score) is eliminated. Alignment is +// moved from the beginning of the Conditions pair (icon over text) +// of lines up to the end of row 1, the Characteristics pair of lines, +// with a separator between Cha:NN and it. Time, when active, is +// placed after Gold. Score, if enabled and active, is shown in the +// filler slot before Gold. When there are no Conditions to display, +// there is an an invisible fake one (blank icon over blank text) +// rendered in order to preserve the vertical space they need. // // FIXME: // When hitpoint bar is shown, attempting to resize horizontally won't @@ -42,7 +57,13 @@ // style sheets used to control color, but removing those constraints // causes the bar display to get screwed up.) // There are separate icons for Satiated and Hungry, but Weak, Fainting, -// and Fainted all share the Hungry one when they should be different. +// and Fainted all share the Hungry one. Weak should have its own, +// Fainting+Fainted should have another. The current two depict +// plates with cutlery which is a bit of an anachronism. Statiated +// could be replaced by a figure in profile with a bulging belly, +// Hungry similar but with a slightly concave belly, Weak either a +// collapsing figure or a much larger concavity or both, Fainting/ +// Fainted a fully collapsed figure. // // TODO: // If/when status conditions become too wide for the status window, scale @@ -51,13 +72,13 @@ // the rest of status. That takes up more space, which is ok, but it // also increases the vertical margin in between them by more than is // necessary. Should squeeze some of that excess blank space out. -// Changed values are highlighted as "gone Up" (green) or "gone Down" (red) -// with NetHackQtLabelledIcon::setLabel() taking an optional boolean -// argument indicating "lower is better" (for AC). That flag should -// have other choices: "changed" (third color with no better or worse -// judgement, for alignment and dungeon location) and "ignore" (don't -// highlight, to suppress the bogus highlighting that currently happens -// when toggling 'showexp' or 'showscore'). +// Highlighting of Xp/Exp needs work when 'showexp' is toggled On or Off. +// The field passed to xp.setLabel() for its better vs worse comparison +// gets swapped from Xp to Exp or vice versa, yielding a nonsensical +// comparison for the first status update after the 'showexp' toggle. +// Toggling 'showscore' while Score is highlighted leaves the highlight +// on blank space until it times out. (Time isn't highlighted and Exp +// is combined with Xp so always updated; only Score is affected.) // extern "C" { @@ -132,7 +153,10 @@ NetHackQtStatusWindow::NetHackQtStatusWindow() : /* miscellaneous; not display fields */ cursy(0), first_set(true), - alreadyfullhp(false) + alreadyfullhp(false), + was_polyd(false), + had_exp(false), + had_score(false) { if (!qt_compact_mode) { int w = NetHackQtBind::mainWidget()->width(); @@ -502,7 +526,7 @@ void NetHackQtStatusWindow::fadeHighlighting() level.dissipateHighlight(); align.dissipateHighlight(); - time.dissipateHighlight(); + //time.dissipateHighlight(); score.dissipateHighlight(); hunger.dissipateHighlight(); @@ -665,12 +689,19 @@ void NetHackQtStatusWindow::HitpointBar() void NetHackQtStatusWindow::updateStats() { if (!parentWidget()) return; + if (cursy != 0) return; /* do a complete update when line 0 is done */ QString buf; - const char *text; - - if (cursy != 0) return; /* do a complete update when line 0 is done */ + if (first_set) { + was_polyd = Upolyd ? true : false; + had_exp = ::flags.showexp ? true : false; + // not '#ifndef SCORE_ON_BOTL' here; use the variable and the widget + had_score = ::flags.showscore ? true : false; // false when disabled + score.setLabel(""); // init if enabled, one-time set if disabled + } + // display hitpoint bar if it is active; it isn't subject to field + // highlighting so we don't track whether it has just been toggled On|Off HitpointBar(); int st = ACURR(A_STR); @@ -747,18 +778,23 @@ void NetHackQtStatusWindow::updateStats() buf = rank_of(u.ulevel, g.pl_character[0], ::flags.female); } QString buf2; - buf2.sprintf("%s the %s", g.plname, buf.toLatin1().constData()); + char buf3[BUFSZ]; + buf2.sprintf("%s the %s", upstart(strcpy(buf3, g.plname)), + buf.toLatin1().constData()); name.setLabel(buf2, NetHackQtLabelledIcon::NoNum, u.ulevel); - char buf3[BUFSZ]; if (!describe_level(buf3)) { Sprintf(buf3, "%s, level %d", g.dungeons[u.uz.dnum].dname, ::depth(&u.uz)); } - // false: always highlight as 'change for the better' regardless of - // new depth compared to old - dlevel.setLabel(buf3, false); + dlevel.setLabel(buf3); + int poly_toggled = !was_polyd ^ !Upolyd; + if (poly_toggled) { + // for this update, changed values aren't better|worse, just different + hp.setCompareMode(NeitherIsBetter); + level.setCompareMode(NeitherIsBetter); + } if (Upolyd) { // You're a monster! buf.sprintf("/%d", u.mhmax); @@ -773,6 +809,9 @@ void NetHackQtStatusWindow::updateStats() // up/down highlighting becomes tricky--don't try very hard; // depending upon font size and status layout, "Level:NN/nnnnnnnn" // might be too wide to fit +#if 0 /* not yet */ + int exp_toggled = !had_exp ^ !::flags.showexp; +#endif static const char *const lvllbl[3] = { "Level:", "Lvl:", "L:" }; QFontMetrics fm(level.label->font()); for (int i = ::flags.showexp ? 0 : 3; i < 4; ++i) { @@ -792,6 +831,14 @@ void NetHackQtStatusWindow::updateStats() // Exp for setLabel()'s Up|Down highlighting ::flags.showexp ? u.uexp : (long) u.ulevel); } + if (poly_toggled) { + // for next update, changed values will be better|worse as usual + hp.setCompareMode(BiggerIsBetter); + level.setCompareMode(BiggerIsBetter); + } + was_polyd = Upolyd ? true : false; + had_exp = (::flags.showexp && !was_polyd) ? true : false; + buf.sprintf("/%d", u.uenmax); power.setLabel("Pow:", (long) u.uen, buf); ac.setLabel("AC:", (long) u.uac); @@ -802,7 +849,7 @@ void NetHackQtStatusWindow::updateStats() goldamt = std::min(goldamt, 99999999L); // ditto gold.setLabel("Gold:", goldamt); - text = NULL; + const char *text = NULL; if (u.ualign.type == A_LAWFUL) { align.setIcon(p_lawful); text = "Lawful"; @@ -816,14 +863,10 @@ void NetHackQtStatusWindow::updateStats() : (u.ualign.type == A_NONE) ? "unaligned" : "other?"; } - if (text) { - // false: don't highlight as 'became lower' even if the internal - // numeric value is becoming lower (N -> C, L -> N || C) - align.setLabel(text, false); - // without this, the ankh pixmap shifts from centered to left - // justified relative to the label text for some unknown reason... - align.ForceResize(); - } + align.setLabel(QString(text)); + // without this, the ankh pixmap shifts from centered to left + // justified relative to the label text for some unknown reason... + align.ForceResize(); if (spreadout) ++k; // when not condensed, Alignment is shown on the Conditions row @@ -832,6 +875,8 @@ void NetHackQtStatusWindow::updateStats() } else blank2.hide(); + // Time isn't highlighted (due to constantly changing) so we don't keep + // track of whether it has just been toggled On or Off if (::flags.time) { // hypothetically Time could grow to enough digits to have trouble // fitting, but it's not worth worrying about @@ -840,7 +885,10 @@ void NetHackQtStatusWindow::updateStats() time.setLabel(""); } #ifdef SCORE_ON_BOTL + int score_toggled = !had_score ^ !::flags.showscore; if (::flags.showscore) { + if (score_toggled) // toggled On + score.setCompareMode(NeitherIsBetter); long pts = botl_score(); if (spreadout) { // plenty of room; Time and Score both have the width of 3 fields @@ -863,17 +911,26 @@ void NetHackQtStatusWindow::updateStats() // set statuslines:3 to take advantage of the extra room that // the spread out status layout provides) } - } else -#endif - { - score.setLabel(""); + } else { + if (score_toggled) { // toggled Off; if already Off, no need to set "" + score.setCompareMode(NoCompare); + score.setLabel(""); // blank when not active + } } + if (score_toggled) + score.setCompareMode(BiggerIsBetter); + had_score = ::flags.showscore ? true : false; +#endif /* SCORE_ON_BOTL */ if (first_set) { first_set=false; + was_polyd = Upolyd ? true : false; + had_exp = ::flags.showexp ? true : false; + had_score = ::flags.showscore ? true : false; + name.highlightWhenChanging(); - dlevel.highlightWhenChanging(); + dlevel.highlightWhenChanging(); dlevel.setCompareMode(NeitherIsBetter); str.highlightWhenChanging(); dex.highlightWhenChanging(); @@ -884,15 +941,16 @@ void NetHackQtStatusWindow::updateStats() hp.highlightWhenChanging(); power.highlightWhenChanging(); - ac.highlightWhenChanging(); ac.lowIsGood(); + ac.highlightWhenChanging(); ac.setCompareMode(SmallerIsBetter); level.highlightWhenChanging(); gold.highlightWhenChanging(); // don't highlight 'time' because it changes almost continuously - //time.highlightWhenChanging(); + // [if we did highlight it, we wouldn't show increase as 'Better'] + //time.highlightWhenChanging(); time.setCompareMode(NeitherIsBetter); score.highlightWhenChanging(); - align.highlightWhenChanging(); + align.highlightWhenChanging(); align.setCompareMode(NeitherIsBetter); hunger.highlightWhenChanging(); encumber.highlightWhenChanging(); diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index 4f24c7027..a24028569 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -138,6 +138,12 @@ private: bool first_set; bool alreadyfullhp; + bool was_polyd; + bool had_exp; + // Time isn't highlighted (due to constantly changing) so we don't + // keep track of whether it was On and is now Off or vice versa + //bool had_time; + bool had_score; QHBoxLayout *InitHitpointBar(); void HitpointBar(); From 03d7d64d1556919cbeb830befb2db7d4be4899db Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 20 Nov 2020 18:56:35 -0800 Subject: [PATCH 434/708] create monster creating concealed mimic From an old bug report (sent directly to devteam, June of 2017): wand or scroll of create monster becomes discovered if it makes a mimic that is concealed as an object or as furniture within the hero's view. Fixing this in the general case [when does seeing a mimic as something other than a monster mean that the mimic is being seen?] is a massive can of worms, but fixing this specific case is trivial. --- doc/fixes37.0 | 5 ++++- include/display.h | 11 ++++++++++- src/makemon.c | 5 +++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index caaf3fa64..83aa7625f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.356 $ $NHDT-Date: 1605726848 2020/11/18 19:14:08 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.357 $ $NHDT-Date: 1605927391 2020/11/21 02:56:31 $ General Fixes and Modified Features ----------------------------------- @@ -300,6 +300,9 @@ since ki-rin look quite a bit like unicorns, make them be more like one: allow them to use their own horn to cure themselves; remove M1_ANIMAL, change MS_NEIGH to MS_SPELL, add MR_POISON; they're still 'A' rather than 'u' and don't care about gems +wand or scroll of create monster that makes a new monster which can be seen + or sensed becomes discovered but was doing so even for a concealed + mimic seen as furniture or an object Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/display.h b/include/display.h index 721b7f10b..28c02becd 100644 --- a/include/display.h +++ b/include/display.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.h $NHDT-Date: 1597700875 2020/08/17 21:47:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 3.7 display.h $NHDT-Date: 1605927391 2020/11/21 02:56:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.48 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -69,6 +69,15 @@ enum explosion_types { * hero can physically see the location of the monster. The function * vobj_at() returns a pointer to an object that the hero can see there. * Infravision is not taken into account. + * + * Note: not reliable for concealed mimics. They don't have + * 'mon->mundetected' set even when mimicking objects or furniture. + * [Fixing this with a pair of mon->m_ap_type checks here (via either + * 'typ!=object && typ!=furniture' or 'typ==nothing || typ==monster') + * will require reviewing every instance of mon_visible(), canseemon(), + * canspotmon(), is_safemon() and perhaps others. Fixing it by setting + * mon->mundetected when concealed would be better but also require + * reviewing all those instances and also existing mundetected instances.] */ #if 0 #define mon_visible(mon) \ diff --git a/src/makemon.c b/src/makemon.c index abf074fd5..67cc83452 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makemon.c $NHDT-Date: 1596498176 2020/08/03 23:42:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.177 $ */ +/* NetHack 3.7 makemon.c $NHDT-Date: 1605927392 2020/11/21 02:56:32 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -1503,7 +1503,8 @@ boolean neverask; x = c.x, y = c.y; mon = makemon(mptr, x, y, NO_MM_FLAGS); - if (mon && canspotmon(mon)) + if (mon && canspotmon(mon) && (M_AP_TYPE(mon) == M_AP_NOTHING + || M_AP_TYPE(mon) == M_AP_MONSTER)) known = TRUE; } return known; From d48e73070054d43b764a4693607bc729940cec00 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 21 Nov 2020 03:46:53 -0800 Subject: [PATCH 435/708] ki-rin body parts Use horse/unicorn body parts. The result for HAIR is "mane" which is appropriate. There's no field for SKIN so the question of whether to specify "scales" is moot. (Snakes and dragons describe HAIR as "scales" but that wouldn't be right for ki-rin.) --- doc/fixes37.0 | 6 +++--- src/polyself.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 83aa7625f..f3c9134a9 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.357 $ $NHDT-Date: 1605927391 2020/11/21 02:56:31 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.358 $ $NHDT-Date: 1605959203 2020/11/21 11:46:43 $ General Fixes and Modified Features ----------------------------------- @@ -298,8 +298,8 @@ if a monster threw a cocktrice egg at the hero but hit and petrified another update persistent inventory when putting on a helmet causes it to auto-curse since ki-rin look quite a bit like unicorns, make them be more like one: allow them to use their own horn to cure themselves; remove M1_ANIMAL, - change MS_NEIGH to MS_SPELL, add MR_POISON; they're still 'A' rather - than 'u' and don't care about gems + change MS_NEIGH to MS_SPELL, add MR_POISON, use horse body parts; + they're still 'A' rather than 'u' and don't care about gems wand or scroll of create monster that makes a new monster which can be seen or sensed becomes discovered but was doing so even for a concealed mimic seen as furniture or an object diff --git a/src/polyself.c b/src/polyself.c index 5beef979f..ccc076076 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 polyself.c $NHDT-Date: 1596498197 2020/08/03 23:43:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.155 $ */ +/* NetHack 3.7 polyself.c $NHDT-Date: 1605959204 2020/11/21 11:46:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.157 $ */ /* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -1783,6 +1783,7 @@ int part; if (mptr == &mons[PM_RAVEN]) return bird_parts[part]; if (mptr->mlet == S_CENTAUR || mptr->mlet == S_UNICORN + || mptr == &mons[PM_KI_RIN] || (mptr == &mons[PM_ROTHE] && part != HAIR)) return horse_parts[part]; if (mptr->mlet == S_LIGHT) { From 3e9d8f9aa5d7cfe3043371d773ea403eb4131b64 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 21 Nov 2020 17:37:01 -0800 Subject: [PATCH 436/708] 'showscore' vs containers When SCORE_ON_BOTL is enabled, you could tell how much gold is inside a container with unknown contents by having 'showsore' On and watching how much the score changed on the status line when picking the container up. --- doc/fixes37.0 | 4 +++- include/extern.h | 6 +++--- src/botl.c | 5 +++-- src/detect.c | 4 ++-- src/dokick.c | 16 +++++++--------- src/end.c | 6 +++--- src/shk.c | 22 ++++++++++++---------- src/topten.c | 5 +++-- src/u_init.c | 4 ++-- src/vault.c | 16 +++++++++------- 10 files changed, 47 insertions(+), 41 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f3c9134a9..aa2041366 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.358 $ $NHDT-Date: 1605959203 2020/11/21 11:46:43 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.359 $ $NHDT-Date: 1606008997 2020/11/22 01:36:37 $ General Fixes and Modified Features ----------------------------------- @@ -303,6 +303,8 @@ since ki-rin look quite a bit like unicorns, make them be more like one: wand or scroll of create monster that makes a new monster which can be seen or sensed becomes discovered but was doing so even for a concealed mimic seen as furniture or an object +'showscore' could be used to determine how much gold was inside a container + whose contents were unknown Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 843cb73eb..ce3d3bd87 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1605493683 2020/11/16 02:28:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.878 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1606008997 2020/11/22 01:36:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.880 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2396,7 +2396,7 @@ E void NDECL(finish_paybill); E struct obj *FDECL(find_oid, (unsigned)); E long FDECL(contained_cost, (struct obj *, struct monst *, long, BOOLEAN_P, BOOLEAN_P)); -E long FDECL(contained_gold, (struct obj *)); +E long FDECL(contained_gold, (struct obj *, BOOLEAN_P)); E void FDECL(picked_container, (struct obj *)); E void FDECL(gem_learned, (int)); E void FDECL(alter_cost, (struct obj *, long)); @@ -2823,7 +2823,7 @@ E void FDECL(uleftvault, (struct monst *)); E void NDECL(invault); E int FDECL(gd_move, (struct monst *)); E void FDECL(paygd, (BOOLEAN_P)); -E long NDECL(hidden_gold); +E long FDECL(hidden_gold, (BOOLEAN_P)); E boolean NDECL(gd_sound); E void FDECL(vault_gd_watching, (unsigned int)); diff --git a/src/botl.c b/src/botl.c index f27714091..4fc411e74 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.c $NHDT-Date: 1596498152 2020/08/03 23:42:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 3.7 botl.c $NHDT-Date: 1606008998 2020/11/22 01:36:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -398,7 +398,8 @@ botl_score() long deepest = deepest_lev_reached(FALSE); long utotal; - utotal = money_cnt(g.invent) + hidden_gold(); + /* hidden_gold(False): only gold in containers whose contents are known */ + utotal = money_cnt(g.invent) + hidden_gold(FALSE); if ((utotal -= u.umoney0) < 0L) utotal = 0L; utotal += u.urexp + (50 * (deepest - 1)) diff --git a/src/detect.c b/src/detect.c index 29acd7a18..575082e20 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 detect.c $NHDT-Date: 1596498155 2020/08/03 23:42:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */ +/* NetHack 3.7 detect.c $NHDT-Date: 1606009000 2020/11/22 01:36:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.123 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -357,7 +357,7 @@ register struct obj *sobj; if (g.youmonst.data == &mons[PM_GOLD_GOLEM]) Sprintf(buf, "You feel like a million %s!", currency(2L)); - else if (money_cnt(g.invent) || hidden_gold()) + else if (money_cnt(g.invent) || hidden_gold(TRUE)) Strcpy(buf, "You feel worried about your future financial situation."); else if (steedgold) diff --git a/src/dokick.c b/src/dokick.c index 80cdcaa50..65cb6f4e6 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dokick.c $NHDT-Date: 1596498160 2020/08/03 23:42:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.155 $ */ +/* NetHack 3.7 dokick.c $NHDT-Date: 1606009001 2020/11/22 01:36:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -341,14 +341,12 @@ register struct obj *gold; out of the vault. If he did do that, player could try fighting, then weasle out of being killed by throwing his/her gold when losing. */ - verbalize( - umoney - ? "Drop the rest and follow me." - : hidden_gold() - ? "You still have hidden gold. Drop it now." - : mtmp->mpeaceful - ? "I'll take care of that; please move along." - : "I'll take that; now get moving."); + verbalize(umoney ? "Drop the rest and follow me." + : hidden_gold(TRUE) + ? "You still have hidden gold. Drop it now." + : mtmp->mpeaceful + ? "I'll take care of that; please move along." + : "I'll take that; now get moving."); } else if (is_mercenary(mtmp->data)) { long goldreqd = 0L; diff --git a/src/end.c b/src/end.c index bdce05a88..ba489f9a4 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1603534633 2020/10/24 10:17:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.214 $ */ +/* NetHack 3.7 end.c $NHDT-Date: 1606009001 2020/11/22 01:36:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.215 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1382,8 +1382,8 @@ int how; umoney = money_cnt(g.invent); tmp = u.umoney0; - umoney += hidden_gold(); /* accumulate gold from containers */ - tmp = umoney - tmp; /* net gain */ + umoney += hidden_gold(TRUE); /* accumulate gold from containers */ + tmp = umoney - tmp; /* net gain */ if (tmp < 0L) tmp = 0L; diff --git a/src/shk.c b/src/shk.c index f393daab9..5ad0fb07a 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1596498208 2020/08/03 23:43:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.189 $ */ +/* NetHack 3.7 shk.c $NHDT-Date: 1606009003 2020/11/22 01:36:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1245,7 +1245,7 @@ dopay() long ltmp; long umoney; int pass, tmp, sk = 0, seensk = 0; - boolean paid = FALSE, stashed_gold = (hidden_gold() > 0L); + boolean paid = FALSE, stashed_gold = (hidden_gold(TRUE) > 0L); g.multi = 0; @@ -1595,7 +1595,8 @@ boolean itemize; long ltmp, quan, save_quan; long umoney = money_cnt(g.invent); int buy; - boolean stashed_gold = (hidden_gold() > 0L), consumed = (which == 0); + boolean stashed_gold = (hidden_gold(TRUE) > 0L), + consumed = (which == 0); if (!obj->unpaid && !bp->useup) { impossible("Paid object on bill??"); @@ -2226,8 +2227,9 @@ boolean unpaid_only; /* count amount of gold inside container 'obj' and any nested containers */ long -contained_gold(obj) +contained_gold(obj, even_if_unknown) struct obj *obj; +boolean even_if_unknown; /* True: all gold; False: limit to known contents */ { register struct obj *otmp; register long value = 0L; @@ -2236,8 +2238,8 @@ struct obj *obj; for (otmp = obj->cobj; otmp; otmp = otmp->nobj) if (otmp->oclass == COIN_CLASS) value += otmp->quan; - else if (Has_contents(otmp)) - value += contained_gold(otmp); + else if (Has_contents(otmp) && (otmp->cknown || even_if_unknown)) + value += contained_gold(otmp, even_if_unknown); return value; } @@ -2611,7 +2613,7 @@ boolean reset_nocharge; /* outer container might be marked no_charge but still have contents which should be charged for; clear no_charge when picking things up */ if (obj->no_charge) { - if (!Has_contents(obj) || (contained_gold(obj) == 0L + if (!Has_contents(obj) || (contained_gold(obj, TRUE) == 0L && contained_cost(obj, shkp, 0L, FALSE, !reset_nocharge) == 0L)) shkp = 0; /* not billable */ @@ -2661,7 +2663,7 @@ boolean ininv, dummy, silent; if (container) { cltmp = contained_cost(obj, shkp, cltmp, FALSE, FALSE); - gltmp = contained_gold(obj); + gltmp = contained_gold(obj, TRUE); if (ltmp) add_one_tobill(obj, dummy, shkp); @@ -2936,7 +2938,7 @@ boolean peaceful, silent; value += stolen_container(obj, shkp, 0L, ininv); if (!ininv) - gvalue += contained_gold(obj); + gvalue += contained_gold(obj, TRUE); } } @@ -3043,7 +3045,7 @@ xchar x, y; /* find the price of content before subfrombill */ cltmp = contained_cost(obj, shkp, cltmp, TRUE, FALSE); /* find the value of contained gold */ - gltmp += contained_gold(obj); + gltmp += contained_gold(obj, TRUE); cgold = (gltmp > 0L); } diff --git a/src/topten.c b/src/topten.c index 284d31ef5..db9208114 100644 --- a/src/topten.c +++ b/src/topten.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 topten.c $NHDT-Date: 1596498218 2020/08/03 23:43:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.73 $ */ +/* NetHack 3.7 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. */ @@ -374,7 +374,8 @@ int how; genders[flags.initgend].filecode, XLOG_SEP, aligns[1 - u.ualignbase[A_ORIGINAL]].filecode); Fprintf(rfile, "%cflags=0x%lx", XLOG_SEP, encodexlogflags()); - Fprintf(rfile, "%cgold=%ld", XLOG_SEP, money_cnt(g.invent) + hidden_gold()); + Fprintf(rfile, "%cgold=%ld", XLOG_SEP, + money_cnt(g.invent) + hidden_gold(TRUE)); Fprintf(rfile, "%cwish_cnt=%ld", XLOG_SEP, u.uconduct.wishes); Fprintf(rfile, "%carti_wish_cnt=%ld", XLOG_SEP, u.uconduct.wisharti); Fprintf(rfile, "\n"); diff --git a/src/u_init.c b/src/u_init.c index a0cb5bb68..81927ed9f 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 u_init.c $NHDT-Date: 1596498222 2020/08/03 23:43:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ +/* NetHack 3.7 u_init.c $NHDT-Date: 1606009005 2020/11/22 01:36:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.72 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -876,7 +876,7 @@ u_init() if (u.umoney0) ini_inv(Money); - u.umoney0 += hidden_gold(); /* in case sack has gold in it */ + u.umoney0 += hidden_gold(TRUE); /* in case sack has gold in it */ find_ac(); /* get initial ac value */ init_attr(75); /* init attribute values */ diff --git a/src/vault.c b/src/vault.c index a15e4eff6..c59ffd433 100644 --- a/src/vault.c +++ b/src/vault.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vault.c $NHDT-Date: 1596498223 2020/08/03 23:43:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.76 $ */ +/* NetHack 3.7 vault.c $NHDT-Date: 1606009006 2020/11/22 01:36:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -249,7 +249,7 @@ struct monst *grd; } /* if carrying gold and arriving anywhere other than next to the guard, set the guard loose */ - if ((money_cnt(g.invent) || hidden_gold()) + if ((money_cnt(g.invent) || hidden_gold(TRUE)) && um_dist(grd->mx, grd->my, 1)) { if (grd->mpeaceful) { if (canspotmon(grd)) /* see or sense via telepathy */ @@ -487,7 +487,7 @@ invault() else verbalize("I don't know you."); umoney = money_cnt(g.invent); - if (!umoney && !hidden_gold()) { + if (!umoney && !hidden_gold(TRUE)) { if (Deaf) pline("%s stomps%s.", noit_Monnam(guard), (Blind) ? "" : " and beckons"); @@ -795,7 +795,7 @@ register struct monst *grd; } umoney = money_cnt(g.invent); - u_carry_gold = umoney > 0L || hidden_gold() > 0L; + u_carry_gold = (umoney > 0L || hidden_gold(TRUE) > 0L); if (egrd->fcend == 1) { if (u_in_vault && (u_carry_gold || um_dist(grd->mx, grd->my, 1))) { if (egrd->warncnt == 3 && !Deaf) @@ -1107,15 +1107,17 @@ boolean silently; return; } +/* amount of gold in carried containers */ long -hidden_gold() +hidden_gold(even_if_unknown) +boolean even_if_unknown; /* True: all gold; False: limit to known contents */ { long value = 0L; struct obj *obj; for (obj = g.invent; obj; obj = obj->nobj) - if (Has_contents(obj)) - value += contained_gold(obj); + if (Has_contents(obj) && (obj->cknown || even_if_unknown)) + value += contained_gold(obj, even_if_unknown); /* unknown gold stuck inside statues may cause some consternation... */ return value; From efea46a93d79846ccd68edc6203a1abf99a90613 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 21 Nov 2020 18:21:16 -0800 Subject: [PATCH 437/708] tty: selecting gold in menus Requested by a beta tester nearly four years ago: '$' is both an inventory "letter" and a group accelator. The letter only works if gold is on the current menu page and was taking precedence over the group accelator. Allow '$' to toggle selection of gold regardless of the page. curses already behaves this way. X11 and Qt menus aren't paginated so also pick gold even if the '$' entry in the menu isn't visible at the time. No idea about Windows GUI... --- doc/fixes37.0 | 3 ++- win/tty/wintty.c | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index aa2041366..1d1f74d7f 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.359 $ $NHDT-Date: 1606008997 2020/11/22 01:36:37 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.360 $ $NHDT-Date: 1606011660 2020/11/22 02:21:00 $ General Fixes and Modified Features ----------------------------------- @@ -506,6 +506,7 @@ Qt+OSX: since menu entry help->"About Qt NetHack" gets hijacked and becomes tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic +tty: '$' can now select gold in a menu even when it isn't on current page Unix: when user name is used as default character name, keep hyphenated value intact instead stripping off dash and whatever follows as if that specified role/race/&c (worked once upon a time; broken since 3.3.0) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 44445f761..05bcfbca4 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ - /* NetHack 3.7 wintty.c $NHDT-Date: 1596498345 2020/08/03 23:45:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.259 $ */ + /* NetHack 3.7 wintty.c $NHDT-Date: 1606011660 2020/11/22 02:21:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -1922,7 +1922,12 @@ struct WinDesc *cw; if (n > 0) /* at least one group accelerator found */ for (rp = gacc, curr = cw->mlist; curr; curr = curr->next) - if (curr->gselector && curr->gselector != curr->selector + if (curr->gselector + && (curr->gselector != curr->selector + /* '$' is both a selector "letter" and a group + accelerator; including it in gacc allows gold to + be selected via group when not on current page */ + || curr->gselector == GOLD_SYM) && !index(gacc, curr->gselector) && (cw->how == PICK_ANY || gcnt[GSELIDX(curr->gselector)] == 1)) { From f43421ae3cd6123143811723a6ddd1327dcc9a11 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 22 Nov 2020 00:32:11 -0800 Subject: [PATCH 438/708] create monster creating concealed mimic revisisted commit 03d7d64d1556919cbeb830befb2db7d4be4899db: | [...] but fixing this specific case is trivial. Not trivial enough to avoid getting the details wrong. An old commit log message (58137a608acf418700dd527bc69b2ad5a198495d, June of 2006) claimed that this was fixed for bag of tricks but that was for monsters in general; mimics could still be wrong. --- doc/fixes37.0 | 8 ++++---- src/makemon.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 1d1f74d7f..19f8eeb93 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.360 $ $NHDT-Date: 1606011660 2020/11/22 02:21:00 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.361 $ $NHDT-Date: 1606033928 2020/11/22 08:32:08 $ General Fixes and Modified Features ----------------------------------- @@ -300,9 +300,9 @@ since ki-rin look quite a bit like unicorns, make them be more like one: allow them to use their own horn to cure themselves; remove M1_ANIMAL, change MS_NEIGH to MS_SPELL, add MR_POISON, use horse body parts; they're still 'A' rather than 'u' and don't care about gems -wand or scroll of create monster that makes a new monster which can be seen - or sensed becomes discovered but was doing so even for a concealed - mimic seen as furniture or an object +wand/scroll of create monster or bag of tricks that makes a new monster which + can be seen or sensed becomes discovered, but was doing so even for a + concealed mimic seen as furniture or an object 'showscore' could be used to determine how much gold was inside a container whose contents were unknown diff --git a/src/makemon.c b/src/makemon.c index 67cc83452..11725b94c 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 makemon.c $NHDT-Date: 1605927392 2020/11/21 02:56:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */ +/* NetHack 3.7 makemon.c $NHDT-Date: 1606033928 2020/11/22 08:32:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.180 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1502,9 +1502,12 @@ boolean neverask; if (!mptr && u.uinwater && enexto(&c, x, y, &mons[PM_GIANT_EEL])) x = c.x, y = c.y; - mon = makemon(mptr, x, y, NO_MM_FLAGS); - if (mon && canspotmon(mon) && (M_AP_TYPE(mon) == M_AP_NOTHING - || M_AP_TYPE(mon) == M_AP_MONSTER)) + if ((mon = makemon(mptr, x, y, NO_MM_FLAGS)) == 0) + continue; /* try again [should probably stop instead] */ + + if ((canseemon(mon) && (M_AP_TYPE(mon) == M_AP_NOTHING + || M_AP_TYPE(mon) == M_AP_MONSTER)) + || sensemon(mon)) known = TRUE; } return known; @@ -2360,7 +2363,9 @@ int *seencount; /* secondary output */ mtmp = makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS); if (mtmp) { ++moncount; - if (canspotmon(mtmp)) + if ((canseemon(mtmp) && (M_AP_TYPE(mtmp) == M_AP_NOTHING + || M_AP_TYPE(mtmp) == M_AP_MONSTER)) + || sensemon(mtmp)) ++seecount; } } while (--creatcnt > 0); From 6d4fd933b265ca64a3046205afd9d960795b6b5c Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 22 Nov 2020 01:10:52 -0800 Subject: [PATCH 439/708] Qt status bit When Qt highlights a field that has gotten better, use the same shade of green as is used for the green range of hitpoint bar. The old value was too dull, like olive green seen in shadow. --- win/Qt/qt_icon.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 19763cffb..b32ac0d9a 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -62,12 +62,18 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l, initHighlight(); } +// set up the style sheet strings used to specify color for status field +// labels [done "once", but once for each LabelledIcon that's constucted, +// so more than 20 copies overall] void NetHackQtLabelledIcon::initHighlight() { - // note: string "green" is much darker than Qt::green - hl_better = "QLabel { background-color : green ; color : white }"; - hl_worse = "QLabel { background-color : red ; color : white }"; - hl_changd = "QLabel { background-color : blue ; color : white }"; + // note: string "green" is much darker than enum Qt::green + // QColor("green") => #00ff00 + // QColor(Qt::green) => #008000 + // QColor("green").lighter(150) => #00c000 /* hitpoint bar's green */ + hl_better = "QLabel { background-color : #00c000 ; color : white }"; + hl_worse = "QLabel { background-color : red ; color : white }"; + hl_changd = "QLabel { background-color : blue ; color : white }"; } void NetHackQtLabelledIcon::setLabel(const QString &t, bool lower) From 3339d0247f8a9d6fd9fb403b153e5aaf1cfdb2d3 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 22 Nov 2020 02:36:10 -0800 Subject: [PATCH 440/708] Qt paperdoll bit For the tool tips shown if you let the mouse pointer hover over any of the cells in the paperdoll (inventory subset showing worn and wielded items), remove the trailing period and add a leading space and a trailing space. Improves readability. --- win/Qt/qt_inv.cpp | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index da2469ed4..732c66f84 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -46,6 +46,7 @@ NetHackQtInvUsageWindow::NetHackQtInvUsageWindow(QWidget* parent) : // needed to enable tool tips setMouseTracking(true); + // paperdoll is 6x3 but the indices are column oriented: 0..2x0..5 for (int x = 0; x <= 2; ++x) for (int y = 0; y <= 5; ++y) tips[x][y] = NULL; @@ -65,7 +66,9 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, { short int glyph; int border; - bool rev = false; + char tipstr[1 + BUFSZ + 1]; // extra room for leading and trailing space + bool rev = (flags == dollReverse), + canbe = (flags != dollUnused); if (nhobj) { border = BORDER_DEFAULT; @@ -79,35 +82,41 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, : BORDER_BLESSED; // set up a tool tip describing the item that will be displayed here - char *itmnam = xprname(nhobj, (char *) 0, nhobj->invlet, TRUE, 0L, 0L); - if (tips[x][y] && strlen(itmnam) > strlen(tips[x][y])) + Sprintf(tipstr, " %s ", // extra spaces for enhanced readability + // xprname: invlet, space, dash, space, object description + xprname(nhobj, (char *) NULL, nhobj->invlet, FALSE, 0L, 0L)); + // tips are managed with nethack's alloc(); we don't track allocation + // amount; allocated buffers get reused when big enough (usual case + // since paperdoll updates occur more often than equipment changes) + if (tips[x][y] && strlen(tipstr) > strlen(tips[x][y])) free((void *) tips[x][y]), tips[x][y] = NULL; if (tips[x][y]) - Strcpy(tips[x][y], itmnam); + Strcpy(tips[x][y], tipstr); // guaranteed to fit else - tips[x][y] = dupstr(itmnam); - - rev = (flags == dollReverse); + tips[x][y] = dupstr(tipstr); #endif glyph = obj_to_glyph(nhobj, rn2_on_display_rng); } else { border = NO_BORDER; #ifdef ENHANCED_PAPERDOLL - // caller passes an alternative tool tip for empty cells - if (tips[x][y] && (!alttip || strlen(alttip) > strlen(tips[x][y]))) + // caller usually passes an alternate tool tip for empty cells + size_t altlen = alttip ? 1U + strlen(alttip) + 1U : 0U; + if (tips[x][y] && (!alttip || altlen > strlen(tips[x][y]))) free((void *) tips[x][y]), tips[x][y] = NULL; - if (tips[x][y]) // above guarantees that test fails if alttip is Null - Strcpy(tips[x][y], alttip); - else if (alttip) - tips[x][y] = dupstr(alttip); + if (alttip) { + Sprintf(tipstr, " %s ", alttip); + if (tips[x][y]) + Strcpy(tips[x][y], tipstr); // guaranteed to fit + else + tips[x][y] = dupstr(tipstr); + } #else nhUse(alttip); #endif // an empty slot is shown as floor tile unless it's always empty - glyph = (flags != dollUnused) ? cmap_to_glyph(S_room) - : GLYPH_UNEXPLORED; + glyph = canbe ? cmap_to_glyph(S_room) : GLYPH_UNEXPLORED; } qt_settings->glyphs().drawBorderedCell(painter, glyph, x, y, border, rev); } From c2e20ff26314f331f0bffc52967d09383c711cad Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 22 Nov 2020 12:49:55 -0500 Subject: [PATCH 441/708] Makefile autodetects Visual Studio 16.8.2 --- sys/winnt/Makefile.msc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index b1c0cc7ca..23aa16cb6 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -543,7 +543,7 @@ rc=Rc # Visual Studio we are using. We set VSVER to 0000 to flag any version that # is too old or untested. # -#NMAKE version 1427291120 from latest VS 2019 (October 13, 2020 version 16.7.6) +#NMAKE version 1428293340 from latest VS 2019 (November 19, 2020 version 16.8.2) #!MESSAGE $(MAKEFLAGS) #!MESSAGE $(MAKEDIR) @@ -567,9 +567,9 @@ VSVER=2013 VSVER=2015 !ELSEIF ($(MAKEVERSION) > 1411000000) && ($(MAKEVERSION) < 1416270312) VSVER=2017 -!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1427291121) +!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1428293341) VSVER=$(VSNEWEST) -!ELSEIF ($(MAKEVERSION) > 1427291120) +!ELSEIF ($(MAKEVERSION) > 1428293340) VSVER=2999 #untested future version !ENDIF From 479bb877661fff4259a140effa22ae05da2b4bfb Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 23 Nov 2020 01:29:53 -0800 Subject: [PATCH 442/708] Qt status again: unhighlight disabled fields If 'showscore' has been On and gets toggled Off while Score is highlighted, remove that highlight immediately instead of letting it stick around a few turns until it times out. --- win/Qt/qt_icon.cpp | 9 +++++++-- win/Qt/qt_stat.cpp | 6 ++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index b32ac0d9a..4076fc65d 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -63,8 +63,8 @@ NetHackQtLabelledIcon::NetHackQtLabelledIcon(QWidget *parent, const char *l, } // set up the style sheet strings used to specify color for status field -// labels [done "once", but once for each LabelledIcon that's constucted, -// so more than 20 copies overall] +// labels [done "once", but once for each LabelledIcon that's constructed, +// so about 30 copies overall with 3.6's status conditions] void NetHackQtLabelledIcon::initHighlight() { // note: string "green" is much darker than enum Qt::green @@ -90,6 +90,11 @@ void NetHackQtLabelledIcon::setLabel(const QString &t, bool lower) : (comp_mode == (lower ? SmallerIsBetter : BiggerIsBetter)) ? hl_better : hl_worse); + } else if (turn_count) { + // if we don't want to highlight this status field but it is + // currently highlighted (perhaps optional Score recently went + // up and has just been toggled off), remove the highlight + unhighlight(); } } } diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index f76612b22..1d47321d1 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -76,9 +76,6 @@ // The field passed to xp.setLabel() for its better vs worse comparison // gets swapped from Xp to Exp or vice versa, yielding a nonsensical // comparison for the first status update after the 'showexp' toggle. -// Toggling 'showscore' while Score is highlighted leaves the highlight -// on blank space until it times out. (Time isn't highlighted and Exp -// is combined with Xp so always updated; only Score is affected.) // extern "C" { @@ -694,9 +691,10 @@ void NetHackQtStatusWindow::updateStats() QString buf; if (first_set) { + // set toggle-detection flags for optional fields was_polyd = Upolyd ? true : false; had_exp = ::flags.showexp ? true : false; - // not '#ifndef SCORE_ON_BOTL' here; use the variable and the widget + // not conditionalized upon '#ifdef SCORE_ON_BOTL' here had_score = ::flags.showscore ? true : false; // false when disabled score.setLabel(""); // init if enabled, one-time set if disabled } From 0c56c063163f410391dd771bff38e09dbf917a89 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 23 Nov 2020 17:39:00 -0800 Subject: [PATCH 443/708] Qt font selection dropdown menu In "Qt settings" (or "Preferences" for OSX), the current font size would show "Medium" if that was the current setting. So far, so good. However, if you clicked on the up/down arrows to get the dropdown menu, it was truncated to "Mediu" there regardless of current setting. Force the menu to be wide enough to show "Medium". --- win/Qt/qt_set.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index 939ae89a7..e3e0295b5 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -141,6 +141,7 @@ NetHackQtSettings::NetHackQtSettings() : connect(&dollheight, SIGNAL(valueChanged(int)), this, SLOT(resizeDoll())); #endif + fontsize.setMinimumContentsLength((int) strlen("Medium")); fontsize.addItem("Huge"); fontsize.addItem("Large"); fontsize.addItem("Medium"); From 43379bffcc499f35a843855df31d3abcd85a7e3c Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 23 Nov 2020 17:45:44 -0800 Subject: [PATCH 444/708] Qt status: highlights when toggling 'showexp' During status update at the time the 'showexp' option gets toggled on or off, prevent comparing Xp (level) against Exp (points) when deciding whether the value has gone up or down. Xp/Exp (when toggling on) or just Xp (when toggling off) will be highligthed in blue (changed, neither better nor worse) rather than green or red. --- win/Qt/qt_stat.cpp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 1d47321d1..dbd011d1e 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -72,10 +72,6 @@ // the rest of status. That takes up more space, which is ok, but it // also increases the vertical margin in between them by more than is // necessary. Should squeeze some of that excess blank space out. -// Highlighting of Xp/Exp needs work when 'showexp' is toggled On or Off. -// The field passed to xp.setLabel() for its better vs worse comparison -// gets swapped from Xp to Exp or vice versa, yielding a nonsensical -// comparison for the first status update after the 'showexp' toggle. // extern "C" { @@ -788,11 +784,12 @@ void NetHackQtStatusWindow::updateStats() dlevel.setLabel(buf3); int poly_toggled = !was_polyd ^ !Upolyd; - if (poly_toggled) { + int exp_toggled = !had_exp ^ !::flags.showexp; + if (poly_toggled) // for this update, changed values aren't better|worse, just different hp.setCompareMode(NeitherIsBetter); + if (poly_toggled || exp_toggled) level.setCompareMode(NeitherIsBetter); - } if (Upolyd) { // You're a monster! buf.sprintf("/%d", u.mhmax); @@ -807,9 +804,6 @@ void NetHackQtStatusWindow::updateStats() // up/down highlighting becomes tricky--don't try very hard; // depending upon font size and status layout, "Level:NN/nnnnnnnn" // might be too wide to fit -#if 0 /* not yet */ - int exp_toggled = !had_exp ^ !::flags.showexp; -#endif static const char *const lvllbl[3] = { "Level:", "Lvl:", "L:" }; QFontMetrics fm(level.label->font()); for (int i = ::flags.showexp ? 0 : 3; i < 4; ++i) { @@ -829,11 +823,11 @@ void NetHackQtStatusWindow::updateStats() // Exp for setLabel()'s Up|Down highlighting ::flags.showexp ? u.uexp : (long) u.ulevel); } - if (poly_toggled) { + if (poly_toggled) // for next update, changed values will be better|worse as usual hp.setCompareMode(BiggerIsBetter); + if (poly_toggled || exp_toggled) level.setCompareMode(BiggerIsBetter); - } was_polyd = Upolyd ? true : false; had_exp = (::flags.showexp && !was_polyd) ? true : false; From 229930e50570599239cfc7df1fd00e367f38e8b4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 24 Nov 2020 19:26:12 +0200 Subject: [PATCH 445/708] Fixes and sanity checks for monster undetected and trapped states Adds sanity checks for mtrapped and mundetected states. Fixes cases where those were left in wrong state. 1. Trapped monster (eg. a nymph) teleported out of a trap 2. Monster was hiding under ball or chain, which then got removed 3. While restoring a level, a zombie corpse revived while monster was hiding under it 4. A general case where the only object was deleted off floor and a monster was hiding under it Monsters hiding under ball or chain will now get revealed when the b or c are moved. --- include/extern.h | 1 + src/ball.c | 4 +++- src/invent.c | 4 +++- src/mkobj.c | 4 ++++ src/mon.c | 36 ++++++++++++++++++++++++++++++++++++ src/restore.c | 2 ++ src/teleport.c | 4 ++++ 7 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/extern.h b/include/extern.h index ce3d3bd87..4ea7e7575 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1514,6 +1514,7 @@ E void FDECL(seemimic, (struct monst *)); E void NDECL(rescham); E void NDECL(restartcham); E void FDECL(restore_cham, (struct monst *)); +E void FDECL(maybe_unhide_at, (XCHAR_P, XCHAR_P)); E boolean FDECL(hideunder, (struct monst *)); E void FDECL(hide_monst, (struct monst *)); E void FDECL(mon_animal_list, (BOOLEAN_P)); diff --git a/src/ball.c b/src/ball.c index 7bc78dd07..60099a83b 100644 --- a/src/ball.c +++ b/src/ball.c @@ -162,7 +162,7 @@ unplacebc_core() obj_extract_self(uball); if (Blind && (u.bc_felt & BC_BALL)) /* drop glyph */ levl[uball->ox][uball->oy].glyph = u.bglyph; - + maybe_unhide_at(uball->ox, uball->oy); newsym(uball->ox, uball->oy); } obj_extract_self(uchain); @@ -536,9 +536,11 @@ xchar ballx, bally, chainx, chainy; /* only matter !before */ } remove_object(uchain); + maybe_unhide_at(uchain->ox, uchain->oy); newsym(uchain->ox, uchain->oy); if (!carried(uball)) { remove_object(uball); + maybe_unhide_at(uball->ox, uball->oy); newsym(uball->ox, uball->oy); } } else { diff --git a/src/invent.c b/src/invent.c index 7c1393d2d..16d6ff01f 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1225,8 +1225,10 @@ register struct obj *obj; } update_map = (obj->where == OBJ_FLOOR); obj_extract_self(obj); - if (update_map) + if (update_map) { + maybe_unhide_at(obj->ox, obj->oy); newsym(obj->ox, obj->oy); + } obfree(obj, (struct obj *) 0); /* frees contents also */ } diff --git a/src/mkobj.c b/src/mkobj.c index f4960008b..71ef55a88 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2175,6 +2175,10 @@ struct obj *obj; panic("dealloc_obj with nobj"); if (obj->cobj) panic("dealloc_obj with cobj"); + if (obj == uball || obj == uchain) + impossible("dealloc_obj called on %s, owornmask=%lx", + (obj == uball) ? "uball" : "uchain", + obj->owornmask); /* free up any timers attached to the object */ if (obj->timed) diff --git a/src/mon.c b/src/mon.c index 6ae225d44..6a534d084 100644 --- a/src/mon.c +++ b/src/mon.c @@ -99,6 +99,29 @@ const char *msg; /* guardian angel on astral level is tame but has emin rather than edog */ if (mtmp->mtame && !has_edog(mtmp) && !mtmp->isminion) impossible("pet without edog (%s)", msg); + + if (mtmp->mtrapped) { + if (mtmp->wormno) { + /* TODO: how to check worm in trap? */ + } else if (!t_at(mtmp->mx, mtmp->my)) + impossible("trapped without a trap (%s)", msg); + } + + /* monster is hiding? */ + if (mtmp->mundetected) { + struct trap *t; + + if (mtmp == u.ustuck) + impossible("hiding monster stuck to you (%s)", msg); + if (m_at(mtmp->mx, mtmp->my) == mtmp && hides_under(mtmp->data) && !OBJ_AT(mtmp->mx, mtmp->my)) + impossible("mon hiding under nonexistent obj (%s)", msg); + if (mtmp->data->mlet == S_EEL && !is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz)) + impossible("eel hiding out of water (%s)", msg); + if (mtmp->mtrapped && (t = t_at(mtmp->mx, mtmp->my)) != 0 + && !(t->ttyp == PIT || t->ttyp == SPIKED_PIT)) + impossible("hiding while trapped in a non-pit (%s)", msg); + } + } void @@ -3537,6 +3560,19 @@ register struct monst *mtmp; return FALSE; } +/* reveal a monster at x,y hiding under an object, + if there are no objects there */ +void +maybe_unhide_at(x, y) +xchar x, y; +{ + struct monst *mtmp; + + if (!OBJ_AT(x, y) && (mtmp = m_at(x, y)) != 0 + && mtmp->mundetected && hides_under(mtmp->data)) + (void) hideunder(mtmp); +} + /* monster/hero tries to hide under something at the current location */ boolean hideunder(mtmp) diff --git a/src/restore.c b/src/restore.c index 3ca9c0e2a..deaabb4fb 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1128,6 +1128,8 @@ xchar lev; place_monster(mtmp, mtmp->mx, mtmp->my); if (mtmp->wormno) place_wsegs(mtmp, NULL); + if (hides_under(mtmp->data) && mtmp->mundetected) + (void) hideunder(mtmp); /* regenerate monsters while on another level */ if (!u.uz.dlevel) diff --git a/src/teleport.c b/src/teleport.c index b46a9b56d..e5e34c5ae 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1258,6 +1258,10 @@ register int x, y; the latter only happens if you've attacked them with polymorph */ if (resident_shk && !inhishop(mtmp)) make_angry_shk(mtmp, oldx, oldy); + + /* trapped monster teleported away */ + if (mtmp->mtrapped && !mtmp->wormno) + (void) mintrap(mtmp); } static stairway * From 018d838eb902534907a07ae7f79f397884b7b3a3 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 24 Nov 2020 09:45:55 -0800 Subject: [PATCH 446/708] today's Qt status update: non-standard conditions Qt's status highlighting was treating any change to hunger or to encumbrance as "worse" (shown in red). That's wrong if you go from weak to just hungry or from stressed to encumbered. Comparing satiated with other hunger states is tricky. I've ranked it between hungry and weak but that's fairly arbitrary. Also, change the highlighting when Lev, Fly, and Ride are new conditions from red to blue. --- win/Qt/qt_icon.cpp | 19 +++++++-------- win/Qt/qt_stat.cpp | 60 +++++++++++++++++++++++++++++++++++----------- win/Qt/qt_stat.h | 7 +++--- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/win/Qt/qt_icon.cpp b/win/Qt/qt_icon.cpp index 4076fc65d..b8f0e694d 100644 --- a/win/Qt/qt_icon.cpp +++ b/win/Qt/qt_icon.cpp @@ -133,19 +133,16 @@ void NetHackQtLabelledIcon::setFont(const QFont& f) if (label) label->setFont(f); } -// [pr] this might no longer be needed; it seems to have been responsible -// for highlighting the blank space where an optional field like Score -// was just toggled off; we don't need or want that anymore... +// used to highlight status conditions going from Off (blank) to On as "Worse" void NetHackQtLabelledIcon::show() { - if ( -#if QT_VERSION >= 300 - isHidden() -#else - !isVisible() -#endif - && comp_mode != NoCompare) - highlight(hl_worse); + // Hunger and Encumbrance are worse when going from not shown + // to anything and they're set to SmallerIsBetter, so both + // BiggerIsBetter and SmallerIsBetter warrant hl_worse here. + // Fly, Lev, and Ride are set NeitherIsBetter so that when + // they appear they won't be classified as worse. + if (isHidden() && comp_mode != NoCompare) + highlight((comp_mode != NeitherIsBetter) ? hl_worse : hl_changd); QWidget::show(); } diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index dbd011d1e..88a6cfa8c 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -718,24 +718,45 @@ void NetHackQtStatusWindow::updateStats() boolean spreadout = (::iflags.wc2_statuslines != 2); int k = 0; // number of conditions shown - const char* hung=hu_stat[u.uhs]; + long qt_uhs = 0L; + const char *hung = hu_stat[u.uhs]; if (hung[0]==' ') { - hunger.hide(); + if (!hunger.isHidden()) { + hunger.setLabel("", NetHackQtLabelledIcon::NoNum, qt_uhs); + hunger.hide(); + } } else { + // satiated is worse (due to risk of death from overeating) + // than not-hungry and we'll treat it as also worse than hungry, + // but better than weak or fainting; the u.uhs enum values + // order them differently so we jump through a hoop + switch (u.uhs) { + case NOT_HUNGRY: qt_uhs = 0L; break; + case HUNGRY: qt_uhs = 1L; break; + case SATIATED: qt_uhs = 2L; break; + case WEAK: qt_uhs = 3L; break; + case FAINTING: qt_uhs = 4L; break; + default: qt_uhs = 5L; break; // fainted, starved + } hunger.setIcon(u.uhs ? p_hungry : p_satiated); - hunger.setLabel(hung); + hunger.setLabel(hung, NetHackQtLabelledIcon::NoNum, qt_uhs); hunger.ForceResize(); ++k, hunger.show(); } - const char *enc = enc_stat[near_capacity()]; + long encindx = (long) near_capacity(); + const char *enc = enc_stat[encindx]; if (enc[0]==' ' || !enc[0]) { - encumber.hide(); + if (!encumber.isHidden()) { + encumber.setLabel("", NetHackQtLabelledIcon::NoNum, encindx); + encumber.hide(); + } } else { - encumber.setIcon(p_encumber[near_capacity() - 1]); - encumber.setLabel(enc); + encumber.setIcon(p_encumber[encindx - 1]); + encumber.setLabel(enc, NetHackQtLabelledIcon::NoNum, encindx); encumber.ForceResize(); ++k, encumber.show(); } + if (Stoned) ++k, stoned.show(); else stoned.hide(); if (Slimed) ++k, slimed.show(); else slimed.hide(); if (Strangled) ++k, strngld.show(); else strngld.hide(); @@ -917,12 +938,13 @@ void NetHackQtStatusWindow::updateStats() if (first_set) { first_set=false; - was_polyd = Upolyd ? true : false; - had_exp = ::flags.showexp ? true : false; - had_score = ::flags.showscore ? true : false; - + /* + * Default compareMode is BiggerIsBetter: an increased value + * is an improvement. + */ name.highlightWhenChanging(); - dlevel.highlightWhenChanging(); dlevel.setCompareMode(NeitherIsBetter); + dlevel.highlightWhenChanging(); + dlevel.setCompareMode(NeitherIsBetter); str.highlightWhenChanging(); dex.highlightWhenChanging(); @@ -933,7 +955,8 @@ void NetHackQtStatusWindow::updateStats() hp.highlightWhenChanging(); power.highlightWhenChanging(); - ac.highlightWhenChanging(); ac.setCompareMode(SmallerIsBetter); + ac.highlightWhenChanging(); + ac.setCompareMode(SmallerIsBetter); level.highlightWhenChanging(); gold.highlightWhenChanging(); @@ -942,10 +965,13 @@ void NetHackQtStatusWindow::updateStats() //time.highlightWhenChanging(); time.setCompareMode(NeitherIsBetter); score.highlightWhenChanging(); - align.highlightWhenChanging(); align.setCompareMode(NeitherIsBetter); + align.highlightWhenChanging(); + align.setCompareMode(NeitherIsBetter); hunger.highlightWhenChanging(); + hunger.setCompareMode(SmallerIsBetter); encumber.highlightWhenChanging(); + encumber.setCompareMode(SmallerIsBetter); stoned.highlightWhenChanging(); slimed.highlightWhenChanging(); strngld.highlightWhenChanging(); @@ -956,9 +982,15 @@ void NetHackQtStatusWindow::updateStats() hallu.highlightWhenChanging(); blind.highlightWhenChanging(); deaf.highlightWhenChanging(); + // the default behavior is to highlight a newly shown condition + // as "worse" but that isn't appropriate for 'other' conds; + // NetHackQtLabelledIcon::show() uses NeitherIsBetter to handle it lev.highlightWhenChanging(); + lev.setCompareMode(NeitherIsBetter); fly.highlightWhenChanging(); + fly.setCompareMode(NeitherIsBetter); ride.highlightWhenChanging(); + ride.setCompareMode(NeitherIsBetter); } } diff --git a/win/Qt/qt_stat.h b/win/Qt/qt_stat.h index a24028569..c09fae6c4 100644 --- a/win/Qt/qt_stat.h +++ b/win/Qt/qt_stat.h @@ -135,14 +135,13 @@ private: QFrame vline2; // for statuslines:2, padding between Gold and Time int cursy; - bool first_set; bool alreadyfullhp; + + // for some fields, we need to know more than just "changed since + // last update"; there's no 'had_time' because Time isn't highlighted bool was_polyd; bool had_exp; - // Time isn't highlighted (due to constantly changing) so we don't - // keep track of whether it was On and is now Off or vice versa - //bool had_time; bool had_score; QHBoxLayout *InitHitpointBar(); From 7e87abb66f21fc0c39dec7f00329b0c0fbf0db34 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 24 Nov 2020 10:43:12 -0800 Subject: [PATCH 447/708] wizard mode buglet: simultaneous Lev+Fly timeout Noticed while working on Qt status highlighting: if levitation and flying timed out at the same time, first Lev timeout called float_down() which reported You have stopped levitating and are now flying. and then Fly timeout left stale "Fly" on the status line due to an optimization which got subverted. ('was_flying' flag was False due to Fly being blocked by Lev; that's correct behavior, but the flag is effectively a cached value that becomes stale when the Lev timeout code executes.) The bug was wizard mode only because #wizintrinsic is the only way to get timed flying. --- doc/fixes37.0 | 5 ++++- src/timeout.c | 24 +++++++++++++++++------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 19f8eeb93..fbd016ffa 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.361 $ $NHDT-Date: 1606033928 2020/11/22 08:32:08 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.362 $ $NHDT-Date: 1606243387 2020/11/24 18:43:07 $ General Fixes and Modified Features ----------------------------------- @@ -305,6 +305,9 @@ wand/scroll of create monster or bag of tricks that makes a new monster which concealed mimic seen as furniture or an object 'showscore' could be used to determine how much gold was inside a container whose contents were unknown +wizard mode (only way to get timed flying): if levitation and flying time out + on same turn, player was told "You have stopped levitating and are + now flying."; status line wasn't updated to remove stale Fly condition Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/timeout.c b/src/timeout.c index 9782401b9..66e56d295 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 timeout.c $NHDT-Date: 1598570054 2020/08/27 23:14:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.119 $ */ +/* NetHack 3.7 timeout.c $NHDT-Date: 1606243387 2020/11/24 18:43:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.122 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -46,11 +46,16 @@ const struct propname { { DETECT_MONSTERS, "monster detection" }, { SEE_INVIS, "see invisible" }, { INVIS, "invisible" }, - { DISPLACED, "displaced" }, /* timed amount possible via eating a - * displacer beast corpse */ - /* properties beyond here don't have timed values during normal play, - so there's not much point in trying to order them sensibly; - they're either on or off based on equipment, role, actions, &c */ + /* timed displacement is possible via eating a displacer beast corpse */ + { DISPLACED, "displaced" }, + /* timed pass-walls is a potential prayer result if surrounded by stone + with nowhere to be safely teleported to */ + { PASSES_WALLS, "pass thru walls" }, + /* + * Properties beyond here don't have timed values during normal play, + * so there's not much point in trying to order them sensibly. + * They're either on or off based on equipment, role, actions, &c. + */ { FIRE_RES, "fire resistance" }, { COLD_RES, "cold resistance" }, { SLEEP_RES, "sleep resistance" }, @@ -81,7 +86,6 @@ const struct propname { { WWALKING, "water walking" }, { SWIMMING, "swimming" }, { MAGICAL_BREATHING, "magical breathing" }, - { PASSES_WALLS, "pass thru walls" }, { SLOW_DIGESTION, "slow digestion" }, { HALF_SPDAM, "half spell damage" }, { HALF_PHDAM, "half physical damage" }, @@ -676,6 +680,12 @@ nh_timeout() } break; case LEVITATION: + /* timed Flying is via #wizintrinsic only; still, we want to + avoid float_down() reporting "you have stopped levitating + and are now flying" if both are timing out together; + relies on knowing that Lev timeout is handled before Fly */ + if ((HFlying & TIMEOUT) == 1L) + --HFlying; /* bypass pending 'case FLYING' */ (void) float_down(I_SPECIAL | TIMEOUT, 0L); break; case FLYING: From 9ea45d7a1f69009fc4496722e8b7327779e59506 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 25 Nov 2020 07:23:23 -0500 Subject: [PATCH 448/708] remove some trailing whitespace --- Cross-compiling | 2 +- Porting | 8 +-- README | 14 ++-- sys/msdos/Install.dos | 58 +++++++-------- sys/unix/Makefile.top | 2 +- sys/unix/Makefile.utl | 2 +- sys/unix/hints/include/cross-post.2020 | 2 +- sys/unix/hints/include/cross-pre.2020 | 8 +-- sys/unix/hints/linux.2020 | 4 +- sys/winnt/Install.nt | 84 +++++++++++----------- sys/winnt/Makefile.gcc | 52 +++++++------- sys/winnt/Makefile.msc | 97 +++++++++++++------------- 12 files changed, 166 insertions(+), 167 deletions(-) diff --git a/Cross-compiling b/Cross-compiling index 96253755d..b0c673dea 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -678,7 +678,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html or nethacklib builds. A "shim" pseudo-windowport is included from pull request 385. - Result: As mentioned, the wasm cross-compile will end up in + Result: As mentioned, the wasm cross-compile will end up in targets/wasm and the nethacklib.a will end up src. diff --git a/Porting b/Porting index 70c8ccd1f..6a57e1aae 100644 --- a/Porting +++ b/Porting @@ -14,7 +14,7 @@ new machine. The basic steps in porting the program are: have the files in the top directory since you're reading this one. :-) - If you will be cross-compiling for your target platform on + If you will be cross-compiling for your target platform on a different platform, you may want to read Cross-compiling in the Top folder as well. @@ -185,7 +185,7 @@ line options to produce several output files that are required for: (a) additional build steps to follow, including some header files: pm.h, onames.h, date.h. (b) creation of files, containing information required by, - or about the game during its execution, that are stored in a + or about the game during its execution, that are stored in a portable, platform-independent way, that need to be inserted into the final game package. @@ -205,7 +205,7 @@ utilities, and so forth. Those produce output files for use during the game and need to be included in the packaging of the game. 4.3. Lua - + Compile and link into a library, or obtain a prebuilt Lua library for your platform. Place the Lua source into lib/lua-5.4.1 (or other folder representing an appropriate Lua version); place the compiled Lua library into @@ -244,7 +244,7 @@ text by makedefs during the build process, have been replaced by Lua versions and are inserted into the game package for processing by the embedded Lua interpreter during game execution. - 5.2 Level Compiler + 5.2 Level Compiler There is no longer a build-time level compiler. Instead, the level descriptions have been converted to Lua and are inserted into the game package diff --git a/README b/README index 8ca02f15c..1e99c8c26 100644 --- a/README +++ b/README @@ -11,7 +11,7 @@ The file doc/fixes37.0 in the source distribution will be updated with a list of fixes as they are committed. 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 +released code, and if stability is paramount, then the most recent NetHack 3.6.6 release is safest for you. We're making the .0 work-in-progress available so that you can observe, test @@ -22,11 +22,11 @@ The file doc/fixes37.0 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 +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 -some general architectural improvements to the game or to its building +some general architectural improvements to the game or to its building process. Among them: * Remove barriers to building NetHack on one platform and operating system, @@ -35,9 +35,9 @@ process. Among them: 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 + * 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 + by NetHack's "makedefs" utility, 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 @@ -60,7 +60,7 @@ considered spoilers: their individual fields and save those fields instead of the entire struct - savefile: use little-endian format for fields where that makes a difference - + - - - - - - - - - - - Please read items (1), (2) and (3) BEFORE doing anything with your new code. @@ -113,7 +113,7 @@ Please read items (1), (2) and (3) BEFORE doing anything with your new code. OpenVMS (aka VMS) V8.4 on Alpha and on Integrity/Itanium/IA64 Instructions have been provided by way of community contribution on: - msdos protected mode using djgpp including a Linux-host djgpp + msdos protected mode using djgpp including a Linux-host djgpp cross-compile Previous versions of NetHack were tested and known to run on the diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index ba96764a0..62f65568a 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -1,5 +1,5 @@ - Copyright (c) NetHack PC Development Team 1990-2002. + Copyright (c) NetHack PC Development Team 1990-2020. NetHack may be freely redistributed. See license for details. ============================================================== Instructions for compiling and installing @@ -9,13 +9,13 @@ Last revision: $NHDT-Date: 1596508786 2020/08/04 02:39:46 $ Credit for a runnable full PC NetHack 3.7 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, +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 on the previous effort of Pierre Martineau, Stephen Spackman, Steve Creps, Mike Threepoint, Mike Stephenson, Norm Meluch and Don Kneller. -There has been very little port-specific maintenance for NetHack on DOS since +There has been very little port-specific maintenance for NetHack on DOS since NetHack 3.3.0. CONTENTS: @@ -51,12 +51,12 @@ I. Dispelling the Myths: with 3.5.x. You may find it useful to obtain copies of lex (flex) and yacc (bison - or byacc). While not strictly necessary to compile nethack, they are - required should you desire to make any changes to the level and dungeon - compilers. Flex and Bison are included with the DJGPP distribution and - are also available on many archive sites. + or byacc). While not strictly necessary to compile nethack, they are + required should you desire to make any changes to the level and dungeon + compilers. Flex and Bison are included with the DJGPP distribution and + are also available on many archive sites. - Also be sure to pick up djgpp v2gnu/fil41b.zip to get ls.exe and + Also be sure to pick up djgpp v2gnu/fil41b.zip to get ls.exe and touch.exe, since the Makefile uses them by default. II. To compile your copy of NetHack on a DOS machine: @@ -76,12 +76,12 @@ II. To compile your copy of NetHack on a DOS machine: (top) | - ------------------------------------------------- - | | | | | | | + ------------------------------------------------- + | | | | | | | util dat doc include src sys win | | - ------ ----- - | | | | + ------ ----- + | | | | share msdos tty share Check the file "Files" in your top level directory for an exact @@ -118,9 +118,9 @@ II. To compile your copy of NetHack on a DOS machine: First check config.h according to the comments to match your system and desired set of features. Mostly you need to check the WIZARD option, - and check TERMLIB and COMPRESS. Also be sure to leave DLB support - commented out in config.h. MSDOS has support for DLB, but it must be - done through the Makefile, rather than config.h, to ensure that the + and check TERMLIB and COMPRESS. Also be sure to leave DLB support + commented out in config.h. MSDOS has support for DLB, but it must be + done through the Makefile, rather than config.h, to ensure that the necessary packaging steps are done. We've managed to enable all the special features. You may include all @@ -154,14 +154,14 @@ II. To compile your copy of NetHack on a DOS machine: occupied for quite some time. If all goes well, you will get an NetHack executable. -9. If you chose DLB support (recommended), make sure that the file nhdat +9. If you chose DLB support (recommended), make sure that the file nhdat got copied into the game directory. If you didn't choose DLB support, make sure the support files -- data, rumors, cmdhelp, opthelp, help, hh,history, guidebook.txt - license, and all the *.lev files -- were copied to the game directory. - If not, move them there from the dat directory yourself. rumors can - be created manually be entering "makedefs -r", data by entering + license, and all the *.lev files -- were copied to the game directory. + If not, move them there from the dat directory yourself. rumors can + be created manually be entering "makedefs -r", data by entering "makedefs -d". Make sure the files NetHack1.tib and NetHacko.tib made it to your game @@ -175,7 +175,7 @@ II. To compile your copy of NetHack on a DOS machine: speed-dialer, making the file hidden on many machines. If you changed your build settings to include TERMCAP support, copy - termcap to your game directory. + termcap to your game directory. Also, make sure the file msdoshlp.txt made it to your game directory. If it didn't, move it from sys\msdos to your game directory @@ -191,8 +191,8 @@ Appendix A - Building the "official binary" If you wish to build a copy of NetHack identical to the one that the pc team distributes, simply do the following: - The 32-bit Protected Mode DPMI version built with 32-bit djgpp - compiler V2.03 or greater, make no changes to any of the defines and use + The 32-bit Protected Mode DPMI version built with 32-bit djgpp + compiler V2.03 or greater, make no changes to any of the defines and use the Makefile.GCC as distributed, and as moved in step 3. Paths below are relative to the top of your unpacked @@ -219,11 +219,11 @@ Appendix B - DJGPP Compiler (gcc ported to msdos) At the time of this release in April 2002, the URL http://www.delorie.com/djgpp/zip-picker.html/ had information on how to obtain djgpp and what pieces to get. - Be sure to pick up djgpp v2gnu/fil41b.zip to get ls.exe and + Be sure to pick up djgpp v2gnu/fil41b.zip to get ls.exe and touch.exe, since the Makefile uses them by default (or change the Makefile to use alternatives). - Special note for Windows 2000 / Windows XP users: You must have a + Special note for Windows 2000 / Windows XP users: You must have a recent djgpp distribution for the build process, and the generated executables to work properly on those platforms. @@ -234,9 +234,9 @@ Appendix B - DJGPP Compiler (gcc ported to msdos) djgpp. The latest version of djgpp, V2.03 with the most recent refresh - will produce a binary that will run under Microsoft Windows, or any - other DPMI provider. djgpp also comes with a DPMI provider called CWSDPMI. - Place CWSDPMI.EXE in your path and it will be used in the absence of any + will produce a binary that will run under Microsoft Windows, or any + other DPMI provider. djgpp also comes with a DPMI provider called CWSDPMI. + Place CWSDPMI.EXE in your path and it will be used in the absence of any other DPMI provider. If you want to use the built-in DJGPP screen routines, uncomment @@ -247,7 +247,7 @@ Appendix C - Additional Notes 1) Save files and bones files from versions of NetHack prior to 3.5.0 will not work with this NetHack. Don't bother trying to keep them. -2) To install an update of NetHack after changing something, type 'make' +2) To install an update of NetHack after changing something, type 'make' for DJGPP from the src directory. If you add, delete, or reorder monsters or objects, or you change the format of saved level files, delete any save and bones files. (Trying to use such files sometimes produces amusing diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 4860b56dd..6c1363aeb 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -47,7 +47,7 @@ DIRPERM = 0755 #SHELLDIR = $(PREFIX)/games # per discussion in Install.X11 and Install.Qt -#VARDATND = +#VARDATND = # VARDATND = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm # VARDATND = x11tiles NetHack.ad pet_mark.xbm pilemark.xbm rip.xpm # for Atari/Gem diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index a2530e49e..0e763c62c 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -193,7 +193,7 @@ DLBOBJS = dlb_main.o $(OBJDIR)/dlb.o $(OALLOC) # builds and for cross-compiles by overriding these in hints # files or on the command line. -TARGETPFX= +TARGETPFX= TARGET_CC = $(CC) TARGET_CFLAGS = $(CFLAGS) TARGET_CLINK = $(CLINK) diff --git a/sys/unix/hints/include/cross-post.2020 b/sys/unix/hints/include/cross-post.2020 index b2d45c787..b87824a54 100644 --- a/sys/unix/hints/include/cross-post.2020 +++ b/sys/unix/hints/include/cross-post.2020 @@ -53,7 +53,7 @@ $(TARGETPFX)winami.o : ../outdated/sys/amiga/winami.c $(HACK_H) $(TARGETPFX)winchar.o : ../outdated/sys/amiga/winchar.c tile.c $(HACK_H) $(TARGETPFX)winfuncs.o : ../outdated/sys/amiga/winfuncs.c $(HACK_H) $(TARGETPFX)winkey.o : ../outdated/sys/amiga/winkey.c $(HACK_H) -$(TARGETPFX)winamenu.o : ../outdated/sys/amiga/winamenu.c $(HACK_H) +$(TARGETPFX)winamenu.o : ../outdated/sys/amiga/winamenu.c $(HACK_H) $(TARGETPFX)winreq.o : ../outdated/sys/amiga/winreq.c \ ../outdated/sys/amiga/colorwin.c \ ../outdated/sys/amiga/clipwin.c $(HACK_H) diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index 6146c8143..d3cb72a50 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -161,7 +161,7 @@ TOOLTOP1 = ../lib/djgpp/bin TOOLTOP2 = ../lib/djgpp/i586-pc-msdosdjgpp/bin override TARGET_CC = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc override TARGET_CXX = $(TOOLTOP2)/g++ -override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar +override TARGET_AR = $(TOOLTOP1)/i586-pc-msdosdjgpp-gcc-ar override TARGET_STUBEDIT = ../lib/djgpp/i586-pc-msdosdjgpp/bin/stubedit override TARGET_CFLAGS = -c -O -I../include -I../sys/msdos -I../win/share \ $(LUAINCL) -DDLB $(PDCURSESDEF) \ @@ -232,7 +232,7 @@ TOOLARCH = -m68020 -noixemul override REGEXOBJ = $(TARGETPFX)cppregex.o override TARGET_CC = $(TOOLTOP)/m68k-amigaos-gcc override TARGET_CXX = $(TOOLTOP)/m68k-amigaos-c++ -override TARGET_AR = $(TOOLTOP)/m68k-amigaos-ar +override TARGET_AR = $(TOOLTOP)/m68k-amigaos-ar override TARGET_STUBEDIT= #override TARGET_CFLAGS = -c -O $(TOOLARCH) -I../include -I../outdated/include override TARGET_CFLAGS = -c -O $(TOOLARCH) \ @@ -369,7 +369,7 @@ WASM_CFLAGS += $(LUAINCL) WASM_CFLAGS += -DNOTTYGRAPHICS -DSHIM_GRAPHICS -DLIBNH WASM_CFLAGS += -DCROSSCOMPILE WASM_TARGET_CFLAGS = -DCROSSCOMPILE_TARGET -DCROSS_TO_WASM -# For src Makefile +# For src Makefile override CFLAGS = $(WASM_CFLAGS) override TARGET_CFLAGS = $(EMCC_CFLAGS) $(WASM_CFLAGS) $(WASM_TARGET_CFLAGS) # @@ -384,7 +384,7 @@ override SYSOBJ= $(TARGETPFX)libnhmain.o \ $(TARGETPFX)ioctl.o $(TARGETPFX)unixtty.o \ $(TARGETPFX)unixunix.o $(TARGETPFX)unixres.o \ $(TARGETPFX)winshim.o -override WINLIB = emranlib +override WINLIB = emranlib override LUALIB= override TOPLUALIB= override REGEXOBJ = $(TARGETPFX)posixregex.o diff --git a/sys/unix/hints/linux.2020 b/sys/unix/hints/linux.2020 index 2d536f4ff..a9aeef494 100755 --- a/sys/unix/hints/linux.2020 +++ b/sys/unix/hints/linux.2020 @@ -1,6 +1,6 @@ # NetHack 3.7 linux.2020 $NHDT-Date: 1599687610 2020/09/09 21:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.11 $ # Copyright (c) Kenneth Lorber, Kensington, Maryland, 2007. -# NetHack may be freely redistributed. See license for details. +# NetHack may be freely redistributed. See license for details. # #--------------------------------------------------------------------- # Linux hints file with support for multiple window ports (interfaces) @@ -191,7 +191,7 @@ POSTINSTALL+= cp -n sys/unix/sysconf $(INSTDIR)/sysconf; \ chmod $(VARFILEPERM) $(INSTDIR)/sysconf; ifneq "$(CCISCLANG)" "" -# gdb may not be installed if clang is chosen compiler so the game +# gdb may not be installed if clang is chosen compiler so the game # won't start in that case due to a sysconf error. Comment out # relevant lines in sysconf. POSTINSTALL+= sed -i -e 's;^GDBPATH=/usr/bin/gdb;\#GDBPATH=/usr/bin/gdb;' \ diff --git a/sys/winnt/Install.nt b/sys/winnt/Install.nt index a226fe50d..101fb965a 100644 --- a/sys/winnt/Install.nt +++ b/sys/winnt/Install.nt @@ -7,7 +7,7 @@ ============================================================== Last revision: $NHDT-Date: 1594155895 2020/07/07 21:04:55 $ -Credit for the porting of NetHack to the Win32 Console Subsystem goes to +Credit for the porting of NetHack to the Win32 Console Subsystem goes to the NT Porting Team started by Michael Allison. Credit for the Win32 Graphical version of NetHack (aka "NetHack for @@ -18,7 +18,7 @@ Alex Kompel, Dion Nicolaas, Yitzhak Sapir, Derek S. Ray, Michael Allison, Pasi Kallinen, Bart House, and Janet Walz contributed to the maintainance of the tty and graphical windows versions of NetHack 3.7.0. -You can build a TTY version of NetHack and a Windows Graphical +You can build a TTY version of NetHack and a Windows Graphical version. You can use one of the following build environments: o A copy of Microsoft Visual Studio 2017 Community Edition or @@ -26,9 +26,9 @@ version. You can use one of the following build environments: OR - o (Untested for 3.7) A copy of MinGW. MinGW is a collection of header - files and import libraries with which native Windows32 programs - can be built; the MinGW distribution contains the GNU Compiler + o (Untested for 3.7) A copy of MinGW. MinGW is a collection of header + files and import libraries with which native Windows32 programs + can be built; the MinGW distribution contains the GNU Compiler Collection. You can download MinGW at http://www.mingw.org/ Earlier versions of MinGW will not allow you to build the Windows @@ -38,7 +38,7 @@ version. You can use one of the following build environments: | Directories for a Win32 NetHack build | \---------------------------------------------/ - + (NetHack-top) | +-----+-----+------+------+-----+----------+---------~---------+ @@ -91,18 +91,18 @@ using. Change to the directory win\win32\vs and run "build.bat". * Optional curses window-port support * Since 3.6.2, the community patch for a window-port that uses curses has been -incorporated into the NetHack source code tree. That window-port, which +incorporated into the NetHack source code tree. That window-port, which evolved from work originally done by Karl Garrison, has been used in several NetHack variants and on nethack.alt.org and on www.hardfought.org/nethack/. If you want to include the curses window-port support in your Visual Studio build, you will have to first obtain the PDCurses sources from https://github.com/wmcbrine/PDCurses -and have them available prior to building NetHack. There are two ways to -enable curses window-port support during the VS build: Either set the -environment variable PDCURSES to a folder containing a PDCurses +and have them available prior to building NetHack. There are two ways to +enable curses window-port support during the VS build: Either set the +environment variable PDCURSES to a folder containing a PDCurses repository/source-tree - OR + OR Place the PDCurses folder alongside the NetHack source repository prior to proceeding with steps 1 through 5 above. @@ -114,8 +114,8 @@ to proceeding with steps 1 through 5 above. -------------------------------------------------------------------------- -- Beginning of prerequisite step -- -The first step in building either version of NetHack via Makefile is to -execute sys\winnt\nhsetup.bat to move some files to their required locations. +The first step in building either version of NetHack via Makefile is to +execute sys\winnt\nhsetup.bat to move some files to their required locations. From the command prompt: cd sys\winnt @@ -138,25 +138,25 @@ command line using the Makefile approach: NetHackW. The executable for Console NetHack will be named NetHack.exe. The -executable for Graphical NetHack will be named NetHackW.exe. The +executable for Graphical NetHack will be named NetHackW.exe. The Makefile configuration will build both; NetHackW.exe and NetHack.exe will be able to use the same datafiles, save files and bones files. -Since the last official release of NetHack, compilers and computer +Since the last official release of NetHack, compilers and computer 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 +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. NetHack's save files and bones files in the 3.7.0 release have not yet -evolved enough to allow them to interchange between the 32-bit version +evolved enough to allow them to interchange between the 32-bit version and the 64-bit version (or between different platforms). Hopefully that will change in an upcoming release. I. Dispelling the Myths: Compiling NetHack for Windows is not as easy as it sounds, nor as hard - as it looks, however it will behoove you to read this entire section + as it looks, however it will behoove you to read this entire section through before beginning the task. We have provided a Makefile for each of the following compilers: @@ -165,10 +165,10 @@ I. Dispelling the Myths: The Community Editions are fine and available at no cost o MinGW 2.0 (with GCC 3.2) - The Microsoft Visual Studio makefile was created for use - with MS NMAKE which is provided with the Microsoft compiler. + The Microsoft Visual Studio makefile was created for use + with MS NMAKE which is provided with the Microsoft compiler. The supplied Makefile may work with earlier versions of the Microsoft - compiler, but that has not been tested. + compiler, but that has not been tested. The GCC Makefile was created for use with GNU Make version 3.79.1, which comes with the MinGW package. @@ -182,41 +182,41 @@ II. To compile your copy of NetHack on a Windows machine: Setting Up -1. It almost goes without saying that you should make sure that your +1. It almost goes without saying that you should make sure that your tools are set up and running correctly. That includes ensuring that all the necessary environment variables for the compiler environment - are set correctly. + are set correctly. - Change your current directory to the src subfolder of the nethack + Change your current directory to the src subfolder of the nethack source tree. cd src - GCC + GCC - For the GCC Makefile, add \bin to your path, where + For the GCC Makefile, add \bin to your path, where is your MinGW root directory.). - Change your current directory to src subfolder of the nethack + Change your current directory to src subfolder of the nethack source tree. cd src 2. Since 3.6.2, the community patch for an optional curses window-port - has been incorporated into the NetHack source code tree. That + has been incorporated into the NetHack source code tree. That window-port, which evolved from work originally done by Karl Garrison, - has been used in several NetHack variants and on nethack.alt.org and - on www.hardfought.org/nethack/. The optional curses window-port is + has been used in several NetHack variants and on nethack.alt.org and + on www.hardfought.org/nethack/. The optional curses window-port is available for Windows, Mac OS X, and Unix (and also DOS). If you want to include the optional curses window-port support in your - command line Makefile build, you will have to first obtain the + command line Makefile build, you will have to first obtain the PDCurses sources from https://github.com/wmcbrine/PDCurses and have that source code tree available prior to building NetHack. - Edit your Makefile and in Question 4 of the four decisions you can + Edit your Makefile and in Question 4 of the four decisions you can make in there, uncomment these two lines: ADD_CURSES=Y PDCURSES_TOP=..\..\pdcurses - Adjust the PDCURSES_TOP macro so that it points to the correct + Adjust the PDCURSES_TOP macro so that it points to the correct location for the top of the PDCurses source tree if it differs from the path shown. @@ -225,8 +225,8 @@ Setting Up subdirectories dat, doc, include, src, sys\share, sys\winnt, win\tty, util. - If you are including the optional Curses window port into your - build,then you will need the top of the PDCurses sources in a + If you are including the optional Curses window port into your + build,then you will need the top of the PDCurses sources in a folder parallel to the top of the NetHack folder (or you will need to change the value of the PDCURSES_TOP macro in the Makefile to specify the appropriate location. @@ -254,7 +254,7 @@ Compiling 5. Now that everything is set up... For the Visual Studio compiler, as mentioned above, you should now be - at the command prompt to carry out the build and your current + at the command prompt to carry out the build and your current directory should be the src subdirectory in the NetHack source tree. In the src subdirectory, issue this command: @@ -270,7 +270,7 @@ Compiling particular machine of course, but you should be able to go for lunch and return to find everything finished. The less memory, and slower your machine, the longer the lunch you may take. :-) - + In any case, it is likely that the command prompt window where you are doing the compiling will be occupied for a while. If all goes well, you will get an NetHack executable. @@ -281,7 +281,7 @@ Notes: your current directory to src and issue the appropriate command for your compiler: - For Microsoft compiler: + For Microsoft compiler: nmake For GCC: @@ -296,19 +296,19 @@ Notes: have to delete dgn_flex.c, dgn_yacc.c, lev_flex.c, and lev_yacc.c from the util directory to ensure that they are remade. -2. Depending on the build and compiler and tools used above, the +2. Depending on the build and compiler and tools used above, the executable produced by the TTY build is either: - - a 32-bit (x86), flat-address space, non-overlayed .exe file, + - a 32-bit (x86), flat-address space, non-overlayed .exe file, which should run on any recent Win32 environment. or - - a 64-bit (x64) .exe file, + - a 64-bit (x64) .exe file, which should run on any 64-bit Windows O/S. Note that saved games are NOT compatible between the 32-bit and the 64-bit versions at this time. NetHack.exe is the tty version. NetHackW.exe is the graphical version. -Play NetHack. +Play NetHack. PROBLEMS diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index b8acaf51f..2df3b9eb6 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -34,7 +34,7 @@ # # Build Options Decisions # -# There are currently 4 decisions that you can choose to make. +# There are currently 4 decisions that you can choose to make. # None of the 4 decisions are absolutely required because defaults are in place: # 1. Where do you want your build to end up? # 2. Do you want debug information in the executable? @@ -92,11 +92,11 @@ TARGET_CPU=x86 # # 4. Uncomment these and set them appropriately if you want to # include curses port support alongside TTY support in your -# NetHack.exe binary. +# NetHack.exe binary. # -# You'll have to set PDCURSES_H to the correct location of the +# You'll have to set PDCURSES_H to the correct location of the # PDCurses header (.h) files and PDCURSES_C to the location -# of your PDCurses C files which must already be resident on +# of your PDCurses C files which must already be resident on # your machine. # # ADD_CURSES=Y @@ -134,7 +134,7 @@ endif #--------------------------------------------------------------- # Location of LUA # -# Original source needs to be obtained from: +# Original source needs to be obtained from: # http://www.lua.org/ftp/lua-5.4.1.tar.gz # # This build assumes that the LUA sources are located @@ -185,8 +185,8 @@ NHV=$(subst ",,$(NHV1)) # MSWSYS - mswin specific files # TTY - window port files (tty) # MSWIN - window port files (win32) -# WCURSES - window port files (curses) -# WSHR - Tile support files +# WCURSES - window port files (curses) +# WSHR - Tile support files # QT - QT window support files INCL =../include @@ -303,13 +303,13 @@ PPMWRITERS = $(O)ppmwrite.o $(O)alloc.o $(O)panic.o # VOBJ01 = $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o -VOBJ02 = $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o -VOBJ03 = $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o -VOBJ04 = $(O)dig.o $(O)display.o $(O)do.o $(O)do_name.o -VOBJ05 = $(O)do_wear.o $(O)dog.o $(O)dogmove.o $(O)dokick.o -VOBJ06 = $(O)dothrow.o $(O)drawing.o $(O)dungeon.o $(O)eat.o -VOBJ07 = $(O)end.o $(O)engrave.o $(O)exper.o $(O)explode.o -VOBJ08 = $(O)extralev.o $(O)files.o $(O)fountain.o $(O)hack.o +VOBJ02 = $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o +VOBJ03 = $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o +VOBJ04 = $(O)dig.o $(O)display.o $(O)do.o $(O)do_name.o +VOBJ05 = $(O)do_wear.o $(O)dog.o $(O)dogmove.o $(O)dokick.o +VOBJ06 = $(O)dothrow.o $(O)drawing.o $(O)dungeon.o $(O)eat.o +VOBJ07 = $(O)end.o $(O)engrave.o $(O)exper.o $(O)explode.o +VOBJ08 = $(O)extralev.o $(O)files.o $(O)fountain.o $(O)hack.o VOBJ09 = $(O)hacklib.o $(O)insight.o $(O)invent.o $(O)isaac64.o VOBJ10 = $(O)light.o $(O)lock.o $(O)mail.o $(O)makemon.o VOBJ11 = $(O)mapglyph.o $(O)mdlib.o $(O)mcastu.o $(O)mhitm.o @@ -350,7 +350,7 @@ CURSESOBJ= endif SOBJ = $(O)windmain.o $(O)winnt.o $(O)win10.o \ - $(O)safeproc.o $(O)nhlan.o $(SOUND) + $(O)safeproc.o $(O)nhlan.o $(SOUND) OBJS = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \ $(VOBJ06) $(VOBJ07) $(VOBJ08) $(VOBJ09) $(VOBJ10) \ @@ -476,7 +476,7 @@ PDCLIB = $(O)pdcurses.a PDCINCL = -I$(PDCURSES_TOP) -I$(PDCSRC) -I$(PDCWINCON) else -PDCLIB = +PDCLIB = endif #========================================== @@ -742,7 +742,7 @@ SHELL=CMD.EXE # Since DOS doesn't allow / as path separator, and GCC doesn't allow \ as # path separator, we must change all pathnames when performing DOS commands. # This is done by blindly applying $(subst /,\, ...) on every command. -# Where any command contain / for another reason (switch char, a little +# Where any command contain / for another reason (switch char, a little # more care is taken. # @@ -794,7 +794,7 @@ recover: $(U)recover.exe $(subst /,\,if exist $(U)recover.exe copy $(U)recover.exe $(GAMEDIR)) $(subst /,\,if exist $(DOC)/recover.txt copy $(DOC)/recover.txt $(GAMEDIR)/recover.txt) -$(O)sp_lev.tag: $(O)utility.tag +$(O)sp_lev.tag: $(O)utility.tag $(subst /,\,echo sp_levs done > $(O)sp_lev.tag) $(O)utility.tag: $(INCL)/date.h $(INCL)/onames.h $(INCL)/pm.h \ @@ -819,7 +819,7 @@ $(O)winres.o: $(TILEBMP16) $(MSWIN)/NetHackW.rc $(MSWIN)/mnsel.bmp \ $(MSWIN)/splash.bmp $(rc) -o$@ --include-dir $(MSWIN) -i $(MSWIN)/NetHackW.rc -$(O)conres.o: $(MSWSYS)/console.rc $(MSWSYS)/NetHack.ico +$(O)conres.o: $(MSWSYS)/console.rc $(MSWSYS)/NetHack.ico $(rc) -o$@ --include-dir $(MSWSYS) -i $(MSWSYS)/console.rc #========================================== @@ -858,7 +858,7 @@ $(GAMEDIR)/NetHackW.exe : gamedir.tag $(PDCLIB) $(O)tile.o $(O)ttystub.o \ endif $(O)nhdefkey.o: - $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(MSWSYS)/nhdefkey.c + $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(MSWSYS)/nhdefkey.c $(GAMEDIR)/nhdefkey.dll : $(O)nhdefkey.o gamedir.tag @echo Linking $@ @@ -866,7 +866,7 @@ $(GAMEDIR)/nhdefkey.dll : $(O)nhdefkey.o gamedir.tag -Wl,--add-stdcall-alias -o $@ $< $(O)nh340key.o: - $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(MSWSYS)/nh340key.c + $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(MSWSYS)/nh340key.c $(GAMEDIR)/nh340key.dll : $(O)nh340key.o gamedir.tag @echo Linking $@ @@ -874,7 +874,7 @@ $(GAMEDIR)/nh340key.dll : $(O)nh340key.o gamedir.tag -Wl,--add-stdcall-alias -o $@ $< $(O)nhraykey.o: - $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(MSWSYS)/nhraykey.c + $(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(MSWSYS)/nhraykey.c $(GAMEDIR)/nhraykey.dll : $(O)nhraykey.o gamedir.tag @echo Linking $@ @@ -1163,7 +1163,7 @@ $(O)til2bm32.o: $(WSHR)/til2bm32.c $(HACK_H) $(TILE_H) $(MSWSYS)/win32api.h $(O)pdcurses.a : $(PDCLIBOBJS) $(PDCOBJS) ar rcs $@ $(PDCLIBOBJS) $(PDCOBJS) - + #============================================================= # LUA #============================================================= @@ -1352,7 +1352,7 @@ $(O)tile.o: $(SRC)/tile.c $(HACK_H) $(O)panic.o: $(U)panic.c $(CONFIG_H) $(cc) $(CFLAGS) -o$@ $(U)panic.c -# +# # sys/share dependencies # @@ -1361,7 +1361,7 @@ $(O)panic.o: $(U)panic.c $(CONFIG_H) # # Other dependencies needed by some ports -# +# ifeq "$(ADD_CURSES)" "Y" # curses window port dependencies @@ -1418,7 +1418,7 @@ endif # with -o$@ # * targets prefixed with $(O) # * $(CC) changed to $(cc) -# but otherwise untouched. +# but otherwise untouched. # That means that there is some irrelevant stuff # in here, but maintenance should be easier. # diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 23aa16cb6..6bbcee59e 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -4,7 +4,7 @@ #============================================================================== # Build Tools Environment # -# NetHack 3.7 Work-in-progress Makefile for +# NetHack 3.7 Work-in-progress Makefile for # MS Visual Studio Visual C++ compiler # # Visual Studio Compilers Tested: @@ -22,11 +22,11 @@ # # BEFORE YOU START, in addition to your C compiler and linker, # -# o You will need a complete Lua source tree parallel to your +# o You will need a complete Lua source tree parallel to your # NetHack source tree. Lua is not an optional requirement, # it is required in order to process the level and dungeon -# description files during the game. You can obtain the -# Lua source from here: +# description files during the game. You can obtain the +# Lua source from here: # https://www.lua.org/download.html # # o If you want to include the curses Window port in the non-GUI @@ -37,7 +37,7 @@ # or via git from here: # git clone https://github.com/wmcbrine/PDCurses.git ../pdcurses # -# o If you want your build of NetHack to include support for +# o If you want your build of NetHack to include support for # compressing your save files, or to be able to exchange and use # compressed save files that originated on another platform such # as Linux or a handheld phone or tablet, then you will need @@ -60,16 +60,16 @@ # # Build Options Decisions # -# There are currently 5 decisions that you can choose to make. -# none of the 5 decisions are absolutely required because defaults +# There are currently 5 decisions that you can choose to make. +# none of the 5 decisions are absolutely required because defaults # are in place: # # 1. Where do you want your build results to end up? # 2. Do you want to include the optional curses port? -# 3. Do you want to include compressed savefile support to +# 3. Do you want to include compressed savefile support to # transfer compressed savefiles between platforms? # 4. Do you want debug information in the executable? -# 5. Do you want to explicitly override auto-detection of +# 5. Do you want to explicitly override auto-detection of # a 32-bit or 64-bit target? # # Mandatory Lua source Location (not optional) @@ -88,13 +88,13 @@ GAMEDIR = ..\binary # Default game build directory # #------------------------------------------------------------------------------ -# OPTIONAL - Curses window port support +# OPTIONAL - Curses window port support # # 2. Uncomment these and set them appropriately if you want to # include curses port support alongside TTY support in your -# NetHack.exe binary. +# NetHack.exe binary. # -# You'll have to set PDCURSES_H to the correct location of the +# You'll have to set PDCURSES_H to the correct location of the # PDCurses header (.h) files and PDCURSES_C to the location # of your PDCurses C files. # @@ -112,13 +112,13 @@ GAMEDIR = ..\binary # Default game build directory # #------------------------------------------------------------------------------ # 4. Do you want debug information available to the executable? -# +# DEBUGINFO = Y # #------------------------------------------------------------------------------ # 5. This Makefile will attempt to auto-detect your selected target architecture # based on Visual Studio command prompt configuration settins etc. -# However, if you want to manually override generation of a +# However, if you want to manually override generation of a # 32-bit or 64-bit build target, you can uncomment the apppropriate # TARGET_CPU line below. # @@ -139,7 +139,7 @@ LUAVER=$(LUA_VERSION) # # Location of LUA # -# Original source needs to be obtained from: +# Original source needs to be obtained from: # http://www.lua.org/ftp/lua-5.4.1.tar.gz # # This build assumes that the LUA sources are located @@ -187,8 +187,8 @@ SSYS = ..\sys\share # Shared system files MSWSYS = ..\sys\winnt # mswin specific files TTY = ..\win\tty # window port files (tty) MSWIN = ..\win\win32 # window port files (win32) -WCURSES = ..\win\curses # window port files (curses) -WSHR = ..\win\share # Tile support files +WCURSES = ..\win\curses # window port files (curses) +WSHR = ..\win\share # Tile support files QT = ..\win\Qt # QT support files X11 = ..\win\X11 # X11 support files @@ -202,8 +202,7 @@ OBJ = o #========================================== # Exe File Info. #========================================== - -# + # # Optional high-quality BSD random number generation routines # (see pcconf.h). Set to nothing if not used. @@ -292,13 +291,13 @@ PPMWRITERS = $(O)ppmwrite.o $(O)alloc$(HOST).o $(O)panic$(HOST).o # VOBJ01 = $(O)allmain.o $(O)alloc.o $(O)apply.o $(O)artifact.o -VOBJ02 = $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o -VOBJ03 = $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o -VOBJ04 = $(O)dig.o $(O)display.o $(O)do.o $(O)do_name.o -VOBJ05 = $(O)do_wear.o $(O)dog.o $(O)dogmove.o $(O)dokick.o -VOBJ06 = $(O)dothrow.o $(O)drawing.o $(O)dungeon.o $(O)eat.o -VOBJ07 = $(O)end.o $(O)engrave.o $(O)exper.o $(O)explode.o -VOBJ08 = $(O)extralev.o $(O)files.o $(O)fountain.o $(O)hack.o +VOBJ02 = $(O)attrib.o $(O)ball.o $(O)bones.o $(O)botl.o +VOBJ03 = $(O)cmd.o $(O)dbridge.o $(O)decl.o $(O)detect.o +VOBJ04 = $(O)dig.o $(O)display.o $(O)do.o $(O)do_name.o +VOBJ05 = $(O)do_wear.o $(O)dog.o $(O)dogmove.o $(O)dokick.o +VOBJ06 = $(O)dothrow.o $(O)drawing.o $(O)dungeon.o $(O)eat.o +VOBJ07 = $(O)end.o $(O)engrave.o $(O)exper.o $(O)explode.o +VOBJ08 = $(O)extralev.o $(O)files.o $(O)fountain.o $(O)hack.o VOBJ09 = $(O)hacklib.o $(O)insight.o $(O)invent.o $(O)isaac64.o VOBJ10 = $(O)light.o $(O)lock.o $(O)mail.o $(O)makemon.o VOBJ11 = $(O)mapglyph.o $(O)mcastu.o $(O)mhitm.o $(O)mhitu.o @@ -341,7 +340,7 @@ CURSESOBJ= $(O)cursdial.o $(O)cursinit.o $(O)cursinvt.o $(O)cursmain.o \ !ENDIF SOBJ = $(O)windmain.o $(O)winnt.o $(O)win10.o \ - $(O)safeproc.o $(O)nhlan.o $(SOUND) + $(O)safeproc.o $(O)nhlan.o $(SOUND) OBJS = $(MDLIB) \ $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \ @@ -472,7 +471,7 @@ PDCLIB = $(O)pdcurses.lib PDCINCL = /I$(PDCURSES_TOP) /I$(PDCSRC) /I$(PDCWINCON) !ELSE -PDCLIB = +PDCLIB = !ENDIF #========================================== @@ -532,15 +531,15 @@ CTAGSOPT =--language-force=c --sort=no -D"Bitfield(x,n)=unsigned x : n" --excmd= # TINC = $(INCL:\=/) TSRC = $(SRC:\=/) - + cc=cl cpp=cpp link=link rc=Rc -# Before we get started, this section is used to determine the version of -# Visual Studio we are using. We set VSVER to 0000 to flag any version that +# Before we get started, this section is used to determine the version of +# Visual Studio we are using. We set VSVER to 0000 to flag any version that # is too old or untested. # #NMAKE version 1428293340 from latest VS 2019 (November 19, 2020 version 16.8.2) @@ -855,26 +854,26 @@ install: $(INCL)\nhlua.h $(O)envchk.tag $(O)obj.tag $(O)utility.tag $(GAMEDIR)\N # Main game targets. #========================================== -# The section for linking the NetHack image looks a little strange at -# first, especially if you are used to UNIX makes, or NDMAKE. It is -# Microsoft nmake specific, and it gets around the problem of the -# link command line being too long for the linker. An "in-line" linker +# The section for linking the NetHack image looks a little strange at +# first, especially if you are used to UNIX makes, or NDMAKE. It is +# Microsoft nmake specific, and it gets around the problem of the +# link command line being too long for the linker. An "in-line" linker # response file is generated temporarily. # # It takes advantage of the following features of nmake: # -# Inline files : +# Inline files : # Specifying the "<<" means to start an inline file. -# Another "<<" at the start of a line closes the +# Another "<<" at the start of a line closes the # inline file. # # Substitution within Macros: # $(mymacro:string1=string2) replaces every -# occurrence of string1 with string2 in the -# macro mymacro. Special ascii key codes may be -# used in the substitution text by preceding it +# occurrence of string1 with string2 in the +# macro mymacro. Special ascii key codes may be +# used in the substitution text by preceding it # with ^ as we have done below. Every occurence -# of a in $(ALLOBJ) is replaced by +# of a in $(ALLOBJ) is replaced by # <+>. GAMEOBJ=$(ALLOBJ:^ =^ @@ -891,7 +890,7 @@ GAMEOBJ=$(GAMEOBJ:^ =^ # libs: $(LIBS) $(conlibs) $(guilibs) $(COMCTRL) # objs: $(GAMEOBJ) $(TTYOBJ) $(O)nttty.o $(O)tile.o $(GUIOBJ) # otherwise: -# libs: $(LIBS) $(conlibs) +# libs: $(LIBS) $(conlibs) # objs: $(GAMEOBJ) $(TTYOBJ) $(O)tile.o $(O)guistub.o @@ -1033,7 +1032,7 @@ $(O)utility.tag: $(INCL)\nhlua.h $(INCL)\date.h $(INCL)\onames.h $(INCL)\pm.h \ @echo utilities made >$@ @echo utilities made. -$(INCL)\nhlua.h: +$(INCL)\nhlua.h: @echo /* nhlua.h - generated by Makefile */ > $@ @echo #include "../lib/lua-$(LUAVER)/src/lua.h" >> $@ @echo LUA_API int (lua_error) (lua_State *L) NORETURN; >> $@ @@ -1056,7 +1055,7 @@ $(O)console.res: $(MSWSYS)\console.rc $(MSWSYS)\NetHack.ico # # Secondary Targets. # - + #========================================== # Makedefs Stuff #========================================== @@ -1112,12 +1111,12 @@ $(U)uudecode.exe: $(O)uudecode.o $(O)uudecode.o: $(SSYS)\uudecode.c @$(cc) $(cflagsBuild) $(CROSSCOMPILE) /D_CRT_SECURE_NO_DEPRECATE -Fo$@ $(SSYS)\uudecode.c -$(MSWSYS)\NetHack.ico : $(U)uudecode.exe $(MSWSYS)\nhico.uu +$(MSWSYS)\NetHack.ico : $(U)uudecode.exe $(MSWSYS)\nhico.uu chdir $(MSWSYS) ..\..\util\uudecode.exe nhico.uu chdir ..\..\src -$(MSWIN)\NetHack.ico : $(U)uudecode.exe $(MSWSYS)\nhico.uu +$(MSWIN)\NetHack.ico : $(U)uudecode.exe $(MSWSYS)\nhico.uu chdir $(MSWIN) ..\..\util\uudecode.exe ../../sys/winnt/nhico.uu chdir ..\..\src @@ -1493,7 +1492,7 @@ $(O)curswins.o: $(WCURSES)\curswins.c $(WCURSES)\curswins.h $(INCL)\wincurs.h $(O)sfstruct.o: $(HACK_H) $(SRC)\sfstruct.c # @$(cc) $(cflagsBuild) -Fo$@ $(SRC)\sfstruct.c - + #=============================================================================== # CROSSCOMPILE #=============================================================================== @@ -1688,10 +1687,10 @@ clean: # OTHER DEPENDENCIES #=================================================================== # -# The rest are stolen from sys/unix/Makefile.src, +# The rest are stolen from sys/unix/Makefile.src, # with the following changes: # * ../include changed to $(INCL) -# * slashes changed to back-slashes +# * slashes changed to back-slashes # * -c (which is included in CFLAGS) substituted with -Fo$@ # * $(CFLAGS) replaced with $(cflagsBuild) # * $(CC) replaced with @$(cc) From d5d75a9e38997be0f9f465f3d63b7f836540f71c Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 25 Nov 2020 07:27:25 -0500 Subject: [PATCH 449/708] move an outdated file: sys/unix/README.linux --- {sys => outdated/sys}/unix/README.linux | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {sys => outdated/sys}/unix/README.linux (100%) diff --git a/sys/unix/README.linux b/outdated/sys/unix/README.linux similarity index 100% rename from sys/unix/README.linux rename to outdated/sys/unix/README.linux From cb5bda40e20c10a0614938ea02af495e0f487413 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 25 Nov 2020 07:53:24 -0500 Subject: [PATCH 450/708] update an old msdos file --- sys/msdos/Install.dos | 268 +++++++++--------------------------------- 1 file changed, 58 insertions(+), 210 deletions(-) diff --git a/sys/msdos/Install.dos b/sys/msdos/Install.dos index 62f65568a..bf981f734 100644 --- a/sys/msdos/Install.dos +++ b/sys/msdos/Install.dos @@ -15,16 +15,11 @@ Stephen White, Ken Washikita and Janet Walz. The present port is based on the previous effort of Pierre Martineau, Stephen Spackman, Steve Creps, Mike Threepoint, Mike Stephenson, Norm Meluch and Don Kneller. -There has been very little port-specific maintenance for NetHack on DOS since -NetHack 3.3.0. - CONTENTS: - I. Dispelling the Myths - II. Compiling on a DOS machine - Appendix A - Building the "official binary" - Appendix B - DJGPP Compiler (gcc ported to msdos) notes - Appendix C - Additional Notes + I. Dispelling the Myths + II. Compiling on Linux or macOS via cross-compiler + Appendix A - Additional Notes Appendix D - Contacting Us I. Dispelling the Myths: @@ -33,233 +28,86 @@ I. Dispelling the Myths: however it will behoove you to read this entire file through before beginning the task. - We have provided a proper Makefile for building NetHack using the - following compilers: - djgpp V2.03 or later - For specific details concerning the djgpp compiler, please see the - appendix B. +II. There once was a time when people built NetHack right on their DOS machine. + The arcane recipe often involved flat cylinders known as "floppy disks", + much gnashing of teeth, squeezing large things into small spaces, and + required the sacrifice of copious amounts of time and coffee. - The makefile named Makefile.GCC is for use with GNU Make that - accompanies djgpp. + These days, to compile your copy of NetHack on Linux or macOS machine using + Andrew Wu's djgpp cross-compiler from: + https://github.com/andrewwutw/build-djgpp + downloaded from: + https://github.com/andrewwutw/build-djgpp/releases/download/v3.0/ + a DOS-extender (for including in msdos packaging) from: + http://sandmann.dotster.com/cwsdpmi/csdpmi7b.zip + and pdcurses from: + https://github.com/wmcbrine/PDCurses.git + and Lua from: + http://www.lua.org/ftp/lua-5.4.1.tar.gz - If you want to build a copy of NetHack that is identical to the - "official binary", please see appendix A. + - A shell script to download the above-mentioned djgpp cross-compiler and + associated support pieces for either linux or macOS is available: + sh sys/msdos/fetch-cross-compiler.sh - The unsupported sys/msdos/Makefile.MSC was for the old 16 bit - Microsoft Visual C 1.52c compiler and has not been made compliant - with 3.5.x. + That script won't install anything, it just does file fetches and stores + them in subfolders of lib. The linux.2020 and macOS.2020 hints files are + configured to find the cross-compiler there if you add + CROSS_TO_MSDOS=1 + on your make command line. - You may find it useful to obtain copies of lex (flex) and yacc (bison - or byacc). While not strictly necessary to compile nethack, they are - required should you desire to make any changes to the level and dungeon - compilers. Flex and Bison are included with the DJGPP distribution and - are also available on many archive sites. + Note: Both the fetch-cross-compiler.sh script and and the msdos + cross-compile and package procedures require unzip and zip to be available + on your host build system. - Also be sure to pick up djgpp v2gnu/fil41b.zip to get ls.exe and - touch.exe, since the Makefile uses them by default. + On your linux host: -II. To compile your copy of NetHack on a DOS machine: - (or "just follow these few 'simple' steps outlined below.") + cd sys/unix ; sh setup.sh hints/linux.2020 ; cd ../.. + make fetch-lua -1. It almost goes without saying that you should make sure that your tools - are set up and running correctly. + On your macOS host: -2. Make sure all the NetHack files are in the appropriate directory - structure. You should have a main directory with subdirectories - dat, doc, include, src, sys\share, sys\msdos, util, win\tty and - win\share. Other subdirectories may also be included in your - distribution, but they are not necessary for use with DOS. You can - delete them to save space. + cd sys/unix ; sh setup.sh hints/macOS.2020 ; cd ../.. + make fetch-lua - Required Source Directories for DOS NetHack: + The MSDOS cross-compile can then be carried out by specifying + CROSS_TO_MSDOS=1 on the make command line: - (top) - | - ------------------------------------------------- - | | | | | | | - util dat doc include src sys win - | | - ------ ----- - | | | | - share msdos tty share + make CROSS_TO_MSDOS=1 all + make CROSS_TO_MSDOS=1 package - Check the file "Files" in your top level directory for an exact - listing of what files are in which directory. In order for the - Makefiles to work, all the source files must be in the proper - locations. + You can explicitly include tty and curses support if desired. The default + you'll end up with is a tty-only cross-compile build: - If you downloaded or ftp'd the sources from a UNIX system, the lines - will probably end in UNIX-style newlines, instead of the carriage - return and line feed pairs used by DOS. Some programs have trouble - with them, so you may need to convert them (with a utility like - Rahul Dhesi's "flip"). + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all + make WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package -3. Go to the sys/msdos directory and ensure that the file setup.bat - has MSDOS style end-of-line characters rather than UNIX style - end-of-line characters. You can do that using a utility like - Rahul Dhesi's "flip", or by invoking the MSDOS edit utility on - setup.bat and saving the file without making any changes. Failure to - do this will prevent the bat file from executing completely, yet no - warning message will be given. + 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 - Run the setup.bat batch file with the following as the argument: + Also note that building the msdos targets using the make command + above, does not preclude you from building local linux or macOS + targets as well. Just drop the CROSS_TO_MSDOS=1 from the make + command line. That's because the cross-compiler hints additions are + enclosed inside ifdef sections and won't interfere with the + non-cross-compile build in that case. - GCC For djgpp and GNU MAKE. +Appendix A - Additional Notes - The appropriate and necessary Makefile movement will be accomplished - for you, as well as verifying a few files and fixing a few file names - on FAT systems with long file name support. - -4. Now go to the include subdirectory to check a couple of the header - files there. Things *should* work as they are, but since you have - probably set up your system in some sort of custom configuration - it doesn't hurt to check out the following: - - First check config.h according to the comments to match your system and - desired set of features. Mostly you need to check the WIZARD option, - and check TERMLIB and COMPRESS. Also be sure to leave DLB support - commented out in config.h. MSDOS has support for DLB, but it must be - done through the Makefile, rather than config.h, to ensure that the - necessary packaging steps are done. - - We've managed to enable all the special features. You may include all - or as few of them as you wish. To conserve disk space, you may wish - to disable LOGFILE and NEWS. - - Also check pcconf.h, which should not need much editing (if you are - including random.c, and if you do not require termcap for screen - management). If you are not including random.c you will need to - comment out RANDOM. - - If using DJGPP, you can choose between SCREEN_BIOS - and SCREEN_DJGPPFAST. Never, never, ever choose both. Bad things - will happen. We are not kidding. - -5. If you want to change the high score list behavior, examine the top of - topten.c, in the src directory. You may want to change the definitions of - PERSMAX, POINTSMIN, and ENTRYMAX. We set POINTSMIN to 51 and ENTRYMAX to - 50 to keep the size of the score list down. - -6. Go to the src directory and edit the top of your Makefile. Be sure the - directory you want the game installed in (GAMEDIR) actually exists. - -7. Now that everything is set up, - - Go to the src directory, and using the GNU Make utility, - "make install". - - Depending on your particular machine and compiler, you can either - grab a cup of coffee or go home for the day. Your computer will be - occupied for quite some time. If all goes well, you will get an - NetHack executable. - -9. If you chose DLB support (recommended), make sure that the file nhdat - got copied into the game directory. - - If you didn't choose DLB support, make sure the support files -- - data, rumors, cmdhelp, opthelp, help, hh,history, guidebook.txt - license, and all the *.lev files -- were copied to the game directory. - If not, move them there from the dat directory yourself. rumors can - be created manually be entering "makedefs -r", data by entering - "makedefs -d". - - Make sure the files NetHack1.tib and NetHacko.tib made it to your game - directory. Copy them from src to the game directory yourself if - necessary. - - Make sure the files defaults.nh and termcap made it to your game - directory. If not, go to sys\share and copy NetHack.cnf to - your game directory as defaults.nh. The name in previous versions was - nethack.cnf, but the CNF extension conflicted with the MS Windows - speed-dialer, making the file hidden on many machines. - - If you changed your build settings to include TERMCAP support, copy - termcap to your game directory. - - Also, make sure the file msdoshlp.txt made it to your game directory. - If it didn't, move it from sys\msdos to your game directory - yourself. - -10. In your game directory, review the settings in defaults.nh and adjust +1. In your game directory, review the settings in defaults.nh and adjust them according to your style of play. -11. Play NetHack. If it works, you're done! - -Appendix A - Building the "official binary" - - If you wish to build a copy of NetHack identical to the one that - the pc team distributes, simply do the following: - - The 32-bit Protected Mode DPMI version built with 32-bit djgpp - compiler V2.03 or greater, make no changes to any of the defines and use - the Makefile.GCC as distributed, and as moved in step 3. - - Paths below are relative to the top of your unpacked - NetHack source distribution: - - md \nethack\binary (must match Makefile) - cd sys\msdos - setup GCC - cd ..\..\src - make install - - - Make sure the following files have been converted from the - unix style "^J" end of line, to the msdos style "^M^J": - license, defaults.nh. - - Place all the files in a clean directory and test. - -Appendix B - DJGPP Compiler (gcc ported to msdos) - - If you have a 386 or better machine, you are in luck. You can compile - NetHack without spending money on a compiler. DJGPP is available free - from many archive sites. - At the time of this release in April 2002, the URL - http://www.delorie.com/djgpp/zip-picker.html/ - had information on how to obtain djgpp and what pieces to get. - Be sure to pick up djgpp v2gnu/fil41b.zip to get ls.exe and - touch.exe, since the Makefile uses them by default (or change - the Makefile to use alternatives). - - Special note for Windows 2000 / Windows XP users: You must have a - recent djgpp distribution for the build process, and the generated - executables to work properly on those platforms. - - Setting up DJGPP is more than adequately explained in the documentation - that comes with it. Be sure to pick up the yacc and flex built with - DJGPP if you intend to do any modification of the special levels or - dungeon compilers. They should be available at the same place you got - djgpp. - - The latest version of djgpp, V2.03 with the most recent refresh - will produce a binary that will run under Microsoft Windows, or any - other DPMI provider. djgpp also comes with a DPMI provider called CWSDPMI. - Place CWSDPMI.EXE in your path and it will be used in the absence of any - other DPMI provider. - - If you want to use the built-in DJGPP screen routines, uncomment - SCREEN_DJGPPFAST in pcconf.h (the default for djgpp). - -Appendix C - Additional Notes - -1) Save files and bones files from versions of NetHack prior to 3.5.0 will not - work with this NetHack. Don't bother trying to keep them. - -2) To install an update of NetHack after changing something, type 'make' - for DJGPP from the src directory. If you add, delete, or reorder monsters or - objects, or you change the format of saved level files, delete any save - and bones files. (Trying to use such files sometimes produces amusing - confusions on the game's part, but usually crashes.) - +2. Play NetHack. If it works, you're done! Appendix D - Contacting the Development Team If you discover a bug and wish to report it, or if you have comments or suggestions we recommend using our "Contact Us" web page at: - http://www.nethack.org/common/contact.html + https://www.nethack.org/common/contact.html If you don't have access to the web, or you want to send us a patch to the NetHack source code feel free to drop us a line c/o: From bc7947ed22722a8e974c4f8722cadb220d54a07d Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Wed, 25 Nov 2020 08:24:08 -0500 Subject: [PATCH 451/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Files b/Files index c1adc3fc9..7d456a19c 100644 --- a/Files +++ b/Files @@ -151,6 +151,10 @@ outdated/sys/os2: (files for OS/2 version - untested for 3.7) Install.os2 Makefile.os2 nhpmico.uu os2.c +outdated/sys/unix: +(files that are no longer maintained for current game code) +README.linux + outdated/sys/wince: (files for Windows CE and PocketPC - untested for 3.7) Install.ce bootstrp.mak celib.c cesetup.bat cesound.c @@ -282,10 +286,10 @@ pmatchregex.c sys/unix: (files for UNIX versions) Install.unx Makefile.dat Makefile.doc Makefile.src -Makefile.top Makefile.utl NewInstall.unx README.linux -README.xcode XCode.xcconfig depend.awk gitinfo.sh -mkmkfile.sh nethack.sh setup.sh sysconf -unixmain.c unixres.c unixunix.c +Makefile.top Makefile.utl NewInstall.unx README.xcode +XCode.xcconfig depend.awk gitinfo.sh mkmkfile.sh +nethack.sh setup.sh sysconf unixmain.c +unixres.c unixunix.c (files for replacement cpp, only needed by some ancient UNIX systems) cpp1.shr cpp2.shr cpp3.shr From dde70b8d4aa4f535900e257db19ffaf3ff4e6713 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 25 Nov 2020 09:15:20 -0800 Subject: [PATCH 452/708] Guidebook bit: ascii_map and tiled_map |ascii_map: |If NetHack can, it should display an ascii character map if it can. |tiled_map: |If NetHack can, it should display a tiled map if it can. Remove the "if {NetHack,it} can" redundancy and expand a little bit. Also, alphabetize "tiled_map" as if the underscore were a space instead of something that happens to collate after letters. As usual, the Guidebook.tex changes are untested. --- doc/Guidebook.mn | 29 ++++++++++++++++++++++++----- doc/Guidebook.tex | 23 ++++++++++++++++++----- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index bf4b30385..e26ba1a19 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.398 $ $NHDT-Date: 1605618309 2020/11/17 13:05:09 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.399 $ $NHDT-Date: 1606324515 2020/11/25 17:15:15 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "November 16, 2020 +.ds f2 "November 25, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -4172,7 +4172,19 @@ Where to align or place the message window (top, bottom, left, or right) .lp align_status Where to align or place the status window (top, bottom, left, or right). .lp ascii_map -If NetHack can, it should display an ascii character map if it can. +.hw DECgraphics IBMgraphics \" don't hyphenate these +If NetHack can, it should display the map using simple +characters (letters and punctuation) rather than \fItiles\fP graphics. +In some cases, characters can be augmented with line-drawing symbols; +use the +.op symset +option to select a symbol set such as \fIDECgraphics\fP +or \fIIBMgraphics\fP if your display supports them. +Setting +.op ascii_map +to \fITrue\fP forces +.op tiled_map +to be \fIFalse\fP. .lp color If NetHack can, it should display color if it can for different monsters, objects, and dungeon features. @@ -4275,14 +4287,21 @@ 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. -.lp tiled_map -If NetHack can, it should display a tiled map if it can. .lp tile_file Specify the name of an alternative tile file to override the default. .lp tile_height Specify the preferred height of each tile in a tile capable port. .lp tile_width Specify the preferred width of each tile in a tile capable port +.lp tiled_map +If NetHack can, it should display the map using \fItiles\fP graphics +rather than simple characters (letters and punctuation, possibly +augmented by line-drawing symbols). +Setting +.op tiled_map +to \fITrue\fP forces +.op ascii_map +to be \fIFalse\fP. .lp use_darkgray Use bold black instead of blue for black glyphs (TTY only). .lp use_inverse diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index df603a3ae..7eee96e54 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{November 16, 2020} +\date{November 25, 2020} \maketitle @@ -4529,7 +4529,16 @@ with the `{\tt O}' command. Where to align or place the status window (top, bottom, left, or right). %.lp \item[\ib{ascii\verb+_+map}] -If {\it NetHack\/} can, it should display an ascii map. +%.hw DECgraphics IBMgraphics \% don't hyphenate these +\hyphenation{DECgraphics IBMgraphics} +If {\it NetHack\/} can, it should display the map using simple +characters (letters and punctuation) rather than {\it tiles\/} graphics. +In some cases, characters can be augmented with line-drawing symbols; +use the {\tt symset} +option to select a symbol set such as {\it DECgraphics\/} +or {\it IBMgraphics\/} if your display supports them. +Setting {\tt ascii\verb+_+map} to {\it True\/} forces +{\tt tiled\verb+_+map} to be {\it False}. %.lp \item[\ib{color}] If {\it NetHack\/} can, it should display color for different monsters, @@ -4661,9 +4670,6 @@ 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. %.lp -\item[\ib{tiled\verb+_+map}] -If {\it NetHack\/} can, it should display a tiled map if it can. -%.lp \item[\ib{tile\verb+_+file}] Specify the name of an alternative tile file to override the default. %.lp @@ -4673,6 +4679,13 @@ Specify the preferred height of each tile in a tile capable port. \item[\ib{tile\verb+_+width}] Specify the preferred width of each tile in a tile capable port %.lp +\item[\ib{tiled\verb+_+map}] +If {\it NetHack\/} can, it should display the map using \fItiles\fP graphics +rather than simple characters (letters and punctuation, possibly +augmented by line-drawing symbols). +Setting {\tt tiled\verb+_+map} to {\it True\/} forces +{\tt ascii\verb+_+map} to be {\it False}. +%.lp \item[\ib{use\verb+_+darkgray}] Use bold black instead of blue for black glyphs (TTY only). %.lp From 6df9ebc1af4239391483b40877713142ec106dec Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 25 Nov 2020 10:21:43 -0800 Subject: [PATCH 453/708] add Guidebook description of rogue level This is in response to the bug report we got however long ago about the map display breaking when the [unfamiliar to player] rogue level was reached. It probably wouldn't have helped back then since the subset of players who read the documentation is about same subset as those who expect the Spanish Inquisition. I wasn't sure whether appending "'s" to an italicized word should be italicized itself and made it revert to the regular font instead. That should be changed if it's incorrect usage. --- doc/Guidebook.mn | 21 +++++++++++++++++++-- doc/Guidebook.tex | 25 +++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index e26ba1a19..975691af8 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.399 $ $NHDT-Date: 1606324515 2020/11/25 17:15:15 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.400 $ $NHDT-Date: 1606328499 2020/11/25 18:21:39 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -103,7 +103,7 @@ travel, you see the 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... +dungeon.... . .hn 1 What is going on here? @@ -1991,6 +1991,23 @@ The .op 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). +.hn 2 +Rogue level +.pg +One dungeon level (occurring in mid to late teens of the main dungeon) +is a tribute to the ancestor game \fIhack\fP's inspiration \fIrogue\fP. +.pg +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 \f(CR*\fP rather than \f(CR$\fP +and stairs are shown as \f(CR%\fP rather than \f(CR<\fP and \f(CR>\fP. +There are some minor differences 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. +.pg +The slight strangeness of this level is a feature, not a bug.... . .hn 1 Monsters diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 7eee96e54..68c0466c4 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -2075,7 +2075,7 @@ Shops do not get restocked with new items, regardless of inventory depletion. \end{itemize} %.hn 2 -\subsubsection*{Movement feedback} +\subsection*{Movement feedback} %.pg Moving around the map usually provides no @@ -2161,6 +2161,27 @@ The option controls how frequently the map gets redrawn when moving more than one step in a single command (so when rushing, running, or traveling). +%.hn 2 +\subsection*{Rogue level} + +%.pg +One dungeon level (occurring in mid to late teens of the main dungeon) +is a tribute to the ancestor game {\it hack}'s inspiration {\it rogue}. + +%.pg +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 {\tt *} rather than {\tt \verb+$+} +and stairs are shown as {\tt \verb+%+} rather than {\tt <} and {\tt >}. +There are some minor differences 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. + +%.pg +The slight strangeness of this level is a feature, not a bug.... + %.hn 1 \section{Monsters} @@ -4848,7 +4869,7 @@ if this does not correct the problem, try {\tt !color}. Cannot be set with the `{\tt O}' command. \elist -%.nh 2 +%.hn 2 \subsection*{Regular Expressions} %.pg From 2db51cf8bd5b0aa93f2375b61d0da51fcdbfc509 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 25 Nov 2020 14:33:14 -0800 Subject: [PATCH 454/708] fix #K3016 - kicking a bag of gold in a shop Kicking a container that had gold in it took the gold amount away from hero's credit or added to hero's debt, then didn't give a refund if the container and its gold landed within the shop. Throwing behaved likewise, just less verbosely. The problem is caused by addtobill() treating gold specially and then subfrombill() not being able to perform a reverse operation. Actually, it may be possible for subfrombill() to do that, but verifying all its uses is too much work. This moves the gold handling for drop+selling into its own routine and adds calls to that for the throwing and kicking refunds. The other calls to subfrombill() outside of shk.c appear to be ok as-is. (The calls inside that file are the ones that still need evaluation if the gold handling is to move to there.) bill_dummy_object() now uses the same o_id assignment for its dummy object as split_object() does for its new partial stack. I don't know whether the old code led to any price glitches. --- doc/fixes37.0 | 5 +++- include/extern.h | 7 ++--- src/dokick.c | 26 +++++++++++++----- src/dothrow.c | 11 +++++--- src/mkobj.c | 10 +++---- src/shk.c | 69 ++++++++++++++++++++++++++++-------------------- 6 files changed, 81 insertions(+), 47 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index fbd016ffa..9e712a198 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.362 $ $NHDT-Date: 1606243387 2020/11/24 18:43:07 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.363 $ $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ General Fixes and Modified Features ----------------------------------- @@ -308,6 +308,9 @@ wand/scroll of create monster or bag of tricks that makes a new monster which wizard mode (only way to get timed flying): if levitation and flying time out on same turn, player was told "You have stopped levitating and are now flying."; status line wasn't updated to remove stale Fly condition +throwing or kicking a shop container (that's light enough to move) made the + hero pay for any gold inside, then didn't refund that amount if the + container landed inside the shop Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 4ea7e7575..0147a619d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1606008997 2020/11/22 01:36:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.880 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.882 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2406,8 +2406,9 @@ E boolean FDECL(billable, (struct monst **, struct obj *, CHAR_P, BOOLEAN_P)); E void FDECL(addtobill, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); E void FDECL(splitbill, (struct obj *, struct obj *)); E void FDECL(subfrombill, (struct obj *, struct monst *)); -E long FDECL(stolen_value, - (struct obj *, XCHAR_P, XCHAR_P, BOOLEAN_P, BOOLEAN_P)); +E long FDECL(stolen_value, (struct obj *, XCHAR_P, XCHAR_P, + BOOLEAN_P, BOOLEAN_P)); +E void FDECL(donate_gold, (long, struct monst *, BOOLEAN_P)); E void FDECL(sellobj_state, (int)); E void FDECL(sellobj, (struct obj *, XCHAR_P, XCHAR_P)); E int FDECL(doinvbill, (int)); diff --git a/src/dokick.c b/src/dokick.c index 65cb6f4e6..114a217b8 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dokick.c $NHDT-Date: 1606009001 2020/11/22 01:36:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 3.7 dokick.c $NHDT-Date: 1606343576 2020/11/25 22:32:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.160 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -508,7 +508,8 @@ xchar x, y; } if (!uarmf && g.kickedobj->otyp == CORPSE - && touch_petrifies(&mons[g.kickedobj->corpsenm]) && !Stone_resistance) { + && touch_petrifies(&mons[g.kickedobj->corpsenm]) + && !Stone_resistance) { You("kick %s with your bare %s.", corpse_xname(g.kickedobj, (const char *) 0, CXN_PFX_THE), makeplural(body_part(FOOT))); @@ -705,12 +706,23 @@ xchar x, y; else (void) stolen_value(g.kickedobj, x, y, (boolean) shkp->mpeaceful, FALSE); + costly = FALSE; /* already billed */ } if (flooreffects(g.kickedobj, g.bhitpos.x, g.bhitpos.y, "fall")) return 1; - if (g.kickedobj->unpaid) - subfrombill(g.kickedobj, shkp); + if (costly) { + long gt = 0L; + + /* costly + landed outside shop handled above; must be inside shop */ + if (g.kickedobj->unpaid) + subfrombill(g.kickedobj, shkp); + + /* if billed for contained gold during kick, get a refund now */ + if (Has_contents(g.kickedobj) + && (gt = contained_gold(g.kickedobj, TRUE)) > 0L) + donate_gold(gt, shkp, FALSE); + } place_object(g.kickedobj, g.bhitpos.x, g.bhitpos.y); stackobj(g.kickedobj); newsym(g.kickedobj->ox, g.kickedobj->oy); @@ -1723,7 +1735,8 @@ unsigned long deliverflags; continue; if (otmp->migr_species != NON_PM - && (mtmp->data->mflags2 & DELIVER_PM) == (unsigned) otmp->migr_species) { + && ((mtmp->data->mflags2 & DELIVER_PM) + == (unsigned) otmp->migr_species)) { obj_extract_self(otmp); otmp->owornmask = 0L; otmp->ox = otmp->oy = 0; @@ -1777,7 +1790,8 @@ long num; if (nodrop) Sprintf(eos(xbuf), "."); else - Sprintf(eos(xbuf), " and %s %s.", otense(otmp, "fall"), g.gate_str); + Sprintf(eos(xbuf), " and %s %s.", + otense(otmp, "fall"), g.gate_str); pline("%s%s", obuf, xbuf); } else if (!nodrop) pline("%s %s %s.", obuf, otense(otmp, "fall"), g.gate_str); diff --git a/src/dothrow.c b/src/dothrow.c index 6719dc9d8..f3015bfd1 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dothrow.c $NHDT-Date: 1596498161 2020/08/03 23:42:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */ +/* NetHack 3.7 dothrow.c $NHDT-Date: 1606343578 2020/11/25 22:32:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -935,10 +935,15 @@ boolean broken; /* ushops0: in case we threw while levitating and recoiled out of shop (most likely to the shk's spot in front of door) */ if (*oshops == *u.ushops || *oshops == *u.ushops0) { - if (is_unpaid(obj)) + if (is_unpaid(obj)) { + long gt = Has_contents(obj) ? contained_gold(obj, TRUE) : 0L; + subfrombill(obj, shkp); - else if (x != shkp->mx || y != shkp->my) + if (gt > 0L) + donate_gold(gt, shkp, TRUE); + } else if (x != shkp->mx || y != shkp->my) { sellobj(obj, x, y); + } } } } diff --git a/src/mkobj.c b/src/mkobj.c index 71ef55a88..4c1b810bb 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1596498183 2020/08/03 23:43:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.186 $ */ +/* NetHack 3.7 mkobj.c $NHDT-Date: 1606343579 2020/11/25 22:32:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -633,9 +633,7 @@ register struct obj *otmp; *dummy = *otmp; dummy->oextra = (struct oextra *) 0; dummy->where = OBJ_FREE; - dummy->o_id = g.context.ident++; - if (!dummy->o_id) - dummy->o_id = g.context.ident++; /* ident overflowed */ + dummy->o_id = nextoid(otmp, dummy); dummy->timed = 0; copy_oextra(dummy, otmp); if (has_omid(dummy)) @@ -647,8 +645,8 @@ register struct obj *otmp; if (cost) alter_cost(dummy, -cost); /* no_charge is only valid for some locations */ - otmp->no_charge = - (otmp->where == OBJ_FLOOR || otmp->where == OBJ_CONTAINED) ? 1 : 0; + otmp->no_charge = (otmp->where == OBJ_FLOOR + || otmp->where == OBJ_CONTAINED) ? 1 : 0; otmp->unpaid = 0; return; } diff --git a/src/shk.c b/src/shk.c index 5ad0fb07a..64afd3207 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1606009003 2020/11/22 01:36:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 3.7 shk.c $NHDT-Date: 1606343581 2020/11/25 22:33:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3003,6 +3003,44 @@ boolean peaceful, silent; return value; } +/* opposite of costly_gold(); hero has dropped gold in a shop; + called from sellobj(); ought to be called from subfrombill() too */ +void +donate_gold(gltmp, shkp, selling) +long gltmp; +struct monst *shkp; +boolean selling; /* True: dropped in shop; False: kicked and landed in shop */ +{ + struct eshk *eshkp = ESHK(shkp); + + if (eshkp->debit >= gltmp) { + if (eshkp->loan) { /* you carry shop's gold */ + if (eshkp->loan > gltmp) + eshkp->loan -= gltmp; + else + eshkp->loan = 0L; + } + eshkp->debit -= gltmp; + Your("debt is %spaid off.", eshkp->debit ? "partially " : ""); + } else { + long delta = gltmp - eshkp->debit; + + eshkp->credit += delta; + if (eshkp->debit) { + eshkp->debit = 0L; + eshkp->loan = 0L; + Your("debt is paid off."); + } + if (eshkp->credit == delta) + You("have %sestablished %ld %s credit.", + !selling ? "re-" : "", delta, currency(delta)); + else + pline("%ld %s added%s to your credit; total is now %ld %s.", + delta, currency(delta), !selling ? " back" : "", + eshkp->credit, currency(eshkp->credit)); + } +} + void sellobj_state(deliberate) int deliberate; @@ -3088,7 +3126,7 @@ xchar x, y; return; } - if (eshkp->robbed) { /* shkp is not angry? */ + if (eshkp->robbed) { /* bones; shop robbed by previous customer */ if (isgold) offer = obj->quan; else if (cgold) @@ -3106,32 +3144,7 @@ xchar x, y; if (!cgold) gltmp = obj->quan; - if (eshkp->debit >= gltmp) { - if (eshkp->loan) { /* you carry shop's gold */ - if (eshkp->loan >= gltmp) - eshkp->loan -= gltmp; - else - eshkp->loan = 0L; - } - eshkp->debit -= gltmp; - Your("debt is %spaid off.", eshkp->debit ? "partially " : ""); - } else { - long delta = gltmp - eshkp->debit; - - eshkp->credit += delta; - if (eshkp->debit) { - eshkp->debit = 0L; - eshkp->loan = 0L; - Your("debt is paid off."); - } - if (eshkp->credit == delta) - You("have established %ld %s credit.", delta, - currency(delta)); - else - pline("%ld %s added to your credit; total is now %ld %s.", - delta, currency(delta), eshkp->credit, - currency(eshkp->credit)); - } + donate_gold(gltmp, shkp, TRUE); if (!offer || g.sell_how == SELL_DONTSELL) { if (!isgold) { From ec153a27bdcff336ff2f6559c732b144d28440d7 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 26 Nov 2020 02:20:00 -0800 Subject: [PATCH 455/708] options help The revamped options handling was't doing dynamic help properly. After listing the booleans, it listed them again amongest the compound options. Since their description field is Null, that could be a big problem. sprintf(buf,"%s",NULL) on OSX produces "(null)" but most sprintf()'s would probably crash instead. The 'other' options (autopickup exceptions, menucolors, &c) were not listed at all. (I don't remember whether that was also the case before the revamp.) Now they're listed but not explained. The 'msg_window' description was unhelpful; this replaces it. A couple of others were longer than necessary so they've been shortened. The rest of optlist.h is reformatting wide lines. Recently added 'safe_wait' option was included in the Guidebook but not in dat/opthelp; add it. --- dat/opthelp | 2 + doc/fixes37.0 | 5 ++- include/optlist.h | 94 +++++++++++++++++++++++------------------------ src/options.c | 47 +++++++++++++++++++++--- 4 files changed, 94 insertions(+), 54 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index 5a9049cac..1bcf57474 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -52,6 +52,8 @@ quick_farsight usually skip the chance to browse the map when [FALSE] rawio allow the use of raw I/O [FALSE] rest_on_space count the space bar as a rest character [FALSE] safe_pet prevent you from (knowingly) attacking your pet(s) [TRUE] +safe_wait require use of 'm' prefix before '.' or 's' to [TRUE] + wait or search when adjacent to a hostile monster sanity_check perform data sanity checks [FALSE] showexp display your accumulated experience points [FALSE] showrace show yourself by your race rather than by role [FALSE] diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9e712a198..68e2814a9 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.363 $ $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.364 $ $NHDT-Date: 1606385979 2020/11/26 10:19:39 $ General Fixes and Modified Features ----------------------------------- @@ -398,6 +398,9 @@ fire/frost horn feedback when zapped by monster was inaccurate (falsely claimed that it was "directed at self" when attacking hero) tins of spinach and 'dead' eggs could cause out of array bounds access attempting to index into mons[] by polyfodder() macro +options help ('? g') listed all boolean options, then repeated them among + the compound options; on OSX they showed a description of "(null)" + but for other sprintf implementations they might cause a crash curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/include/optlist.h b/include/optlist.h index 5bc7ec31e..06fb03f6a 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -151,10 +151,10 @@ pfx_##a, "the kinds of information to disclose at end of game") NHOPTC(dogname, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, "the name of your (first) dog (e.g., dogname:Fang)") - NHOPTC(dungeon, MAXDCHARS + 1,opt_in, set_in_config, No, Yes, No, No, NoAlias, - "the symbols to use in drawing the dungeon map") - NHOPTC(effects, MAXECHARS + 1, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "the symbols to use in drawing special effects") + NHOPTC(dungeon, MAXDCHARS + 1,opt_in, set_in_config, No, Yes, No, No, + NoAlias, "the symbols to use in drawing the dungeon map") + NHOPTC(effects, MAXECHARS + 1, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "the symbols to use in drawing special effects") NHOPTB(eight_bit_tty, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc_eight_bit_input) NHOPTB(extmenu, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, @@ -171,14 +171,14 @@ pfx_##a, "the font to use in the message window") NHOPTC(font_size_map, 20, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, "the size of the map font") - NHOPTC(font_size_menu, 20, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the size of the menu font") - NHOPTC(font_size_message, 20, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the size of the message font") - NHOPTC(font_size_status, 20, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the size of the status font") - NHOPTC(font_size_text, 20, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the size of the text font") + NHOPTC(font_size_menu, 20, opt_in, set_gameview, Yes, Yes, Yes, No, + NoAlias, "the size of the menu font") + NHOPTC(font_size_message, 20, opt_in, set_gameview, Yes, Yes, Yes, No, + NoAlias, "the size of the message font") + NHOPTC(font_size_status, 20, opt_in, set_gameview, Yes, Yes, Yes, No, + NoAlias, "the size of the status font") + NHOPTC(font_size_text, 20, opt_in, set_gameview, Yes, Yes, Yes, No, + NoAlias, "the size of the text font") NHOPTC(font_status, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, "the font to use in status window") NHOPTC(font_text, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, @@ -214,7 +214,7 @@ pfx_##a, NHOPTB(hitpointbar, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc2_hitpointbar) NHOPTC(horsename, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "the name of your (first) horse (e.g., horsename:Silver)") + "name of your (first) horse (e.g., horsename:Silver)") #ifdef BACKWARD_COMPAT NHOPTC(IBMgraphics, 70, opt_in, set_in_config, Yes, Yes, No, No, NoAlias, "load IBMGraphics display symbols") @@ -226,8 +226,8 @@ pfx_##a, NHOPTB(ignintr, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias, (boolean *) 0) #endif - NHOPTB(implicit_uncursed, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, - &flags.implicit_uncursed) + NHOPTB(implicit_uncursed, 0, opt_out, set_in_game, On, Yes, No, No, + NoAlias, &flags.implicit_uncursed) NHOPTB(large_font, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias, &iflags.obsolete) NHOPTB(legacy, 0, opt_out, set_in_config, On, Yes, No, No, NoAlias, @@ -248,18 +248,18 @@ pfx_##a, &flags.mention_decor) NHOPTB(mention_walls, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.mention_walls) - NHOPTC(menu_deselect_all, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "deselect all items in a menu") - NHOPTC(menu_deselect_page, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "deselect all items on this page of a menu") + NHOPTC(menu_deselect_all, 4, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "deselect all items in a menu") + NHOPTC(menu_deselect_page, 4, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "deselect all items on this page of a menu") NHOPTC(menu_first_page, 4, opt_in, set_in_config, No, No, Yes, No, NoAlias, "jump to the first page in a menu") NHOPTC(menu_headings, 4, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, "display style for menu headings") NHOPTC(menu_invert_all, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, "invert all items in a menu") - NHOPTC(menu_invert_page, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "invert all items on this page of a menu") + NHOPTC(menu_invert_page, 4, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "invert all items on this page of a menu") NHOPTC(menu_last_page, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, "jump to the last page in a menu") NHOPTC(menu_next_page, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, @@ -273,34 +273,34 @@ pfx_##a, NHOPTB(menu_overlay, 0, opt_in, set_in_config, Off, No, No, No, NoAlias, (boolean *) 0) #endif - NHOPTC(menu_previous_page, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "goto the previous menu page") + NHOPTC(menu_previous_page, 4, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "goto the previous menu page") NHOPTC(menu_search, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, "search for a menu item") NHOPTC(menu_select_all, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, "select all items in a menu") - NHOPTC(menu_select_page, 4, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "select all items on this page of a menu") + NHOPTC(menu_select_page, 4, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "select all items on this page of a menu") NHOPTB(menu_tab_sep, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.menu_tab_sep) NHOPTB(menucolors, 0, opt_in, set_in_game, Off, Yes, Yes, No, NoAlias, &iflags.use_menu_color) NHOPTC(menuinvertmode, 5, opt_in, set_in_game, No, Yes, No, No, NoAlias, "behaviour of menu iverts") - NHOPTC(menustyle, MENUTYPELEN, opt_in, set_in_game, Yes, Yes, No, Yes, NoAlias, - "user interface for object selection") + NHOPTC(menustyle, MENUTYPELEN, opt_in, set_in_game, Yes, Yes, No, Yes, + NoAlias, "user interface for object selection") NHOPTB(monpolycontrol, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.mon_polycontrol) - NHOPTC(monsters, MAXMCLASSES, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "the symbols to use for monsters") + NHOPTC(monsters, MAXMCLASSES, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "the symbols to use for monsters") NHOPTC(mouse_support, 0, opt_in, set_in_game, No, Yes, No, No, NoAlias, "game receives click info from mouse") #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) NHOPTC(msg_window, 1, opt_in, set_in_game, Yes, Yes, No, Yes, NoAlias, - "the type of message window required") + "control of \"view previous message(s)\" (^P) behavior") #else NHOPTC(msg_window, 1, opt_in, set_in_config, Yes, Yes, No, Yes, NoAlias, - "the type of message window required") + "control of \"view previous message(s)\" (^P) behavior") #endif NHOPTC(msghistory, 5, opt_in, set_gameview, Yes, Yes, No, No, NoAlias, "number of top line messages to save") @@ -319,10 +319,10 @@ pfx_##a, &flags.null) NHOPTC(number_pad, 1, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, "use the number pad for movement") - NHOPTC(objects, MAXOCLASSES, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "the symbols to use for objects") - NHOPTC(packorder, MAXOCLASSES, opt_in, set_in_game, No, Yes, No, No, NoAlias, - "the inventory order of the items in your pack") + NHOPTC(objects, MAXOCLASSES, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "the symbols to use for objects") + NHOPTC(packorder, MAXOCLASSES, opt_in, set_in_game, No, Yes, No, No, + NoAlias, "the inventory order of the items in your pack") #ifdef CHANGE_COLOR #ifndef WIN32 NHOPTC(palette, 15, opt_in, set_in_game, No, Yes, No, No, "hicolor", @@ -344,12 +344,12 @@ pfx_##a, "maximum burden picked up before prompt") NHOPTB(pickup_thrown, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.pickup_thrown) - NHOPTC(pickup_types, MAXOCLASSES, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, - "types of objects to pick up automatically") + NHOPTC(pickup_types, MAXOCLASSES, opt_in, set_in_game, No, Yes, No, Yes, + NoAlias, "types of objects to pick up automatically") NHOPTC(pile_limit, 24, opt_in, set_in_game, Yes, Yes, No, No, NoAlias, "threshold for \"there are many objects here\"") - NHOPTC(player_selection, 12, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "choose character via dialog or prompts") + NHOPTC(player_selection, 12, opt_in, set_gameview, No, Yes, No, No, + NoAlias, "choose character via dialog or prompts") NHOPTC(playmode, 8, opt_in, set_gameview, No, Yes, No, No, NoAlias, "normal play, non-scoring explore mode, or debug mode") NHOPTB(popup_dialog, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, @@ -372,7 +372,7 @@ pfx_##a, NHOPTB(rest_on_space, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &flags.rest_on_space) NHOPTC(roguesymset, 70, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, - "load a set of rogue display symbols from the symbols file") + "load a set of rogue display symbols from symbols file") NHOPTC(role, PL_CSIZ, opt_in, set_gameview, No, Yes, No, No, "character", "your starting role (e.g., Barbarian, Valkyrie)") NHOPTC(runmode, sizeof "teleport", opt_in, set_in_game, Yes, Yes, No, Yes, @@ -434,7 +434,7 @@ pfx_##a, NHOPTC(suppress_alert, 8, opt_in, set_in_game, No, Yes, Yes, No, NoAlias, "suppress alerts about version-specific features") NHOPTC(symset, 70, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, - "load a set of display symbols from the symbols file") + "load a set of display symbols from symbols file") NHOPTC(term_cols, 6, opt_in, set_in_config, No, Yes, No, No, "termcolumns", "number of columns") NHOPTC(term_rows, 6, opt_in, set_in_config, No, Yes, No, No, NoAlias, @@ -460,8 +460,8 @@ pfx_##a, &flags.tombstone) NHOPTB(toptenwin, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.toptenwin) - NHOPTC(traps, MAXTCHARS + 1, opt_in, set_in_config, No, Yes, No, No, NoAlias, - "the symbols to use in drawing traps") + NHOPTC(traps, MAXTCHARS + 1, opt_in, set_in_config, No, Yes, No, No, + NoAlias, "the symbols to use in drawing traps") NHOPTB(travel, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.travelcmd) #ifdef DEBUG @@ -484,8 +484,8 @@ pfx_##a, "method of video updating") #endif #ifdef VIDEOSHADES - NHOPTC(videocolors, 40, opt_in, set_gameview, No, Yes, No, No, "videocolours", - "color mappings for internal screen routines") + NHOPTC(videocolors, 40, opt_in, set_gameview, No, Yes, No, No, + "videocolours", "color mappings for internal screen routines") NHOPTC(videoshades, 32, opt_in, set_gameview, No, Yes, No, No, NoAlias, "gray shades to map to black/gray/white") #endif @@ -527,8 +527,8 @@ pfx_##a, #endif NHOPTC(windowcolors, 80, opt_in, set_gameview, No, Yes, No, No, NoAlias, "the foreground/background colors of windows") - NHOPTC(windowtype, WINTYPELEN, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "windowing system to use") + NHOPTC(windowtype, WINTYPELEN, opt_in, set_gameview, No, Yes, No, No, + NoAlias, "windowing system to use") NHOPTB(wizweight, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.wizweight) NHOPTB(wraptext, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, diff --git a/src/options.c b/src/options.c index 1b946f29d..fab931033 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1605618310 2020/11/17 13:05:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.480 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1606385980 2020/11/26 10:19:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.481 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -5788,7 +5788,8 @@ int optidx; if (using_alias) Sprintf(buf, " (via alias: %s)", allopt[optidx].alias); config_error_add("%s option specified multiple times: %s%s", - (allopt[optidx].opttyp == CompOpt) ? "compound" : "boolean", + (allopt[optidx].opttyp == CompOpt) ? "compound" + : "boolean", allopt[optidx].name, buf); #endif /* ?MAC */ return; @@ -7400,8 +7401,7 @@ static struct other_opts { int NDECL((*othr_count_func)); } othropt[] = { { "autopickup exceptions", set_in_game, OPT_OTHER_APEXC, count_apes }, - { "status condition fields", set_in_game, - OPT_OTHER_COND, count_cond }, + { "status condition fields", set_in_game, OPT_OTHER_COND, count_cond }, { "menu colors", set_in_game, OPT_OTHER_MENUCOLOR, count_menucolors }, { "message types", set_in_game, OPT_OTHER_MSGTYPE, msgtype_count }, #ifdef STATUS_HILITES @@ -8102,8 +8102,14 @@ static const char *opt_intro[] = { static const char *opt_epilog[] = { "", - "Some of the options can be set only before the game is started; those", - "items will not be selectable in the 'O' command's menu.", + "Some of the options can only be set before the game is started;", + "those items will not be selectable in the 'O' command's menu.", + "Some options are stored in a game's save file, and will keep saved", + "values when restoring that game even if you have updated your", + "config file to change them. Such changes will matter for new games.", + "The \"other settings\" can be set with 'O', but when set within the", + "configuration file they use their own directives rather than OPTIONS.", + "See NetHack's \"Guidebook\" for details.", (char *) 0 }; @@ -8135,15 +8141,44 @@ option_help() /* Compound options */ putstr(datawin, 0, "Compound options:"); for (i = 0; allopt[i].name; i++) { + if (allopt[i].opttyp != CompOpt) /* skip booleans */ + continue; Sprintf(buf2, "`%s'", allopt[i].name); Sprintf(buf, "%-20s - %s%c", buf2, allopt[i].descr, allopt[i + 1].name ? ',' : '.'); putstr(datawin, 0, buf); } + putstr(datawin, 0, ""); + + putstr(datawin, 0, "Other settings:"); + for (i = 0; othropt[i].name; ++i) { + Sprintf(buf, "`%s'", othropt[i].name); + putstr(datawin, 0, buf); + } for (i = 0; opt_epilog[i]; i++) putstr(datawin, 0, opt_epilog[i]); + /* + * TODO: + * briefly describe interface-specific option-like settings for + * the currently active interface: + * X11 uses X-specific "application defaults" from NetHack.ad; + * Qt has menu accessible "game -> Qt settings" (non-OSX) or + * "nethack -> Preferences" (OSX) to maintain a few options + * (font size, map tile size, paperdoll show/hide flag and + * tile size) which persist across games; + * Windows GUI also has some port-specific menus; + * tty and curses: anything? + * Best done via a new windowprocs function rather than plugging + * in details here. + * + * Maybe: + * switch from text window to pick-none menu so that user can + * scroll back up. (Not necessary for Qt where text windows are + * already scrollable.) + */ + display_nhwindow(datawin, FALSE); destroy_nhwindow(datawin); return; From b2199840cd9d91099615d83a36952895c9bbc2bb Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 26 Nov 2020 12:00:00 -0800 Subject: [PATCH 456/708] options help Add a few missing options to dat/opthelp (without worrying about "if FOO was set at compile time"). No doubt there are lots of others still missing. Reword a few options in dat/opthelp and also in the dynamic help derived from optlist.h, particuarly catname, dogname, horsename whose descriptions have always been confusing or maybe confused. --- dat/opthelp | 37 +++++++++++++++++++++++++------------ include/optlist.h | 46 +++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index 1bcf57474..9ca82f9be 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -135,6 +135,8 @@ disclose the types of information you want [ni na nv ng nc no] 'o' dungeon overview) fruit the name of a fruit you enjoy eating [slime mold] (basically a whimsy which NetHack uses from time to time). +hilite_status specifies a rule for highlighting a status field [] + (multiple instances are allowed) menustyle user interface for selection of multiple objects: [Full] Traditional -- prompt for classes of interest, then prompt item-by-item for those classes; @@ -145,13 +147,24 @@ menustyle user interface for selection of multiple objects: [Full] only the first letter ('T','C','F','P') matters (With Traditional, many actions allow pseudo-class 'm' to request a menu for choosing items: one-shot Combination.) +msg_window behavior of ^P message recall for tty interface: [s] + single -- one message at a time + full -- full window with all saved top line messages + reverse -- full with messages printed most-recent-first + combination -- first two of consecutive ^P commands show + single messages, third yields full set +msg_window behavior of ^P message recall for curses interface: [r] + reverse -- full window, most recent first + full -- full with messages printed least recent first, + initially positioned on last page to start + with most recent messages in view number_pad alphabetic versus numeric control over movement: [0] 0 -- traditional hjkl + yubn movement (default); 1 -- digits control movement, for use with numeric keypad; 2 -- same as 1, but '5' works as 'g' prefix rather than 'G'; 3 -- numeric for phone keypad (1,2,3 above, 7,8,9 below); 4 -- phone keypad (3) combined with '5' preference (2); - -1 -- alphabetic movement but 'z' swapped with 'y'. + -1 -- "qwertz"; alphabetic movement but 'z' swapped with 'y'. Setting number_pad (to a positive value) affects how all digit keys are handled, not just those on numeric keypad. packorder a list of default symbols for kinds of [")[%?+!=/(*`0_] @@ -192,6 +205,11 @@ scores the parts of the score list you wish [!own/3 top/2 around] to see when the game ends. You choose a combination of top scores, scores around the top scores, and all of your own scores. +statushilites whether to display status highlights (when non-zero) and [0] + also how many turns to display temporary highlights (for + 'up', 'down', and 'changed' hilite_status rules) +statuslines whether to use expanded (3) or condensed (2) status [2] + (for tty and curses; 2 is traditional, 3 is recommended) suppress_alert disable various version-specific warnings about changes [] in game play or the user interface, such as notification given for the 'Q' command that quitting is now done via #quit @@ -217,8 +235,8 @@ Compound options which may be set only on startup are: align Your starting alignment (lawful, neutral, chaotic, [random] or random). Many roles restrict the choice to a subset. You may specify just the first letter. -catname the name of your first cat [none] -dogname the name of your first dog [none] +catname name of your starting pet when it is a kitten [none] +dogname name of your starting pet when it is a little dog [none] Several roles who start with a dog have one whose name is pre-set (for example, "Hachi" for Samurai), but that name will be overridden if you specify dogname. @@ -226,7 +244,7 @@ gender Your starting gender (male, female, or random). [random] You may specify just the first letter. Although you can still denote your gender using the old "male" and "female" boolean options, the "gender" option will take precedence. -horsename the name of your first horse [none] +horsename name of your starting pet when it is a pony [none] menu_* specify single character accelerators for menu commands. Here is a list of all commands with their default keystroke followed by a list of window-ports that implement them: @@ -266,6 +284,9 @@ role Your starting role (e.g., role:Barbarian, role:Valk). [random] as possible. You can also still denote your role by appending it to the "name" option (e.g., name:Vic-V), but the "role" option will take precedence. +statuslines whether to use expanded (3) or condensed (2) status [2] + (unlike for tty and curses, for Qt this can only be be set at + startup; also unlike tty and curses, 2 is recommended over 3) windowtype windowing system to be used [depends on operating system and compile-time setup] if more than one choice is available. Most instances of the program support only one window-type; @@ -275,14 +296,6 @@ windowtype windowing system to be used [depends on operating system and command or from outside the program by examining the text file named 'options' which is generated when building it. -Compound option if TTY_GRAPHICS was set at compile time: -msg_window the type of message window to use: [single] - single -- One message at a time - full -- Full window with all saved top line messages - reverse -- Same as full, but messages printed most-recent-first - combination -- Two single messages, then as full - - Some sample options lists are: !autopickup,!tombstone,name:Gandalf,scores:own/3 top/2 around female,nonews,dogname:Rover,rest_on_space,!verbose,menustyle:traditional diff --git a/include/optlist.h b/include/optlist.h index 06fb03f6a..0e290c143 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -120,7 +120,7 @@ pfx_##a, "deprecated (use S_boulder in sym file instead)") #endif NHOPTC(catname, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "the name of your (first) cat (e.g., catname:Tabby)") + "name of your starting pet when it is a kitten") #ifdef INSURANCE NHOPTB(checkpoint, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.ins_chkpt) @@ -150,11 +150,11 @@ pfx_##a, opt_in, set_in_game, Yes, Yes, No, Yes, NoAlias, "the kinds of information to disclose at end of game") NHOPTC(dogname, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "the name of your (first) dog (e.g., dogname:Fang)") + "name of your starting pet when it is a little dog") NHOPTC(dungeon, MAXDCHARS + 1,opt_in, set_in_config, No, Yes, No, No, - NoAlias, "the symbols to use in drawing the dungeon map") + NoAlias, "list of symbols to use in drawing the dungeon map") NHOPTC(effects, MAXECHARS + 1, opt_in, set_in_config, No, Yes, No, No, - NoAlias, "the symbols to use in drawing special effects") + NoAlias, "list of symbols to use in drawing special effects") NHOPTB(eight_bit_tty, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc_eight_bit_input) NHOPTB(extmenu, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, @@ -164,29 +164,29 @@ pfx_##a, NHOPTB(fixinv, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.invlet_constant) NHOPTC(font_map, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the font to use in the map window") + "font to use in the map window") NHOPTC(font_menu, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the font to use in menus") + "font to use in menus") NHOPTC(font_message, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the font to use in the message window") + "font to use in the message window") NHOPTC(font_size_map, 20, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the size of the map font") + "size of the map font") NHOPTC(font_size_menu, 20, opt_in, set_gameview, Yes, Yes, Yes, No, - NoAlias, "the size of the menu font") + NoAlias, "size of the menu font") NHOPTC(font_size_message, 20, opt_in, set_gameview, Yes, Yes, Yes, No, - NoAlias, "the size of the message font") + NoAlias, "size of the message font") NHOPTC(font_size_status, 20, opt_in, set_gameview, Yes, Yes, Yes, No, - NoAlias, "the size of the status font") + NoAlias, "size of the status font") NHOPTC(font_size_text, 20, opt_in, set_gameview, Yes, Yes, Yes, No, - NoAlias, "the size of the text font") + NoAlias, "size of the text font") NHOPTC(font_status, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the font to use in status window") + "font to use in status window") NHOPTC(font_text, 40, opt_in, set_gameview, Yes, Yes, Yes, No, NoAlias, - "the font to use in text windows") + "font to use in text windows") NHOPTB(force_invmenu, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.force_invmenu) NHOPTC(fruit, PL_FSIZ, opt_in, set_in_game, No, Yes, No, No, NoAlias, - "the name of a fruit you enjoy eating") + "name of a fruit you enjoy eating") NHOPTB(fullscreen, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias, &iflags.wc2_fullscreen) NHOPTC(gender, 8, opt_in, set_gameview, No, Yes, No, No, NoAlias, @@ -209,12 +209,12 @@ pfx_##a, &iflags.hilite_pile) #ifdef STATUS_HILITES NHOPTC(hilite_status, 13, opt_out, set_in_game, Yes, Yes, Yes, No, NoAlias, - "hilite_status") + "a status highlighting rule (can occur multiple times)") #endif NHOPTB(hitpointbar, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc2_hitpointbar) NHOPTC(horsename, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "name of your (first) horse (e.g., horsename:Silver)") + "name of your starting pet when it is a pony") #ifdef BACKWARD_COMPAT NHOPTC(IBMgraphics, 70, opt_in, set_in_config, Yes, Yes, No, No, NoAlias, "load IBMGraphics display symbols") @@ -292,7 +292,7 @@ pfx_##a, NHOPTB(monpolycontrol, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.mon_polycontrol) NHOPTC(monsters, MAXMCLASSES, opt_in, set_in_config, No, Yes, No, No, - NoAlias, "the symbols to use for monsters") + NoAlias, "list of symbols to use for monsters") NHOPTC(mouse_support, 0, opt_in, set_in_game, No, Yes, No, No, NoAlias, "game receives click info from mouse") #if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) @@ -320,7 +320,7 @@ pfx_##a, NHOPTC(number_pad, 1, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, "use the number pad for movement") NHOPTC(objects, MAXOCLASSES, opt_in, set_in_config, No, Yes, No, No, - NoAlias, "the symbols to use for objects") + NoAlias, "list of symbols to use for objects") NHOPTC(packorder, MAXOCLASSES, opt_in, set_in_game, No, Yes, No, No, NoAlias, "the inventory order of the items in your pack") #ifdef CHANGE_COLOR @@ -422,8 +422,8 @@ pfx_##a, NHOPTC(statushilites, 20, opt_in, set_in_game, Yes, Yes, Yes, No, NoAlias, "0=no status highlighting, N=show highlights for N turns") #else - NHOPTC(statushilites, 20, opt_in, set_in_config, Yes, Yes, Yes, No, NoAlias, - "highlight control") + NHOPTC(statushilites, 20, opt_in, set_in_config, Yes, Yes, Yes, No, + NoAlias, "highlight control") #endif NHOPTC(statuslines, 20, opt_in, set_in_game, No, Yes, No, No, NoAlias, "2 or 3 lines for status display") @@ -461,7 +461,7 @@ pfx_##a, NHOPTB(toptenwin, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.toptenwin) NHOPTC(traps, MAXTCHARS + 1, opt_in, set_in_config, No, Yes, No, No, - NoAlias, "the symbols to use in drawing traps") + NoAlias, "list of symbols to use in drawing traps") NHOPTB(travel, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.travelcmd) #ifdef DEBUG @@ -528,7 +528,7 @@ pfx_##a, NHOPTC(windowcolors, 80, opt_in, set_gameview, No, Yes, No, No, NoAlias, "the foreground/background colors of windows") NHOPTC(windowtype, WINTYPELEN, opt_in, set_gameview, No, Yes, No, No, - NoAlias, "windowing system to use") + NoAlias, "windowing system to use (should be specified first)") NHOPTB(wizweight, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.wizweight) NHOPTB(wraptext, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, From 7c91c76265a3ce29396715fe098946e351f7eb09 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 26 Nov 2020 15:48:56 -0500 Subject: [PATCH 457/708] remove a comma at the end of an enumerator list --- include/you.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/you.h b/include/you.h index 738fb61e9..c8d4c4fe6 100644 --- a/include/you.h +++ b/include/you.h @@ -340,7 +340,7 @@ enum utotypes { UTOTYPE_FALLING = 0x02, UTOTYPE_PORTAL = 0x04, UTOTYPE_RMPORTAL = 0x10, /* remove portal */ - UTOTYPE_DEFERRED = 0x20, /* deferred_goto */ + UTOTYPE_DEFERRED = 0x20 /* deferred_goto */ }; /*** Information about the player ***/ From 8d91a9f764ea6d3f43914a409caf280aaeb59f91 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 26 Nov 2020 18:47:45 -0800 Subject: [PATCH 458/708] more options help "Name of your starting pet when it is a kitten" could be construed as meaning that it will no longer apply once the kitten grows into a housecat. Use "if" instead of "when". The 'other settings' were in alphabetical order except for "status condition fields" which presumably started out as "condition fields". Move it into proper place for current description. --- dat/opthelp | 6 +++--- include/optlist.h | 6 +++--- src/options.c | 17 ++++++++--------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index 9ca82f9be..f3debdc5d 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -235,8 +235,8 @@ Compound options which may be set only on startup are: align Your starting alignment (lawful, neutral, chaotic, [random] or random). Many roles restrict the choice to a subset. You may specify just the first letter. -catname name of your starting pet when it is a kitten [none] -dogname name of your starting pet when it is a little dog [none] +catname name of your starting pet if it is a kitten [none] +dogname name of your starting pet if it is a little dog [none] Several roles who start with a dog have one whose name is pre-set (for example, "Hachi" for Samurai), but that name will be overridden if you specify dogname. @@ -244,7 +244,7 @@ gender Your starting gender (male, female, or random). [random] You may specify just the first letter. Although you can still denote your gender using the old "male" and "female" boolean options, the "gender" option will take precedence. -horsename name of your starting pet when it is a pony [none] +horsename name of your starting pet if it is a pony [none] menu_* specify single character accelerators for menu commands. Here is a list of all commands with their default keystroke followed by a list of window-ports that implement them: diff --git a/include/optlist.h b/include/optlist.h index 0e290c143..7ae20db6e 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -120,7 +120,7 @@ pfx_##a, "deprecated (use S_boulder in sym file instead)") #endif NHOPTC(catname, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "name of your starting pet when it is a kitten") + "name of your starting pet if it is a kitten") #ifdef INSURANCE NHOPTB(checkpoint, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.ins_chkpt) @@ -150,7 +150,7 @@ pfx_##a, opt_in, set_in_game, Yes, Yes, No, Yes, NoAlias, "the kinds of information to disclose at end of game") NHOPTC(dogname, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "name of your starting pet when it is a little dog") + "name of your starting pet if it is a little dog") NHOPTC(dungeon, MAXDCHARS + 1,opt_in, set_in_config, No, Yes, No, No, NoAlias, "list of symbols to use in drawing the dungeon map") NHOPTC(effects, MAXECHARS + 1, opt_in, set_in_config, No, Yes, No, No, @@ -214,7 +214,7 @@ pfx_##a, NHOPTB(hitpointbar, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, &iflags.wc2_hitpointbar) NHOPTC(horsename, PL_PSIZ, opt_in, set_gameview, No, Yes, No, No, NoAlias, - "name of your starting pet when it is a pony") + "name of your starting pet if it is a pony") #ifdef BACKWARD_COMPAT NHOPTC(IBMgraphics, 70, opt_in, set_in_config, Yes, Yes, No, No, NoAlias, "load IBMGraphics display symbols") diff --git a/src/options.c b/src/options.c index fab931033..c38d06aa3 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1606385980 2020/11/26 10:19:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.481 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1606445249 2020/11/27 02:47:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.482 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -246,13 +246,12 @@ static boolean FDECL(add_menu_coloring_parsed, (const char *, int, int)); static void FDECL(free_one_menu_coloring, (int)); static int NDECL(count_menucolors); static boolean FDECL(parse_role_opts, (int, BOOLEAN_P, const char *, - char *, char **)); + char *, char **)); static void FDECL(doset_add_menu, (winid, const char *, int, int)); -static void FDECL(opts_add_others, (winid, const char *, int, - char *, int)); +static void FDECL(opts_add_others, (winid, const char *, int, char *, int)); static int FDECL(handle_add_list_remove, (const char *, int)); static void FDECL(remove_autopickup_exception, - (struct autopickup_exception *)); + (struct autopickup_exception *)); static int NDECL(count_apes); static int NDECL(count_cond); @@ -7401,9 +7400,9 @@ static struct other_opts { int NDECL((*othr_count_func)); } othropt[] = { { "autopickup exceptions", set_in_game, OPT_OTHER_APEXC, count_apes }, - { "status condition fields", set_in_game, OPT_OTHER_COND, count_cond }, { "menu colors", set_in_game, OPT_OTHER_MENUCOLOR, count_menucolors }, { "message types", set_in_game, OPT_OTHER_MSGTYPE, msgtype_count }, + { "status condition fields", set_in_game, OPT_OTHER_COND, count_cond }, #ifdef STATUS_HILITES { "status hilite rules", set_in_game, OPT_OTHER_STATHILITE, count_status_hilites }, @@ -8105,8 +8104,8 @@ static const char *opt_epilog[] = { "Some of the options can only be set before the game is started;", "those items will not be selectable in the 'O' command's menu.", "Some options are stored in a game's save file, and will keep saved", - "values when restoring that game even if you have updated your", - "config file to change them. Such changes will matter for new games.", + "values when restoring that game even if you have updated your config-", + "uration file to change them. Such changes will matter for new games.", "The \"other settings\" can be set with 'O', but when set within the", "configuration file they use their own directives rather than OPTIONS.", "See NetHack's \"Guidebook\" for details.", @@ -8152,7 +8151,7 @@ option_help() putstr(datawin, 0, "Other settings:"); for (i = 0; othropt[i].name; ++i) { - Sprintf(buf, "`%s'", othropt[i].name); + Sprintf(buf, " %s", othropt[i].name); putstr(datawin, 0, buf); } From bb9df368af0236299560b34d7ecaff36a805ca9c Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 27 Nov 2020 02:38:17 -0800 Subject: [PATCH 459/708] fix github issue #401 - roast/rust/rot in peace This tries to fix the problem of the extra message when a tame golem is completely destroyed (paper or straw golem burned, iron golem rusted, wood or leather golem rotted) being issued at odd times. I basically punted on the visibility aspect since the original logic was strange: you had to be able to see both the attacker's and defender's spots and at least one of those two monsters. Now mon-attacks-mon visibility requires that you be able to see one of the two and if you don't see both, the unseen one will be referred to as "it". The "may the iron golem rust in peace" message is independent of that and may be displayed after "you have a sad feeling", but now that's intentional and will refer to an unseen pet by name or monster type, not "it". This needs a lot of testing and hasn't attempted to address issue #402: only some attacks that should compeletely destroy a golem actually do so. (So a hit by fire elemental against a paper golem does, but passive fire counterattack when a paper golem hits a fire elemental doesn't, nor does a wand of fire or being hit by Firebrand.) Fixes #401 --- doc/fixes37.0 | 3 ++- include/mondata.h | 7 +++++-- src/mhitm.c | 24 +++++++++--------------- src/mhitu.c | 6 +++--- src/mon.c | 35 +++++++++++++++++++++++++++-------- src/mondata.c | 28 ++++++++++++++++------------ src/uhitm.c | 6 +++--- 7 files changed, 65 insertions(+), 44 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 68e2814a9..f8f4b42c5 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.364 $ $NHDT-Date: 1606385979 2020/11/26 10:19:39 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.365 $ $NHDT-Date: 1606473484 2020/11/27 10:38:04 $ General Fixes and Modified Features ----------------------------------- @@ -311,6 +311,7 @@ wizard mode (only way to get timed flying): if levitation and flying time out throwing or kicking a shop container (that's light enough to move) made the hero pay for any gold inside, then didn't refund that amount if the container landed inside the shop +try to fix message sequencing for tame golems that "roast/rot/rust in peace" Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/mondata.h b/include/mondata.h index db9d83d92..1ab07c6e3 100644 --- a/include/mondata.h +++ b/include/mondata.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.h $NHDT-Date: 1596498548 2020/08/03 23:49:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.44 $ */ +/* NetHack 3.7 mondata.h $NHDT-Date: 1606473485 2020/11/27 10:38:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.45 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -224,9 +224,12 @@ #define nonliving(ptr) \ (is_undead(ptr) || (ptr) == &mons[PM_MANES] || weirdnonliving(ptr)) -/* no corpse (ie, blank scrolls) if killed by fire */ +/* no corpse (ie, blank scrolls) if killed by fire; special case instakill */ #define completelyburns(ptr) \ ((ptr) == &mons[PM_PAPER_GOLEM] || (ptr) == &mons[PM_STRAW_GOLEM]) +#define completelyrots(ptr) \ + ((ptr) == &mons[PM_WOOD_GOLEM] || (ptr) == &mons[PM_LEATHER_GOLEM]) +#define completelyrusts(ptr) ((ptr) == &mons[PM_IRON_GOLEM]) /* Used for conduct with corpses, tins, and digestion attacks */ /* G_NOCORPSE monsters might still be swallowed as a purple worm */ diff --git a/src/mhitm.c b/src/mhitm.c index fba87b7e4..bbeafbaf5 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitm.c $NHDT-Date: 1596498178 2020/08/03 23:42:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.140 $ */ +/* NetHack 3.7 mhitm.c $NHDT-Date: 1606473486 2020/11/27 10:38:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.144 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -335,8 +335,8 @@ register struct monst *magr, *mdef; tmp++; /* Set up the visibility of action */ - g.vis = (cansee(magr->mx, magr->my) && cansee(mdef->mx, mdef->my) - && (canspotmon(magr) || canspotmon(mdef))); + g.vis = ((cansee(magr->mx, magr->my) && canspotmon(magr)) + || (cansee(mdef->mx, mdef->my) && canspotmon(mdef))); /* Set flag indicating monster has moved this turn. Necessary since a * monster might get an attack out of sequence (i.e. before its move) in @@ -369,7 +369,7 @@ register struct monst *magr, *mdef; /* D: Do a ranged attack here! */ strike = thrwmm(magr, mdef); if (strike) - /* We don't really know if we hit or not; pretend we did. */ + /* don't really know if we hit or not; pretend we did */ res[i] |= MM_HIT; if (DEADMONSTER(mdef)) res[i] = MM_DEF_DIED; @@ -1024,11 +1024,9 @@ int dieroll; if (completelyburns(pd)) { /* paper golem or straw golem */ if (g.vis && canseemon(mdef)) pline("%s burns completely!", Monnam(mdef)); - mondead(mdef); /* was mondied() but that dropped paper scrolls */ + monkilled(mdef, (char *) 0, AD_FIRE); if (!DEADMONSTER(mdef)) return 0; - else if (mdef->mtame && !g.vis) - pline("May %s roast in peace.", mon_nam(mdef)); return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); @@ -1100,14 +1098,12 @@ int dieroll; case AD_RUST: if (magr->mcan) break; - if (pd == &mons[PM_IRON_GOLEM]) { + if (completelyrusts(pd)) { /* PM_IRON_GOLEM */ if (g.vis && canseemon(mdef)) pline("%s falls to pieces!", Monnam(mdef)); - mondied(mdef); + monkilled(mdef, (char *) 0, AD_RUST); if (!DEADMONSTER(mdef)) return 0; - else if (mdef->mtame && !g.vis) - pline("May %s rust in peace.", mon_nam(mdef)); return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } erode_armor(mdef, ERODE_RUST); @@ -1124,14 +1120,12 @@ int dieroll; case AD_DCAY: if (magr->mcan) break; - if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) { + if (completelyrots(pd)) { /* PM_WOOD_GOLEM || PM_LEATHER_GOLEM */ if (g.vis && canseemon(mdef)) pline("%s falls to pieces!", Monnam(mdef)); - mondied(mdef); + monkilled(mdef, (char *) 0, AD_DCAY); if (!DEADMONSTER(mdef)) return 0; - else if (mdef->mtame && !g.vis) - pline("May %s rot in peace.", mon_nam(mdef)); return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } erode_armor(mdef, ERODE_CORRODE); diff --git a/src/mhitu.c b/src/mhitu.c index f28f0c6b7..b9df18ce7 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitu.c $NHDT-Date: 1596498179 2020/08/03 23:42:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.194 $ */ +/* NetHack 3.7 mhitu.c $NHDT-Date: 1606473488 2020/11/27 10:38:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.196 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1490,7 +1490,7 @@ register struct attack *mattk; hitmsg(mtmp, mattk); if (mtmp->mcan) break; - if (u.umonnum == PM_IRON_GOLEM) { + if (completelyrusts(g.youmonst.data)) { You("rust!"); /* KMH -- this is okay with unchanging */ rehumanize(); @@ -1508,7 +1508,7 @@ register struct attack *mattk; hitmsg(mtmp, mattk); if (mtmp->mcan) break; - if (u.umonnum == PM_WOOD_GOLEM || u.umonnum == PM_LEATHER_GOLEM) { + if (completelyrots(g.youmonst.data)) { You("rot!"); /* KMH -- this is okay with unchanging */ rehumanize(); diff --git a/src/mon.c b/src/mon.c index 6a534d084..725daf8cc 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1604880454 2020/11/09 00:07:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.351 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1606473489 2020/11/27 10:38:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.354 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2582,20 +2582,39 @@ struct monst *mdef; const char *fltxt; int how; { - if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my)) - && fltxt) + struct permonst *mptr = mdef->data; + + if (fltxt && (mdef->wormno ? worm_known(mdef) + : cansee(mdef->mx, mdef->my))) pline("%s is %s%s%s!", Monnam(mdef), - nonliving(mdef->data) ? "destroyed" : "killed", + nonliving(mptr) ? "destroyed" : "killed", *fltxt ? " by the " : "", fltxt); else + /* sad feeling is deferred until after potential life-saving */ iflags.sad_feeling = (mdef->mtame != 0); - /* no corpses if digested or disintegrated */ - g.disintegested = (how == AD_DGST || how == -AD_RBRE); + /* no corpse if digested or disintegrated or flammable golem burnt up; + no corpse for a paper golem means no scrolls; golems that rust or + rot completely are described as "falling to pieces" so they do + leave a corpse (which means staves for wood golem, leather armor for + leather golem, iron chains for iron golem, not a regular corpse) */ + g.disintegested = (how == AD_DGST || how == -AD_RBRE + || (how == AD_FIRE && completelyburns(mptr))); if (g.disintegested) - mondead(mdef); + mondead(mdef); /* never leaves a corpse */ else - mondied(mdef); + mondied(mdef); /* calls mondead() and maybe leaves a corpse */ + + /* extra message if pet golem is completely destroyed; + if not visible, this will follow "you have a sad feeling" */ + if (mdef->mtame) { + const char *rxt = (how == AD_FIRE && completelyburns(mptr)) ? "roast" + : (how == AD_RUST && completelyrusts(mptr)) ? "rust" + : (how == AD_DCAY && completelyrots(mptr)) ? "rot" + : 0; + if (rxt) + pline("May %s %s in peace.", noit_mon_nam(mdef), rxt); + } } void diff --git a/src/mondata.c b/src/mondata.c index 5ccc48bb3..e15fef59a 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mondata.c $NHDT-Date: 1603507386 2020/10/24 02:43:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.86 $ */ +/* NetHack 3.7 mondata.c $NHDT-Date: 1606473489 2020/11/27 10:38:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -509,7 +509,7 @@ int max_passive_dmg(mdef, magr) register struct monst *mdef, *magr; { - int i, dmg = 0, multi2 = 0; + int i, dmg, multi2 = 0; uchar adtyp; /* each attack by magr can result in passive damage */ @@ -531,25 +531,29 @@ register struct monst *mdef, *magr; break; } + dmg = 0; for (i = 0; i < NATTK; i++) if (mdef->data->mattk[i].aatyp == AT_NONE || mdef->data->mattk[i].aatyp == AT_BOOM) { adtyp = mdef->data->mattk[i].adtyp; - if ((adtyp == AD_ACID && !resists_acid(magr)) - || (adtyp == AD_COLD && !resists_cold(magr)) - || (adtyp == AD_FIRE && !resists_fire(magr)) - || (adtyp == AD_ELEC && !resists_elec(magr)) - || adtyp == AD_PHYS) { + if ((adtyp == AD_FIRE && completelyburns(magr->data)) + || (adtyp == AD_DCAY && completelyrots(magr->data)) + || (adtyp == AD_RUST && completelyrusts(magr->data))) { + dmg = magr->mhp; + } else if ((adtyp == AD_ACID && !resists_acid(magr)) + || (adtyp == AD_COLD && !resists_cold(magr)) + || (adtyp == AD_FIRE && !resists_fire(magr)) + || (adtyp == AD_ELEC && !resists_elec(magr)) + || adtyp == AD_PHYS) { dmg = mdef->data->mattk[i].damn; if (!dmg) dmg = mdef->data->mlevel + 1; dmg *= mdef->data->mattk[i].damd; - } else - dmg = 0; - - return dmg * multi2; + } + dmg *= multi2; + break; } - return 0; + return dmg; } /* determine whether two monster types are from the same species */ diff --git a/src/uhitm.c b/src/uhitm.c index 7ad48d82e..f099665b1 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1604880456 2020/11/09 00:07:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.242 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1606473490 2020/11/27 10:38:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.243 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1935,7 +1935,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } break; case AD_RUST: - if (pd == &mons[PM_IRON_GOLEM]) { + if (completelyrusts(pd)) { /* iron golem */ pline("%s falls to pieces!", Monnam(mdef)); xkilled(mdef, XKILL_NOMSG); } @@ -1947,7 +1947,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ tmp = 0; break; case AD_DCAY: - if (pd == &mons[PM_WOOD_GOLEM] || pd == &mons[PM_LEATHER_GOLEM]) { + if (completelyrots(pd)) { /* wood golem or leather golem */ pline("%s falls to pieces!", Monnam(mdef)); xkilled(mdef, XKILL_NOMSG); } From 2a7cb3c4b615b06b68fca85c78359e1a95288814 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 27 Nov 2020 18:10:47 +0200 Subject: [PATCH 460/708] Split some parts of getobj into functions --- src/invent.c | 300 ++++++++++++++++++++++++++++----------------------- 1 file changed, 164 insertions(+), 136 deletions(-) diff --git a/src/invent.c b/src/invent.c index 16d6ff01f..67f1bfa43 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1464,6 +1464,157 @@ const char *action; return !strcmp(action, "wear") || !strcmp(action, "put on"); } +/* helper for getobj(), exclude obj if it cannot be used to do word */ +static boolean +getobj_obj_exclude(word, otmp) +const char *word; +struct obj *otmp; +{ + return ((taking_off(word) /* exclude if not worn */ + && !(otmp->owornmask & (W_ARMOR | W_ACCESSORY))) + || (putting_on(word) /* exclude if already worn */ + && (otmp->owornmask & (W_ARMOR | W_ACCESSORY))) +#if 0 /* 3.4.1 -- include currently wielded weapon among 'wield' choices */ + || (!strcmp(word, "wield") + && (otmp->owornmask & W_WEP)) +#endif + || (!strcmp(word, "ready") /* exclude when wielded... */ + && ((otmp == uwep || (otmp == uswapwep && u.twoweap)) + && otmp->quan == 1L)) /* ...unless more than one */ + || ((!strcmp(word, "dip") || !strcmp(word, "grease")) + && inaccessible_equipment(otmp, (const char *) 0, FALSE))); +} + +/* helper for getobj(), exclude obj if it cannot be used to do word */ +static boolean +getobj_obj_exclude_too(word, otmp) +const char *word; +struct obj *otmp; +{ + short otyp = otmp->otyp; + + return ((putting_on(word) + && ((otmp->oclass == FOOD_CLASS && otyp != MEAT_RING) + || (otmp->oclass == TOOL_CLASS && otyp != BLINDFOLD + && otyp != TOWEL && otyp != LENSES))) + || (!strcmp(word, "wield") + && (otmp->oclass == TOOL_CLASS && !is_weptool(otmp))) + || (!strcmp(word, "eat") && !is_edible(otmp)) + || (!strcmp(word, "sacrifice") + && (otyp != CORPSE && otyp != AMULET_OF_YENDOR + && otyp != FAKE_AMULET_OF_YENDOR)) + || (!strcmp(word, "write with") + && (otmp->oclass == TOOL_CLASS + && otyp != MAGIC_MARKER && otyp != TOWEL)) + || (!strcmp(word, "tin") + && (otyp != CORPSE || !tinnable(otmp))) + || (!strcmp(word, "rub") + && ((otmp->oclass == TOOL_CLASS && otyp != OIL_LAMP + && otyp != MAGIC_LAMP && otyp != BRASS_LANTERN) + || (otmp->oclass == GEM_CLASS && !is_graystone(otmp)) + || (otmp->oclass == FOOD_CLASS + && otmp->otyp != LUMP_OF_ROYAL_JELLY))) + || (!strcmp(word, "use or apply") + /* Picks, axes, pole-weapons, bullwhips */ + && ((otmp->oclass == WEAPON_CLASS + && !is_pick(otmp) && !is_axe(otmp) + && !is_pole(otmp) && otyp != BULLWHIP) + || (otmp->oclass == POTION_CLASS + /* only applicable potion is oil, and it will only + be offered as a choice when already discovered */ + && (otyp != POT_OIL || !otmp->dknown + || !objects[POT_OIL].oc_name_known)) + || (otmp->oclass == FOOD_CLASS + && otyp != CREAM_PIE && otyp != EUCALYPTUS_LEAF + && otyp != LUMP_OF_ROYAL_JELLY) + || (otmp->oclass == GEM_CLASS && !is_graystone(otmp)))) + || (!strcmp(word, "rub the royal jelly on") && otmp->otyp != EGG) + || (!strcmp(word, "invoke") + && !otmp->oartifact + && !objects[otyp].oc_unique + && (otyp != FAKE_AMULET_OF_YENDOR || otmp->known) + && otyp != CRYSTAL_BALL /* synonym for apply */ + /* note: presenting the possibility of invoking non-artifact + mirrors and/or lamps is simply a cruel deception... */ + && otyp != MIRROR + && otyp != MAGIC_LAMP + && (otyp != OIL_LAMP /* don't list known oil lamp */ + || (otmp->dknown && objects[OIL_LAMP].oc_name_known))) + || (!strcmp(word, "untrap with") + && ((otmp->oclass == TOOL_CLASS && otyp != CAN_OF_GREASE) + || (otmp->oclass == POTION_CLASS + /* only applicable potion is oil, and it will only + be offered as a choice when already discovered */ + && (otyp != POT_OIL || !otmp->dknown + || !objects[POT_OIL].oc_name_known)))) + || (!strcmp(word, "tip") && !Is_container(otmp) + /* include horn of plenty if sufficiently discovered */ + && (otmp->otyp != HORN_OF_PLENTY || !otmp->dknown + || !objects[HORN_OF_PLENTY].oc_name_known)) + || (!strcmp(word, "charge") && !is_chargeable(otmp)) + || (!strcmp(word, "open") && otyp != TIN) + || (!strcmp(word, "call") && !objtyp_is_callable(otyp))); +} + +/* helper for getobj(), obj is acceptable but not listed */ +static boolean +getobj_obj_acceptable_unlisted(word, otmp, let) +const char *word; +struct obj *otmp; +char let; +{ + long dummymask; + short otyp = otmp->otyp; + + return (/* ugly check for unworn armor that can't be worn */ + (putting_on(word) && let == ARMOR_CLASS + && !canwearobj(otmp, &dummymask, FALSE)) + /* or armor with 'P' or 'R' or accessory with 'W' or 'T' */ + || ((putting_on(word) || taking_off(word)) + && ((let == ARMOR_CLASS) ^ (otmp->oclass == ARMOR_CLASS))) + /* or unsuitable items rubbed on known touchstone */ + || (!strncmp(word, "rub on the stone", 16) + && let == GEM_CLASS && otmp->dknown + && objects[otyp].oc_name_known) + /* suppress corpses on astral, amulets elsewhere */ + || (!strcmp(word, "sacrifice") + /* (!astral && amulet) || (astral && !amulet) */ + && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS))) + /* suppress container being stashed into */ + || (!strcmp(word, "stash") && !ck_bag(otmp)) + /* worn armor (shirt, suit) covered by worn armor (suit, cloak) + or accessory (ring) covered by cursed worn armor (gloves) */ + || (taking_off(word) + && inaccessible_equipment(otmp, (const char *) 0, + (boolean) (otmp->oclass == RING_CLASS))) + || (!strcmp(word, "write on") + && (!(otyp == SCR_BLANK_PAPER || otyp == SPE_BLANK_PAPER) + || !otmp->dknown || !objects[otyp].oc_name_known))); +} + +void +mime_action(word) +const char *word; +{ + char buf[BUFSZ]; + char *bp = buf; + char *suf = (char *) 0; + + strcpy(buf, word); + if ((bp = strstr(buf, " on the ")) != 0) { + /* rub on the stone[s] */ + *bp = '\0'; + suf = (bp + 1); + } + if ((bp = strstr(buf, " or ")) != 0) { + *bp = '\0'; + bp = (rn2(2) ? buf : (bp + 4)); + } else + bp = buf; + You("mime %s something%s%s.", ing_suffix(bp), suf ? " " : "", + suf ? suf : ""); +} + /* * getobj returns: * struct obj *xxx: object to do something with. @@ -1492,7 +1643,6 @@ register const char *let, *word; boolean cntgiven = FALSE; boolean msggiven = FALSE; boolean oneloop = FALSE; - long dummymask; Loot *sortedinvent, *srtinv; if (*let == ALLOW_COUNT) @@ -1550,134 +1700,27 @@ register const char *let, *word; register int otyp = otmp->otyp; bp[foo++] = otmp->invlet; -/* clang-format off */ -/* *INDENT-OFF* */ - /* ugly check: remove inappropriate things */ - if ( - (taking_off(word) /* exclude if not worn */ - && !(otmp->owornmask & (W_ARMOR | W_ACCESSORY))) - || (putting_on(word) /* exclude if already worn */ - && (otmp->owornmask & (W_ARMOR | W_ACCESSORY))) -#if 0 /* 3.4.1 -- include currently wielded weapon among 'wield' choices */ - || (!strcmp(word, "wield") - && (otmp->owornmask & W_WEP)) -#endif - || (!strcmp(word, "ready") /* exclude when wielded... */ - && ((otmp == uwep || (otmp == uswapwep && u.twoweap)) - && otmp->quan == 1L)) /* ...unless more than one */ - || ((!strcmp(word, "dip") || !strcmp(word, "grease")) - && inaccessible_equipment(otmp, (const char *) 0, FALSE)) - ) { + /* remove inappropriate things */ + if (getobj_obj_exclude(word, otmp)) { foo--; foox++; } - /* Second ugly check; unlike the first it won't trigger an - * "else" in "you don't have anything else to ___". + /* remove inappropriate thing, but unlike the first it won't + * trigger an "else" in "you don't have anything else to ___". */ - else if ( - (putting_on(word) - && ((otmp->oclass == FOOD_CLASS && otmp->otyp != MEAT_RING) - || (otmp->oclass == TOOL_CLASS && otyp != BLINDFOLD - && otyp != TOWEL && otyp != LENSES))) - || (!strcmp(word, "wield") - && (otmp->oclass == TOOL_CLASS && !is_weptool(otmp))) - || (!strcmp(word, "eat") && !is_edible(otmp)) - || (!strcmp(word, "sacrifice") - && (otyp != CORPSE && otyp != AMULET_OF_YENDOR - && otyp != FAKE_AMULET_OF_YENDOR)) - || (!strcmp(word, "write with") - && (otmp->oclass == TOOL_CLASS - && otyp != MAGIC_MARKER && otyp != TOWEL)) - || (!strcmp(word, "tin") - && (otyp != CORPSE || !tinnable(otmp))) - || (!strcmp(word, "rub") - && ((otmp->oclass == TOOL_CLASS && otyp != OIL_LAMP - && otyp != MAGIC_LAMP && otyp != BRASS_LANTERN) - || (otmp->oclass == GEM_CLASS && !is_graystone(otmp)) - || (otmp->oclass == FOOD_CLASS - && otmp->otyp != LUMP_OF_ROYAL_JELLY))) - || (!strcmp(word, "use or apply") - /* Picks, axes, pole-weapons, bullwhips */ - && ((otmp->oclass == WEAPON_CLASS - && !is_pick(otmp) && !is_axe(otmp) - && !is_pole(otmp) && otyp != BULLWHIP) - || (otmp->oclass == POTION_CLASS - /* only applicable potion is oil, and it will only - be offered as a choice when already discovered */ - && (otyp != POT_OIL || !otmp->dknown - || !objects[POT_OIL].oc_name_known)) - || (otmp->oclass == FOOD_CLASS - && otyp != CREAM_PIE && otyp != EUCALYPTUS_LEAF - && otyp != LUMP_OF_ROYAL_JELLY) - || (otmp->oclass == GEM_CLASS && !is_graystone(otmp)))) - || (!strcmp(word, "rub the royal jelly on") && otmp->otyp != EGG) - || (!strcmp(word, "invoke") - && !otmp->oartifact - && !objects[otyp].oc_unique - && (otyp != FAKE_AMULET_OF_YENDOR || otmp->known) - && otyp != CRYSTAL_BALL /* synonym for apply */ - /* note: presenting the possibility of invoking non-artifact - mirrors and/or lamps is simply a cruel deception... */ - && otyp != MIRROR - && otyp != MAGIC_LAMP - && (otyp != OIL_LAMP /* don't list known oil lamp */ - || (otmp->dknown && objects[OIL_LAMP].oc_name_known))) - || (!strcmp(word, "untrap with") - && ((otmp->oclass == TOOL_CLASS && otyp != CAN_OF_GREASE) - || (otmp->oclass == POTION_CLASS - /* only applicable potion is oil, and it will only - be offered as a choice when already discovered */ - && (otyp != POT_OIL || !otmp->dknown - || !objects[POT_OIL].oc_name_known)))) - || (!strcmp(word, "tip") && !Is_container(otmp) - /* include horn of plenty if sufficiently discovered */ - && (otmp->otyp != HORN_OF_PLENTY || !otmp->dknown - || !objects[HORN_OF_PLENTY].oc_name_known)) - || (!strcmp(word, "charge") && !is_chargeable(otmp)) - || (!strcmp(word, "open") && otyp != TIN) - || (!strcmp(word, "call") && !objtyp_is_callable(otyp)) - || (!strcmp(word, "adjust") && otmp->oclass == COIN_CLASS - && !usegold) - ) { + else if (getobj_obj_exclude_too(word, otmp) + || (!strcmp(word, "adjust") && otmp->oclass == COIN_CLASS + && !usegold)) { foo--; } - /* Third ugly check: acceptable but not listed as likely - * candidates in the prompt or in the inventory subset if - * player responds with '?'. - */ - else if ( - /* ugly check for unworn armor that can't be worn */ - (putting_on(word) && *let == ARMOR_CLASS - && !canwearobj(otmp, &dummymask, FALSE)) - /* or armor with 'P' or 'R' or accessory with 'W' or 'T' */ - || ((putting_on(word) || taking_off(word)) - && ((*let == ARMOR_CLASS) ^ (otmp->oclass == ARMOR_CLASS))) - /* or unsuitable items rubbed on known touchstone */ - || (!strncmp(word, "rub on the stone", 16) - && *let == GEM_CLASS && otmp->dknown - && objects[otyp].oc_name_known) - /* suppress corpses on astral, amulets elsewhere */ - || (!strcmp(word, "sacrifice") - /* (!astral && amulet) || (astral && !amulet) */ - && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS))) - /* suppress container being stashed into */ - || (!strcmp(word, "stash") && !ck_bag(otmp)) - /* worn armor (shirt, suit) covered by worn armor (suit, cloak) - or accessory (ring) covered by cursed worn armor (gloves) */ - || (taking_off(word) - && inaccessible_equipment(otmp, (const char *) 0, - (boolean) (otmp->oclass == RING_CLASS))) - || (!strcmp(word, "write on") - && (!(otyp == SCR_BLANK_PAPER || otyp == SPE_BLANK_PAPER) - || !otmp->dknown || !objects[otyp].oc_name_known)) - ) { - /* acceptable but not listed as likely candidate */ + else if (getobj_obj_acceptable_unlisted(word, otmp, *let)) { + /* acceptable but not listed as likely candidates in the prompt + * or in the inventory subset if player responds with '?'. + */ foo--; allowall = TRUE; *ap++ = otmp->invlet; } -/* *INDENT-ON* */ -/* clang-format on */ } else { /* "ugly check" for reading fortune cookies, part 2 */ if ((!strcmp(word, "read") && is_readable(otmp))) @@ -1743,23 +1786,8 @@ register const char *let, *word; return (struct obj *) 0; } if (ilet == HANDS_SYM) { /* '-' */ - if (!allownone) { - char *suf = (char *) 0; - - strcpy(buf, word); - if ((bp = strstr(buf, " on the ")) != 0) { - /* rub on the stone[s] */ - *bp = '\0'; - suf = (bp + 1); - } - if ((bp = strstr(buf, " or ")) != 0) { - *bp = '\0'; - bp = (rn2(2) ? buf : (bp + 4)); - } else - bp = buf; - You("mime %s something%s%s.", ing_suffix(bp), suf ? " " : "", - suf ? suf : ""); - } + if (!allownone) + mime_action(word); return (allownone ? (struct obj *) &cg.zeroobj : (struct obj *) 0); } redo_menu: From bbb3d35252e4c79dd1147539db8316e5534ace75 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 27 Nov 2020 19:59:16 +0200 Subject: [PATCH 461/708] Unify enlightenment self-knowledgeable effect --- include/extern.h | 1 + src/potion.c | 6 +----- src/zap.c | 16 +++++++++++----- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/include/extern.h b/include/extern.h index 0147a619d..946550810 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3165,6 +3165,7 @@ E int FDECL(bhito, (struct obj *, struct obj *)); E int FDECL(bhitpile, (struct obj *, int (*)(OBJ_P, OBJ_P), int, int, SCHAR_P)); E int FDECL(zappable, (struct obj *)); +E void NDECL(do_enlightenment_effect); E void FDECL(zapnodir, (struct obj *)); E int NDECL(dozap); E int FDECL(zapyourself, (struct obj *, BOOLEAN_P)); diff --git a/src/potion.c b/src/potion.c index 34ff6de8e..bf2f2becd 100644 --- a/src/potion.c +++ b/src/potion.c @@ -725,11 +725,7 @@ register struct obj *otmp; (void) adjattrib(A_INT, 1, FALSE); (void) adjattrib(A_WIS, 1, FALSE); } - You_feel("self-knowledgeable..."); - display_nhwindow(WIN_MESSAGE, FALSE); - enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS); - pline_The("feeling subsides."); - exercise(A_WIS, TRUE); + do_enlightenment_effect(); } break; case SPE_INVISIBILITY: diff --git a/src/zap.c b/src/zap.c index edb4943d2..0b4f7f4bd 100644 --- a/src/zap.c +++ b/src/zap.c @@ -2227,6 +2227,16 @@ register struct obj *wand; return 1; } +void +do_enlightenment_effect() +{ + You_feel("self-knowledgeable..."); + display_nhwindow(WIN_MESSAGE, FALSE); + enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS); + pline_The("feeling subsides."); + exercise(A_WIS, TRUE); +} + /* * zapnodir - zaps a NODIR wand/spell. * added by GAN 11/03/86 @@ -2267,11 +2277,7 @@ register struct obj *obj; break; case WAN_ENLIGHTENMENT: known = TRUE; - You_feel("self-knowledgeable..."); - display_nhwindow(WIN_MESSAGE, FALSE); - enlightenment(MAGICENLIGHTENMENT, ENL_GAMEINPROGRESS); - pline_The("feeling subsides."); - exercise(A_WIS, TRUE); + do_enlightenment_effect(); break; } if (known) { From daf1381cc2796e6dc7e5f8de04fec0200da8c41b Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 27 Nov 2020 11:10:44 -0800 Subject: [PATCH 462/708] autodescribe vs MSGTYPE I was baffled about why moving the cursor across a fire elemental kept putting up --More-- until I remembered that I once used MSGTYPE=stop "[Ff]ire" to test Qt's handling for that. Turns out that I left it in my config file. autodescribe feedback should not be honoring that; honoring MSGTYPE=norepeat is not as clear-cut but this disables it too. User sounds were also kept enabled during autodescribe but I have no way to test them. Like norepeat, disabling just falls into place. The pline.c change is unrelated. It just eliminates a wide line (from adding 'g.') in the source by using a shorter variable name. --- doc/fixes37.0 | 4 +++- src/do_name.c | 4 ++-- src/pline.c | 12 ++++++------ 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f8f4b42c5..c5e5d77be 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.365 $ $NHDT-Date: 1606473484 2020/11/27 10:38:04 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.366 $ $NHDT-Date: 1606504240 2020/11/27 19:10:40 $ General Fixes and Modified Features ----------------------------------- @@ -312,6 +312,8 @@ throwing or kicking a shop container (that's light enough to move) made the hero pay for any gold inside, then didn't refund that amount if the container landed inside the shop try to fix message sequencing for tame golems that "roast/rot/rust in peace" +autodescribe when moving the cursor was erroneously honoring MSGTYPE=stop + and potentially delivering sounds Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/do_name.c b/src/do_name.c index cc58b3290..8484419b4 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1596498162 2020/08/03 23:42:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.182 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1606504240 2020/11/27 19:10:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.184 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -556,7 +556,7 @@ int cx, cy; if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch, (struct permonst **) 0)) { (void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords); - custompline(SUPPRESS_HISTORY, + custompline((SUPPRESS_HISTORY | OVERRIDE_MSGTYPE), "%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf, (iflags.autodescribe && getpos_getvalid && !(*getpos_getvalid)(cx, cy)) diff --git a/src/pline.c b/src/pline.c index 96715481a..f88a34d88 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pline.c $NHDT-Date: 1596498196 2020/08/03 23:43:16 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.96 $ */ +/* NetHack 3.7 pline.c $NHDT-Date: 1606504240 2020/11/27 19:10:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.100 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -50,16 +50,16 @@ const char *line; } /* called during save (unlike the interface-specific message history, - this data isn't saved and restored); end-of-game releases saved_pline[] + this data isn't saved and restored); end-of-game releases saved_plines[] while writing its contents to the final dump log */ void dumplogfreemessages() { - unsigned indx; + unsigned i; - for (indx = 0; indx < DUMPLOG_MSG_COUNT; ++indx) - if (g.saved_plines[indx]) - free((genericptr_t) g.saved_plines[indx]), g.saved_plines[indx] = 0; + for (i = 0; i < DUMPLOG_MSG_COUNT; ++i) + if (g.saved_plines[i]) + free((genericptr_t) g.saved_plines[i]), g.saved_plines[i] = 0; g.saved_pline_index = 0; } #endif From 36d977f61f7cbd629bf71e5c12a12c3c68ca19be Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 27 Nov 2020 23:43:52 +0200 Subject: [PATCH 463/708] Unify HP loss and passing out from overexertion --- include/extern.h | 1 + src/allmain.c | 12 +----------- src/hack.c | 26 +++++++++++++++++--------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/include/extern.h b/include/extern.h index 946550810..f2e2ba258 100644 --- a/include/extern.h +++ b/include/extern.h @@ -896,6 +896,7 @@ E int NDECL(wiz_debug_cmd_traveldisplay); #endif E boolean NDECL(u_rooted); E void NDECL(domove); +E void NDECL(overexert_hp); E boolean NDECL(overexertion); E void NDECL(invocation_message); E void NDECL(switch_terrain); diff --git a/src/allmain.c b/src/allmain.c index d015e7621..6cdf9bd4d 100644 --- a/src/allmain.c +++ b/src/allmain.c @@ -215,17 +215,7 @@ boolean resuming; if (wtcap > MOD_ENCUMBER && u.umoved) { if (!(wtcap < EXT_ENCUMBER ? g.moves % 30 : g.moves % 10)) { - if (Upolyd && u.mh > 1) { - u.mh--; - g.context.botl = TRUE; - } else if (!Upolyd && u.uhp > 1) { - u.uhp--; - g.context.botl = TRUE; - } else { - You("pass out from exertion!"); - exercise(A_CON, FALSE); - fall_asleep(-10, FALSE); - } + overexert_hp(); } } diff --git a/src/hack.c b/src/hack.c index f50538ada..3566831a2 100644 --- a/src/hack.c +++ b/src/hack.c @@ -2061,6 +2061,22 @@ int x1, y1, x2, y2; } } +/* HP loss or passing out from overexerting yourself */ +void +overexert_hp() +{ + int *hp = (!Upolyd ? &u.uhp : &u.mh); + + if (*hp > 1) { + *hp -= 1; + g.context.botl = TRUE; + } else { + You("pass out from exertion!"); + exercise(A_CON, FALSE); + fall_asleep(-10, FALSE); + } +} + /* combat increases metabolism */ boolean overexertion() @@ -2070,15 +2086,7 @@ overexertion() execute if you decline to attack a peaceful monster */ gethungry(); if ((g.moves % 3L) != 0L && near_capacity() >= HVY_ENCUMBER) { - int *hp = (!Upolyd ? &u.uhp : &u.mh); - - if (*hp > 1) { - *hp -= 1; - } else { - You("pass out from exertion!"); - exercise(A_CON, FALSE); - fall_asleep(-10, FALSE); - } + overexert_hp(); } return (boolean) (g.multi < 0); /* might have fainted (forced to sleep) */ } From 9ecbee4a4c833222a17f6f42f09fd652eae8649c Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 27 Nov 2020 17:59:46 -0800 Subject: [PATCH 464/708] remove unused variable from getobj() split and do a bit of reformatting. --- src/invent.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/invent.c b/src/invent.c index 67f1bfa43..6766de676 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1601595710 2020/10/01 23:41:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.302 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1606528765 2020/11/28 01:59:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1586,7 +1586,7 @@ char let; or accessory (ring) covered by cursed worn armor (gloves) */ || (taking_off(word) && inaccessible_equipment(otmp, (const char *) 0, - (boolean) (otmp->oclass == RING_CLASS))) + (boolean) (otmp->oclass == RING_CLASS))) || (!strcmp(word, "write on") && (!(otyp == SCR_BLANK_PAPER || otyp == SPE_BLANK_PAPER) || !otmp->dknown || !objects[otyp].oc_name_known))); @@ -1697,26 +1697,23 @@ register const char *let, *word; if (!*let || index(let, otmp->oclass) || (usegold && otmp->invlet == GOLD_SYM) || (useboulder && otmp->otyp == BOULDER)) { - register int otyp = otmp->otyp; - bp[foo++] = otmp->invlet; + /* remove inappropriate things */ if (getobj_obj_exclude(word, otmp)) { foo--; foox++; - } - /* remove inappropriate thing, but unlike the first it won't - * trigger an "else" in "you don't have anything else to ___". - */ - else if (getobj_obj_exclude_too(word, otmp) - || (!strcmp(word, "adjust") && otmp->oclass == COIN_CLASS - && !usegold)) { + + /* remove more inappropriate things, but unlike the first it won't + trigger an "else" in "you don't have anything else to ___" */ + } else if (getobj_obj_exclude_too(word, otmp) + || (!strcmp(word, "adjust") + && otmp->oclass == COIN_CLASS && !usegold)) { foo--; - } - else if (getobj_obj_acceptable_unlisted(word, otmp, *let)) { - /* acceptable but not listed as likely candidates in the prompt - * or in the inventory subset if player responds with '?'. - */ + + /* acceptable but not listed as likely candidates in the prompt + or in the inventory subset if player responds with '?' */ + } else if (getobj_obj_acceptable_unlisted(word, otmp, *let)) { foo--; allowall = TRUE; *ap++ = otmp->invlet; @@ -1729,9 +1726,9 @@ register const char *let, *word; } unsortloot(&sortedinvent); - bp[foo] = 0; + bp[foo] = '\0'; if (foo == 0 && bp > buf && bp[-1] == ' ') - *--bp = 0; + *--bp = '\0'; Strcpy(lets, bp); /* necessary since we destroy buf */ if (foo > 5) /* compactify string */ compactify(bp); From 5361958bdc941db6d90551b7817fc95990ce1992 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 28 Nov 2020 02:19:28 -0800 Subject: [PATCH 465/708] more "golem rust in peace" Be prepared for life-saving to contradict " falls to pieces". Purely hypothetically at present (with no plans to change) since golems don't benefit from amulets of life-saving. --- src/mhitm.c | 16 ++++++++++++---- src/mon.c | 6 ++++-- src/trap.c | 19 ++++++++++--------- src/uhitm.c | 16 ++++++++++++---- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/mhitm.c b/src/mhitm.c index bbeafbaf5..efed25f15 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mhitm.c $NHDT-Date: 1606473486 2020/11/27 10:38:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.144 $ */ +/* NetHack 3.7 mhitm.c $NHDT-Date: 1606558747 2020/11/28 10:19:07 $ $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. */ @@ -1022,8 +1022,12 @@ int dieroll; if (g.vis && canseemon(mdef)) pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk)); if (completelyburns(pd)) { /* paper golem or straw golem */ + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ if (g.vis && canseemon(mdef)) - pline("%s burns completely!", Monnam(mdef)); + pline("%s %s!", Monnam(mdef), + !mlifesaver(mdef) ? "burns completely" + : "is totally engulfed in flames"); monkilled(mdef, (char *) 0, AD_FIRE); if (!DEADMONSTER(mdef)) return 0; @@ -1100,7 +1104,8 @@ int dieroll; break; if (completelyrusts(pd)) { /* PM_IRON_GOLEM */ if (g.vis && canseemon(mdef)) - pline("%s falls to pieces!", Monnam(mdef)); + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); monkilled(mdef, (char *) 0, AD_RUST); if (!DEADMONSTER(mdef)) return 0; @@ -1121,8 +1126,11 @@ int dieroll; if (magr->mcan) break; if (completelyrots(pd)) { /* PM_WOOD_GOLEM || PM_LEATHER_GOLEM */ + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ if (g.vis && canseemon(mdef)) - pline("%s falls to pieces!", Monnam(mdef)); + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); monkilled(mdef, (char *) 0, AD_DCAY); if (!DEADMONSTER(mdef)) return 0; diff --git a/src/mon.c b/src/mon.c index 725daf8cc..476b36ce6 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1606473489 2020/11/27 10:38:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.354 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1606558762 2020/11/28 10:19:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.355 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2591,7 +2591,7 @@ int how; *fltxt ? " by the " : "", fltxt); else /* sad feeling is deferred until after potential life-saving */ - iflags.sad_feeling = (mdef->mtame != 0); + iflags.sad_feeling = mdef->mtame ? TRUE : FALSE; /* no corpse if digested or disintegrated or flammable golem burnt up; no corpse for a paper golem means no scrolls; golems that rust or @@ -2605,6 +2605,8 @@ int how; else mondied(mdef); /* calls mondead() and maybe leaves a corpse */ + if (!DEADMONSTER(mdef)) + return; /* life-saved */ /* extra message if pet golem is completely destroyed; if not visible, this will follow "you have a sad feeling" */ if (mdef->mtame) { diff --git a/src/trap.c b/src/trap.c index d8b19b3d4..558fb2f0f 100644 --- a/src/trap.c +++ b/src/trap.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 trap.c $NHDT-Date: 1604442297 2020/11/03 22:24:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.365 $ */ +/* NetHack 3.7 trap.c $NHDT-Date: 1606558763 2020/11/28 10:19:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.367 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2369,12 +2369,11 @@ register struct monst *mtmp; (void) water_damage(target, "shirt", TRUE); } - if (mptr == &mons[PM_IRON_GOLEM]) { + if (completelyrusts(mptr)) { if (in_sight) - pline("%s falls to pieces!", Monnam(mtmp)); - else if (mtmp->mtame) - pline("May %s rust in peace.", mon_nam(mtmp)); - mondied(mtmp); + pline("%s %s to pieces!", Monnam(mtmp), + !mlifesaver(mtmp) ? "falls" : "starts to fall"); + monkilled(mtmp, (const char *) 0, AD_RUST); if (DEADMONSTER(mtmp)) trapkilled = TRUE; } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { @@ -2400,8 +2399,10 @@ register struct monst *mtmp; int num = d(2, 4), alt; boolean immolate = FALSE; - /* paper burns very fast, assume straw is tightly - * packed and burns a bit slower */ + /* paper burns very fast, assume straw is tightly packed + and burns a bit slower + (note: this is inconsistent with mattackm()'s AD_FIRE + damage where completelyburns() includes straw golem) */ switch (monsndx(mptr)) { case PM_PAPER_GOLEM: immolate = TRUE; @@ -5245,7 +5246,7 @@ boolean nocorpse; dam = 1; } mon->mhp -= dam; - if (DEADMONSTER(mon)) { + if (mon->mhp <= 0) { int xx = mon->mx, yy = mon->my; monkilled(mon, "", nocorpse ? -AD_RBRE : AD_PHYS); diff --git a/src/uhitm.c b/src/uhitm.c index f099665b1..a9ebc349c 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1606473490 2020/11/27 10:38:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.243 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1606558760 2020/11/28 10:19:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1769,7 +1769,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */ pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk)); if (completelyburns(pd)) { /* paper golem or straw golem */ if (!Blind) - pline("%s burns completely!", Monnam(mdef)); + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ + pline("%s %s!", Monnam(mdef), + !mlifesaver(mdef) ? "burns completely" + : "is totally engulfed in flames"); else You("smell burning%s.", (pd == &mons[PM_PAPER_GOLEM]) ? " paper" @@ -1936,7 +1940,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ break; case AD_RUST: if (completelyrusts(pd)) { /* iron golem */ - pline("%s falls to pieces!", Monnam(mdef)); + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); xkilled(mdef, XKILL_NOMSG); } erode_armor(mdef, ERODE_RUST); @@ -1948,7 +1955,8 @@ int specialdmg; /* blessed and/or silver bonus against various things */ break; case AD_DCAY: if (completelyrots(pd)) { /* wood golem or leather golem */ - pline("%s falls to pieces!", Monnam(mdef)); + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); xkilled(mdef, XKILL_NOMSG); } erode_armor(mdef, ERODE_ROT); From fb188dc1aa9c03b5849a6e211c949a79ee1acf96 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 28 Nov 2020 12:48:09 +0200 Subject: [PATCH 466/708] Unify mfndpos monster movement flags --- include/extern.h | 1 + src/dogmove.c | 23 +------------------ src/mon.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++ src/monmove.c | 29 +----------------------- src/priest.c | 18 +-------------- 5 files changed, 63 insertions(+), 67 deletions(-) diff --git a/include/extern.h b/include/extern.h index f2e2ba258..3be154e70 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1482,6 +1482,7 @@ E boolean FDECL(mpickstuff, (struct monst *, const char *)); E int FDECL(curr_mon_load, (struct monst *)); E int FDECL(max_mon_load, (struct monst *)); E int FDECL(can_carry, (struct monst *, struct obj *)); +E long FDECL(mon_allowflags, (struct monst *)); E int FDECL(mfndpos, (struct monst *, coord *, long *, long)); E boolean FDECL(monnear, (struct monst *, int, int)); E void NDECL(dmonsfree); diff --git a/src/dogmove.c b/src/dogmove.c index 30a2f8725..e4f8f4513 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -934,17 +934,7 @@ int after; /* this is extra fast monster movement */ if (appr == -2) return 0; - allowflags = ALLOW_M | ALLOW_TRAPS | ALLOW_SSM | ALLOW_SANCT; - if (passes_walls(mtmp->data)) - allowflags |= (ALLOW_ROCK | ALLOW_WALL); - if (passes_bars(mtmp->data)) - allowflags |= ALLOW_BARS; - if (throws_rocks(mtmp->data)) - allowflags |= ALLOW_ROCK; - if (is_displacer(mtmp->data)) - allowflags |= ALLOW_MDISP; if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) { - allowflags |= ALLOW_U; if (!has_edog) { /* Guardian angel refuses to be conflicted; rather, * it disappears, angrily, and sends in some nasties @@ -960,18 +950,7 @@ int after; /* this is extra fast monster movement */ You("get released!"); } #endif - if (!nohands(mtmp->data) && !verysmall(mtmp->data)) { - allowflags |= OPENDOOR; - if (monhaskey(mtmp, TRUE)) - allowflags |= UNLOCKDOOR; - /* note: the Wizard and Riders can unlock doors without a key; - they won't use that ability if someone manages to tame them */ - } - if (is_giant(mtmp->data)) - allowflags |= BUSTDOOR; - if (tunnels(mtmp->data) - && !Is_rogue_level(&u.uz)) /* same restriction as m_move() */ - allowflags |= ALLOW_DIG; + allowflags = mon_allowflags(mtmp); cnt = mfndpos(mtmp, poss, info, allowflags); /* Normally dogs don't step on cursed items, but if they have no diff --git a/src/mon.c b/src/mon.c index 476b36ce6..38a2992c6 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1541,6 +1541,65 @@ struct obj *otmp; return iquan; } +/* return flags based on monster data, for mfndpos() */ +long +mon_allowflags(mtmp) +struct monst *mtmp; +{ + long flags = 0L; + boolean can_open = !(nohands(mtmp->data) || verysmall(mtmp->data)); + boolean can_unlock = ((can_open && monhaskey(mtmp, TRUE)) + || mtmp->iswiz || is_rider(mtmp->data)); + boolean doorbuster = is_giant(mtmp->data); + + if (mtmp->mtame) + flags |= ALLOW_M | ALLOW_TRAPS | ALLOW_SANCT | ALLOW_SSM; + else if (mtmp->mpeaceful) + flags |= ALLOW_SANCT | ALLOW_SSM; + else + flags |= ALLOW_U; + if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) + flags |= ALLOW_U; + if (mtmp->isshk) + flags |= ALLOW_SSM; + if (mtmp->ispriest) + flags |= ALLOW_SSM | ALLOW_SANCT; + if (passes_walls(mtmp->data)) + flags |= (ALLOW_ROCK | ALLOW_WALL); + if (throws_rocks(mtmp->data)) + flags |= ALLOW_ROCK; + if (tunnels(mtmp->data) + && !Is_rogue_level(&u.uz)) /* same restriction as m_move() */ + flags |= ALLOW_DIG; + if (doorbuster) + flags |= BUSTDOOR; + if (can_open) + flags |= OPENDOOR; + if (can_unlock) + flags |= UNLOCKDOOR; + if (passes_bars(mtmp->data)) + flags |= ALLOW_BARS; + if (is_displacer(mtmp->data)) + flags |= ALLOW_MDISP; + if (is_minion(mtmp->data) || is_rider(mtmp->data)) + flags |= ALLOW_SANCT; + /* unicorn may not be able to avoid hero on a noteleport level */ + if (is_unicorn(mtmp->data) && !noteleport_level(mtmp)) + flags |= NOTONL; + if (passes_walls(mtmp->data)) + flags |= (ALLOW_WALL | ALLOW_ROCK); + if (passes_bars(mtmp->data)) + flags |= ALLOW_BARS; + if (is_human(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR]) + flags |= ALLOW_SSM; + if ((is_undead(mtmp->data) && mtmp->data->mlet != S_GHOST) || is_vampshifter(mtmp)) + flags |= NOGARLIC; + if (throws_rocks(mtmp->data)) + flags |= ALLOW_ROCK; + + return flags; +} + /* return number of acceptable neighbour positions */ int mfndpos(mon, poss, info, flag) diff --git a/src/monmove.c b/src/monmove.c index 00986f4fb..dc64ae9d2 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1173,34 +1173,7 @@ register int after; nix = omx; niy = omy; - flag = 0L; - if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) - flag |= (ALLOW_SANCT | ALLOW_SSM); - else - flag |= ALLOW_U; - if (is_minion(ptr) || is_rider(ptr)) - flag |= ALLOW_SANCT; - /* unicorn may not be able to avoid hero on a noteleport level */ - if (is_unicorn(ptr) && !noteleport_level(mtmp)) - flag |= NOTONL; - if (passes_walls(ptr)) - flag |= (ALLOW_WALL | ALLOW_ROCK); - if (passes_bars(ptr)) - flag |= ALLOW_BARS; - if (can_tunnel) - flag |= ALLOW_DIG; - if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) - flag |= ALLOW_SSM; - if ((is_undead(ptr) && ptr->mlet != S_GHOST) || is_vampshifter(mtmp)) - flag |= NOGARLIC; - if (throws_rocks(ptr)) - flag |= ALLOW_ROCK; - if (can_open) - flag |= OPENDOOR; - if (can_unlock) - flag |= UNLOCKDOOR; - if (doorbuster) - flag |= BUSTDOOR; + flag = mon_allowflags(mtmp); { register int i, j, nx, ny, nearer; int jcnt, cnt; diff --git a/src/priest.c b/src/priest.c index f7a8b0c49..3b0c6c1e5 100644 --- a/src/priest.c +++ b/src/priest.c @@ -67,23 +67,7 @@ register xchar omx, omy, gx, gy; nix = omx; niy = omy; - if (mtmp->isshk) - allowflags = ALLOW_SSM; - else - allowflags = ALLOW_SSM | ALLOW_SANCT; - if (passes_walls(mtmp->data)) - allowflags |= (ALLOW_ROCK | ALLOW_WALL); - if (throws_rocks(mtmp->data)) - allowflags |= ALLOW_ROCK; - if (tunnels(mtmp->data)) - allowflags |= ALLOW_DIG; - if (!nohands(mtmp->data) && !verysmall(mtmp->data)) { - allowflags |= OPENDOOR; - if (monhaskey(mtmp, TRUE)) - allowflags |= UNLOCKDOOR; - } - if (is_giant(mtmp->data)) - allowflags |= BUSTDOOR; + allowflags = mon_allowflags(mtmp); cnt = mfndpos(mtmp, poss, info, allowflags); if (mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */ From 0d6481ad8c5c2bf46543fccb2591dd981242f3de Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 28 Nov 2020 08:59:03 -0500 Subject: [PATCH 467/708] spelling correction tidbit Closes #415 --- doc/Guidebook.mn | 2 +- doc/fixes36.1 | 2 +- doc/fixes36.4 | 2 +- include/patchlevel.h | 2 +- outdated/sys/wince/mhmsgwnd.c | 2 +- win/win32/mhmsgwnd.c | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 975691af8..6a0366a73 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2458,7 +2458,7 @@ NetHack. Here is a list of the armor class values provided by suits of armor: . .\" Replace the old one suit per line table with a more condensed one. -.\" AC4 and AC7 have been split into two lines to accomodate plain text +.\" AC4 and AC7 have been split into two lines to accommodate plain text .\" output (Guidebook.txt). AC4 needs it to reduce overall width; after .\" that, AC7 became the longest and the table looks better by shortening .\" it to get the second column (number) closer to the text on most lines. diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 5fda55113..3b0b27ddb 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -853,7 +853,7 @@ X11: new NetHack*highlight_prompt resource to control whether the persistent configuration will be highlighted when it's expecting input X11: NetHack*extcmd_height_delta resource can be used to adjust initial size of the extended commands menu -X11: status display split into three columns to accomodate Stone/Deaf/Lev/&c; +X11: status display split into three columns to accommodate Stone/Deaf/Lev/&c; NetHack*status_condition.foreground, .background, and .showGrip resources replaced by status_condition[1-3].* X11: more terminal-like default resources diff --git a/doc/fixes36.4 b/doc/fixes36.4 index a4b8991c4..912f80723 100644 --- a/doc/fixes36.4 +++ b/doc/fixes36.4 @@ -11,7 +11,7 @@ GDBPATH and GREPPATH from sysconf or -D... on compilation command line were at end of game when that was enabled fix the article used in the message when your steed encounters a polymorph trap allow teleporting onto the vibrating square -message "your knapsack can't accomodate any more items" when picking stuff up +message "your knapsack can't accommodate any more items" when picking stuff up or removing such from container was inaccurate if there was some gold pending; vary the message rather than add more convoluted pickup code dozen-ish assorted spelling/typo fixes in messages and source comments diff --git a/include/patchlevel.h b/include/patchlevel.h index a6d3fba00..d240f2245 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -98,7 +98,7 @@ * fix the article used in the message when your steed encounters a polymorph * trap * allow teleporting onto the vibrating square - * message "your knapsack can't accomodate any more items" when picking stuff + * message "your knapsack can't accommodate any more items" when picking stuff * up or removing such from container was inaccurate if there was some * gold pending; vary the message rather than add more convoluted pickup * code diff --git a/outdated/sys/wince/mhmsgwnd.c b/outdated/sys/wince/mhmsgwnd.c index 1c8976564..a73eec3e9 100644 --- a/outdated/sys/wince/mhmsgwnd.c +++ b/outdated/sys/wince/mhmsgwnd.c @@ -609,7 +609,7 @@ mswin_message_window_size(HWND hWnd, LPSIZE sz) data = (PNHMessageWindow) GetWindowLong(hWnd, GWL_USERDATA); if (data) { - /* set size to accomodate MSG_VISIBLE_LINES, highligh rectangle and + /* set size to accommodate MSG_VISIBLE_LINES, highligh rectangle and horizontal scroll bar (difference between window rect and client rect */ GetClientRect(hWnd, &client_rt); diff --git a/win/win32/mhmsgwnd.c b/win/win32/mhmsgwnd.c index f4f6fe09d..c821583cc 100644 --- a/win/win32/mhmsgwnd.c +++ b/win/win32/mhmsgwnd.c @@ -769,7 +769,7 @@ mswin_message_window_size(HWND hWnd, LPSIZE sz) sz->cx = rt.right - rt.left; sz->cy = rt.bottom - rt.top; - /* set size to accomodate MSG_VISIBLE_LINES and + /* set size to accommodate MSG_VISIBLE_LINES and horizontal scroll bar (difference between window rect and client rect */ GetClientRect(hWnd, &client_rt); From df8e2dcd74e29519a85f7cada470115730cfe809 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 28 Nov 2020 20:15:30 -0800 Subject: [PATCH 468/708] -Wshadow fix Not caused by a hidden macro this time... |mon.c:1549:10: warning: declaration shadows a variable in the | global scope [-Wshadow] | long flags = 0L; | ^ |../include/flag.h:392:29: note: previous declaration is here |extern NEARDATA struct flag flags; --- src/mon.c | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/mon.c b/src/mon.c index 38a2992c6..76ed3b28e 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1606558762 2020/11/28 10:19:22 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.355 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1606623308 2020/11/29 04:15:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.357 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1546,58 +1546,59 @@ long mon_allowflags(mtmp) struct monst *mtmp; { - long flags = 0L; + long allowflags = 0L; boolean can_open = !(nohands(mtmp->data) || verysmall(mtmp->data)); boolean can_unlock = ((can_open && monhaskey(mtmp, TRUE)) || mtmp->iswiz || is_rider(mtmp->data)); boolean doorbuster = is_giant(mtmp->data); if (mtmp->mtame) - flags |= ALLOW_M | ALLOW_TRAPS | ALLOW_SANCT | ALLOW_SSM; + allowflags |= ALLOW_M | ALLOW_TRAPS | ALLOW_SANCT | ALLOW_SSM; else if (mtmp->mpeaceful) - flags |= ALLOW_SANCT | ALLOW_SSM; + allowflags |= ALLOW_SANCT | ALLOW_SSM; else - flags |= ALLOW_U; + allowflags |= ALLOW_U; if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) - flags |= ALLOW_U; + allowflags |= ALLOW_U; if (mtmp->isshk) - flags |= ALLOW_SSM; + allowflags |= ALLOW_SSM; if (mtmp->ispriest) - flags |= ALLOW_SSM | ALLOW_SANCT; + allowflags |= ALLOW_SSM | ALLOW_SANCT; if (passes_walls(mtmp->data)) - flags |= (ALLOW_ROCK | ALLOW_WALL); + allowflags |= (ALLOW_ROCK | ALLOW_WALL); if (throws_rocks(mtmp->data)) - flags |= ALLOW_ROCK; + allowflags |= ALLOW_ROCK; if (tunnels(mtmp->data) && !Is_rogue_level(&u.uz)) /* same restriction as m_move() */ - flags |= ALLOW_DIG; + allowflags |= ALLOW_DIG; if (doorbuster) - flags |= BUSTDOOR; + allowflags |= BUSTDOOR; if (can_open) - flags |= OPENDOOR; + allowflags |= OPENDOOR; if (can_unlock) - flags |= UNLOCKDOOR; + allowflags |= UNLOCKDOOR; if (passes_bars(mtmp->data)) - flags |= ALLOW_BARS; + allowflags |= ALLOW_BARS; if (is_displacer(mtmp->data)) - flags |= ALLOW_MDISP; + allowflags |= ALLOW_MDISP; if (is_minion(mtmp->data) || is_rider(mtmp->data)) - flags |= ALLOW_SANCT; + allowflags |= ALLOW_SANCT; /* unicorn may not be able to avoid hero on a noteleport level */ if (is_unicorn(mtmp->data) && !noteleport_level(mtmp)) - flags |= NOTONL; + allowflags |= NOTONL; if (passes_walls(mtmp->data)) - flags |= (ALLOW_WALL | ALLOW_ROCK); + allowflags |= (ALLOW_WALL | ALLOW_ROCK); if (passes_bars(mtmp->data)) - flags |= ALLOW_BARS; + allowflags |= ALLOW_BARS; if (is_human(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR]) - flags |= ALLOW_SSM; - if ((is_undead(mtmp->data) && mtmp->data->mlet != S_GHOST) || is_vampshifter(mtmp)) - flags |= NOGARLIC; + allowflags |= ALLOW_SSM; + if ((is_undead(mtmp->data) && mtmp->data->mlet != S_GHOST) + || is_vampshifter(mtmp)) + allowflags |= NOGARLIC; if (throws_rocks(mtmp->data)) - flags |= ALLOW_ROCK; + allowflags |= ALLOW_ROCK; - return flags; + return allowflags; } /* return number of acceptable neighbour positions */ From f2218839a329ca4f5406a8c845b480d933a9b54c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 29 Nov 2020 14:10:25 +0200 Subject: [PATCH 469/708] Move some function names to start of line --- src/options.c | 12 ++++++++---- src/version.c | 3 ++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/options.c b/src/options.c index c38d06aa3..e82877b5a 100644 --- a/src/options.c +++ b/src/options.c @@ -4232,7 +4232,8 @@ char *op; * Prefix-handling functions */ -int pfxfn_cond_(optidx, req, negated, opts, op) +int +pfxfn_cond_(optidx, req, negated, opts, op) int optidx UNUSED; int req; boolean negated; @@ -4276,7 +4277,8 @@ char *op UNUSED; return optn_ok; } -int pfxfn_font(optidx, req, negated, opts, op) +int +pfxfn_font(optidx, req, negated, opts, op) int optidx; int req; boolean negated; @@ -4412,7 +4414,8 @@ char *op; } #if defined(MICRO) && !defined(AMIGA) -int pfxfn_IBM_(optidx, req, negated, opts, op) +int +pfxfn_IBM_(optidx, req, negated, opts, op) int optidx; int req; boolean negated; @@ -4640,7 +4643,8 @@ char *op; return optn_ok; } -int spcfn_misc_menu_cmd(midx, req, negated, opts, op) +int +spcfn_misc_menu_cmd(midx, req, negated, opts, op) int midx; int req; boolean negated; diff --git a/src/version.c b/src/version.c index a499c3a51..f8fd308d1 100644 --- a/src/version.c +++ b/src/version.c @@ -247,7 +247,8 @@ doextversion() return 0; } -void early_version_info(pastebuf) +void +early_version_info(pastebuf) boolean pastebuf; { char buf[BUFSZ], buf2[BUFSZ]; From 74565c890db2d13560dc91bd705bd2b4e5c5cff0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 29 Nov 2020 19:08:27 +0200 Subject: [PATCH 470/708] Split readobjnam into multiple functions Also add several new tests for it --- src/objnam.c | 1328 ++++++++++++++++++++++++--------------------- test/testwish.lua | 17 + 2 files changed, 735 insertions(+), 610 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index 0d54695a9..5dfbc5f54 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -10,6 +10,26 @@ #define SCHAR_LIM 127 #define NUMOBUF 12 +struct _readobjnam_data { + char globbuf[BUFSZ]; + char fruitbuf[BUFSZ]; + char *bp; + char *origbp; + char oclass; + char *un, *dn, *actualn; + const char *name; + char *p; + int cnt, spe, spesgn, typ, very, rechrg; + int blessed, uncursed, iscursed, ispoisoned, isgreased; + int eroded, eroded2, erodeproof, locked, unlocked, broken, real, fake; + int halfeaten, mntmp, contents; + int islit, unlabeled, ishistoric, isdiluted, trapped; + int tmp, tinv, tvariety; + int wetness, gsize; + int ftype; + struct obj *otmp; +}; + static char *FDECL(strprepend, (char *, const char *)); static char *NDECL(nextobuf); static void FDECL(releaseobuf, (char *)); @@ -25,6 +45,12 @@ static boolean FDECL(wishymatch, (const char *, const char *, BOOLEAN_P)); static short FDECL(rnd_otyp_by_wpnskill, (SCHAR_P)); static short FDECL(rnd_otyp_by_namedesc, (const char *, CHAR_P, int)); static struct obj *FDECL(wizterrainwish, (char *, char *, int, int)); +static void FDECL(readobjnam_init, (char *, struct _readobjnam_data *)); +static int FDECL(readobjnam_preparse, (struct _readobjnam_data *)); +static void FDECL(readobjnam_parse_charges, (struct _readobjnam_data *)); +static int FDECL(readobjnam_postparse1, (struct _readobjnam_data *)); +static int FDECL(readobjnam_postparse2, (struct _readobjnam_data *)); +static int FDECL(readobjnam_postparse3, (struct _readobjnam_data *)); struct Jitem { int item; @@ -3225,251 +3251,218 @@ int locked, trapped; return (struct obj *) 0; } -/* - * Return something wished for. Specifying a null pointer for - * the user request string results in a random object. Otherwise, - * if asking explicitly for "nothing" (or "nil") return no_wish; - * if not an object return &cg.zeroobj; if an error (no matching object), - * return null. - */ -struct obj * -readobjnam(bp, no_wish) -register char *bp; -struct obj *no_wish; -{ - register char *p; - register int i; - register struct obj *otmp; - int cnt, spe, spesgn, typ, very, rechrg; - int blessed, uncursed, iscursed, ispoisoned, isgreased; - int eroded, eroded2, erodeproof, locked, unlocked, broken, real, fake; - int halfeaten, mntmp, contents; - int islit, unlabeled, ishistoric, isdiluted, trapped; - int tmp, tinv, tvariety; - int wetness, gsize = 0; - struct fruit *f; - int ftype = g.context.current_fruit; - char fruitbuf[BUFSZ], globbuf[BUFSZ]; - /* Fruits must not mess up the ability to wish for real objects (since - * you can leave a fruit in a bones file and it will be added to - * another person's game), so they must be checked for last, after - * stripping all the possible prefixes and seeing if there's a real - * name in there. So we have to save the full original name. However, - * it's still possible to do things like "uncursed burnt Alaska", - * or worse yet, "2 burned 5 course meals", so we need to loop to - * strip off the prefixes again, this time stripping only the ones - * possible on food. - * We could get even more detailed so as to allow food names with - * prefixes that _are_ possible on food, so you could wish for - * "2 3 alarm chilis". Currently this isn't allowed; options.c - * automatically sticks 'candied' in front of such names. - */ - char oclass; - char *un, *dn, *actualn, *origbp = bp; - const char *name = 0; - - cnt = spe = spesgn = typ = 0; - very = rechrg = blessed = uncursed = iscursed = ispoisoned = - isgreased = eroded = eroded2 = erodeproof = halfeaten = - islit = unlabeled = ishistoric = isdiluted = trapped = - locked = unlocked = broken = real = fake = 0; - tvariety = RANDOM_TIN; - mntmp = NON_PM; #define UNDEFINED 0 #define EMPTY 1 #define SPINACH 2 - contents = UNDEFINED; - oclass = 0; - actualn = dn = un = 0; - wetness = 0; - if (!bp) - goto any; - /* first, remove extra whitespace they may have typed */ - (void) mungspaces(bp); - /* allow wishing for "nothing" to preserve wishless conduct... - [now requires "wand of nothing" if that's what was really wanted] */ - if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil") - || !strcmpi(bp, "none")) - return no_wish; - /* save the [nearly] unmodified choice string */ - Strcpy(fruitbuf, bp); +static void +readobjnam_init(bp, d) +char *bp; +struct _readobjnam_data *d; +{ + d->cnt = d->spe = d->spesgn = d->typ = 0; + d->very = d->rechrg = d->blessed = d->uncursed = d->iscursed = d->ispoisoned = + d->isgreased = d->eroded = d->eroded2 = d->erodeproof = d->halfeaten = + d->islit = d->unlabeled = d->ishistoric = d->isdiluted = d->trapped = + d->locked = d->unlocked = d->broken = d->real = d->fake = 0; + d->tvariety = RANDOM_TIN; + d->mntmp = NON_PM; + d->contents = UNDEFINED; + d->oclass = 0; + d->actualn = d->dn = d->un = 0; + d->wetness = 0; + d->gsize = 0; + d->bp = d->origbp = bp; + d->p = (char *) 0; + d->name = (const char *) 0; + d->otmp = (struct obj *) 0; + d->ftype = g.context.current_fruit; +} +static int +readobjnam_preparse(d) +struct _readobjnam_data *d; +{ for (;;) { register int l; - if (!bp || !*bp) - goto any; - if (!strncmpi(bp, "an ", l = 3) || !strncmpi(bp, "a ", l = 2)) { - cnt = 1; - } else if (!strncmpi(bp, "the ", l = 4)) { + if (!d->bp || !*d->bp) + return 1; + if (!strncmpi(d->bp, "an ", l = 3) || !strncmpi(d->bp, "a ", l = 2)) { + d->cnt = 1; + } else if (!strncmpi(d->bp, "the ", l = 4)) { ; /* just increment `bp' by `l' below */ - } else if (!cnt && digit(*bp) && strcmp(bp, "0")) { - cnt = atoi(bp); - while (digit(*bp)) - bp++; - while (*bp == ' ') - bp++; + } else if (!d->cnt && digit(*d->bp) && strcmp(d->bp, "0")) { + d->cnt = atoi(d->bp); + while (digit(*d->bp)) + d->bp++; + while (*d->bp == ' ') + d->bp++; l = 0; - } else if (*bp == '+' || *bp == '-') { - spesgn = (*bp++ == '+') ? 1 : -1; - spe = atoi(bp); - while (digit(*bp)) - bp++; - while (*bp == ' ') - bp++; + } else if (*d->bp == '+' || *d->bp == '-') { + d->spesgn = (*d->bp++ == '+') ? 1 : -1; + d->spe = atoi(d->bp); + while (digit(*d->bp)) + d->bp++; + while (*d->bp == ' ') + d->bp++; l = 0; - } else if (!strncmpi(bp, "blessed ", l = 8) - || !strncmpi(bp, "holy ", l = 5)) { - blessed = 1; - } else if (!strncmpi(bp, "moist ", l = 6) - || !strncmpi(bp, "wet ", l = 4)) { - if (!strncmpi(bp, "wet ", 4)) - wetness = rn2(3) + 3; + } else if (!strncmpi(d->bp, "blessed ", l = 8) + || !strncmpi(d->bp, "holy ", l = 5)) { + d->blessed = 1; + } else if (!strncmpi(d->bp, "moist ", l = 6) + || !strncmpi(d->bp, "wet ", l = 4)) { + if (!strncmpi(d->bp, "wet ", 4)) + d->wetness = rn2(3) + 3; else - wetness = rnd(2); - } else if (!strncmpi(bp, "cursed ", l = 7) - || !strncmpi(bp, "unholy ", l = 7)) { - iscursed = 1; - } else if (!strncmpi(bp, "uncursed ", l = 9)) { - uncursed = 1; - } else if (!strncmpi(bp, "rustproof ", l = 10) - || !strncmpi(bp, "erodeproof ", l = 11) - || !strncmpi(bp, "corrodeproof ", l = 13) - || !strncmpi(bp, "fixed ", l = 6) - || !strncmpi(bp, "fireproof ", l = 10) - || !strncmpi(bp, "rotproof ", l = 9)) { - erodeproof = 1; - } else if (!strncmpi(bp, "lit ", l = 4) - || !strncmpi(bp, "burning ", l = 8)) { - islit = 1; - } else if (!strncmpi(bp, "unlit ", l = 6) - || !strncmpi(bp, "extinguished ", l = 13)) { - islit = 0; + d->wetness = rnd(2); + } else if (!strncmpi(d->bp, "cursed ", l = 7) + || !strncmpi(d->bp, "unholy ", l = 7)) { + d->iscursed = 1; + } else if (!strncmpi(d->bp, "uncursed ", l = 9)) { + d->uncursed = 1; + } else if (!strncmpi(d->bp, "rustproof ", l = 10) + || !strncmpi(d->bp, "erodeproof ", l = 11) + || !strncmpi(d->bp, "corrodeproof ", l = 13) + || !strncmpi(d->bp, "fixed ", l = 6) + || !strncmpi(d->bp, "fireproof ", l = 10) + || !strncmpi(d->bp, "rotproof ", l = 9)) { + d->erodeproof = 1; + } else if (!strncmpi(d->bp, "lit ", l = 4) + || !strncmpi(d->bp, "burning ", l = 8)) { + d->islit = 1; + } else if (!strncmpi(d->bp, "unlit ", l = 6) + || !strncmpi(d->bp, "extinguished ", l = 13)) { + d->islit = 0; /* "unlabeled" and "blank" are synonymous */ - } else if (!strncmpi(bp, "unlabeled ", l = 10) - || !strncmpi(bp, "unlabelled ", l = 11) - || !strncmpi(bp, "blank ", l = 6)) { - unlabeled = 1; - } else if (!strncmpi(bp, "poisoned ", l = 9)) { - ispoisoned = 1; + } else if (!strncmpi(d->bp, "unlabeled ", l = 10) + || !strncmpi(d->bp, "unlabelled ", l = 11) + || !strncmpi(d->bp, "blank ", l = 6)) { + d->unlabeled = 1; + } else if (!strncmpi(d->bp, "poisoned ", l = 9)) { + d->ispoisoned = 1; /* "trapped" recognized but not honored outside wizard mode */ - } else if (!strncmpi(bp, "trapped ", l = 8)) { - trapped = 0; /* undo any previous "untrapped" */ + } else if (!strncmpi(d->bp, "trapped ", l = 8)) { + d->trapped = 0; /* undo any previous "untrapped" */ if (wizard) - trapped = 1; - } else if (!strncmpi(bp, "untrapped ", l = 10)) { - trapped = 2; /* not trapped */ + d->trapped = 1; + } else if (!strncmpi(d->bp, "untrapped ", l = 10)) { + d->trapped = 2; /* not trapped */ /* locked, unlocked, broken: box/chest lock states */ - } else if (!strncmpi(bp, "locked ", l = 7)) { - locked = 1, unlocked = broken = 0; - } else if (!strncmpi(bp, "unlocked ", l = 9)) { - unlocked = 1, locked = broken = 0; - } else if (!strncmpi(bp, "broken ", l = 7)) { - broken = 1, locked = unlocked = 0; - } else if (!strncmpi(bp, "greased ", l = 8)) { - isgreased = 1; - } else if (!strncmpi(bp, "very ", l = 5)) { + } else if (!strncmpi(d->bp, "locked ", l = 7)) { + d->locked = 1, d->unlocked = d->broken = 0; + } else if (!strncmpi(d->bp, "unlocked ", l = 9)) { + d->unlocked = 1, d->locked = d->broken = 0; + } else if (!strncmpi(d->bp, "broken ", l = 7)) { + d->broken = 1, d->locked = d->unlocked = 0; + } else if (!strncmpi(d->bp, "greased ", l = 8)) { + d->isgreased = 1; + } else if (!strncmpi(d->bp, "very ", l = 5)) { /* very rusted very heavy iron ball */ - very = 1; - } else if (!strncmpi(bp, "thoroughly ", l = 11)) { - very = 2; - } else if (!strncmpi(bp, "rusty ", l = 6) - || !strncmpi(bp, "rusted ", l = 7) - || !strncmpi(bp, "burnt ", l = 6) - || !strncmpi(bp, "burned ", l = 7)) { - eroded = 1 + very; - very = 0; - } else if (!strncmpi(bp, "corroded ", l = 9) - || !strncmpi(bp, "rotted ", l = 7)) { - eroded2 = 1 + very; - very = 0; - } else if (!strncmpi(bp, "partly eaten ", l = 13) - || !strncmpi(bp, "partially eaten ", l = 16)) { - halfeaten = 1; - } else if (!strncmpi(bp, "historic ", l = 9)) { - ishistoric = 1; - } else if (!strncmpi(bp, "diluted ", l = 8)) { - isdiluted = 1; - } else if (!strncmpi(bp, "empty ", l = 6)) { - contents = EMPTY; - } else if (!strncmpi(bp, "small ", l = 6)) { /* glob sizes */ + d->very = 1; + } else if (!strncmpi(d->bp, "thoroughly ", l = 11)) { + d->very = 2; + } else if (!strncmpi(d->bp, "rusty ", l = 6) + || !strncmpi(d->bp, "rusted ", l = 7) + || !strncmpi(d->bp, "burnt ", l = 6) + || !strncmpi(d->bp, "burned ", l = 7)) { + d->eroded = 1 + d->very; + d->very = 0; + } else if (!strncmpi(d->bp, "corroded ", l = 9) + || !strncmpi(d->bp, "rotted ", l = 7)) { + d->eroded2 = 1 + d->very; + d->very = 0; + } else if (!strncmpi(d->bp, "partly eaten ", l = 13) + || !strncmpi(d->bp, "partially eaten ", l = 16)) { + d->halfeaten = 1; + } else if (!strncmpi(d->bp, "historic ", l = 9)) { + d->ishistoric = 1; + } else if (!strncmpi(d->bp, "diluted ", l = 8)) { + d->isdiluted = 1; + } else if (!strncmpi(d->bp, "empty ", l = 6)) { + d->contents = EMPTY; + } else if (!strncmpi(d->bp, "small ", l = 6)) { /* glob sizes */ /* "small" might be part of monster name (mimic, if wishing for its corpse) rather than prefix for glob size; when used for globs, it might be either "small glob of " or "small glob" and user might add 's' even though plural doesn't accomplish anything because globs don't stack */ - if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob")) + if (strncmpi(d->bp + l, "glob", 4) && !strstri(d->bp + l, " glob")) break; - gsize = 1; - } else if (!strncmpi(bp, "medium ", l = 7)) { + d->gsize = 1; + } else if (!strncmpi(d->bp, "medium ", l = 7)) { /* xname() doesn't display "medium" but without this there'd be no way to ask for the intermediate size ("glob" without size prefix yields smallest one) */ - gsize = 2; - } else if (!strncmpi(bp, "large ", l = 6)) { + d->gsize = 2; + } else if (!strncmpi(d->bp, "large ", l = 6)) { /* "large" might be part of monster name (dog, cat, koboold, mimic) or object name (box, round shield) rather than prefix for glob size */ - if (strncmpi(bp + l, "glob", 4) && !strstri(bp + l, " glob")) + if (strncmpi(d->bp + l, "glob", 4) && !strstri(d->bp + l, " glob")) break; /* "very large " had "very " peeled off on previous iteration */ - gsize = (very != 1) ? 3 : 4; - } else if (!strncmpi(bp, "real ", l = 5)) { + d->gsize = (d->very != 1) ? 3 : 4; + } else if (!strncmpi(d->bp, "real ", l = 5)) { /* accept "real Amulet of Yendor" with "blessed" or "cursed" or useless "erodeproof" before or after "real" ... */ - real = 1; /* don't negate 'fake' here; "real fake amulet" and + d->real = 1; /* don't negate 'fake' here; "real fake amulet" and * "fake real amulet" will both yield fake amulet * (so will "real amulet" outside of wizard mode) */ - } else if (!strncmpi(bp, "fake ", l = 5)) { + } else if (!strncmpi(d->bp, "fake ", l = 5)) { /* ... and "fake Amulet of Yendor" likewise */ - fake = 1, real = 0; + d->fake = 1, d->real = 0; /* ['real' isn't actually needed (unless we someday add "real gem" for random non-glass, non-stone)] */ } else break; - bp += l; + d->bp += l; } - if (!cnt) - cnt = 1; /* will be changed to 2 if makesingular() changes string */ - if (strlen(bp) > 1 && (p = rindex(bp, '(')) != 0) { + return 0; +} + +static void +readobjnam_parse_charges(d) +struct _readobjnam_data *d; +{ + if (strlen(d->bp) > 1 && (d->p = rindex(d->bp, '(')) != 0) { boolean keeptrailingchars = TRUE; - p[(p > bp && p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */ - ++p; /* advance past '(' */ - if (!strncmpi(p, "lit)", 4)) { - islit = 1; - p += 4 - 1; /* point at ')' */ + d->p[(d->p > d->bp && d->p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */ + ++d->p; /* advance past '(' */ + if (!strncmpi(d->p, "lit)", 4)) { + d->islit = 1; + d->p += 4 - 1; /* point at ')' */ } else { - spe = atoi(p); - while (digit(*p)) - p++; - if (*p == ':') { - p++; - rechrg = spe; - spe = atoi(p); - while (digit(*p)) - p++; + d->spe = atoi(d->p); + while (digit(*d->p)) + d->p++; + if (*d->p == ':') { + d->p++; + d->rechrg = d->spe; + d->spe = atoi(d->p); + while (digit(*d->p)) + d->p++; } - if (*p != ')') { - spe = rechrg = 0; + if (*d->p != ')') { + d->spe = d->rechrg = 0; /* mis-matched parentheses; rest of string will be ignored * [probably we should restore everything back to '(' * instead since it might be part of "named ..."] */ keeptrailingchars = FALSE; } else { - spesgn = 1; + d->spesgn = 1; } } if (keeptrailingchars) { - char *pp = eos(bp); + char *pp = eos(d->bp); /* 'pp' points at 'pb's terminating '\0', 'p' points at ')' and will be incremented past it */ do { - *pp++ = *++p; - } while (*p); + *pp++ = *++d->p; + } while (*d->p); } } /* @@ -3477,14 +3470,21 @@ struct obj *no_wish; * smaller. Also, spe should always be positive --some cheaters may * try to confuse atoi(). */ - if (spe < 0) { - spesgn = -1; /* cheaters get what they deserve */ - spe = abs(spe); + if (d->spe < 0) { + d->spesgn = -1; /* cheaters get what they deserve */ + d->spe = abs(d->spe); } - if (spe > SCHAR_LIM) - spe = SCHAR_LIM; - if (rechrg < 0 || rechrg > 7) - rechrg = 7; /* recharge_limit */ + if (d->spe > SCHAR_LIM) + d->spe = SCHAR_LIM; + if (d->rechrg < 0 || d->rechrg > 7) + d->rechrg = 7; /* recharge_limit */ +} + +static int +readobjnam_postparse1(d) +struct _readobjnam_data *d; +{ + int i; /* now we have the actual name, as delivered by xname, say * green potions called whisky @@ -3495,38 +3495,38 @@ struct obj *no_wish; * wand of wishing * elven cloak */ - if ((p = strstri(bp, " named ")) != 0) { - *p = 0; - name = p + 7; + if ((d->p = strstri(d->bp, " named ")) != 0) { + *d->p = 0; + d->name = d->p + 7; } - if ((p = strstri(bp, " called ")) != 0) { - *p = 0; - un = p + 8; + if ((d->p = strstri(d->bp, " called ")) != 0) { + *d->p = 0; + d->un = d->p + 8; /* "helmet called telepathy" is not "helmet" (a specific type) * "shield called reflection" is not "shield" (a general type) */ for (i = 0; i < SIZE(o_ranges); i++) - if (!strcmpi(bp, o_ranges[i].name)) { - oclass = o_ranges[i].oclass; - goto srch; + if (!strcmpi(d->bp, o_ranges[i].name)) { + d->oclass = o_ranges[i].oclass; + return 1; /*goto srch;*/ } } - if ((p = strstri(bp, " labeled ")) != 0) { - *p = 0; - dn = p + 9; - } else if ((p = strstri(bp, " labelled ")) != 0) { - *p = 0; - dn = p + 10; + if ((d->p = strstri(d->bp, " labeled ")) != 0) { + *d->p = 0; + d->dn = d->p + 9; + } else if ((d->p = strstri(d->bp, " labelled ")) != 0) { + *d->p = 0; + d->dn = d->p + 10; } - if ((p = strstri(bp, " of spinach")) != 0) { - *p = 0; - contents = SPINACH; + if ((d->p = strstri(d->bp, " of spinach")) != 0) { + *d->p = 0; + d->contents = SPINACH; } /* real vs fake is only useful for wizard mode but we'll accept its parsing in normal play (result is never real Amulet for that case) */ - if ((p = strstri(bp, OBJ_DESCR(objects[AMULET_OF_YENDOR]))) != 0 - && (p == bp || p[-1] == ' ')) { - char *s = bp; + if ((d->p = strstri(d->bp, OBJ_DESCR(objects[AMULET_OF_YENDOR]))) != 0 + && (d->p == d->bp || d->p[-1] == ' ')) { + char *s = d->bp; /* "Amulet of Yendor" matches two items, name of real Amulet and description of fake one; player can explicitly specify @@ -3538,17 +3538,17 @@ struct obj *no_wish; loop above, these have to be in the right order when more than one is present (similar to worthless glass gems below) */ if (!strncmpi(s, "cheap ", 6)) - fake = 1, s += 6; + d->fake = 1, s += 6; if (!strncmpi(s, "plastic ", 8)) - fake = 1, s += 8; + d->fake = 1, s += 8; if (!strncmpi(s, "imitation ", 10)) - fake = 1, s += 10; + d->fake = 1, s += 10; nhUse(s); /* suppress potential assigned-but-not-used complaint */ /* when 'fake' is True, it overrides 'real' if both were given; when it is False, force 'real' whether that was specified or not */ - real = !fake; - typ = real ? AMULET_OF_YENDOR : FAKE_AMULET_OF_YENDOR; - goto typfnd; + d->real = !d->fake; + d->typ = d->real ? AMULET_OF_YENDOR : FAKE_AMULET_OF_YENDOR; + return 2; /*goto typfnd;*/ } /* @@ -3564,17 +3564,17 @@ struct obj *no_wish; * -- boots, gloves, and lenses -- are also not mergable, so cnt is * ignored anyway. */ - if (!strncmpi(bp, "pair of ", 8)) { - bp += 8; - cnt *= 2; - } else if (!strncmpi(bp, "pairs of ", 9)) { - bp += 9; - if (cnt > 1) - cnt *= 2; - } else if (!strncmpi(bp, "set of ", 7)) { - bp += 7; - } else if (!strncmpi(bp, "sets of ", 8)) { - bp += 8; + if (!strncmpi(d->bp, "pair of ", 8)) { + d->bp += 8; + d->cnt *= 2; + } else if (!strncmpi(d->bp, "pairs of ", 9)) { + d->bp += 9; + if (d->cnt > 1) + d->cnt *= 2; + } else if (!strncmpi(d->bp, "set of ", 7)) { + d->bp += 7; + } else if (!strncmpi(d->bp, "sets of ", 8)) { + d->bp += 8; } /* intercept pudding globs here; they're a valid wish target, @@ -3582,28 +3582,28 @@ struct obj *no_wish; * * also don't let player wish for multiple globs. */ - i = (int) strlen(bp); - p = (char *) 0; + i = (int) strlen(d->bp); + d->p = (char *) 0; /* check for "glob", " glob", and "glob of " */ - if (!strcmpi(bp, "glob") || !BSTRCMPI(bp, bp + i - 5, " glob") - || !strcmpi(bp, "globs") || !BSTRCMPI(bp, bp + i - 6, " globs") - || (p = strstri(bp, "glob of ")) != 0 - || (p = strstri(bp, "globs of ")) != 0) { - mntmp = name_to_mon(!p ? bp : (strstri(p, " of ") + 4)); + if (!strcmpi(d->bp, "glob") || !BSTRCMPI(d->bp, d->bp + i - 5, " glob") + || !strcmpi(d->bp, "globs") || !BSTRCMPI(d->bp, d->bp + i - 6, " globs") + || (d->p = strstri(d->bp, "glob of ")) != 0 + || (d->p = strstri(d->bp, "globs of ")) != 0) { + d->mntmp = name_to_mon(!d->p ? d->bp : (strstri(d->p, " of ") + 4)); /* if we didn't recognize monster type, pick a valid one at random */ - if (mntmp == NON_PM) - mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE); + if (d->mntmp == NON_PM) + d->mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE); /* construct canonical spelling in case name_to_mon() recognized a variant (grey ooze) or player used inverted syntax ( glob); if player has given a valid monster type but not valid glob type, object name lookup won't find it and wish attempt will fail */ - Sprintf(globbuf, "glob of %s", mons[mntmp].mname); - bp = globbuf; - mntmp = NON_PM; /* not useful for "glob of " object lookup */ - cnt = 0; /* globs don't stack */ - oclass = FOOD_CLASS; - actualn = bp, dn = 0; - goto srch; + Sprintf(d->globbuf, "glob of %s", mons[d->mntmp].mname); + d->bp = d->globbuf; + d->mntmp = NON_PM; /* not useful for "glob of " object lookup */ + d->cnt = 0; /* globs don't stack */ + d->oclass = FOOD_CLASS; + d->actualn = d->bp, d->dn = 0; + return 1; /*goto srch;*/ } else { /* * Find corpse type using "of" (figurine of an orc, tin of orc meat) @@ -3613,77 +3613,77 @@ struct obj *no_wish; * names "gauntlets of ogre power" and "gauntlets of giant strength" * (or the alternate spelling of those, "gloves of ..."). */ - if (!strstri(bp, "wand ") && !strstri(bp, "spellbook ") - && !strstri(bp, "gauntlets ") && !strstri(bp, "gloves ") - && !strstri(bp, "finger ")) { - if ((p = strstri(bp, "tin of ")) != 0) { - if (!strcmpi(p + 7, "spinach")) { - contents = SPINACH; - mntmp = NON_PM; + if (!strstri(d->bp, "wand ") && !strstri(d->bp, "spellbook ") + && !strstri(d->bp, "gauntlets ") && !strstri(d->bp, "gloves ") + && !strstri(d->bp, "finger ")) { + if ((d->p = strstri(d->bp, "tin of ")) != 0) { + if (!strcmpi(d->p + 7, "spinach")) { + d->contents = SPINACH; + d->mntmp = NON_PM; } else { - tmp = tin_variety_txt(p + 7, &tinv); - tvariety = tinv; - mntmp = name_to_mon(p + 7 + tmp); + d->tmp = tin_variety_txt(d->p + 7, &d->tinv); + d->tvariety = d->tinv; + d->mntmp = name_to_mon(d->p + 7 + d->tmp); } - typ = TIN; - goto typfnd; - } else if ((p = strstri(bp, " of ")) != 0 - && (mntmp = name_to_mon(p + 4)) >= LOW_PM) - *p = 0; + d->typ = TIN; + return 2; /*goto typfnd;*/ + } else if ((d->p = strstri(d->bp, " of ")) != 0 + && (d->mntmp = name_to_mon(d->p + 4)) >= LOW_PM) + *d->p = 0; } } /* Find corpse type w/o "of" (red dragon scale mail, yeti corpse) */ - if (strncmpi(bp, "samurai sword", 13) /* not the "samurai" monster! */ - && strncmpi(bp, "wizard lock", 11) /* not the "wizard" monster! */ - && strncmpi(bp, "ninja-to", 8) /* not the "ninja" rank */ - && strncmpi(bp, "master key", 10) /* not the "master" rank */ - && strncmpi(bp, "magenta", 7)) { /* not the "mage" rank */ + if (strncmpi(d->bp, "samurai sword", 13) /* not the "samurai" monster! */ + && strncmpi(d->bp, "wizard lock", 11) /* not the "wizard" monster! */ + && strncmpi(d->bp, "ninja-to", 8) /* not the "ninja" rank */ + && strncmpi(d->bp, "master key", 10) /* not the "master" rank */ + && strncmpi(d->bp, "magenta", 7)) { /* not the "mage" rank */ const char *rest = 0; - if (mntmp < LOW_PM && strlen(bp) > 2 - && (mntmp = name_to_monplus(bp, &rest)) >= LOW_PM) { - char *obp = bp; + if (d->mntmp < LOW_PM && strlen(d->bp) > 2 + && (d->mntmp = name_to_monplus(d->bp, &rest)) >= LOW_PM) { + char *obp = d->bp; /* 'rest' is a pointer past the matching portion; if that was an alternate name or a rank title rather than the canonical monster name we wouldn't otherwise know how much to skip */ - bp = (char *) rest; /* cast away const */ + d->bp = (char *) rest; /* cast away const */ - if (*bp == ' ') { - bp++; - } else if (!strncmpi(bp, "s ", 2) - || (bp > origbp && !strncmpi(bp - 1, "s' ", 3))) { - bp += 2; - } else if (!strncmpi(bp, "es ", 3) - || !strncmpi(bp, "'s ", 3)) { - bp += 3; - } else if (!*bp && !actualn && !dn && !un && !oclass) { + if (*d->bp == ' ') { + d->bp++; + } else if (!strncmpi(d->bp, "s ", 2) + || (d->bp > d->origbp && !strncmpi(d->bp - 1, "s' ", 3))) { + d->bp += 2; + } else if (!strncmpi(d->bp, "es ", 3) + || !strncmpi(d->bp, "'s ", 3)) { + d->bp += 3; + } else if (!*d->bp && !d->actualn && !d->dn && !d->un && !d->oclass) { /* no referent; they don't really mean a monster type */ - bp = obp; - mntmp = NON_PM; + d->bp = obp; + d->mntmp = NON_PM; } } } /* first change to singular if necessary */ - if (*bp + if (*d->bp /* we want "tricks" to match "bag of tricks" [rnd_otyp_by_namedesc()] but that wouldn't work if it gets singularized to "trick" ["tricks bag" matches whether or not this exception is present because singularize operates on "bag" and wishymatch()'s 'of inversion' finds a match] */ - && strcmpi(bp, "tricks") + && strcmpi(d->bp, "tricks") /* an odd potential wish; fail rather than get a false match with "cloth" because it might yield a "cloth spellbook" rather than a "piece of cloth" cloak [maybe we should give random armor?] */ - && strcmpi(bp, "clothes") + && strcmpi(d->bp, "clothes") ) { - char *sng = makesingular(bp); + char *sng = makesingular(d->bp); - if (strcmp(bp, sng)) { - if (cnt == 1) - cnt = 2; - Strcpy(bp, sng); + if (strcmp(d->bp, sng)) { + if (d->cnt == 1) + d->cnt = 2; + Strcpy(d->bp, sng); } } @@ -3692,53 +3692,53 @@ struct obj *no_wish; const struct alt_spellings *as = spellings; while (as->sp) { - if (wishymatch(bp, as->sp, TRUE)) { - typ = as->ob; - goto typfnd; + if (wishymatch(d->bp, as->sp, TRUE)) { + d->typ = as->ob; + return 2; /*goto typfnd;*/ } as++; } /* can't use spellings list for this one due to shuffling */ - if (!strncmpi(bp, "grey spell", 10)) - *(bp + 2) = 'a'; + if (!strncmpi(d->bp, "grey spell", 10)) + *(d->bp + 2) = 'a'; - if ((p = strstri(bp, "armour")) != 0) { + if ((d->p = strstri(d->bp, "armour")) != 0) { /* skip past "armo", then copy remainder beyond "u" */ - p += 4; - while ((*p = *(p + 1)) != '\0') - ++p; /* self terminating */ + d->p += 4; + while ((*d->p = *(d->p + 1)) != '\0') + ++d->p; /* self terminating */ } } /* dragon scales - assumes order of dragons */ - if (!strcmpi(bp, "scales") && mntmp >= PM_GRAY_DRAGON - && mntmp <= PM_YELLOW_DRAGON) { - typ = GRAY_DRAGON_SCALES + mntmp - PM_GRAY_DRAGON; - mntmp = NON_PM; /* no monster */ - goto typfnd; + if (!strcmpi(d->bp, "scales") && d->mntmp >= PM_GRAY_DRAGON + && d->mntmp <= PM_YELLOW_DRAGON) { + d->typ = GRAY_DRAGON_SCALES + d->mntmp - PM_GRAY_DRAGON; + d->mntmp = NON_PM; /* no monster */ + return 2; /*goto typfnd;*/ } - p = eos(bp); - if (!BSTRCMPI(bp, p - 10, "holy water")) { - typ = POT_WATER; - if ((p - bp) >= 12 && *(p - 12) == 'u') - iscursed = 1; /* unholy water */ + d->p = eos(d->bp); + if (!BSTRCMPI(d->bp, d->p - 10, "holy water")) { + d->typ = POT_WATER; + if ((d->p - d->bp) >= 12 && *(d->p - 12) == 'u') + d->iscursed = 1; /* unholy water */ else - blessed = 1; - goto typfnd; + d->blessed = 1; + return 2; /*goto typfnd;*/ } - if (unlabeled && !BSTRCMPI(bp, p - 6, "scroll")) { - typ = SCR_BLANK_PAPER; - goto typfnd; + if (d->unlabeled && !BSTRCMPI(d->bp, d->p - 6, "scroll")) { + d->typ = SCR_BLANK_PAPER; + return 2; /*goto typfnd;*/ } - if (unlabeled && !BSTRCMPI(bp, p - 9, "spellbook")) { - typ = SPE_BLANK_PAPER; - goto typfnd; + if (d->unlabeled && !BSTRCMPI(d->bp, d->p - 9, "spellbook")) { + d->typ = SPE_BLANK_PAPER; + return 2; /*goto typfnd;*/ } /* specific food rather than color of gem/potion/spellbook[/scales] */ - if (!BSTRCMPI(bp, p - 6, "orange") && mntmp == NON_PM) { - typ = ORANGE; - goto typfnd; + if (!BSTRCMPI(d->bp, d->p - 6, "orange") && d->mntmp == NON_PM) { + d->typ = ORANGE; + return 2; /*goto typfnd;*/ } /* * NOTE: Gold pieces are handled as objects nowadays, and therefore @@ -3746,62 +3746,62 @@ struct obj *no_wish; * gold/money concept. Maybe we want to add other monetary units as * well in the future. (TH) */ - if (!BSTRCMPI(bp, p - 10, "gold piece") - || !BSTRCMPI(bp, p - 7, "zorkmid") - || !strcmpi(bp, "gold") || !strcmpi(bp, "money") - || !strcmpi(bp, "coin") || *bp == GOLD_SYM) { - if (cnt > 5000 && !wizard) - cnt = 5000; - else if (cnt < 1) - cnt = 1; - otmp = mksobj(GOLD_PIECE, FALSE, FALSE); - otmp->quan = (long) cnt; - otmp->owt = weight(otmp); + if (!BSTRCMPI(d->bp, d->p - 10, "gold piece") + || !BSTRCMPI(d->bp, d->p - 7, "zorkmid") + || !strcmpi(d->bp, "gold") || !strcmpi(d->bp, "money") + || !strcmpi(d->bp, "coin") || *d->bp == GOLD_SYM) { + if (d->cnt > 5000 && !wizard) + d->cnt = 5000; + else if (d->cnt < 1) + d->cnt = 1; + d->otmp = mksobj(GOLD_PIECE, FALSE, FALSE); + d->otmp->quan = (long) d->cnt; + d->otmp->owt = weight(d->otmp); g.context.botl = 1; - return otmp; + return 3; /*return otmp;*/ } /* check for single character object class code ("/" for wand, &c) */ - if (strlen(bp) == 1 && (i = def_char_to_objclass(*bp)) < MAXOCLASSES + if (strlen(d->bp) == 1 && (i = def_char_to_objclass(*d->bp)) < MAXOCLASSES && i > ILLOBJ_CLASS && (i != VENOM_CLASS || wizard)) { - oclass = i; - goto any; + d->oclass = i; + return 4; /*goto any;*/ } /* Search for class names: XXXXX potion, scroll of XXXXX. Avoid */ /* false hits on, e.g., rings for "ring mail". */ - if (strncmpi(bp, "enchant ", 8) - && strncmpi(bp, "destroy ", 8) - && strncmpi(bp, "detect food", 11) - && strncmpi(bp, "food detection", 14) - && strncmpi(bp, "ring mail", 9) - && strncmpi(bp, "studded leather armor", 21) - && strncmpi(bp, "leather armor", 13) - && strncmpi(bp, "tooled horn", 11) - && strncmpi(bp, "food ration", 11) - && strncmpi(bp, "meat ring", 9)) + if (strncmpi(d->bp, "enchant ", 8) + && strncmpi(d->bp, "destroy ", 8) + && strncmpi(d->bp, "detect food", 11) + && strncmpi(d->bp, "food detection", 14) + && strncmpi(d->bp, "ring mail", 9) + && strncmpi(d->bp, "studded leather armor", 21) + && strncmpi(d->bp, "leather armor", 13) + && strncmpi(d->bp, "tooled horn", 11) + && strncmpi(d->bp, "food ration", 11) + && strncmpi(d->bp, "meat ring", 9)) for (i = 0; i < (int) (sizeof wrpsym); i++) { register int j = strlen(wrp[i]); - if (!strncmpi(bp, wrp[i], j)) { - oclass = wrpsym[i]; - if (oclass != AMULET_CLASS) { - bp += j; - if (!strncmpi(bp, " of ", 4)) - actualn = bp + 4; + if (!strncmpi(d->bp, wrp[i], j)) { + d->oclass = wrpsym[i]; + if (d->oclass != AMULET_CLASS) { + d->bp += j; + if (!strncmpi(d->bp, " of ", 4)) + d->actualn = d->bp + 4; /* else if(*bp) ?? */ } else - actualn = bp; - goto srch; + d->actualn = d->bp; + return 1; /*goto srch;*/ } - if (!BSTRCMPI(bp, p - j, wrp[i])) { - oclass = wrpsym[i]; - p -= j; - *p = 0; - if (p > bp && p[-1] == ' ') - p[-1] = 0; - actualn = dn = bp; - goto srch; + if (!BSTRCMPI(d->bp, d->p - j, wrp[i])) { + d->oclass = wrpsym[i]; + d->p -= j; + *d->p = 0; + if (d->p > d->bp && d->p[-1] == ' ') + d->p[-1] = 0; + d->actualn = d->dn = d->bp; + return 1; /*goto srch;*/ } } @@ -3821,51 +3821,61 @@ struct obj *no_wish; * " object", but " trap" is suggested--to either the trap * name or the object name. */ - if (wizard && (!strncmpi(bp, "bear", 4) || !strncmpi(bp, "land", 4))) { - boolean beartrap = (lowc(*bp) == 'b'); - char *zp = bp + 4; /* skip "bear"/"land" */ + if (wizard && (!strncmpi(d->bp, "bear", 4) || !strncmpi(d->bp, "land", 4))) { + boolean beartrap = (lowc(*d->bp) == 'b'); + char *zp = d->bp + 4; /* skip "bear"/"land" */ if (*zp == ' ') ++zp; /* embedded space is optional */ if (!strncmpi(zp, beartrap ? "trap" : "mine", 4)) { zp += 4; - if (trapped == 2 || !strcmpi(zp, " object")) { + if (d->trapped == 2 || !strcmpi(zp, " object")) { /* "untrapped " or " object" */ - typ = beartrap ? BEARTRAP : LAND_MINE; - goto typfnd; - } else if (trapped == 1 || *zp != '\0') { + d->typ = beartrap ? BEARTRAP : LAND_MINE; + return 2; /*goto typfnd;*/ + } else if (d->trapped == 1 || *zp != '\0') { /* "trapped " or " trap" (actually "*") */ /* use canonical trap spelling, skip object matching */ - Strcpy(bp, trapname(beartrap ? BEAR_TRAP : LANDMINE, TRUE)); - goto wiztrap; + Strcpy(d->bp, trapname(beartrap ? BEAR_TRAP : LANDMINE, TRUE)); + return 5; /*goto wiztrap;*/ } /* [no prefix or suffix; we're going to end up matching the object name and getting a disarmed trap object] */ } } - retry: + return 0; +} + +static int +readobjnam_postparse2(d) +struct _readobjnam_data *d; +{ + int i; + /* "grey stone" check must be before general "stone" */ for (i = 0; i < SIZE(o_ranges); i++) - if (!strcmpi(bp, o_ranges[i].name)) { - typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range); - goto typfnd; + if (!strcmpi(d->bp, o_ranges[i].name)) { + d->typ = rnd_class(o_ranges[i].f_o_range, o_ranges[i].l_o_range); + return 2; /*goto typfnd;*/ } - if (!BSTRCMPI(bp, p - 6, " stone") || !BSTRCMPI(bp, p - 4, " gem")) { - p[!strcmpi(p - 4, " gem") ? -4 : -6] = '\0'; - oclass = GEM_CLASS; - dn = actualn = bp; - goto srch; - } else if (!strcmpi(bp, "looking glass")) { + if (!BSTRCMPI(d->bp, d->p - 6, " stone") || !BSTRCMPI(d->bp, d->p - 4, " gem")) { + d->p[!strcmpi(d->p - 4, " gem") ? -4 : -6] = '\0'; + d->oclass = GEM_CLASS; + d->dn = d->actualn = d->bp; + return 1; /*goto srch;*/ + } else if (!strcmpi(d->bp, "looking glass")) { ; /* avoid false hit on "* glass" */ - } else if (!BSTRCMPI(bp, p - 6, " glass") || !strcmpi(bp, "glass")) { - register char *s = bp; + } else if (!BSTRCMPI(d->bp, d->p - 6, " glass") || !strcmpi(d->bp, "glass")) { + register char *s = d->bp; /* treat "broken glass" as a non-existent item; since "broken" is also a chest/box prefix it might have been stripped off above */ - if (broken || strstri(s, "broken")) - return (struct obj *) 0; + if (d->broken || strstri(s, "broken")) { + d->otmp = (struct obj *) 0; + return 3; /* return otmp */ + } if (!strncmpi(s, "worthless ", 10)) s += 10; if (!strncmpi(s, "piece of ", 9)) @@ -3876,59 +3886,68 @@ struct obj *no_wish; s += 9; if (!strcmpi(s, "glass")) { /* choose random color */ /* 9 different kinds */ - typ = LAST_GEM + rnd(9); - if (objects[typ].oc_class == GEM_CLASS) - goto typfnd; + d->typ = LAST_GEM + rnd(9); + if (objects[d->typ].oc_class == GEM_CLASS) + return 2; /*goto typfnd;*/ else - typ = 0; /* somebody changed objects[]? punt */ + d->typ = 0; /* somebody changed objects[]? punt */ } else { /* try to construct canonical form */ char tbuf[BUFSZ]; Strcpy(tbuf, "worthless piece of "); Strcat(tbuf, s); /* assume it starts with the color */ - Strcpy(bp, tbuf); + Strcpy(d->bp, tbuf); } } - actualn = bp; - if (!dn) - dn = actualn; /* ex. "skull cap" */ - srch: + d->actualn = d->bp; + if (!d->dn) + d->dn = d->actualn; /* ex. "skull cap" */ + + return 0; +} + +static int +readobjnam_postparse3(d) +struct _readobjnam_data *d; +{ + int i; + /* check real names of gems first */ - if (!oclass && actualn) { + if (!d->oclass && d->actualn) { for (i = g.bases[GEM_CLASS]; i <= LAST_GEM; i++) { register const char *zn; - if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(actualn, zn)) { - typ = i; - goto typfnd; + if ((zn = OBJ_NAME(objects[i])) != 0 && !strcmpi(d->actualn, zn)) { + d->typ = i; + return 2; /*goto typfnd;*/ } } /* "tin of foo" would be caught above, but plain "tin" has a random chance of yielding "tin wand" unless we do this */ - if (!strcmpi(actualn, "tin")) { - typ = TIN; - goto typfnd; + if (!strcmpi(d->actualn, "tin")) { + d->typ = TIN; + return 2; /*goto typfnd;*/ } } - if (((typ = rnd_otyp_by_namedesc(actualn, oclass, 1)) != STRANGE_OBJECT) - || (dn != actualn - && (typ = rnd_otyp_by_namedesc(dn, oclass, 1)) != STRANGE_OBJECT) - || ((typ = rnd_otyp_by_namedesc(un, oclass, 1)) != STRANGE_OBJECT) - || (origbp != actualn - && ((typ = rnd_otyp_by_namedesc(origbp, oclass, 1)) + if (((d->typ = rnd_otyp_by_namedesc(d->actualn, d->oclass, 1)) != STRANGE_OBJECT) + || (d->dn != d->actualn + && (d->typ = rnd_otyp_by_namedesc(d->dn, d->oclass, 1)) != STRANGE_OBJECT) + || ((d->typ = rnd_otyp_by_namedesc(d->un, d->oclass, 1)) != STRANGE_OBJECT) + || (d->origbp != d->actualn + && ((d->typ = rnd_otyp_by_namedesc(d->origbp, d->oclass, 1)) != STRANGE_OBJECT))) - goto typfnd; - typ = 0; + return 2; /*goto typfnd;*/ + d->typ = 0; - if (actualn) { + if (d->actualn) { struct Jitem *j = Japanese_items; while (j->item) { - if (actualn && !strcmpi(actualn, j->name)) { - typ = j->item; - goto typfnd; + if (d->actualn && !strcmpi(d->actualn, j->name)) { + d->typ = j->item; + return 2; /*goto typfnd;*/ } j++; } @@ -3936,17 +3955,31 @@ struct obj *no_wish; /* if we've stripped off "armor" and failed to match anything in objects[], append "mail" and try again to catch misnamed requests like "plate armor" and "yellow dragon scale armor" */ - if (oclass == ARMOR_CLASS && !strstri(bp, "mail")) { + if (d->oclass == ARMOR_CLASS && !strstri(d->bp, "mail")) { /* modifying bp's string is ok; we're about to resort to random armor if this also fails to match anything */ - Strcat(bp, " mail"); - goto retry; + Strcat(d->bp, " mail"); + return 6; /*goto retry;*/ } - if (!strcmpi(bp, "spinach")) { - contents = SPINACH; - typ = TIN; - goto typfnd; + if (!strcmpi(d->bp, "spinach")) { + d->contents = SPINACH; + d->typ = TIN; + return 2; /*goto typfnd;*/ } + /* Fruits must not mess up the ability to wish for real objects (since + * you can leave a fruit in a bones file and it will be added to + * another person's game), so they must be checked for last, after + * stripping all the possible prefixes and seeing if there's a real + * name in there. So we have to save the full original name. However, + * it's still possible to do things like "uncursed burnt Alaska", + * or worse yet, "2 burned 5 course meals", so we need to loop to + * strip off the prefixes again, this time stripping only the ones + * possible on food. + * We could get even more detailed so as to allow food names with + * prefixes that _are_ possible on food, so you could wish for + * "2 3 alarm chilis". Currently this isn't allowed; options.c + * automatically sticks 'candied' in front of such names. + */ /* Note: not strcmpi. 2 fruits, one capital, one not, are possible. Also not strncmp. We used to ignore trailing text with it, but that resulted in "grapefruit" matching "grape" if the latter came @@ -3955,11 +3988,12 @@ struct obj *no_wish; char *fp; int l, cntf; int blessedf, iscursedf, uncursedf, halfeatenf; + struct fruit *f; blessedf = iscursedf = uncursedf = halfeatenf = 0; cntf = 0; - fp = fruitbuf; + fp = d->fruitbuf; for (;;) { if (!fp || !*fp) break; @@ -3997,11 +4031,11 @@ struct obj *no_wish; else if (!strcmp(fp, makeplural(f->fname))) ftyp = 3; if (ftyp) { - typ = SLIME_MOLD; - blessed = blessedf; - iscursed = iscursedf; - uncursed = uncursedf; - halfeaten = halfeatenf; + d->typ = SLIME_MOLD; + d->blessed = blessedf; + d->iscursed = iscursedf; + d->uncursed = uncursedf; + d->halfeaten = halfeatenf; /* adjust count if user explicitly asked for singular amount (can't happen unless fruit has been given an already pluralized name) @@ -4010,24 +4044,98 @@ struct obj *no_wish; cntf = 1; else if (ftyp == 3 && !cntf) cntf = 2; - cnt = cntf; - ftype = f->fid; - goto typfnd; + d->cnt = cntf; + d->ftype = f->fid; + return 2; /*goto typfnd;*/ } } } - if (!oclass && actualn) { + if (!d->oclass && d->actualn) { short objtyp; /* Perhaps it's an artifact specified by name, not type */ - name = artifact_name(actualn, &objtyp); - if (name) { - typ = objtyp; - goto typfnd; + d->name = artifact_name(d->actualn, &objtyp); + if (d->name) { + d->typ = objtyp; + return 2; /*goto typfnd;*/ } } + return 0; +} + + +/* + * Return something wished for. Specifying a null pointer for + * the user request string results in a random object. Otherwise, + * if asking explicitly for "nothing" (or "nil") return no_wish; + * if not an object return &cg.zeroobj; if an error (no matching object), + * return null. + */ +struct obj * +readobjnam(bp, no_wish) +register char *bp; +struct obj *no_wish; +{ + register char *p; + struct _readobjnam_data d; + + readobjnam_init(bp, &d); + + if (!bp) + goto any; + /* first, remove extra whitespace they may have typed */ + (void) mungspaces(bp); + /* allow wishing for "nothing" to preserve wishless conduct... + [now requires "wand of nothing" if that's what was really wanted] */ + if (!strcmpi(bp, "nothing") || !strcmpi(bp, "nil") + || !strcmpi(bp, "none")) + return no_wish; + /* save the [nearly] unmodified choice string */ + Strcpy(d.fruitbuf, bp); + + if (readobjnam_preparse(&d)) + goto any; + + if (!d.cnt) + d.cnt = 1; /* will be changed to 2 if makesingular() changes string */ + + readobjnam_parse_charges(&d); + + switch (readobjnam_postparse1(&d)) { + default: + case 0: break; + case 1: goto srch; + case 2: goto typfnd; + case 3: return d.otmp; + case 4: goto any; + case 5: goto wiztrap; + } + + retry: + switch (readobjnam_postparse2(&d)) { + default: + case 0: break; + case 1: goto srch; + case 2: goto typfnd; + case 3: return d.otmp; + case 4: goto any; + case 5: goto wiztrap; + } + + srch: + switch (readobjnam_postparse3(&d)) { + default: + case 0: break; + case 1: goto srch; + case 2: goto typfnd; + case 3: return d.otmp; + case 4: goto any; + case 5: goto wiztrap; + case 6: goto retry; + } + /* * Let wizards wish for traps and furniture. * Must come after objects check so wizards can still wish for @@ -4037,50 +4145,50 @@ struct obj *no_wish; wiztrap: if (wizard && !g.program_state.wizkit_wishing) { /* [inline code moved to separate routine to unclutter readobjnam] */ - if ((otmp = wizterrainwish(bp, p, locked, trapped)) != 0) - return otmp; + if ((d.otmp = wizterrainwish(d.bp, p, d.locked, d.trapped)) != 0) + return d.otmp; } - if (!oclass && !typ) { - if (!strncmpi(bp, "polearm", 7)) { - typ = rnd_otyp_by_wpnskill(P_POLEARMS); + if (!d.oclass && !d.typ) { + if (!strncmpi(d.bp, "polearm", 7)) { + d.typ = rnd_otyp_by_wpnskill(P_POLEARMS); goto typfnd; - } else if (!strncmpi(bp, "hammer", 6)) { - typ = rnd_otyp_by_wpnskill(P_HAMMER); + } else if (!strncmpi(d.bp, "hammer", 6)) { + d.typ = rnd_otyp_by_wpnskill(P_HAMMER); goto typfnd; } } - if (!oclass) + if (!d.oclass) return ((struct obj *) 0); any: - if (!oclass) - oclass = wrpsym[rn2((int) sizeof wrpsym)]; + if (!d.oclass) + d.oclass = wrpsym[rn2((int) sizeof wrpsym)]; typfnd: - if (typ) - oclass = objects[typ].oc_class; + if (d.typ) + d.oclass = objects[d.typ].oc_class; /* handle some objects that are only allowed in wizard mode */ - if (typ && !wizard) { - switch (typ) { + if (d.typ && !wizard) { + switch (d.typ) { case AMULET_OF_YENDOR: - typ = FAKE_AMULET_OF_YENDOR; + d.typ = FAKE_AMULET_OF_YENDOR; break; case CANDELABRUM_OF_INVOCATION: - typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE); + d.typ = rnd_class(TALLOW_CANDLE, WAX_CANDLE); break; case BELL_OF_OPENING: - typ = BELL; + d.typ = BELL; break; case SPE_BOOK_OF_THE_DEAD: - typ = SPE_BLANK_PAPER; + d.typ = SPE_BLANK_PAPER; break; case MAGIC_LAMP: - typ = OIL_LAMP; + d.typ = OIL_LAMP; break; default: /* catch any other non-wishable objects (venom) */ - if (objects[typ].oc_nowish) + if (objects[d.typ].oc_nowish) return (struct obj *) 0; break; } @@ -4088,76 +4196,76 @@ struct obj *no_wish; /* if asking for corpse of a monster which leaves behind a glob, give glob instead of rejecting the monster type to create random corpse */ - if (typ == CORPSE && mntmp >= LOW_PM && mons[mntmp].mlet == S_PUDDING) { - typ = GLOB_OF_GRAY_OOZE + (mntmp - PM_GRAY_OOZE); - mntmp = NON_PM; /* not used for globs */ + if (d.typ == CORPSE && d.mntmp >= LOW_PM && mons[d.mntmp].mlet == S_PUDDING) { + d.typ = GLOB_OF_GRAY_OOZE + (d.mntmp - PM_GRAY_OOZE); + d.mntmp = NON_PM; /* not used for globs */ } /* * Create the object, then fine-tune it. */ - otmp = typ ? mksobj(typ, TRUE, FALSE) : mkobj(oclass, FALSE); - typ = otmp->otyp, oclass = otmp->oclass; /* what we actually got */ + d.otmp = d.typ ? mksobj(d.typ, TRUE, FALSE) : mkobj(d.oclass, FALSE); + d.typ = d.otmp->otyp, d.oclass = d.otmp->oclass; /* what we actually got */ - if (islit && (typ == OIL_LAMP || typ == MAGIC_LAMP || typ == BRASS_LANTERN - || Is_candle(otmp) || typ == POT_OIL)) { - place_object(otmp, u.ux, u.uy); /* make it viable light source */ - begin_burn(otmp, FALSE); - obj_extract_self(otmp); /* now release it for caller's use */ + if (d.islit && (d.typ == OIL_LAMP || d.typ == MAGIC_LAMP || d.typ == BRASS_LANTERN + || Is_candle(d.otmp) || d.typ == POT_OIL)) { + place_object(d.otmp, u.ux, u.uy); /* make it viable light source */ + begin_burn(d.otmp, FALSE); + obj_extract_self(d.otmp); /* now release it for caller's use */ } /* if player specified a reasonable count, maybe honor it */ - if (cnt > 0 && objects[typ].oc_merge - && (wizard || cnt < rnd(6) || (cnt <= 7 && Is_candle(otmp)) - || (cnt <= 20 && ((oclass == WEAPON_CLASS && is_ammo(otmp)) - || typ == ROCK || is_missile(otmp))))) - otmp->quan = (long) cnt; + if (d.cnt > 0 && objects[d.typ].oc_merge + && (wizard || d.cnt < rnd(6) || (d.cnt <= 7 && Is_candle(d.otmp)) + || (d.cnt <= 20 && ((d.oclass == WEAPON_CLASS && is_ammo(d.otmp)) + || d.typ == ROCK || is_missile(d.otmp))))) + d.otmp->quan = (long) d.cnt; - if (oclass == VENOM_CLASS) - otmp->spe = 1; + if (d.oclass == VENOM_CLASS) + d.otmp->spe = 1; - if (spesgn == 0) { - spe = otmp->spe; + if (d.spesgn == 0) { + d.spe = d.otmp->spe; } else if (wizard) { ; /* no alteration to spe */ - } else if (oclass == ARMOR_CLASS || oclass == WEAPON_CLASS - || is_weptool(otmp) - || (oclass == RING_CLASS && objects[typ].oc_charged)) { - if (spe > rnd(5) && spe > otmp->spe) - spe = 0; - if (spe > 2 && Luck < 0) - spesgn = -1; + } else if (d.oclass == ARMOR_CLASS || d.oclass == WEAPON_CLASS + || is_weptool(d.otmp) + || (d.oclass == RING_CLASS && objects[d.typ].oc_charged)) { + if (d.spe > rnd(5) && d.spe > d.otmp->spe) + d.spe = 0; + if (d.spe > 2 && Luck < 0) + d.spesgn = -1; } else { - if (oclass == WAND_CLASS) { - if (spe > 1 && spesgn == -1) - spe = 1; + if (d.oclass == WAND_CLASS) { + if (d.spe > 1 && d.spesgn == -1) + d.spe = 1; } else { - if (spe > 0 && spesgn == -1) - spe = 0; + if (d.spe > 0 && d.spesgn == -1) + d.spe = 0; } - if (spe > otmp->spe) - spe = otmp->spe; + if (d.spe > d.otmp->spe) + d.spe = d.otmp->spe; } - if (spesgn == -1) - spe = -spe; + if (d.spesgn == -1) + d.spe = -d.spe; /* set otmp->spe. This may, or may not, use spe... */ - switch (typ) { + switch (d.typ) { case TIN: - if (contents == EMPTY) { - otmp->corpsenm = NON_PM; - otmp->spe = 0; - } else if (contents == SPINACH) { - otmp->corpsenm = NON_PM; - otmp->spe = 1; + if (d.contents == EMPTY) { + d.otmp->corpsenm = NON_PM; + d.otmp->spe = 0; + } else if (d.contents == SPINACH) { + d.otmp->corpsenm = NON_PM; + d.otmp->spe = 1; } break; case TOWEL: - if (wetness) - otmp->spe = wetness; + if (d.wetness) + d.otmp->spe = d.wetness; break; case SLIME_MOLD: - otmp->spe = ftype; + d.otmp->spe = d.ftype; /* Fall through */ case SKELETON_KEY: case CHEST: @@ -4171,76 +4279,76 @@ struct obj *no_wish; case SCR_MAIL: /* 0: delivered in-game via external event (or randomly for fake mail); 1: from bones or wishing; 2: written with marker */ - otmp->spe = 1; + d.otmp->spe = 1; break; #endif case WAN_WISHING: if (!wizard) { - otmp->spe = (rn2(10) ? -1 : 0); + d.otmp->spe = (rn2(10) ? -1 : 0); break; } /*FALLTHRU*/ default: - otmp->spe = spe; + d.otmp->spe = d.spe; } /* set otmp->corpsenm or dragon scale [mail] */ - if (mntmp >= LOW_PM) { + if (d.mntmp >= LOW_PM) { int humanwere; - if (mntmp == PM_LONG_WORM_TAIL) - mntmp = PM_LONG_WORM; + if (d.mntmp == PM_LONG_WORM_TAIL) + d.mntmp = PM_LONG_WORM; /* werecreatures in beast form are all flagged no-corpse so for corpses and tins, switch to their corresponding human form; for figurines, override the can't-be-human restriction instead */ - if (typ != FIGURINE && is_were(&mons[mntmp]) - && (g.mvitals[mntmp].mvflags & G_NOCORPSE) != 0 - && (humanwere = counter_were(mntmp)) != NON_PM) - mntmp = humanwere; + if (d.typ != FIGURINE && is_were(&mons[d.mntmp]) + && (g.mvitals[d.mntmp].mvflags & G_NOCORPSE) != 0 + && (humanwere = counter_were(d.mntmp)) != NON_PM) + d.mntmp = humanwere; - switch (typ) { + switch (d.typ) { case TIN: - otmp->spe = 0; /* No spinach */ - if (dead_species(mntmp, FALSE)) { - otmp->corpsenm = NON_PM; /* it's empty */ - } else if ((!(mons[mntmp].geno & G_UNIQ) || wizard) - && !(g.mvitals[mntmp].mvflags & G_NOCORPSE) - && mons[mntmp].cnutrit != 0) { - otmp->corpsenm = mntmp; + d.otmp->spe = 0; /* No spinach */ + if (dead_species(d.mntmp, FALSE)) { + d.otmp->corpsenm = NON_PM; /* it's empty */ + } else if ((!(mons[d.mntmp].geno & G_UNIQ) || wizard) + && !(g.mvitals[d.mntmp].mvflags & G_NOCORPSE) + && mons[d.mntmp].cnutrit != 0) { + d.otmp->corpsenm = d.mntmp; } break; case CORPSE: - if ((!(mons[mntmp].geno & G_UNIQ) || wizard) - && !(g.mvitals[mntmp].mvflags & G_NOCORPSE)) { - if (mons[mntmp].msound == MS_GUARDIAN) - mntmp = genus(mntmp, 1); - set_corpsenm(otmp, mntmp); + if ((!(mons[d.mntmp].geno & G_UNIQ) || wizard) + && !(g.mvitals[d.mntmp].mvflags & G_NOCORPSE)) { + if (mons[d.mntmp].msound == MS_GUARDIAN) + d.mntmp = genus(d.mntmp, 1); + set_corpsenm(d.otmp, d.mntmp); } break; case EGG: - mntmp = can_be_hatched(mntmp); + d.mntmp = can_be_hatched(d.mntmp); /* this also sets hatch timer if appropriate */ - set_corpsenm(otmp, mntmp); + set_corpsenm(d.otmp, d.mntmp); break; case FIGURINE: - if (!(mons[mntmp].geno & G_UNIQ) - && (!is_human(&mons[mntmp]) || is_were(&mons[mntmp])) + if (!(mons[d.mntmp].geno & G_UNIQ) + && (!is_human(&mons[d.mntmp]) || is_were(&mons[d.mntmp])) #ifdef MAIL_STRUCTURES - && mntmp != PM_MAIL_DAEMON + && d.mntmp != PM_MAIL_DAEMON #endif ) - otmp->corpsenm = mntmp; + d.otmp->corpsenm = d.mntmp; break; case STATUE: - otmp->corpsenm = mntmp; - if (Has_contents(otmp) && verysmall(&mons[mntmp])) - delete_contents(otmp); /* no spellbook */ - otmp->spe = ishistoric ? STATUE_HISTORIC : 0; + d.otmp->corpsenm = d.mntmp; + if (Has_contents(d.otmp) && verysmall(&mons[d.mntmp])) + delete_contents(d.otmp); /* no spellbook */ + d.otmp->spe = d.ishistoric ? STATUE_HISTORIC : 0; break; case SCALE_MAIL: /* Dragon mail - depends on the order of objects & dragons. */ - if (mntmp >= PM_GRAY_DRAGON && mntmp <= PM_YELLOW_DRAGON) - otmp->otyp = GRAY_DRAGON_SCALE_MAIL + mntmp - PM_GRAY_DRAGON; + if (d.mntmp >= PM_GRAY_DRAGON && d.mntmp <= PM_YELLOW_DRAGON) + d.otmp->otyp = GRAY_DRAGON_SCALE_MAIL + d.mntmp - PM_GRAY_DRAGON; break; } } @@ -4248,143 +4356,143 @@ struct obj *no_wish; /* set blessed/cursed -- setting the fields directly is safe * since weight() is called below and addinv() will take care * of luck */ - if (iscursed) { - curse(otmp); - } else if (uncursed) { - otmp->blessed = 0; - otmp->cursed = (Luck < 0 && !wizard); - } else if (blessed) { - otmp->blessed = (Luck >= 0 || wizard); - otmp->cursed = (Luck < 0 && !wizard); - } else if (spesgn < 0) { - curse(otmp); + if (d.iscursed) { + curse(d.otmp); + } else if (d.uncursed) { + d.otmp->blessed = 0; + d.otmp->cursed = (Luck < 0 && !wizard); + } else if (d.blessed) { + d.otmp->blessed = (Luck >= 0 || wizard); + d.otmp->cursed = (Luck < 0 && !wizard); + } else if (d.spesgn < 0) { + curse(d.otmp); } /* set eroded and erodeproof */ - if (erosion_matters(otmp)) { - if (eroded && (is_flammable(otmp) || is_rustprone(otmp))) - otmp->oeroded = eroded; - if (eroded2 && (is_corrodeable(otmp) || is_rottable(otmp))) - otmp->oeroded2 = eroded2; + if (erosion_matters(d.otmp)) { + if (d.eroded && (is_flammable(d.otmp) || is_rustprone(d.otmp))) + d.otmp->oeroded = d.eroded; + if (d.eroded2 && (is_corrodeable(d.otmp) || is_rottable(d.otmp))) + d.otmp->oeroded2 = d.eroded2; /* * 3.6.1: earlier versions included `&& !eroded && !eroded2' here, * but damageproof combined with damaged is feasible (eroded * armor modified by confused reading of cursed destroy armor) * so don't prevent player from wishing for such a combination. */ - if (erodeproof && (is_damageable(otmp) || otmp->otyp == CRYSKNIFE)) - otmp->oerodeproof = (Luck >= 0 || wizard); + if (d.erodeproof && (is_damageable(d.otmp) || d.otmp->otyp == CRYSKNIFE)) + d.otmp->oerodeproof = (Luck >= 0 || wizard); } /* set otmp->recharged */ - if (oclass == WAND_CLASS) { + if (d.oclass == WAND_CLASS) { /* prevent wishing abuse */ - if (otmp->otyp == WAN_WISHING && !wizard) - rechrg = 1; - otmp->recharged = (unsigned) rechrg; + if (d.otmp->otyp == WAN_WISHING && !wizard) + d.rechrg = 1; + d.otmp->recharged = (unsigned) d.rechrg; } /* set poisoned */ - if (ispoisoned) { - if (is_poisonable(otmp)) - otmp->opoisoned = (Luck >= 0); - else if (oclass == FOOD_CLASS) + if (d.ispoisoned) { + if (is_poisonable(d.otmp)) + d.otmp->opoisoned = (Luck >= 0); + else if (d.oclass == FOOD_CLASS) /* try to taint by making it as old as possible */ - otmp->age = 1L; + d.otmp->age = 1L; } /* and [un]trapped */ - if (trapped) { - if (Is_box(otmp) || typ == TIN) - otmp->otrapped = (trapped == 1); + if (d.trapped) { + if (Is_box(d.otmp) || d.typ == TIN) + d.otmp->otrapped = (d.trapped == 1); } /* empty for containers rather than for tins */ - if (contents == EMPTY) { - if (otmp->otyp == BAG_OF_TRICKS || otmp->otyp == HORN_OF_PLENTY) { - if (otmp->spe > 0) - otmp->spe = 0; - } else if (Has_contents(otmp)) { + if (d.contents == EMPTY) { + if (d.otmp->otyp == BAG_OF_TRICKS || d.otmp->otyp == HORN_OF_PLENTY) { + if (d.otmp->spe > 0) + d.otmp->spe = 0; + } else if (Has_contents(d.otmp)) { /* this assumes that artifacts can't be randomly generated inside containers */ - delete_contents(otmp); - otmp->owt = weight(otmp); + delete_contents(d.otmp); + d.otmp->owt = weight(d.otmp); } } /* set locked/unlocked/broken */ - if (Is_box(otmp)) { - if (locked) { - otmp->olocked = 1, otmp->obroken = 0; - } else if (unlocked) { - otmp->olocked = 0, otmp->obroken = 0; - } else if (broken) { - otmp->olocked = 0, otmp->obroken = 1; + if (Is_box(d.otmp)) { + if (d.locked) { + d.otmp->olocked = 1, d.otmp->obroken = 0; + } else if (d.unlocked) { + d.otmp->olocked = 0, d.otmp->obroken = 0; + } else if (d.broken) { + d.otmp->olocked = 0, d.otmp->obroken = 1; } } - if (isgreased) - otmp->greased = 1; + if (d.isgreased) + d.otmp->greased = 1; - if (isdiluted && otmp->oclass == POTION_CLASS && otmp->otyp != POT_WATER) - otmp->odiluted = 1; + if (d.isdiluted && d.otmp->oclass == POTION_CLASS && d.otmp->otyp != POT_WATER) + d.otmp->odiluted = 1; /* set tin variety */ - if (otmp->otyp == TIN && tvariety >= 0 && (rn2(4) || wizard)) - set_tin_variety(otmp, tvariety); + if (d.otmp->otyp == TIN && d.tvariety >= 0 && (rn2(4) || wizard)) + set_tin_variety(d.otmp, d.tvariety); - if (name) { + if (d.name) { const char *aname; short objtyp; /* an artifact name might need capitalization fixing */ - aname = artifact_name(name, &objtyp); - if (aname && objtyp == otmp->otyp) - name = aname; + aname = artifact_name(d.name, &objtyp); + if (aname && objtyp == d.otmp->otyp) + d.name = aname; /* 3.6 tribute - fix up novel */ - if (otmp->otyp == SPE_NOVEL) { + if (d.otmp->otyp == SPE_NOVEL) { const char *novelname; - novelname = lookup_novel(name, &otmp->novelidx); + novelname = lookup_novel(d.name, &d.otmp->novelidx); if (novelname) - name = novelname; + d.name = novelname; } - otmp = oname(otmp, name); + d.otmp = oname(d.otmp, d.name); /* name==aname => wished for artifact (otmp->oartifact => got it) */ - if (otmp->oartifact || name == aname) { - otmp->quan = 1L; + if (d.otmp->oartifact || d.name == aname) { + d.otmp->quan = 1L; u.uconduct.wisharti++; /* KMH, conduct */ } } /* more wishing abuse: don't allow wishing for certain artifacts */ /* and make them pay; charge them for the wish anyway! */ - if ((is_quest_artifact(otmp) - || (otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) { - artifact_exists(otmp, safe_oname(otmp), FALSE); - obfree(otmp, (struct obj *) 0); - otmp = (struct obj *) &cg.zeroobj; + if ((is_quest_artifact(d.otmp) + || (d.otmp->oartifact && rn2(nartifact_exist()) > 1)) && !wizard) { + artifact_exists(d.otmp, safe_oname(d.otmp), FALSE); + obfree(d.otmp, (struct obj *) 0); + d.otmp = (struct obj *) &cg.zeroobj; pline("For a moment, you feel %s in your %s, but it disappears!", something, makeplural(body_part(HAND))); - return otmp; + return d.otmp; } - if (halfeaten && otmp->oclass == FOOD_CLASS) { - if (otmp->otyp == CORPSE) - otmp->oeaten = mons[otmp->corpsenm].cnutrit; + if (d.halfeaten && d.otmp->oclass == FOOD_CLASS) { + if (d.otmp->otyp == CORPSE) + d.otmp->oeaten = mons[d.otmp->corpsenm].cnutrit; else - otmp->oeaten = objects[otmp->otyp].oc_nutrition; + d.otmp->oeaten = objects[d.otmp->otyp].oc_nutrition; /* (do this adjustment before setting up object's weight) */ - consume_oeaten(otmp, 1); + consume_oeaten(d.otmp, 1); } - otmp->owt = weight(otmp); - if (very && otmp->otyp == HEAVY_IRON_BALL) - otmp->owt += IRON_BALL_W_INCR; - else if (gsize > 1 && otmp->globby) + d.otmp->owt = weight(d.otmp); + if (d.very && d.otmp->otyp == HEAVY_IRON_BALL) + d.otmp->owt += IRON_BALL_W_INCR; + else if (d.gsize > 1 && d.otmp->globby) /* 0: unspecified => small; 1: small => keep default owt of 20; 2: medium => 120; 3: large => 320; 4: very large => 520 */ - otmp->owt += 100 + (gsize - 2) * 200; + d.otmp->owt += 100 + (d.gsize - 2) * 200; - return otmp; + return d.otmp; } int diff --git a/test/testwish.lua b/test/testwish.lua index 7aada046b..cc09606b9 100644 --- a/test/testwish.lua +++ b/test/testwish.lua @@ -1,6 +1,12 @@ local wishtest_objects = { ["a rock"] = { otyp_name = "rock", quan = 1, oclass = "*" }, + ["a gold piece"] = { otyp_name = "gold piece", quan = 1, oclass = "$" }, + ["2 zorkmids"] = { otyp_name = "gold piece", quan = 2, oclass = "$" }, + ["2 worthless pieces of red glass"] = { otyp_name = "worthless piece of red glass", quan = 2, oclass = "*" }, + ["red glass"] = { otyp_name = "worthless piece of red glass", quan = 1, oclass = "*" }, + ["red gem"] = { otyp_descr = "red", oclass = "*" }, + ["orange gem"] = { otyp_descr = "orange", oclass = "*" }, ["5 +3 blessed silver daggers"] = { otyp_name = "silver dagger", blessed = 1, cursed = 0, spe = 3, quan = 5 }, ["an empty locked large box"] = { otyp_name = "large box", is_container = 1, has_contents = 0, olocked = 1 }, ["an empty trapped unlocked chest"] = { otyp_name = "chest", is_container = 1, has_contents = 0, olocked = 0, otrapped = 1 }, @@ -10,19 +16,27 @@ local wishtest_objects = { ["potion of holy water"] = { otyp_name = "water", oclass = "!", blessed = 1, cursed = 0 }, ["potion of unholy water"] = { otyp_name = "water", oclass = "!", blessed = 0, cursed = 1 }, ["cursed greased +2 grey dragon scale mail"] = { otyp_name = "gray dragon scale mail", oclass = "[", blessed = 0, cursed = 1, spe = 2, greased = 1 }, + ["+1 yellow dragon scales"] = { otyp_name = "yellow dragon scales", oclass = "[", spe = 1 }, ["uncursed magic marker (11)"] = { otyp_name = "magic marker", blessed = 0, cursed = 0, spe = 11 }, + ["wand of locking (1:5)"] = { otyp_name = "locking", oclass = "/", recharged = 1, spe = 5 }, + ["wand of opening (0:4)"] = { otyp_name = "opening", oclass = "/", recharged = 0, spe = 4 }, ["lit oil lamp"] = { otyp_name = "oil lamp", lamplit = 1 }, + ["oil lamp (lit)"] = { otyp_name = "oil lamp", lamplit = 1 }, ["6 burning tallow candles"] = { otyp_name = "tallow candle", lamplit = 1, quan = 6 }, ["unlit oil lamp"] = { otyp_name = "oil lamp", lamplit = 0 }, ["7 extinguished wax candles"] = { otyp_name = "wax candle", lamplit = 0, quan = 7 }, ["2 blank scrolls"] = { otyp_name = "blank paper", quan = 2 }, ["3 unlabeled scrolls"] = { otyp_name = "blank paper", quan = 3 }, ["1 unlabelled scroll"] = { otyp_name = "blank paper", quan = 1 }, + ["blank spellbook"] = { otyp_name = "blank paper", oclass = "+" }, + ["unlabeled spellbook"] = { otyp_name = "blank paper", oclass = "+" }, + ["unlabelled spellbook"] = { otyp_name = "blank paper", oclass = "+" }, ["3 rusty poisoned darts"] = { otyp_name = "dart", quan = 3, opoisoned = 1, oeroded = 1 }, ["4 diluted dark green potions named whisky"] = { otyp_descr = "dark green", oclass = "!", quan = 4, odiluted = 1, has_oname = 1, oname = "whisky" }, ["poisoned food ration"] = { otyp_name = "food ration", oclass = "%", age = 1 }, ["empty tin"] = { otyp_name = "tin", oclass = "%", corpsenm = -1, spe = 0 }, ["blessed tin of spinach"] = { otyp_name = "tin", oclass = "%", corpsenm = -1, spe = 1, blessed = 1 }, + ["spinach"] = { otyp_name = "tin", oclass = "%", corpsenm = -1, spe = 1 }, ["trapped tin of floating eye meat"] = { otyp_name = "tin", oclass = "%", otrapped = 1, corpsenm_name = "floating eye" }, ["hill orc corpse"] = { otyp_name = "corpse", oclass = "%", corpsenm_name = "hill orc" }, ["destroy armor"] = { otyp_name = "destroy armor", oclass = "?" }, @@ -34,12 +48,15 @@ local wishtest_objects = { ["-1 ring mail"] = { otyp_name = "ring mail", oclass = "[", spe = -1 }, ["studded leather armor"] = { otyp_name = "studded leather armor", oclass = "[" }, ["leather armor"] = { otyp_name = "leather armor", oclass = "[" }, + ["plate armor"] = { otyp_name = "plate mail", oclass = "[" }, + ["yellow dragon scale armor"] = { otyp_name = "yellow dragon scale mail", oclass = "[" }, ["tooled horn"] = { otyp_name = "tooled horn", oclass = "(" }, ["meat ring"] = { otyp_name = "meat ring", oclass = "%" }, ["beartrap"] = { otyp_name = "beartrap", oclass = "(" }, ["bear trap"] = { otyp_name = "beartrap", oclass = "(" }, ["landmine"] = { otyp_name = "land mine", oclass = "(" }, ["land mine"] = { otyp_name = "land mine", oclass = "(" }, + ["bag of tricks"] = { otyp_name = "bag of tricks", oclass = "(" }, ["sprig of wolfsbane"] = { otyp_name = "sprig of wolfsbane", oclass = "%" }, ["wolfsbane"] = { otyp_name = "sprig of wolfsbane", oclass = "%" }, ["clove of garlic"] = { otyp_name = "clove of garlic", oclass = "%" }, From 69dd0485fb3b61bc0a642a75237a652873eadfa4 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 29 Nov 2020 16:58:56 -0800 Subject: [PATCH 471/708] Qt message window: horizontal scrolling Multiple stints of flailing about without a clue finally led to a breakthrough. When writing a new message to the multi-line message window, force the view back to showing the starts of lines if player has scrolled it to the side and left it that way. Put another way, if it has been scrolled to the right, scroll it as far as possible back to the left. --- doc/fixes37.0 | 4 +++- win/Qt/qt_msg.cpp | 18 ++++++++++++++++-- win/Qt/qt_msg.h | 7 ++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c5e5d77be..392ff76e2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.366 $ $NHDT-Date: 1606504240 2020/11/27 19:10:40 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.367 $ $NHDT-Date: 1606697932 2020/11/30 00:58:52 $ General Fixes and Modified Features ----------------------------------- @@ -500,6 +500,8 @@ Qt: don't clobber an existing save file after choosing "new game" in the saved game selection widget Qt: don't get stuck in a loop after choosing "play" while the character name field is empty in the character selection widget +Qt: when a new message is issued, pan the message window to its left edge if + player panned it horizontally then didn't manually scroll it back Qt: {maybe just Qt+OSX:} when viewing a text window ('V' to look at 'history' for instance), clicking on [Search], entering a search target in the resulting popup and clicking on [Okay] or typing , the text diff --git a/win/Qt/qt_msg.cpp b/win/Qt/qt_msg.cpp index c9c3537b8..66fd93dae 100644 --- a/win/Qt/qt_msg.cpp +++ b/win/Qt/qt_msg.cpp @@ -23,9 +23,12 @@ extern "C" { namespace nethack_qt_ { NetHackQtMessageWindow::NetHackQtMessageWindow() : - list(new QListWidget()) + list(new QListWidget()), + scrollarea(new QScrollArea()) { list->setFocusPolicy(Qt::NoFocus); + scrollarea->setFocusPolicy(Qt::NoFocus); + scrollarea->takeWidget(); ::iflags.window_inited = 1; map = 0; currgetmsg = 0; @@ -39,7 +42,9 @@ NetHackQtMessageWindow::~NetHackQtMessageWindow() delete list; } -QWidget* NetHackQtMessageWindow::Widget() { return list; } +QWidget* NetHackQtMessageWindow::Widget() { + return list; +} void NetHackQtMessageWindow::setMap(NetHackQtMapWindow2* m) { @@ -152,6 +157,8 @@ void NetHackQtMessageWindow::PutStr(int attr, const QString& text) item->setBackground(bg); } } +#else + nhUse(attr); #endif if (list->count() >= (int) ::iflags.msg_history) @@ -163,6 +170,13 @@ void NetHackQtMessageWindow::PutStr(int attr, const QString& text) // selects most recent message, which causes it to be highlighted list->setCurrentRow(list->count() - 1); + // if message window has been scrolled right, force back to left edge + QScrollBar *sb = list->horizontalScrollBar(); + if (sb && sb->value() > 0) { + sb->setValue(0); + this->viewport()->update(); + } + if (map) map->putMessage(attr, text2); } diff --git a/win/Qt/qt_msg.h b/win/Qt/qt_msg.h index ca84acaf5..b3274bc13 100644 --- a/win/Qt/qt_msg.h +++ b/win/Qt/qt_msg.h @@ -13,7 +13,7 @@ namespace nethack_qt_ { class NetHackQtMapWindow2; -class NetHackQtMessageWindow : QObject, public NetHackQtWindow { +class NetHackQtMessageWindow : QScrollArea, public NetHackQtWindow { Q_OBJECT public: NetHackQtMessageWindow(); @@ -37,8 +37,9 @@ public: void AddToStr(const char *answerbuf); private: - QListWidget* list; - bool changed; + QListWidget *list; + QScrollArea *scrollarea; + bool changed; int currgetmsg; NetHackQtMapWindow2* map; From a8ed1ab5fdb987ad28e6be5659a80298730dc1a8 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 12:06:37 +0200 Subject: [PATCH 472/708] Test wishing "bags of tricks" --- test/testwish.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/test/testwish.lua b/test/testwish.lua index cc09606b9..f4a1c1a72 100644 --- a/test/testwish.lua +++ b/test/testwish.lua @@ -57,6 +57,7 @@ local wishtest_objects = { ["landmine"] = { otyp_name = "land mine", oclass = "(" }, ["land mine"] = { otyp_name = "land mine", oclass = "(" }, ["bag of tricks"] = { otyp_name = "bag of tricks", oclass = "(" }, + ["bags of tricks"] = { otyp_name = "bag of tricks", oclass = "(" }, ["sprig of wolfsbane"] = { otyp_name = "sprig of wolfsbane", oclass = "%" }, ["wolfsbane"] = { otyp_name = "sprig of wolfsbane", oclass = "%" }, ["clove of garlic"] = { otyp_name = "clove of garlic", oclass = "%" }, From de8337f402ea7a1b38d885e4965b3c1b7ae88af3 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 30 Nov 2020 03:18:45 -0800 Subject: [PATCH 473/708] Qt extended commands When responding to '#', the Qt interface puts up a grid of buttons labelled with the names of commands. Then if the user types instead of clicking on a button, buttons which can no longer match are removed rather than grayed out. The remaining ones keep their same relative positions. Once whole rows or whole columns were gone, it looked awful. With rows gone, the size of the grid shrank but the popup stayed the same size, so the one-line prompt area expanded to fill up the vacated vertical space. That caused the prompt and partial response to move as they stayed centered in their growing area. With columns gone, the width of the buttons in remaining columns expanded and they spread out to take up vacated horizontal space. Once the candidate commands were all in one column, the buttons spanned the width of the grid. (That's mostly my fault due to changing the grid from being row-oriented [a b c] [d e ] to column oriented [a d] [b e] [c ] which resulted in columns going away a lot faster and possibly down to one when the old layout always had at least two. But old layout could drop to one row; the current layout always has at least two.) Also, accept ^[ as ESC. Typing ESC when partial input is present kills that input but keeps prompting. Typing ESC when no input is present (none entered yet or a second of two consecutive ESCs) cancels the operation. Allow ^U to kill partial input. If used when no input is present, nothing happens, similar to backspace. Unlike tty and curses, it's hardcoded here. That shouldn't be a problem because ESC can be used as a substitute if ^U isn't what the player normally uses. --- win/Qt/qt_menu.cpp | 2 +- win/Qt/qt_menu.h | 2 + win/Qt/qt_xcmd.cpp | 102 +++++++++++++++++++++++++++++++-------------- 3 files changed, 74 insertions(+), 32 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 731333d99..ab8b59ea7 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -55,7 +55,7 @@ namespace nethack_qt_ { void centerOnMain( QWidget* w ); // end temporary -static uchar keyValue(QKeyEvent *key_event) +uchar keyValue(QKeyEvent *key_event) { // key_event manipulation derived from NetHackQtBind::notify() const int k = key_event->key(); diff --git a/win/Qt/qt_menu.h b/win/Qt/qt_menu.h index e69265a4f..18be9e732 100644 --- a/win/Qt/qt_menu.h +++ b/win/Qt/qt_menu.h @@ -15,6 +15,8 @@ namespace nethack_qt_ { +extern uchar keyValue(QKeyEvent *key_event); // also used in qt_xcmd.cpp + class NetHackQtTextListBox : public QListWidget { public: NetHackQtTextListBox(QWidget* parent = NULL) : QListWidget(parent) { } diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index a1a343610..ce81fbb44 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -3,6 +3,15 @@ // NetHack may be freely redistributed. See license for details. // qt_xcmd.cpp -- extended command widget +// +// TODO: +// Add button that toggles the grid of command names from column-oriented +// to row-oriented and vice versa. +// Add another button to filter out commands that can be invoked by a +// 'normal' keystroke (not Meta) with current key bindings. +// If not those, move the [cancel] button from being absurdly wide at the +// top of the popup to being ordinary width, right justified on same +// line as the prompt where user's typed characters are shown. extern "C" { #include "hack.h" @@ -23,6 +32,8 @@ extern "C" { namespace nethack_qt_ { +extern uchar keyValue(QKeyEvent *key_event); // from qt_menu.cpp + // temporary void centerOnMain(QWidget *); // end temporary @@ -31,7 +42,8 @@ static inline bool interesting_command(unsigned indx) { return (!(extcmdlist[indx].flags & CMD_NOT_AVAILABLE) - /* 'wizard' is #undef'd above [why?] so rely on its internals */ + /* 'wizard' is #undef'd above because Qt uses that token + so rely on its internals */ && (flags.debug || !(extcmdlist[indx].flags & WIZMODECMD))); } @@ -40,7 +52,7 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : { QVBoxLayout *l = new QVBoxLayout(this); - QPushButton* can = new QPushButton("Cancel", this); + QPushButton *can = new QPushButton("Cancel", this); can->setDefault(true); can->setMinimumSize(can->sizeHint()); l->addWidget(can); @@ -66,7 +78,7 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : when resulting 'nrows' is too big, if GroupBox supports that); it used to be hardcoded 4 but after every command became accessible as an extended command, that resulted in so many rows that some of - the buttoms were chopped off at the bottom of the grid */ + the buttons were chopped off at the bottom of the grid */ unsigned ncols = !flags.debug ? 6 : 8, nrows = (ncmds + ncols - 1) / ncols; /* @@ -84,21 +96,36 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : */ bool by_column = true; - QVBoxLayout* bl = new QVBoxLayout(grid); + QVBoxLayout *bl = new QVBoxLayout(grid); bl->addSpacing(fm.height()); - QGridLayout* gl = new QGridLayout(); + QGridLayout *gl = new QGridLayout(); bl->addLayout(gl); for (i = j = 0; extcmdlist[i].ef_txt; ++i) { if (interesting_command(i)) { QPushButton *pb = new QPushButton(extcmdlist[i].ef_txt, grid); pb->setMinimumSize(butw, pb->sizeHint().height()); + // force the button to have fixed width or it can move around a + // pixel or two (tiny but visibly noticeable) when enableButtons() + // hides whole columns [see stretch comment below] + pb->setMaximumSize(pb->minimumSize()); group->addButton(pb, i + 1); - if (by_column) - /* 0..R-1 down first column, R..2*R-1 down second column,...*/ - gl->addWidget(pb, j % nrows, j / nrows); - else - /* 0..C-1 across first row, C..2*C-1 across second row, ... */ - gl->addWidget(pb, j / ncols, j % ncols); + /* + * by_column: + * 0..R-1 down first column, R..2*R-1 down second column, ... + * otherwise: + * 0..C-1 across first row, C..2*C-1 across second row, ... + */ + int row = by_column ? j % nrows : j / ncols; + int col = by_column ? j / nrows : j % ncols; + gl->addWidget(pb, row, col); + // these stretch settings prevent the grid from becoming very + // ugly when enableButtons() disables whole rows and/or columns + // as typed characters reduce the pool of possible matches + if (row == 0) + gl->setColumnStretch(col, 1); + if (col == 0) + gl->setRowStretch(row, 1); + buttons.append(pb); ++j; } @@ -116,23 +143,35 @@ void NetHackQtExtCmdRequestor::cancel() reject(); } +#define Ctrl(c) (0x1f & (c)) /* ASCII */ +// Note: we don't necessarily have access to a terminal to query +// it for user's preferred kill character, so use hardcoded ^U. +#define KILL_CHAR Ctrl('u') + void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) { - QString text = event->text(); - if (text == "\r" || text == "\n" || text == " " || text == "\033") - { - reject(); - } - else if (text == "\b" || text == "\177") - { - QString promptstr = prompt->text(); - if (promptstr != "#") - prompt->setText(promptstr.left(promptstr.size()-1)); + QString promptstr = prompt->text(); + uchar uc = keyValue(event); + if (!uc) { + // shift or control or meta, another character should be coming + QWidget::keyPressEvent(event); + } else if (uc == '\033' || uc == KILL_CHAR) { + // Escape when some response is already present kills that text + // but keeps prompting; escape when response is empty cancels. + // Kill gets rid of current text, if any, and always re-prompts. + if (uc == '\033' && promptstr == "#") + reject(); // cancel() if ESC used when string is empty + prompt->setText("#"); enableButtons(); - } - else - { - QString promptstr = prompt->text() + text; + } else if (uc == '\b' || uc == '\177') { + if (promptstr != "#") + prompt->setText(promptstr.left(promptstr.size() - 1)); + enableButtons(); + /*} else if (uc == '\r' || uc == '\n'; || uc == ' ') {*/ + } else if (uc < ' ' || uc > std::max('z', 'Z')) { + reject(); // done() + } else { + promptstr += QChar(uc); // event()->text() QString typedstr = promptstr.mid(1); // skip the '#' unsigned matches = 0; unsigned match = 0; @@ -171,19 +210,20 @@ int NetHackQtExtCmdRequestor::get() return result()-1; } -/* - * FIXME: - * This looks terrible. [Possibly a difference between initial - * implementation using Qt2 and the current Qt version?] - */ // Enable only buttons that match the current prompt string void NetHackQtExtCmdRequestor::enableButtons() { QString typedstr = prompt->text().mid(1); // skip the '#' std::size_t len = typedstr.size(); + // This used to look really bad when whole rows became empty: the + // grid shrank and the one line prompt area expanded to fill the + // vacated vertical space. Hiding whole columns looked bad too, + // remaining buttons were widened to take the space. Now the grid is + // forced to have fixed layout (via stretch settings in constructor). for (auto b = buttons.begin(); b != buttons.end(); ++b) { - (*b)->setVisible((*b)->text().left(len) == typedstr); + bool showit = ((*b)->text().left(len) == typedstr); + (*b)->setVisible(showit); } } From 30b59acc404dd6df6e9990bd314fe530f4447e3a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 14:42:48 +0200 Subject: [PATCH 474/708] More wish tests --- test/testwish.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/testwish.lua b/test/testwish.lua index f4a1c1a72..d28c82e3b 100644 --- a/test/testwish.lua +++ b/test/testwish.lua @@ -43,6 +43,7 @@ local wishtest_objects = { ["enchant weapon"] = { otyp_name = "enchant weapon", oclass = "?" }, ["scroll of food detection"] = { otyp_name = "food detection", oclass = "?" }, ["scroll of detect food"] = { otyp_name = "food detection", oclass = "?" }, + ["2 scrolls of charging"] = { otyp_name = "charging", oclass = "?", quan = 2 }, ["spellbook of food detection"] = { otyp_name = "detect food", oclass = "+" }, ["spell"] = { NO_OBJ = 1 }, ["-1 ring mail"] = { otyp_name = "ring mail", oclass = "[", spe = -1 }, @@ -50,6 +51,11 @@ local wishtest_objects = { ["leather armor"] = { otyp_name = "leather armor", oclass = "[" }, ["plate armor"] = { otyp_name = "plate mail", oclass = "[" }, ["yellow dragon scale armor"] = { otyp_name = "yellow dragon scale mail", oclass = "[" }, + ["speed boots"] = { otyp_name = "speed boots", oclass = "[" }, + ["speedboots"] = { otyp_name = "speed boots", oclass = "[" }, + ["erodeproof speedboots"] = { otyp_name = "speed boots", oclass = "[", oerodeproof = 1 }, + ["fixed boots of speed"] = { otyp_name = "speed boots", oclass = "[", oerodeproof = 1 }, + ["blessed fireproof +2 pair of speed boots"] = { otyp_name = "speed boots", oclass = "[", oerodeproof = 1, blessed = 1, spe = 2 }, ["tooled horn"] = { otyp_name = "tooled horn", oclass = "(" }, ["meat ring"] = { otyp_name = "meat ring", oclass = "%" }, ["beartrap"] = { otyp_name = "beartrap", oclass = "(" }, From f8fcab34009786631f84cf7d129fd0972a5dc882 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 30 Nov 2020 11:40:21 -0800 Subject: [PATCH 475/708] move 'g.restoring' to 'g.program_state.restoring' Move the core's global restoring flag (not the same as main()'s local resuming flag) to a more logical place. Add a saving flag in the process, but it isn't being set or cleared anywhere yet. (Once in use it will probably fix the exception during save that was just reported, but before that it would be useful to figure out what specifically caused the event.) The program_state struct really ought to be standalone rather than part of struct g but I haven't made that change. Removing an unused variable for wishing and some reformatting that whent along with it got mixed in. Removes some trailing whitespace in sfstruct.c too. Only lightly tested... --- doc/fixes37.0 | 7 ++++++- include/decl.h | 4 +++- src/artifact.c | 5 +++-- src/botl.c | 8 +++++--- src/invent.c | 4 ++-- src/objnam.c | 38 +++++++++++++++++++++----------------- src/restore.c | 10 +++++----- src/sfstruct.c | 22 +++++++++++----------- sys/msdos/vidvesa.c | 3 +-- sys/msdos/vidvga.c | 5 ++--- 10 files changed, 59 insertions(+), 47 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 392ff76e2..90c6c6799 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.367 $ $NHDT-Date: 1606697932 2020/11/30 00:58:52 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.368 $ $NHDT-Date: 1606765210 2020/11/30 19:40:10 $ General Fixes and Modified Features ----------------------------------- @@ -736,3 +736,8 @@ add an additional note to mextra.h and obj.h comments that reminds people to appropriately init new fields if they need to initialize to something other than zero rework stairs structure into a linked list +move 'restoring' to the program_state struct; add corresponding 'saving'; + both used to enforce no updating of status lines or of persistent + inventory when the relevant activity is in progress + + diff --git a/include/decl.h b/include/decl.h index 87000f88c..def2db1cb 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1600468452 2020/09/18 22:34:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.242 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1606765210 2020/11/30 19:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -94,6 +94,8 @@ struct sinfo { int something_worth_saving; /* in case of panic */ int panicking; /* `panic' is in progress */ int exiting; /* an exit handler is executing */ + int saving; + int restoring; int in_moveloop; int in_impossible; int in_self_recover; diff --git a/src/artifact.c b/src/artifact.c index c71c0e87c..7bb0fc7d0 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 artifact.c $NHDT-Date: 1596498149 2020/08/03 23:42:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 3.7 artifact.c $NHDT-Date: 1606765210 2020/11/30 19:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.161 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -534,7 +534,8 @@ long wp_mask; * that can print a message--need to guard against being printed * when restoring a game */ - (void) make_hallucinated((long) !on, g.restoring ? FALSE : TRUE, + (void) make_hallucinated((long) !on, + g.program_state.restoring ? FALSE : TRUE, wp_mask); } if (spfx & SPFX_ESP) { diff --git a/src/botl.c b/src/botl.c index 4fc411e74..23dd6906c 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 botl.c $NHDT-Date: 1606008998 2020/11/22 01:36:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ +/* NetHack 3.7 botl.c $NHDT-Date: 1606765211 2020/11/30 19:40:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -238,7 +238,8 @@ void bot() { /* dosave() flags completion by setting u.uhp to -1 */ - if ((u.uhp != -1) && g.youmonst.data && iflags.status_updates) { + if (u.uhp != -1 && g.youmonst.data && iflags.status_updates + && !g.program_state.saving && !g.program_state.restoring) { if (VIA_WINDOWPORT()) { bot_via_windowport(); } else { @@ -254,7 +255,8 @@ bot() void timebot() { - if (flags.time && iflags.status_updates) { + if (flags.time && iflags.status_updates + && !g.program_state.saving && !g.program_state.restoring) { if (VIA_WINDOWPORT()) { stat_update_time(); } else { diff --git a/src/invent.c b/src/invent.c index 6766de676..f7be4f669 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1606528765 2020/11/28 01:59:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1606765212 2020/11/30 19:40:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.308 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2496,7 +2496,7 @@ learn_unseen_invent() void update_inventory() { - if (g.restoring) + if (g.program_state.saving || g.program_state.restoring) return; /* diff --git a/src/objnam.c b/src/objnam.c index 5dfbc5f54..0daa19c9a 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1604745123 2020/11/07 10:32:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.305 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1606765213 2020/11/30 19:40:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1293,8 +1293,8 @@ unsigned doname_flags; /* treat 'restoring' like suppress_price because shopkeeper and bill might not be available yet while restore is in progress (objects won't normally be formatted during that time, but if - 'perm_invent' is enabled then they might be) */ - if (iflags.suppress_price || g.restoring) { + 'perm_invent' is enabled then they might be [not any more...]) */ + if (iflags.suppress_price || g.program_state.restoring) { ; /* don't attempt to obtain any shop pricing, even if 'with_price' */ } else if (is_unpaid(obj)) { /* in inventory or in container in invent */ long quotedprice = unpaid_cost(obj, TRUE); @@ -3261,10 +3261,11 @@ char *bp; struct _readobjnam_data *d; { d->cnt = d->spe = d->spesgn = d->typ = 0; - d->very = d->rechrg = d->blessed = d->uncursed = d->iscursed = d->ispoisoned = - d->isgreased = d->eroded = d->eroded2 = d->erodeproof = d->halfeaten = - d->islit = d->unlabeled = d->ishistoric = d->isdiluted = d->trapped = - d->locked = d->unlocked = d->broken = d->real = d->fake = 0; + d->very = d->rechrg = d->blessed = d->uncursed = d->iscursed + = d->ispoisoned = d->isgreased = d->eroded = d->eroded2 + = d->erodeproof = d->halfeaten = d->islit = d->unlabeled + = d->ishistoric = d->isdiluted = d->trapped = d->locked + = d->unlocked = d->broken = d->real = d->fake = 0; d->tvariety = RANDOM_TIN; d->mntmp = NON_PM; d->contents = UNDEFINED; @@ -4078,13 +4079,12 @@ readobjnam(bp, no_wish) register char *bp; struct obj *no_wish; { - register char *p; struct _readobjnam_data d; readobjnam_init(bp, &d); - if (!bp) goto any; + /* first, remove extra whitespace they may have typed */ (void) mungspaces(bp); /* allow wishing for "nothing" to preserve wishless conduct... @@ -4145,7 +4145,7 @@ struct obj *no_wish; wiztrap: if (wizard && !g.program_state.wizkit_wishing) { /* [inline code moved to separate routine to unclutter readobjnam] */ - if ((d.otmp = wizterrainwish(d.bp, p, d.locked, d.trapped)) != 0) + if ((d.otmp = wizterrainwish(d.bp, d.p, d.locked, d.trapped)) != 0) return d.otmp; } @@ -4196,7 +4196,8 @@ struct obj *no_wish; /* if asking for corpse of a monster which leaves behind a glob, give glob instead of rejecting the monster type to create random corpse */ - if (d.typ == CORPSE && d.mntmp >= LOW_PM && mons[d.mntmp].mlet == S_PUDDING) { + if (d.typ == CORPSE && d.mntmp >= LOW_PM + && mons[d.mntmp].mlet == S_PUDDING) { d.typ = GLOB_OF_GRAY_OOZE + (d.mntmp - PM_GRAY_OOZE); d.mntmp = NON_PM; /* not used for globs */ } @@ -4206,8 +4207,9 @@ struct obj *no_wish; d.otmp = d.typ ? mksobj(d.typ, TRUE, FALSE) : mkobj(d.oclass, FALSE); d.typ = d.otmp->otyp, d.oclass = d.otmp->oclass; /* what we actually got */ - if (d.islit && (d.typ == OIL_LAMP || d.typ == MAGIC_LAMP || d.typ == BRASS_LANTERN - || Is_candle(d.otmp) || d.typ == POT_OIL)) { + if (d.islit && (d.typ == OIL_LAMP || d.typ == MAGIC_LAMP + || d.typ == BRASS_LANTERN + || Is_candle(d.otmp) || d.typ == POT_OIL)) { place_object(d.otmp, u.ux, u.uy); /* make it viable light source */ begin_burn(d.otmp, FALSE); obj_extract_self(d.otmp); /* now release it for caller's use */ @@ -4348,7 +4350,8 @@ struct obj *no_wish; case SCALE_MAIL: /* Dragon mail - depends on the order of objects & dragons. */ if (d.mntmp >= PM_GRAY_DRAGON && d.mntmp <= PM_YELLOW_DRAGON) - d.otmp->otyp = GRAY_DRAGON_SCALE_MAIL + d.mntmp - PM_GRAY_DRAGON; + d.otmp->otyp = GRAY_DRAGON_SCALE_MAIL + + d.mntmp - PM_GRAY_DRAGON; break; } } @@ -4380,7 +4383,8 @@ struct obj *no_wish; * armor modified by confused reading of cursed destroy armor) * so don't prevent player from wishing for such a combination. */ - if (d.erodeproof && (is_damageable(d.otmp) || d.otmp->otyp == CRYSKNIFE)) + if (d.erodeproof + && (is_damageable(d.otmp) || d.otmp->otyp == CRYSKNIFE)) d.otmp->oerodeproof = (Luck >= 0 || wizard); } @@ -4431,8 +4435,8 @@ struct obj *no_wish; if (d.isgreased) d.otmp->greased = 1; - if (d.isdiluted && d.otmp->oclass == POTION_CLASS && d.otmp->otyp != POT_WATER) - d.otmp->odiluted = 1; + if (d.isdiluted && d.otmp->oclass == POTION_CLASS) + d.otmp->odiluted = (d.otmp->otyp != POT_WATER); /* set tin variety */ if (d.otmp->otyp == TIN && d.tvariety >= 0 && (rn2(4) || wizard)) diff --git a/src/restore.c b/src/restore.c index deaabb4fb..3622c02ab 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 restore.c $NHDT-Date: 1605305492 2020/11/13 22:11:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.171 $ */ +/* NetHack 3.7 restore.c $NHDT-Date: 1606765214 2020/11/30 19:40:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.173 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -643,9 +643,9 @@ unsigned int *stuckid, *steedid; while (bc_obj) { struct obj *nobj = bc_obj->nobj; + bc_obj->nobj = (struct obj *) 0; if (bc_obj->owornmask) setworn(bc_obj, bc_obj->owornmask); - bc_obj->nobj = (struct obj *) 0; bc_obj = nobj; } g.migrating_objs = restobjchn(nhfp, FALSE); @@ -771,7 +771,7 @@ NHFILE *nhfp; int rtmp; struct obj *otmp; - g.restoring = TRUE; + g.program_state.restoring = 1; get_plname_from_file(nhfp, g.plname); getlev(nhfp, 0, (xchar) 0); if (!restgamestate(nhfp, &stuckid, &steedid)) { @@ -786,7 +786,7 @@ NHFILE *nhfp; is not really affiliated with an open file */ close_nhfile(nhfp); (void) delete_savefile(); - g.restoring = FALSE; + g.program_state.restoring = 0; return 0; } restlevelstate(stuckid, steedid); @@ -895,8 +895,8 @@ NHFILE *nhfp; g.vision_full_recalc = 1; /* recompute vision (not saved) */ run_timers(); /* expire all timers that have gone off while away */ + g.program_state.restoring = 0; /* affects bot() so clear before docrt() */ docrt(); - g.restoring = FALSE; clear_nhwindow(WIN_MESSAGE); /* Success! */ diff --git a/src/sfstruct.c b/src/sfstruct.c index ae9851987..d33841cea 100644 --- a/src/sfstruct.c +++ b/src/sfstruct.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 sfstruct.c $NHDT-Date: 1593953360 2020/07/05 12:49:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.3 $ */ +/* NetHack 3.7 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, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -75,8 +75,8 @@ static FILE *bw_FILE[MAXFD] = {0,0,0,0,0}; * Some notes: * * Once buffered IO (stdio) has been enabled on the file - * associated with a descriptor via fdopen(): - * + * associated with a descriptor via fdopen(): + * * 1. If you use bufoff and bufon to try and toggle the * use of write vs fwrite; the code just tracks which * routine is to be called through the tracking @@ -86,7 +86,7 @@ static FILE *bw_FILE[MAXFD] = {0,0,0,0,0}; * if it is a free slot. * bw_buffered[] - indicator that buffered IO routines * are available for use. - * bw_FILE[] - the non-zero FILE * for use in calling + * bw_FILE[] - the non-zero FILE * for use in calling * fwrite() when bw_buffered[] is also * non-zero. * @@ -265,7 +265,7 @@ register unsigned int len; return; } else { pline("Read %d instead of %u bytes.", rlen, len); - if (g.restoring) { + if (g.program_state.restoring) { (void) nhclose(fd); (void) delete_savefile(); error("Error restoring old game."); @@ -291,7 +291,7 @@ int fd; const char *fncname; int linenum; { - TRACE(fd); + TRACE(fd); bufon(fd); } @@ -301,7 +301,7 @@ int fd; const char *fncname; int linenum; { - TRACE(fd); + TRACE(fd); bufoff(fd); } @@ -311,7 +311,7 @@ int fd; const char *fncname; int linenum; { - TRACE(fd); + TRACE(fd); bflush(fd); } @@ -323,7 +323,7 @@ register unsigned num; const char *fncname; int linenum; { - TRACE(fd); + TRACE(fd); bwrite(fd, loc, num); } @@ -333,7 +333,7 @@ int fd; const char *fncname; int linenum; { - TRACE(fd); + TRACE(fd); bclose(fd); } @@ -354,7 +354,7 @@ register unsigned int len; const char *fncname; int linenum; { - TRACE(fd); + TRACE(fd); mread(fd, buf, len); } #endif diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index a631dc2e8..747dd0ac0 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -76,7 +76,6 @@ extern int attrib_text_normal; /* text mode normal attribute */ extern int attrib_gr_normal; /* graphics mode normal attribute */ extern int attrib_gr_intense; /* graphics mode intense attribute */ extern boolean inmap; /* in the map window */ -/* extern boolean g.restoring; */ /* * Global Variables @@ -786,7 +785,7 @@ int x, y; clipymax = ROWNO - 1; } if (clipx != oldx || clipy != oldy) { - if (on_level(&u.uz0, &u.uz) && !g.restoring) + if (on_level(&u.uz0, &u.uz) && !g.program_state.restoring) /* (void) doredraw(); */ vesa_redrawmap(); } diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index a9962019a..badff0432 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 vidvga.c $NHDT-Date: 1596498278 2020/08/03 23:44:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.25 $ */ +/* NetHack 3.7 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. */ /* @@ -430,7 +430,6 @@ static void vga_cliparound(x, y) int x, y; { -/* extern boolean g.restoring; */ int oldx = clipx; if (!iflags.tile_view || iflags.over_view || iflags.traditional_view) @@ -444,7 +443,7 @@ int x, y; clipx = clipxmax - (viewport_size - 1); } if (clipx != oldx) { - if (on_level(&u.uz0, &u.uz) && !g.restoring) + if (on_level(&u.uz0, &u.uz) && !g.program_state.restoring) /* (void) doredraw(); */ vga_redrawmap(1); } From 516af11dc7e8ae2455b6e8eb66baae508f8da866 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 30 Nov 2020 16:16:14 -0800 Subject: [PATCH 476/708] reduce the number of #seeXYZ commands Noticed while working on Qt's extended command handling, there are an awful lot of "seeXYZ" commands. Keep the inventory display ones (named versions of ')' to show wielded weapon(s), '[' for worn armor, '"' for worn amulet, &c) and rename the others: | #seenv -> #wizseenv debugging command | #seespells -> #showspells '+' command | #seetrap -> #showtrap '^' command Also, expand the descriptions of #shell and #suspend a bit in the Guidebook. LaTeX version is untested. --- dat/wizhelp | 2 +- doc/Guidebook.mn | 39 +++++++++++++++++++++++++-------------- doc/Guidebook.tex | 44 ++++++++++++++++++++++++++++++-------------- doc/fixes37.0 | 5 ++++- src/cmd.c | 12 ++++++------ 5 files changed, 66 insertions(+), 36 deletions(-) diff --git a/dat/wizhelp b/dat/wizhelp index 46b46dd52..0237b1a3c 100644 --- a/dat/wizhelp +++ b/dat/wizhelp @@ -13,7 +13,6 @@ Debug-Mode Quick Reference: #lightsources == show mobile light sources #panic == panic test (warning: current game will be terminated) #polyself == polymorph self -#seenv == show seen vectors #stats == show memory statistics #terrain == show current level (more options than in normal play) #timeout == look at timeout queue and hero's timed intrinsics @@ -25,6 +24,7 @@ Debug-Mode Quick Reference: #wizmakemap == recreate the current dungeon level #wizrumorcheck == validate rumor indexing; also show first, second, and last random engravings, epitaphs, and hallucinatory monsters +#wizseenv == show map locations' seen vectors #wizsmell == smell a monster #wizwhere == show dungeon placement of all special levels #wmode == show wall modes diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 6a0366a73..82880c6d1 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.400 $ $NHDT-Date: 1606328499 2020/11/25 18:21:39 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.402 $ $NHDT-Date: 1606781766 2020/12/01 00:16:06 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "November 25, 2020 +.ds f2 "November 30, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1005,6 +1005,7 @@ Suspend the game .\" .UX: print "UNIX" now and a trademark footnote at bottom of current page; .\" 2nd arg (literal '(') _precedes_ it, 1st arg (quoted string) follows it .UX " versions with job control only)." ( +See \(lq#suspend\(rq below for more details. .lp : Look at what is here. .lp ; @@ -1058,6 +1059,7 @@ Show what types of objects have been discovered. Show discovered types for one class of objects. .lp ! Escape to a shell. +See \(lq#shell\(rq below for more details. .lp # Perform an extended command. .lp "" @@ -1388,28 +1390,28 @@ Default key is \(oq[\(cq. .lp "#seegold " Count your gold. Default key is \(oq$\(cq. -.lp "#seenv " -Show seen vectors. -Autocompletes. -Debug mode only. .lp #seerings Show the ring(s) currently worn. Default key is \(oq=\(cq. -.lp #seespells -List and reorder known spells. -Default key is \(oq+\(cq. .lp #seetools Show the tools currently in use. Default key is \(oq(\(cq. -.lp "#seetrap " -Show the type of an adjacent trap. -Default key is \(oq\(ha\(cq. \" 'hat' (circumflex character) .lp #seeweapon Show the weapon currently wielded. Default key is \(oq)\(cq. .lp "#shell " -Do a shell escape. +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 +configuration file. +Use the shell command \(oq\f(CRexit\fP\(cq to return to the game. Default key is \(oq!\(cq. +.lp #showspells +List and reorder known spells. +Default key is \(oq+\(cq. +.lp "#showtrap" +Show the type of an adjacent trap. +Default key is \(oq\(ha\(cq. \" 'hat' (circumflex character) .lp "#sit " Sit down. Autocompletes. @@ -1419,7 +1421,12 @@ Show memory usage statistics. Autocompletes. Debug mode only. .lp "#suspend " -Suspend the game. +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 \fItty\fP and \fIcurses\fP interfaces on +.UX \. \" yields "UNIX." +Use the shell command \(oq\f(CRfg\fP\(cq to return to the game. Default key is \(oq\(haZ\(cq. .lp "#swap " Swap wielded and secondary weapons. @@ -1566,6 +1573,10 @@ and hallucinatory monsters. .lp "" Autocompletes. Debug mode only. +.lp #wizseenv +Show map locations' seen vectors. +Autocompletes. +Debug mode only. .lp #wizsmell Smell monster. Autocompletes. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 68c0466c4..045329d68 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{November 25, 2020} +\date{November 30, 2020} \maketitle @@ -1095,6 +1095,7 @@ Zap (cast) a spell.\\ %.lp \item[\tb{\^{}Z}] Suspend the game (UNIX versions with job control only). +See ``\#suspend'' below for more details. %.lp \item[\tb{:}] Look at what is here. @@ -1159,6 +1160,7 @@ Show discovered types for one class of objects. %.lp \item[\tb{!}] Escape to a shell. +See ``\#shell'' below for more details. %.lp \item[\tb{\#}] Perform an extended command.\\ @@ -1472,28 +1474,30 @@ Show the armor currently worn. Default key is `{\tt [}'. \item[\tb{\#seegold}] Count your gold. Default key is `{\tt \$}'. %.lp -\item[\tb{\#seenv}] -Show seen vectors. -Autocompletes. -Debug mode only. -%.lp \item[\tb{\#seerings}] Show the ring(s) currently worn. Default key is `{\tt =}'. %.lp -\item[\tb{\#seespells}] -List and reorder known spells. Default key is `{\tt +}'. -%.lp \item[\tb{\#seetools}] Show the tools currently in use. Default key is `{\tt (}'. %.lp -\item[\tb{\#seetrap}] -Show the type of an adjacent trap. Default key is `{\tt \^{}}'. -%.lp \item[\tb{\#seeweapon}] Show the weapon currently wielded. Default key is `{\tt )}'. %.lp \item[\tb{\#shell}] -Do a shell escape. Default key is `{\tt !}'. +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 +configuration file. +Use the shell command `{\tt exit}' to return to the game. +Default key is `{\tt !}'. +%.lp +\item[\tb{\#showspells}] +List and reorder known spells. +Default key is `{\tt +}'. +%.lp +\item[\tb{\#showtrap}] +Show the type of an adjacent trap. +Default key is `{\tt \^{}}'. %.lp \item[\tb{\#sit}] Sit down. Autocompletes. Default key is `{\tt M-s}'. @@ -1504,7 +1508,14 @@ Autocompletes. Debug mode only. %.lp \item[\tb{\#suspend}] -Suspend the game. Default key is `{\tt \^{}Z}'. +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 {\it tty\/} and {\it curses\/} interfaces on +%.UX \. \" yields "UNIX." +UNIX. +Use the shell command `{\tt fg}' to return to the game. +Default key is `{\tt \^{}Z}'. %.lp \item[\tb{\#swap}] Swap wielded and secondary weapons. Default key is `{\tt x}'. @@ -1661,6 +1672,11 @@ and hallucinatory monsters.\\ Autocompletes. Debug mode only. %.lp +\item[\tb{\#wizseenv}] +Show map locations' seen vectors. +Autocompletes. +Debug mode only. +%.lp \item[\tb{\#wizsmell}] Smell monster. Autocompletes. diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 90c6c6799..0fc0401a4 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.368 $ $NHDT-Date: 1606765210 2020/11/30 19:40:10 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.369 $ $NHDT-Date: 1606781767 2020/12/01 00:16:07 $ General Fixes and Modified Features ----------------------------------- @@ -314,6 +314,8 @@ throwing or kicking a shop container (that's light enough to move) made the try to fix message sequencing for tame golems that "roast/rot/rust in peace" autodescribe when moving the cursor was erroneously honoring MSGTYPE=stop and potentially delivering sounds +reduce the number of "seeXYZ" commands by renaming some: #seenv -> #wizseenv, + #seespells -> #showspells, and #seetrap -> #showtrap Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -404,6 +406,7 @@ tins of spinach and 'dead' eggs could cause out of array bounds access options help ('? g') listed all boolean options, then repeated them among the compound options; on OSX they showed a description of "(null)" but for other sprintf implementations they might cause a crash +change name of #wizlevelflip to #wizfliplevel curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/cmd.c b/src/cmd.c index ac1f1e21a..d4d999ef7 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1605779800 2020/11/19 09:56:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.425 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1606781767 2020/12/01 00:16:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.426 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1874,15 +1874,10 @@ struct ext_func_tab extcmdlist[] = { { ARMOR_SYM, "seearmor", "show the armor currently worn", doprarm, IFBURIED }, { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED }, - { '\0', "seenv", "show seen vectors", - wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { RING_SYM, "seerings", "show the ring(s) currently worn", doprring, IFBURIED }, - { SPBOOK_SYM, "seespells", "list and reorder known spells", - dovspell, IFBURIED }, { TOOL_SYM, "seetools", "show the tools currently in use", doprtool, IFBURIED }, - { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED }, { WEAPON_SYM, "seeweapon", "show the weapon currently wielded", doprwep, IFBURIED }, { '!', "shell", "do a shell escape", @@ -1891,6 +1886,9 @@ struct ext_func_tab extcmdlist[] = { | CMD_NOT_AVAILABLE #endif /* SHELL */ }, + { SPBOOK_SYM, "showspells", "list and reorder known spells", + dovspell, IFBURIED }, + { '^', "showtrap", "show the type of adjacent trap", doidtrap, IFBURIED }, { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE }, { '\0', "stats", "show memory statistics", wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, @@ -1963,6 +1961,8 @@ struct ext_func_tab extcmdlist[] = { wiz_map, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '\0', "wizrumorcheck", "verify rumor boundaries", wiz_rumor_check, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, + { '\0', "wizseenv", "show map locations' seen vectors", + wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '\0', "wizsmell", "smell monster", wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '\0', "wizwhere", "show locations of special levels", From 2c19db61aa87f9de231d3516590b579b64075b9a Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 30 Nov 2020 20:22:18 -0500 Subject: [PATCH 477/708] daily cron update doc/Guidebook.txt --- doc/Guidebook.txt | 4208 +++++++++++++++++++++++---------------------- 1 file changed, 2137 insertions(+), 2071 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index dfe138943..78e198ac6 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - November 16, 2020 + November 30, 2020 @@ -76,7 +76,7 @@ Menace. It is late at night, so you make camp at the entrance and spend the night sleeping under the open skies. In the morn- ing, you gather your gear, eat what may be your last meal out- - side, and enter the dungeon... + side, and enter the dungeon.... 2. What is going on here? @@ -126,7 +126,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1086,7 +1086,8 @@ Z. - to cast at yourself, use `.' for the direction. - ^Z Suspend the game (UNIX(R) versions with job control only). + ^Z Suspend the game (UNIX(R) versions with job control only). + See "#suspend" below for more details. : Look at what is here. @@ -1111,12 +1112,11 @@ ( Tell what tools you are using. - __________ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1134,29 +1134,29 @@ + 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 an- - other to swap places with it. Swapping pairs of spells + 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 an- + other to swap places with it. Swapping pairs of spells changes their casting letters, so the change lasts after the - current `+' command finishes. Sorting the whole list is - temporary. To make the most recent sort order persist be- - yond 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 + current `+' command finishes. Sorting the whole list is + temporary. To make the most recent sort order persist be- + yond 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. ` Show discovered types for one class of objects. - ! Escape to a shell. + ! Escape to a shell. See "#shell" below for more details. # Perform an extended command. - As you can see, the authors of NetHack used up all the let- + As you can see, the authors of NetHack used up all the let- ters, so this is a way to introduce the less frequently used com- mands. What extended commands are available depends on what fea- tures the game was compiled with. @@ -1165,24 +1165,24 @@ 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 + 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 particu- lar location when inventory listings are displayed. You can move to a currently empty slot, or if the destination is oc- cupied--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 + 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 letter. - Adjusting without a count used to collect all compatible - stacks when moving to the destination. That behavior has + 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 + into its own inventory slot. If it has a name assigned, + other stacks with the same name or with no name will merge - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1192,31 +1192,31 @@ - provided that all their other attributes match. If it does - not have a name, only other stacks with no name are eligi- - ble. In either case, otherwise compatible stacks with a - different name will not be merged. This contrasts with us- + provided that all their other attributes match. If it does + not have a name, only other stacks with no name are eligi- + ble. In either case, otherwise compatible stacks with a + different name will not be merged. This contrasts with us- ing "#adjust" to move from one slot to a different slot. In - that situation, moving (no count given) a compatible stack + that situation, moving (no count given) a compatible 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 + 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 current dungeon level. All levels with annotations are dis- - played by the "#overview" command. Autocompletes. Default + played by the "#overview" command. Autocompletes. Default key is `M-A', and also `^N' if number_pad is on. #apply - Apply (use) a tool such as a pick-axe, a key, or a lamp. + Apply (use) a tool such as a pick-axe, a key, or a lamp. Default key is `a'. - If the tool used acts on items on the floor, using the `m' + 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 + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. #attributes @@ -1226,9 +1226,9 @@ Toggle the autopickup option on/off. Default key is `@'. #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 level (same as "#annotate"). Default key is + 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 @@ -1241,14 +1241,14 @@ Close a door. Default key is `c'. #conduct - List voluntary challenges you have maintained. Autocom- + List voluntary challenges you have maintained. Autocom- pletes. Default key is `M-C'. See the section below entitled "Conduct" for details. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1259,7 +1259,7 @@ #dip - Dip an object into something. Autocompletes. Default key + Dip an object into something. Autocompletes. Default key is `M-d'. #down @@ -1272,22 +1272,22 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips + 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 Enter the explore mode. Requires confirmation; default response is n (no). To real- - ly switch to explore mode, respond with y. You can set the - paranoid_confirmation:quit option to require a response of + ly switch to explore mode, respond with y. You can set the + paranoid_confirmation:quit option to require a response of yes instead. #fire @@ -1297,11 +1297,11 @@ Force a lock. Autocompletes. Default key is `M-f'. #glance - Show what type of thing a map symbol corresponds to. De- + Show what type of thing a map symbol corresponds to. De- fault key is `;'. #help - Show the help menu. Default key is `?', and also `h' if + Show the help menu. Default key is `?', and also `h' if number_pad is on. #herecmdmenu @@ -1314,7 +1314,7 @@ Show your inventory. Default key is `i'. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1328,15 +1328,15 @@ Inventory specific item types. Default key is `I'. #invoke - Invoke an object's special powers. Autocompletes. Default + Invoke an object's special powers. Autocompletes. Default key is `M-i'. #jump - Jump to another location. Autocompletes. Default key is + 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 + Kick something. Default key is `^D', and `k' if number_pad is on. #known @@ -1348,7 +1348,7 @@ is ``'. #levelchange - Change your experience level. Autocompletes. Debug mode + Change your experience level. Autocompletes. Debug mode only. #lightsources @@ -1358,29 +1358,29 @@ Look at what is here, under you. Default key is `:'. #loot - 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 + 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 number_pad is on. #monster - Use a monster's special ability (when polymorphed into mon- + Use a monster's special ability (when polymorphed into mon- ster form). Autocompletes. Default key is `M-m'. #name - Name a monster, an individual object, or a type of object. - Same as "#call". Autocompletes. Default keys are `N', `M- + 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 + Offer a sacrifice to the gods. Autocompletes. Default key is `M-o'. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1390,8 +1390,8 @@ - You'll need to find an altar to have any chance at success. - Corpses of recently killed monsters are the fodder of + 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 al- @@ -1404,22 +1404,22 @@ Show and change option settings. Default key is `O'. #overview - Display information you've discovered about the dungeon. - Any visited level (unless forgotten due to amnesia) with an - annotation is included, and many things (altars, thrones, - fountains, and so on; extra stairs leading to another dun- - geon branch) trigger an automatic annotation. If dungeon + Display information you've discovered about the dungeon. + Any visited level (unless forgotten due to amnesia) with an + annotation is included, and many things (altars, thrones, + fountains, and so on; extra stairs leading to another dun- + geon branch) trigger an automatic annotation. If dungeon overview is chosen during end-of-game disclosure, every vis- - ited level will be included regardless of annotations. Au- + ited level will be included regardless of annotations. Au- tocompletes. Default keys are `^O', and `M-O'. #panic Test the panic routine. Terminates the current game. Auto- completes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. - To really panic, respond with y. You can set the para- - noid_confirmation:quit option to require a response of yes + Asks for confirmation; default is n (no); continue playing. + To really panic, respond with y. You can set the para- + noid_confirmation:quit option to require a response of yes instead. #pay @@ -1433,20 +1433,20 @@ Polymorph self. Autocompletes. Debug mode only. #pray - Pray to the gods for help. Autocompletes. Default key is + 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 re- + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having re- ceived 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 + 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. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1457,54 +1457,54 @@ #prevmsg - Show previously displayed game messages. Default key is + Show previously displayed game messages. Default key is `^P'. #puton - Put on an accessory (ring, amulet, etc). Default key is + Put on an accessory (ring, amulet, etc). Default key is `P'. #quaff Quaff (drink) something. Default key is `q'. #quit - Quit the program without saving your game. Autocompletes. + Quit the program without saving your game. Autocompletes. Default key is `M-q'. - Since using this command by accident would throw away the - current game, you are asked to confirm your intent before + 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_con- + really quit, respond with y. You can set the paranoid_con- firmation: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 + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if + Redraw the screen. Default key is `^R', and also `^L' if number_pad is on. #remove - Remove an accessory (ring, amulet, etc). Default key is + Remove an accessory (ring, amulet, etc). Default key is `R'. #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- + Rub a lamp or a stone. Autocompletes. Default key is `M- r'. #save Save the game and exit the program. Default key is `S'. #search - Search for traps and secret doors around you. Default key + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1512,7 +1512,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1531,36 +1531,42 @@ #seegold Count your gold. Default key is `$'. - #seenv - Show seen vectors. Autocompletes. Debug mode only. - #seerings Show the ring(s) currently worn. Default key is `='. - #seespells - List and reorder known spells. Default key is `+'. - #seetools Show the tools currently in use. Default key is `('. - #seetrap - Show the type of an adjacent trap. Default key is `^'. - #seeweapon Show the weapon currently wielded. Default key is `)'. #shell - Do a shell escape. Default key is `!'. + Do a shell escape, switching from NetHack to a subprocess. + Can be disabled at the time the program is built. When en- + abled, access for specific users can be controlled by the + system configuration file. Use the shell command `exit' to + return to the game. Default key is `!'. + + #showspells + List and reorder known spells. Default key is `+'. + + #showtrap + Show the type of an adjacent trap. Default key is `^'. #sit Sit down. Autocompletes. Default key is `M-s'. #stats - Show memory usage statistics. Autocompletes. Debug mode + Show memory usage statistics. Autocompletes. Debug mode only. #suspend - Suspend the game. Default key is `^Z'. + 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'. @@ -1571,14 +1577,8 @@ #takeoffall Remove all armor. Default key is `A'. - #teleport - Teleport around the level. Default key is `^T'. - #terrain - Show bare map without displaying monsters, objects, or - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1588,6 +1588,11 @@ + #teleport + Teleport around the level. Default key is `^T'. + + #terrain + Show bare map without displaying monsters, objects, or traps. Autocompletes. #therecmdmenu @@ -1636,15 +1641,10 @@ List vanquished monsters. Autocompletes. Debug mode only. #version - Print compile time options for this version of NetHack. Au- - tocompletes. Default key is `M-v'. - - #versionshort - Show version string. Default key is `v'. + Print compile time options for this version of NetHack. - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1654,6 +1654,11 @@ + Autocompletes. Default key is `M-v'. + + #versionshort + Show version string. Default key is `v'. + #vision Show vision array. Autocompletes. Debug mode only. @@ -1703,14 +1708,9 @@ Set one or more intrinsic attributes. Autocompletes. Debug mode only. - #wizlevelport - Teleport to another level. Autocompletes. Debug mode only. - Default key is `^V'. - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1720,6 +1720,10 @@ + #wizlevelport + Teleport to another level. Autocompletes. Debug mode only. + Default key is `^V'. + #wizmap Map the level. Autocompletes. Debug mode only. Default key is `^F'. @@ -1733,15 +1737,19 @@ Autocompletes. Debug mode only. + #wizseenv + Show map locations' seen vectors. Autocompletes. Debug + mode only. + #wizsmell Smell monster. Autocompletes. Debug mode only. #wizwhere - Show locations of special levels. Autocompletes. Debug + Show locations of special levels. Autocompletes. Debug mode only. #wizwish - Wish for something. Autocompletes. Debug mode only. De- + Wish for something. Autocompletes. Debug mode only. De- fault key is `^W'. #wmode @@ -1756,27 +1764,19 @@ If your keyboard has a meta key (which, when pressed in com- - bination with another key, modifies it by setting the "meta" - [8th, or "high"] bit), you can invoke many extended commands by + bination 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. - In Windows, OS/2, PC and ST NetHack, the "Alt" key can be + In Windows, OS/2, PC and ST NetHack, the "Alt" key can be used in this fashion; on the Amiga, set the altmeta option to get - this behavior. On other systems, if typing "Alt" plus another - key transmits a two character sequence consisting of an Escape + this behavior. 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+key. - M-? #? (not supported by all platforms) - M-2 #twoweapon (unless the number_pad option is enabled) - - M-a #adjust - - - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1786,6 +1786,12 @@ + M-? #? (not supported by all platforms) + + M-2 #twoweapon (unless the number_pad option is enabled) + + M-a #adjust + M-A #annotate M-c #chat @@ -1834,15 +1840,9 @@ - If the number_pad option is on, some additional letter com- - mands are available: - - h #help - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1852,6 +1852,11 @@ + If the number_pad option is on, some additional letter com- + mands are available: + + h #help + j #jump k #kick @@ -1864,51 +1869,46 @@ 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. + 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 corridors 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 + Secret corridors are hidden and appear to be solid rock. + You can find them with the `s' (search) command when adjacent to them. Multiple search attempts may be needed. When searching is - successful, secret corridors become ordinary open corridor loca- - tions. Mapping magic reveals secret corridors, so converts them + successful, secret corridors become ordinary open corridor loca- + tions. Mapping magic reveals secret corridors, so converts them into ordinary corridors 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, + 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 at- + 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 at- tribute. - Open doors cannot be entered diagonally; you must approach - them straight on, horizontally or vertically. Doorways without + 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 + Unlocking magic exists but usually won't be available early on. You can get through a locked door without magic by first us- - ing an unlocking tool with the `a' (apply) command, and then + ing 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. Alternatively, 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) + 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. Alternatively, you can break a closed door + (whether locked or not) down by kicking it via the `^D' (kick) - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1918,63 +1918,63 @@ - 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 + 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 effec- + it. If you accede, success will eliminate the trap but failure + will set off the trap's explosion. (If you decline, you effec- tively forget that a trap was found there.) - Closed doors can be useful for shutting out monsters. Most - monsters 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 + Closed doors can be useful for shutting out monsters. Most + monsters 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. 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 + 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 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 + 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 someone else trigger it, or you discover it with - the `s' (search) command (multiple attempts are often needed; if - your luck is poor, many attempts might be needed). Wands of se- - cret door detection and spell of detect unseen also reveal traps - within a modest radius but only if the trap is also within line- + the `s' (search) command (multiple attempts are often needed; if + your luck is poor, many attempts might be needed). Wands of se- + cret 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 + 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, usual- - ly will avoid moving onto a trap which is shown on your map if + ly 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 adja- + Some traps such as pits, bear traps, and webs hold you in + one place. You can escape by simply trying to move to an adja- cent spot and repeat as needed; eventually you will get free. - Other traps can send you to different locations. Tele- - porters send you elsewhere on the same dungeon level. Level - teleporters send you to a random dungeon level, the destination - chosen from a few levels lower all the way to the top. 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. All of these traps choose a - new destination each time they're activated. Magic portals also - send you to a different level but behave differently. Some + Other traps can send you to different locations. Tele- + porters send you elsewhere on the same dungeon level. Level + teleporters send you to a random dungeon level, the destination + chosen from a few levels lower all the way to the top. Trap - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -1984,63 +1984,63 @@ - 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 necessarily - to a specific location there. + 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. All of these traps choose a + new destination each time they're activated. Magic portals also + send you to a different level but behave differently. Some por- + tals 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 necessarily 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." + 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 + 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 Sokoban game, you can only move in the four + beyond them. In the Sokoban game, you can only move in the four cardinal compass directions, 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 traditional rules of + 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 traditional 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. + 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 in- - to 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 section for information about getting + to 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 section 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 + 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 in- - stance, fairly early in the dungeon you will find a level with + to the next level. There are some exceptions though. For in- + stance, fairly early in the dungeon you will find a level with two down staircases, one continuing into the dungeon and the oth- - er 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 dun- + er 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 dun- geon. - When you traverse a set of stairs, or trigger a trap which - sends you to another level, the level you're leaving will be de- - activated and stored in a file on disk. If you're moving to a + When you traverse a set of stairs, or trigger a trap which + sends you to another level, the level you're leaving will be de- + activated 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 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 de- - scribed below). Monsters are only active on the current level; - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2050,63 +2050,63 @@ + 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 de- + scribed 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 + 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 occa- - sionally one of these creatures will displace you during the + sionally 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 + Ladders serve the same purpose as staircases, and the two + types of inter-level connections are nearly indistinguishable during game play. 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 + 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 us- + inquire about the price of an item prior to picking it up by us- ing the "#chat" command while standing on it. Using an item pri- or 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 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 shopkeeper isn't interested (generally, your item - needs to be compatible with the type of merchandise carried by + 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 shopkeeper 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. + 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 shop where it was obtained; other shopkeepers - won't honor it. (If you happen to find a "credit card" in the + 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 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.) - The `$' command, which reports the amount of gold you are + The `$' command, which reports the amount of gold you are carrying (in inventory, not inside bags or boxes), will also show - current shop debt or credit, if any. The "Iu" command lists un- + current shop debt or credit, if any. The "Iu" command lists un- paid items (those which still belong to the shop) if you are car- - rying any. The "Ix" command shows an inventory-like display of - any unpaid items which have been used up, along with other shop - fees, if any. + rying any. The "Ix" command shows an inventory-like display of + any unpaid items which have been used up, along with other shop - - - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2116,19 +2116,21 @@ + fees, if any. + 5.4.1. Shop idiosyncrasies Several aspects of shop behavior might be unexpected. * 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 + * 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 + * While the shopkeeper watches you like a hawk, he or she will generally ignore any other customers. - * If a shop is "closed for inventory," it will not open of its + * 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 inven- @@ -2136,43 +2138,41 @@ 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 + 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 + 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. + 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 num- - ber refers to the count of separate stacks of objects present - rather than the sum of the quantities of those stacks (so 7 ar- - rows 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 loca- + ber refers to the count of separate stacks of objects present + rather than the sum of the quantities of those stacks (so 7 ar- + rows 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 loca- tion). - The "nopickup" command prefix (default `m') can be used be- - fore a movement direction to step on objects without attempting + The "nopickup" command prefix (default `m') can be used be- + fore 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 + 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 + 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 any- - thing unless it is covered by one or more objects so is obscured - on the map. Setting this option to true will describe such + 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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2182,16 +2182,19 @@ - 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 ob- - jects, in which case the back on land circumstance is implied. + anything unless it is covered by one or more objects so is ob- + scured 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. Assum- + ing 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 re- + peat 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 im- + plied. 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 @@ -2210,35 +2213,32 @@ drawn 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 dungeon) is a tribute to the ancestor game hack's inspira- + tion rogue. + + It is usually displayed differently from other levels: pos- + sibly 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 differences 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.... + 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 do very well). - - The commands `/' and `;' may be used to obtain information - about those monsters who are displayed on the screen. The com- - mand "#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 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 mon- - sters 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 unless you attack them. Some of them are very dangerous - when angered. Remember: discretion is the better part of valor. + Monsters you cannot see are not displayed on the screen. + Beware! You may suddenly come upon one in a dark place. Some - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2248,63 +2248,63 @@ - In most circumstances, if you attempt to attack a peaceful - monster by moving into its location, you'll be asked to confirm - your intent. By default an answer of `y' acknowledges that in- - tent, which can be error prone if you're using `y' to move. You + 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 com- + mand "#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 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 mon- + sters 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 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 + monster by moving into its location, you'll be asked to confirm + your intent. By default an answer of `y' acknowledges that in- + tent, which can be error prone if you're using `y' to move. You can set the paranoid_confirmation option to require a response of "yes" instead. - 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 mon- + 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 mon- ster 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 re- + 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 re- member 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 mon- - sters with you. Like you, your pet needs food to survive. Dogs - and cats usually feed themselves on fresh carrion and other - meats; horses need vegetarian food which is harder to come by. - If you're worried about your pet or want to train it, you can + pony (`u'), which follows you about the dungeon and fights mon- + sters with you. Like you, your pet needs food to survive. Dogs + and cats usually feed themselves on fresh carrion and other + meats; horses need vegetarian 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 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 pets useful for low-level characters. - - 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-adjacent 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 rid- - den 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 or- - der 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. + 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 - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2314,63 +2314,63 @@ - Riding skill is managed by the "#enhance" command. See the + you, which makes pets useful for low-level characters. + + 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-adjacent 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 rid- + den 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 or- + der 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 section on Weapon proficiency for more information about that. Use the `a' (apply) command and pick a saddle in your inven- - tory to attempt to put that saddle on an adjacent creature. If + tory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. Use the "#loot" command while adjacent to a saddled creature - to try to remove the saddle from that creature. If successful, + 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 adventur- + You may encounter the shades and corpses of other adventur- ers (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 little damage. You can plunder the deceased - adventurer's possessions; however, they are likely to be cursed. + 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 last victory. 6.5. Persistence of Monsters Monsters (a generic reference which also includes humans and - pets) are only shown while they can be seen or otherwise sensed. - Moving to a location where you can't see or sense a monster any - more will result in it disappearing from your map, similarly if + pets) are only shown while they can be seen or otherwise sensed. + Moving 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 who moved rather than you. - 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 per- - sist 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 automatically by - walking over the object (unless you turn off the autopickup op- - tion (see below), or move with the `m' prefix (see above)), or - manually by using the `,' command. - - 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 de- - pends on your strength and your constitution. The stronger and + However, if you encounter a monster which you can't see or + sense--perhaps it is invisible and has just tapped you on the - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2380,63 +2380,63 @@ - sturdier you are, the less the additional load will affect you. + noggin--a special "remembered, unseen monster" marker will be + displayed at the location where you think it is. That will per- + sist 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 automatically by + walking over the object (unless you turn off the autopickup op- + tion (see below), or move with the `m' prefix (see above)), or + manually by using the `,' command. + + 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 de- + pends 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 encum- + you are carrying around with you through the dungeon will encum- ber you. Your reactions will get slower and you'll burn calories - faster, requiring food more frequently to cope with it. Eventu- - ally, you'll be so overloaded that you'll either have to discard + faster, requiring food more frequently to cope with it. Eventu- + ally, 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, Overtaxed, or Overloaded will be shown on the bottom + NetHack will tell you how badly you have loaded yourself. + If you are encumbered, one of the conditions Burdened, Stressed, + Strained, Overtaxed, or Overloaded will be shown on the bottom line status display. When you pick up an object, it is assigned an inventory let- - ter. Many commands that operate on objects must ask you to find - out which object you want to use. When NetHack asks you to + ter. 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 pre- - sented with a list of inventory letters to choose from (see Com- + sented with a list of inventory letters to choose from (see Com- mands, above). - Some objects, such as weapons, are easily differentiated. - Others, 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 + Some objects, such as weapons, are easily differentiated. + Others, 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 "#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 in- - stead 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 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 en- - chantments 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, a blessed weapon will do slightly more damage against - demons. - - Objects which are neither cursed nor blessed are referred to - as uncursed. They could just as easily have been described as + 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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2446,63 +2446,63 @@ - unblessed, but the uncursed designation is what you will see - within the game. A "glass half full versus glass half empty" + 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 in- + stead 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 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 en- + chantments 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, a blessed weapon will do slightly more damage against + demons. + + 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 + 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. - An item with unknown status will be reported in your inven- + An item with unknown status will be reported in your inven- tory with no prefix. An item which you know the state of will be - distinguished 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 + distinguished 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 information is displayed. The implicit_uncursed op- - tion can be used to control this; toggle it off to have uncursed + tion can be used to control 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 "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term + or "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term beatitude is occasionally used as well.) 7.2. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will - gratuitously 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 normally 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 cross- - bow 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 weapon's enchantment is to have it magically iden- - tified somehow. Most 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 (en- - chantment and/or erosion), experience level, strength, dexterity, - encumbrance, and proficiency (see below). The monster's armor + Given a chance, most monsters in the Mazes of Menace will + gratuitously try to kill you. You need weapons for self-defense + (killing them first). Without a weapon, you do only 1-2 hit - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2512,63 +2512,63 @@ - class--a general defense rating, not necessarily due to wearing - of armor--is a factor too; also, some monsters are particularly + points of damage (plus bonuses, if any). Monk characters are an + exception; they normally 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 cross- + bow 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 weapon's enchantment is to have it magically iden- + tified somehow. Most 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 (en- + chantment and/or erosion), experience level, strength, dexterity, + encumbrance, and proficiency (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 simul- + 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 simul- taneously as primary and secondary; use the `X' command to engage - or disengage that. Only some types of characters (barbarians, + or disengage that. Only some types of characters (barbarians, for instance) have the necessary skill available. Even with that - skill, using two weapons at once incurs a penalty in the chance + 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 all. To accomplish that, wield `-', or else use the `A' com- - mand which allows you to unwield the current weapon in addition + There might be times when you'd rather not wield any weapon + at all. To accomplish that, wield `-', or else use the `A' com- + mand which 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 + 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 dam- - age to monsters in NetHack. Some of the more obscure weapons + age to monsters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to Unearthed Arcana, an AD&D supplement. - The commands to use weapons are `w' (wield), `t' (throw), - `f' (fire, an alternate way of throwing), `Q' (quiver), `x' (ex- + The commands to use weapons are `w' (wield), `t' (throw), + `f' (fire, an alternate way of throwing), `Q' (quiver), `x' (ex- change), `X' (twoweapon), and "#enhance" (see below). - 7.2.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 target. The distance something can be thrown de- - pends 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. - - 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. - - - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2578,63 +2578,63 @@ - Some characters have the ability to fire a volley of multi- - ple items in a single turn. Knowing how to load several rounds + 7.2.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 target. The distance something can be thrown de- + pends 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. + + 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. + + Some characters have the ability to fire a volley of multi- + ple items in a single turn. 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 wield- - ing 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 + 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 wield- + ing 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 lim- - it the number of shots by using a numeric prefix before the `t' - or `f' command. For 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 shoot- - ing the same number (3, here) as if no limit had been specified. + it the number of shots by using a numeric prefix before the `t' + or `f' command. For 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 shoot- + ing 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 + same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.2.2. Weapon proficiency You will have varying degrees of skill in the weapons avail- - able. Weapon proficiency, or weapon skills, affect how well you - can use particular types of weapons, and you'll be able to im- - prove your skills as you progress through a game, depending on + able. Weapon proficiency, or weapon skills, affect how well you + can use particular types of weapons, and you'll be able to im- + prove your skills as 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 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" (some- - times also referred to as "restricted", because you won't be able - to advance), "unskilled", "basic", "skilled", and "expert". Re- - stricted skills simply will not appear in the list shown by "#en- - hance". (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 "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 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 + 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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2644,63 +2644,63 @@ - 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 your to- - tal overall skills, so you need to actively choose which skills + 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" (some- + times also referred to as "restricted", because you won't be able + to advance), "unskilled", "basic", "skilled", and "expert". Re- + stricted skills simply will not appear in the list shown by "#en- + hance". (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 "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 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 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 your to- + tal overall skills, so you need to actively choose which skills to enhance and which to ignore. 7.2.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 + up to do so can seem cumbersome but becomes second nature with use. To wield two weapons, you need to use the "#twoweapon" com- - mand. But first you need to have a weapon in each hand. (Note - that your two weapons are not fully equal; the one in the hand - you normally wield with is considered primary and the other one + mand. But first you need to have a weapon in each hand. (Note + that your two 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 + you stop--or before you begin, for that matter--wielding two weapons at once. The primary is your wielded weapon and the sec- - ondary is just an item in your inventory that's been designated + ondary 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 + 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 + if neither hand holds the correct weapon, use `w', `x', `w' to first wield the intended secondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the push- - weapon option. When it is enabled, then using `w' to wield some- - thing causes the currently wielded weapon to become your alter- - nate 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 posi- - tion. - - When in two-weapon combat mode, using the `X' command tog- - gles back to single-weapon mode. Throwing or dropping either of - the weapons or having one of them be stolen or destroyed will al- - so make you revert to single-weapon combat. - - 7.3. Armor (`[') - - Lots of unfriendly things lurk about; you need armor to pro- - tect yourself from their blows. Some types of armor offer better - protection than others. Your armor class is a measure of this - protection. Armor class (AC) is measured as in AD&D, with 10 be- - ing 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. - NetHack 3.7 November 16, 2020 + + NetHack 3.7 November 30, 2020 @@ -2710,7 +2710,30 @@ - Here is a list of the armor class values provided by suits + The whole process can be simplified via use of the push- + weapon option. When it is enabled, then using `w' to wield some- + thing causes the currently wielded weapon to become your alter- + nate 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 posi- + tion. + + When in two-weapon combat mode, using the `X' command tog- + gles back to single-weapon mode. Throwing or dropping either of + the weapons or having one of them be stolen or destroyed will al- + so make you revert to single-weapon combat. + + 7.3. Armor (`[') + + Lots of unfriendly things lurk about; you need armor to pro- + tect yourself from their blows. Some types of armor offer better + protection than others. Your armor class is a measure of this + protection. Armor class (AC) is measured as in AD&D, with 10 be- + ing 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 armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -2724,49 +2747,26 @@ 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 even further. Most of these provide a one or two - point improvement to 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. + 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 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 corrosion to suits worn un- der them and against some monster touch attacks. - 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 + 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 immediately find out the armor class and any - "plusses" it provides. Cursed pieces of armor usually have nega- - tive enchantments (minuses) in addition 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 in- - hibit spell casting. - - The nudist option can be set (prior to game start) to at- - tempt to play the entire game without wearing any armor (a self- - imposed challenge which is extremely difficult to accomplish). - - 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 nor- - mally for accessories 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.4. 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 + your armor class one unit further to 4. When you put on a piece + of armor, you immediately find out the armor class and any + "plusses" it provides. Cursed pieces of armor usually have - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2776,63 +2776,63 @@ - usually stay fresh, but ice boxes are heavy, and tins take a - while to open. + negative enchantments (minuses) in addition 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 in- + hibit spell casting. + + The nudist option can be set (prior to game start) to at- + tempt to play the entire game without wearing any armor (a self- + imposed challenge which is extremely difficult to accomplish). + + 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 nor- + mally for accessories 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.4. 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 usual- + ly 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 + 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 what you eat." Some character roles and some monsters are vegetarian. Veg- - etarian monsters will typically never eat animal corpses, while - vegetarian players can, but with some rather unpleasant side-ef- + etarian monsters will typically never eat animal corpses, while + vegetarian players can, but with some rather unpleasant side-ef- fects. - You can name one food item after something you like to eat + You can name one food item after something you like to eat with the fruit option. The command to eat food is `e'. 7.5. Scrolls (`?') - Scrolls are labeled with various titles, probably chosen by + 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 + 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, + 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 ob- - jects of subtle enchantment are difficult to identify without + is cursed or blessed, and how many uses it has left. Some ob- + jects of subtle enchantment are difficult to identify without these. - 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" en- - vironment variable to the file name of your mailbox. You may al- - so 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. - - The command to read a scroll is `r'. - - 7.6. Potions (`!') - - 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 of the undead, so potions of holy water are good - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2842,63 +2842,63 @@ - things to throw (`t') at them. It is also sometimes very useful + 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" en- + vironment variable to the file name of your mailbox. You may al- + so 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. + + The command to read a scroll is `r'. + + 7.6. Potions (`!') + + 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 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. The command to drink a potion is `q' (quaff). 7.7. Wands (`/') - Wands usually have multiple magical charges. Some types of + 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, however, for this is often unwise. Other types of wands - don't require a direction. The number of charges in a wand is + them at yourself (just give a `.' or `s' for the direction). Be + warned, however, 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, at- - tempts to use the wand will usually result in nothing happening. + When the number of charges left in a wand becomes zero, at- + tempts to use the wand will usually result in nothing happening. Occasionally, 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 + 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 cer- + 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 cer- tainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory - display will include additional information in parentheses: the - number of times it has been recharged followed by a colon and - then by its current 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 `a' (apply) command. - - 7.8. Rings (`=') - - Rings are very useful items, since they are relatively per- - manent magic, unlike the usually fleeting effects of potions, - scrolls, and wands. - - 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 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 manually take them off before putting on or remov- - ing a ring and then re-wear them after. That's done implicitly + When you have fully identified a particular wand, inventory + display will include additional information in parentheses: the + number of times it has been recharged followed by a colon and - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2908,6 +2908,29 @@ + then by its current 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 `a' (apply) command. + + 7.8. Rings (`=') + + Rings are very useful items, since they are relatively per- + manent magic, unlike the usually fleeting effects of potions, + scrolls, and wands. + + 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 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 manually take them off before putting on or remov- + ing 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). @@ -2916,55 +2939,32 @@ 7.9. Spellbooks (`+') 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 + `r' (read) command, they transfer to the reader the knowledge of + a spell (and therefore eventually become unreadable)--unless the attempt backfires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! - 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 the energy and the time required in + 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 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 within you. Casting temporarily drains your magical + 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 ad- - ditional food. Casting of spells also requires practice. With - practice, your skill in each category of spell casting will im- - prove. Over time, however, your memory of each spell will dim, + ditional food. Casting of spells also requires practice. With + practice, your skill in each category of spell casting will im- + prove. Over time, however, your memory of each spell will dim, and you will need to relearn it. Some spells require a direction in which to cast them, simi- - lar to wands. To cast one at yourself, just give a `.' or `s' - for the direction. A few spells require you to pick a target lo- - cation 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 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".) - - Casting a spell also requires flexible movement, and wearing - various 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 level, skill category, chance of failure when casting, and an - estimate of how strongly it is remembered. The `Z' (cast) com- - mand casts a spell. + lar to wands. To cast one at yourself, just give a `.' or `s' - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -2974,18 +2974,42 @@ + for the direction. A few spells require you to pick a target lo- + cation 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 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".) + + Casting a spell also requires flexible movement, and wearing + various 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 level, skill category, chance of failure when casting, and an + estimate of how strongly it is remembered. The `Z' (cast) com- + mand casts a spell. + 7.10. Tools (`(') Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For - example, lamps burn out after a while. Other tools are contain- + tools have a limited number of uses, akin to wand charges. For + example, lamps burn out after a while. Other tools are contain- ers, 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 + 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 + 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 @@ -2996,41 +3020,17 @@ 7.10.1. Containers - You may encounter bags, boxes, and chests in your travels. - A tool of this sort can be opened with the "#loot" extended com- - mand when you are standing on top of it (that is, on the same - floor spot), or with the `a' (apply) command when you are carry- - ing it. However, chests are often locked, and are in any case - unwieldy objects. You must set one down before unlocking it by + You may encounter bags, boxes, and chests in your travels. + A tool of this sort can be opened with the "#loot" extended com- + mand when you are standing on top of it (that is, on the same + floor spot), or with the `a' (apply) command when you are carry- + ing 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' command, 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 with the "#untrap" extended command. - - 7.11. Amulets (`"') - - Amulets are very similar to rings, and often more powerful. - Like rings, amulets have various magical properties, some benefi- - cial, 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 to grow hungry more rapidly. - - 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 normally 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. + kicking it with the `^D' command, or by using a weapon to force - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3040,63 +3040,63 @@ + 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 with the "#untrap" extended command. + + 7.11. Amulets (`"') + + Amulets are very similar to rings, and often more powerful. + Like rings, amulets have various magical properties, some benefi- + cial, 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 to grow hungry more rapidly. + + 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 normally 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.12. 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. + 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 projec- - tile weapons (if you have a sling). In the most desperate of + much less valuable. All rocks, however, can be used as projec- + tile weapons (if you have a sling). In the most desperate of cases, you can still throw them by hand. 7.13. Large rocks (``') - Statues and boulders are not particularly useful, and are - generally heavy. It is rumored that some statues are not what + Statues and boulders are not particularly useful, and are + generally heavy. It is rumored that some statues are not what they seem. - Boulders occasionally block your path. You can push one + 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 pick-axe. Very large humanoids (giants and - their ilk) have been known to pick up boulders and use them as + its path, or you can smash it into a pile of small rocks with + breaking magic or a pick-axe. 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 + 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 instead. - - 7.14. 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 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 de- - scribed 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 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.15. Persistence of Objects - - Normally, if you have seen an object at a particular map lo- - cation 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 - NetHack 3.7 November 16, 2020 + + NetHack 3.7 November 30, 2020 @@ -3106,63 +3106,63 @@ - more--perhaps a monster has picked it up or it has rotted away-- - until you can see or feel that location again. One notable ex- - ception is that if the object gets covered by the "remembered, - unseen monster" marker. When that marker is later removed after + For some configurations of the program, statues are no + longer shown as ``' but by the letter representing the monster + they depict instead. + + 7.14. 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 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 de- + scribed 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 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.15. Persistence of Objects + + Normally, if you have seen an object at a particular map lo- + cation 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 ex- + ception is that if the object gets covered 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, + 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-discov- er 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 op- - tion can be enabled in order to show an item differently when it + only the top item of the pile is displayed. The hilite_pile op- + tion 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 challenges, 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 + 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 challenges, 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 most difficult of these is the foodless challenge. Although - creatures can survive long periods of time without food, there is - a physiological need for water; thus there is no restriction on - drinking beverages, even if they provide some minor food bene- - fits. 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 veg- - etables. 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 normally indigestible material eaten - while polymorphed into a creature that can digest it is also con- - sidered vegan food. Note however that eating such items still - counts against foodless conduct. - - Vegetarians do not eat animals; however, they are less se- - lective 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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3172,63 +3172,63 @@ + 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 physiological need for water; thus there is no restriction on + drinking beverages, even if they provide some minor food bene- + fits. 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 veg- + etables. 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 normally indigestible material eaten + while polymorphed into a creature that can digest it is also con- + sidered vegan food. Note however that eating such items still + counts against foodless conduct. + + Vegetarians do not eat animals; however, they are less se- + lective 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 - foodless 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 + Eating any kind of meat violates the vegetarian, vegan, and + foodless 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 polymorphed is treated as if you ate the creature's - corpse. Eating leather, dragon hide, or bone items while poly- - morphed into a creature that can digest it, or eating monster + corpse. Eating leather, dragon hide, or bone items while poly- + morphed 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 - indigestible, and others which are hazardous to eat. Using a + Regardless of conduct, there will be some items which are + indigestible, and others which are hazardous to eat. Using a swallow-and-digest attack against a monster is equivalent to eat- - ing 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 + ing 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 contain milk, so they are - compatible with a vegan diet. Slime molds or player-defined - "fruits", although they could be anything from "cherries" to + compatible with a vegan diet. Slime molds or player-defined + "fruits", although they could be anything from "cherries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you - cannot #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 con- - duct; 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 be- - ing 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. - - 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 particularly difficult challenge, although it is still - possible to gain experience by other means. - - An illiterate character does not read or write. This in- - cludes reading a scroll, spellbook, fortune cookie message, or t- - shirt; writing 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) + cannot #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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3238,63 +3238,63 @@ - in your starting inventory is assumed to be learned from your + 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 other religious + figure; a true atheist would hear the words but attach no special + meaning to them. + + 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 particularly difficult challenge, although it is still + possible to gain experience by other means. + + An illiterate character does not read or write. This in- + cludes reading a scroll, spellbook, fortune cookie message, or t- + shirt; writing 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 men- + briefly described in the earlier section about Traps. As men- tioned 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 + 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 diago- + that are active when in that branch of the dungeon. Some rules + can't be bypassed, such as being unable to push a boulder diago- nally. 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, providing you with + 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, providing 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 ac- - tions in the future. (Note: the Sokoban conduct will only be - displayed if you have entered the Sokoban branch of the dungeon + tions 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 disclosed conduct even if you haven't done anything interest- - ing there. Ending the game with "never broke the Sokoban rules" + of disclosed conduct even if you haven't done anything interest- + ing there. Ending the game with "never broke the Sokoban rules" conduct is most meaningful if you also manage to perform the "ob- tained the Sokoban prize" achievement (see Achievements below).) - There are several other challenges tracked by the game. It + There are several other challenges tracked by the game. It is possible to eliminate one or more species of monsters by geno- - cide; 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, spell, or potion of polymorph; - avoiding these effects are each considered challenges. Polymor- - phing 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 challenge, as is a - game without wishing for an artifact (even if the artifact imme- - diately disappears). When the game offers you an opportunity to - make a wish for an item, you may choose "nothing" if you want to - decline. - - 8.1. Achievements - - End of game disclosure will also display various achieve- - ments 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. - - - Attained rank title . + cide; playing without this feature is considered a challenge. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3304,6 +3304,31 @@ + 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, spell, or potion of polymorph; + avoiding these effects are each considered challenges. Polymor- + phing 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 challenge, as is a + game without wishing for an artifact (even if the artifact imme- + diately disappears). When the game offers you an opportunity to + make a wish for an item, you may choose "nothing" if you want to + decline. + + 8.1. Achievements + + End of game disclosure will also display various achieve- + ments 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. + + - Attained rank title . Shop - Entered a shop. Temple - Entered a temple. Mines - Entered the Gnomish Mines. @@ -3331,36 +3356,11 @@ Notes: - 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 ex- - perience levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for - experience level 1 is not recorded as an achievement. Losing - enough levels to revert to lower rank(s) does not discard the - corresponding achievement(s). - - There's no guaranteed Novel so the achievement to read one - might not always be attainable (except perhaps by wishing). Sim- - ilarly, 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 achievement. - - The Medusa achievement is recorded if she dies for any rea- - son, even if you are not directly responsible, and only if she - dies. - - Blind and Nudist are also conducts, and they can only be en- - abled by setting the correspondingly named option in + Achievements are recorded and subsequently reported in the + order in which they happen during your current game rather than - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3370,25 +3370,50 @@ - NETHACKOPTIONS or run-time configuration file prior to game - start. In the case of Blind, the option also enforces the con- - duct. They aren't really significant accomplishments unless/un- - til you make substantial progress into the dungeon. + the order listed here. + + There are nine titles for each role, bestowed at ex- + perience levels 1, 3, 6, 10, 14, 18, 22, 26, and 30. The one for + experience level 1 is not recorded as an achievement. Losing + enough levels to revert to lower rank(s) does not discard the + corresponding achievement(s). + + There's no guaranteed Novel so the achievement to read one + might not always be attainable (except perhaps by wishing). Sim- + ilarly, 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 achievement. + + The Medusa achievement is recorded if she dies for any rea- + son, even if you are not directly responsible, and only if she + dies. + + Blind and Nudist are also conducts, and they can only be en- + abled by setting the correspondingly named option in NETHACKOP- + TIONS or run-time configuration file prior to game start. In the + case of Blind, the option also enforces the conduct. They aren't + really significant accomplishments unless/until you make substan- + tial progress into the dungeon. 9. Options - Due to variations in personal tastes and conceptions of 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, + 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 file, or in the NETHACKOPTIONS environment vari- + them. You can also set options automatically by placing them in + a configuration file, or in the NETHACKOPTIONS environment vari- able. Some versions of NetHack also have front-end programs that - allow you to set options before starting the game or a global + allow you to set options before starting the game or a global configuration for system administrators. 9.2. Using a configuration file @@ -3396,37 +3421,12 @@ The default name of the configuration file varies on differ- ent operating systems. - On UNIX, Linux, and Mac OS X it is ".nethackrc" in the us- - er's home directory. The file may not exist, but it is a normal + On UNIX, Linux, and Mac OS X it is ".nethackrc" in the us- + er'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, it is ".nethackrc" in the folder "\%USERPRO- - FILE%\NetHack\3.6". The file may not exist, but it is a normal - ASCII text file can can be created with any text editor. After - running NetHack for the first time, you should find a default - template for the configuration file named ".nethackrc.template" - in "\%USERPROFILE%\NetHack\3.6". If you had not created the con- - figuration file, NetHack will create the configuration file 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 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 directive and their names are case insensi- - tive. Lines after a section marker belong to that section up un- - til another section starts or a marker without a name is encoun- - tered or the file ends. Lines within sections are ignored unless - a CHOOSE directive has selected that section. - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3436,7 +3436,32 @@ - You can use different configuration directives in the file, + On Windows, it is ".nethackrc" in the folder "\%USERPRO- + FILE%\NetHack\3.6". The file may not exist, but it is a normal + ASCII text file can can be created with any text editor. After + running NetHack for the first time, you should find a default + template for the configuration file named ".nethackrc.template" + in "\%USERPROFILE%\NetHack\3.6". If you had not created the con- + figuration file, NetHack will create the configuration file 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 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 directive and their names are case insensi- + tive. Lines after a section marker belong to that section up un- + til another section starts or a marker without a name is encoun- + tered or the file ends. Lines within sections are ignored unless + a CHOOSE directive has selected that section. + + You can use different configuration directives in the file, some of which can be used multiple times. In general, the direc- tives are written in capital letters, followed by an equals sign, followed by settings particular to that directive. @@ -3444,14 +3469,14 @@ 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 op- - tions take more diverse values. Prefix a boolean option with - "no" or `!' to turn it off. For compound options, the option + There are two types of options, boolean and compound options. + Boolean options toggle a setting on or off, while compound op- + tions 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 per- sistent, and apply only to new games. You can specify multiple OPTIONS directives, and multiple options separated by commas in - a single OPTIONS directive. (Comma separated options are pro- + a single OPTIONS directive. (Comma separated options are pro- cessed from right to left.) Example: @@ -3460,39 +3485,14 @@ OPTIONS=!legacy,autopickup,pickup_types:$"=/!?+ HACKDIR - 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 neces- + 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 neces- sary or recommended. - LEVELDIR - 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. - - BONESDIR - The location that bones files are kept. Defaults to HACKDIR, - must be writable. - - LOCKDIR - The location that file synchronization locks are stored. - Defaults to HACKDIR, must be writable. - - TROUBLEDIR - 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. Autocom- - pletion has no effect for the X11 windowport. You can specify - multiple autocompletions. To enable autocompletion, list the - extended command. Prefix the command with "!" to disable the - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3502,6 +3502,31 @@ + LEVELDIR + 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. + + BONESDIR + The location that bones files are kept. Defaults to HACKDIR, + must be writable. + + LOCKDIR + The location that file synchronization locks are stored. + Defaults to HACKDIR, must be writable. + + TROUBLEDIR + 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. Autocom- + pletion has no effect for the X11 windowport. You can specify + multiple autocompletions. To enable autocompletion, list the + extended command. Prefix the command with "!" to disable the autocompletion for that command. Example: @@ -3509,13 +3534,13 @@ AUTOCOMPLETE=zap,!annotate AUTOPICKUP_EXCEPTION - Set exceptions to the pickup_types option. See the "Configur- + Set exceptions to the pickup_types option. See the "Configur- ing Autopickup Exceptions" section. BINDINGS - Change the key bindings of some special keys, menu accelera- + Change the key bindings of some special keys, menu accelera- tors, or extended commands. You can specify multiple bindings. - Format is key followed by the command, separated by a colon. + Format is key followed by the command, separated by a colon. See the "Changing Key Bindings" section for more information. Example: @@ -3523,11 +3548,26 @@ BIND=^X:getpos.autodescribe CHOOSE - Chooses at random one of the comma-separated parameters as an + Chooses at random one of the comma-separated parameters as an active section name. Lines in other sections are ignored. Example: + + + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 55 + + + OPTIONS=color CHOOSE=char A,char B [char A] @@ -3537,9 +3577,9 @@ [] #end of CHOOSE OPTIONS=!rest_on_space - If [] is present, the preceding section is closed and no new - section begins; whatever follows will be common to all sec- - tions. Otherwise the last section extends to the end of the + If [] is present, the preceding section is closed and no new + section begins; whatever follows will be common to all sec- + tions. Otherwise the last section extends to the end of the options file. MENUCOLOR @@ -3547,36 +3587,24 @@ ing Menu Colors" section. MSGTYPE - Change the way messages are shown in the top status line. See + Change the way messages are shown in the top status line. See the "Configuring Message Types" section. ROGUESYMBOLS - Custom symbols for for the rogue level's symbol set. See SYM- + Custom symbols for for the rogue level's symbol set. See SYM- BOLS below. SOUND - Define a sound mapping. See the "Configuring User Sounds" - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 55 - - - - section. + Define a sound mapping. See the "Configuring User Sounds" sec- + tion. SOUNDDIR - Define the directory that contains the sound files. See the + Define the directory that contains the sound files. See the "Configuring 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 + 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: @@ -3585,9 +3613,9 @@ SYMBOLS=S_boulder:0,S_golem:7 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 + 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. Example: @@ -3596,6 +3624,18 @@ + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 56 + + + + + Here is an example of configuration file contents: # Set your character's role, race, gender, and alignment. @@ -3618,24 +3658,12 @@ 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. 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" - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 56 - - - - before the name. Others take a character string as a value. You - can set string options by typing the option name, a colon or + 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" be- + fore 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 ter- minated by the next comma or the end of string. @@ -3645,7 +3673,7 @@ % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" - in csh (note the need to escape the `!' since it's special to + 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" @@ -3655,42 +3683,14 @@ 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 + 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. If it does start with `/', the at-sign is op- - tional. - - 9.4. Customization options - - Here are explanations of what the various options do. Char- - acter 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 with the game. Changing a persistent option in the config- - uration file applies only to new games. - - acoustics - Enable messages about what your character hears (default on). - Note that this has nothing to do with your computer's audio ca- - pabilities. Persistent. - - align - Your starting alignment (align:lawful, align:neutral, or - align:chaotic). You may specify just the first letter. The - default is to randomly pick an appropriate alignment. If you - prefix the value with `!' or "no", you will exclude that align- - ment from being picked randomly. Cannot be set with the `O' - command. Persistent. - NetHack 3.7 November 16, 2020 + + NetHack 3.7 November 30, 2020 @@ -3700,8 +3700,38 @@ + 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. If it does start with `/', the at-sign is op- + tional. + + 9.4. Customization options + + Here are explanations of what the various options do. Char- + acter 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 with the game. Changing a persistent option in the config- + uration file applies only to new games. + + acoustics + Enable messages about what your character hears (default on). + Note that this has nothing to do with your computer's audio ca- + pabilities. Persistent. + + align + Your starting alignment (align:lawful, align:neutral, or + align:chaotic). You may specify just the first letter. The + default is to randomly pick an appropriate alignment. If you + prefix the value with `!' or "no", you will exclude that align- + ment from being picked randomly. Cannot be set with the `O' + command. Persistent. + autodescribe - Automatically describe the terrain under cursor when asked to + Automatically describe the terrain under cursor when asked to get a location on the map (default true). The whatis_coord op- tion controls whether the description includes map coordinates. @@ -3710,23 +3740,36 @@ into a place that can be dug (default false). Persistent. autoopen - Walking into a closed door attempts to open it (default true). + Walking into a closed door attempts to open it (default true). Persistent. autopickup - Automatically pick up things onto which you move (default on). + Automatically pick up things onto which you move (default on). Persistent. See pickup_types to refine the behavior. 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 ready some suitable weapon. Note that it - will not take into account the blessed/cursed status, enchant- - ment, damage, or quality of the weapon; you are free to manual- - ly 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. + 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, enchant- + ment, damage, or quality of the weapon; you are free to + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 58 + + + + 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. Persis- + tent. autounlock Walking into a locked door or looting a locked container while @@ -3754,18 +3797,6 @@ Synonym for "role" to pick the type of your character (for ex- ample "character:Monk"). See role for more details. - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 58 - - - checkpoint Save game state after each level change, for possible recovery after program crash (default on). Persistent. @@ -3789,6 +3820,18 @@ disclose Controls what information the program reveals when the game ends. Value is a space separated list of prompting/category + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 59 + + + pairs (default is "ni na nv ng nc no", prompt with default re- sponse of `n' for each candidate). Persistent. The possibili- ties are: @@ -3820,18 +3863,6 @@ answering `y' rather than `a', will default to showing monsters in the traditional order, from high level to low level. - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 59 - - - Omitted categories are implicitly added with `n' prefix. Spec- ified categories with omitted prefix implicitly use `+' prefix. Order of the disclosure categories does not matter, program @@ -3854,41 +3885,10 @@ extmenu Changes the extended commands interface to pop-up a menu of - available commands. It is keystroke compatible with the tradi- - tional 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 avail- - able commands (on) or just the subset of commands which have - traditionally been considered extended ones (off). - - female - An obsolete synonym for "gender:female". Cannot be set with - the `O' command. - - 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 inventory letters. Persistent. - - force_invmenu - 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 - "fruit:mango") (default "slime mold"). Basically a nostalgic - whimsy that NetHack uses from time to time. You should set - this to something 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 + available commands. It is keystroke compatible with the - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3898,63 +3898,63 @@ - specify just the first letter. Although you can still denote + 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 avail- + able commands (on) or just the subset of commands which have + traditionally been considered extended ones (off). + + female + An obsolete synonym for "gender:female". Cannot be set with + the `O' command. + + 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 inventory letters. Persistent. + + force_invmenu + 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 + "fruit:mango") (default "slime mold"). Basically a nostalgic + whimsy that NetHack uses from time to time. You should set + this to something 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 + specify just the first letter. Although you can still denote your gender using the "male" and "female" options, the "gender" - option will take precedence. The default is to randomly pick - an appropriate gender. If you prefix the value with `!' or - "no", you will exclude that gender from being picked randomly. + option will take precedence. The default is to randomly pick + an appropriate gender. If you prefix the value with `!' or + "no", you will exclude that gender from being picked randomly. 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 de- - fault). Gold is never blessed or cursed, but it is not de- + 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 de- + fault). Gold is never blessed or cursed, but it is not de- scribed as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with + If more information is available for an object looked at with the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the "More info?" prompt, but it also + ing help off makes just looking at things faster, since you + aren't interrupted with the "More info?" prompt, but it also means that you might miss some interesting and/or important in- formation. Persistent. - 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. Same as "#herecmdmenu" and "#therecmdmenu" com- - mands. - hilite_pet - 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 curses interface, the petattr option controls how to - 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-symbol beside the object on the top of the pile. - - hitpointbar - Show a hit point bar graph behind your name and title. Only - available for TTY and Windows GUI, and only when statushilites - is on. - - horsename - Name your starting horse (for example "horsename:Trigger"). - - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -3964,6 +3964,37 @@ + 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. Same as "#herecmdmenu" and "#therecmdmenu" com- + mands. + + hilite_pet + 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 curses interface, the petattr option controls how to + 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-symbol beside the object on the top of the pile. + + hitpointbar + Show a hit point bar graph behind your name and title. Only + available for TTY and Windows GUI, and only when statushilites + is on. + + horsename + Name your starting horse (for example "horsename:Trigger"). Cannot be set with the `O' command. ignintr @@ -3972,7 +4003,7 @@ implicit_uncursed Omit "uncursed" from object descriptions when it can be deduced - from other aspects of the description (default on). Persis- + from other aspects of the description (default on). Persis- tent. If you use menu coloring, you may want to turn this off. @@ -3982,45 +4013,14 @@ on). Persistent. lit_corridor - Show corridor squares seen by night vision or a light source + Show corridor squares seen by night vision or a light source held by 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', 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' command. - - mention_decor - Give feedback when walking onto various dungeon features such - as stairs, fountains, or altars which are ordinarily only de- - scribed when covered by one or more objects (default off). - Persistent. - - mention_walls - Give feedback when walking against a wall (default off). Per- - sistent. - - menucolors - Enable coloring menu lines (default off). See "Configuring - Menu Colors" on how to configure the colors. - - menustyle - Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for early versions; it - consists of a prompt for object class characters, followed by + When using a menu to interact with a container, use the old - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4030,63 +4030,63 @@ - an object-by-object prompt for all items matching the selected - object class(es). Combination starts with a prompt for object + `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' command. + + mention_decor + Give feedback when walking onto various dungeon features such + as stairs, fountains, or altars which are ordinarily only de- + scribed when covered by one or more objects (default off). + Persistent. + + mention_walls + Give feedback when walking against a wall (default off). Per- + sistent. + + menucolors + Enable coloring menu lines (default off). See "Configuring + Menu Colors" on how to configure the colors. + + menustyle + Controls the interface used when you need to choose various ob- + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for 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 interest, but then displays a menu of matching ob- - jects 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. Partial skips the ob- + jects 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. Partial skips the ob- ject class filtering and immediately displays a menu of all ob- jects. Persistent. menu_deselect_all - Menu character accelerator to deselect all items in a menu. + Menu character accelerator to deselect all items in a menu. Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- fault `\'. menu_first_page Menu character accelerator to jump to the first page in a menu. Implemented by the Amiga, Gem and tty ports. Default `^'. - menu_headings - Controls how the headings in a menu are highlighted. Values - are "none", "bold", "dim", "underline", "blink", or "inverse". - Not all ports can actually display all types. - - menu_invert_all - Menu character accelerator to invert all items in a menu. Im- - plemented by the Amiga, Gem, X11 and tty ports. Default `@'. - - menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default - `~'. - - menu_last_page - Menu character accelerator to jump to the last page in a menu. - Implemented by the Amiga, Gem and tty ports. Default `|'. - - menu_next_page - Menu character accelerator to goto the next menu page. Imple- - mented by the Amiga, Gem and tty ports. Default `>'. - - menu_objsyms - Show object symbols in menu headings in menus where the object - symbols act as menu accelerators (default off). - - menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- - fault on) - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4096,21 +4096,52 @@ + menu_headings + Controls how the headings in a menu are highlighted. Values + are "none", "bold", "dim", "underline", "blink", or "inverse". + Not all ports can actually display all types. + + menu_invert_all + Menu character accelerator to invert all items in a menu. Im- + plemented by the Amiga, Gem, X11 and tty ports. Default `@'. + + menu_invert_page + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default + `~'. + + menu_last_page + Menu character accelerator to jump to the last page in a menu. + Implemented by the Amiga, Gem and tty ports. Default `|'. + + menu_next_page + Menu character accelerator to goto the next menu page. Imple- + mented by the Amiga, Gem and tty ports. Default `>'. + + menu_objsyms + Show object symbols in menu headings in menus where the object + symbols act as menu accelerators (default off). + + menu_overlay + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- + fault on) + menu_previous_page Menu character accelerator to goto the previous menu page. Im- plemented by the Amiga, Gem and tty ports. Default `<'. menu_search - Menu character accelerator to search for a menu item. Imple- + Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default `:'. menu_select_all - Menu character accelerator to select all items in a menu. Im- + Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `.'. menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `,'. monpolycontrol @@ -4118,41 +4149,10 @@ off). Debug mode only. mouse_support - Allow use of the mouse for input and travel. Valid settings - are: - - 0 - disabled - 1 - enabled and make OS adjustments to support mouse use - 2 - like 1 but does not make any OS adjustments - - Omitting a value is the same as specifying 1 and negating - mouse_support is the same as specifying 0. - - msghistory - 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. - Currently 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); - c - combination, two messages as "single", then as "full"; - 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 "single"). - - 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 + Allow use of the mouse for input and travel. Valid settings - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4162,9 +4162,40 @@ + are: + + 0 - disabled + 1 - enabled and make OS adjustments to support mouse use + 2 - like 1 but does not make any OS adjustments + + Omitting a value is the same as specifying 1 and negating + mouse_support is the same as specifying 0. + + msghistory + 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. + Currently 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); + c - combination, two messages as "single", then as "full"; + 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 "single"). + + 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 one will be automatically chosen. Cannot + -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. Cannot be set with the `O' command. news @@ -4179,46 +4210,15 @@ Send padding nulls to the terminal (default on). Persistent. number_pad - Use digit keys instead of letters to move (default 0 or off). + Use digit keys instead of letters to move (default 0 or off). Valid settings are: 0 - move by letters; "yuhjklbn" 1 - move by numbers; digit `5' acts as `G' movement prefix 2 - like 1 but `5' works as `g' prefix instead of as `G' - 3 - by numbers using phone key layout; 123 above, 789 below - 4 - combines 3 with 2; phone layout plus MS-DOS compatibility - -1 - by letters but use `z' to go northwest, `y' to zap wands - - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 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 accommo- - date some QWERTZ keyboards 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 - "")[%?+!=/(*`0_"). The value of this option should be a string - containing the symbols for the various object types. Any omit- - ted 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_confirma- - tion:pray. - - Confirm - for any prompts which are set to require "yes" - rather than `y', also require "no" to reject in- - stead of accepting any non-yes response as no - quit - require "yes" rather than `y' to confirm quitting - the game or switching into non-scoring explore - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4228,42 +4228,85 @@ + 3 - by numbers using phone key layout; 123 above, 789 below + 4 - combines 3 with 2; phone layout plus MS-DOS compatibility + -1 - by letters but use `z' to go northwest, `y' to zap wands + + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 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 accommo- + date some QWERTZ keyboards 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 + "")[%?+!=/(*`0_"). The value of this option should be a string + containing the symbols for the various object types. Any omit- + ted 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_confirma- + tion:pray. + + Confirm - for any prompts which are set to require "yes" + rather than `y', also require "no" to reject in- + stead of accepting any non-yes response as no + 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 useful in normal play; applies to explore + 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 - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attack- + attack - require "yes" rather than `y' to confirm attack- ing a peaceful monster; wand-break - require "yes" rather than `y' to confirm breaking a wand; - eating - require "yes" rather than `y' to confirm whether + 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 + form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather + pray - require `y' to confirm an attempt to pray rather than immediately praying; on by default; - Remove - require selection from inventory for `R' and `T' - commands even when wearing just one applicable + Remove - require selection from inventory for `R' and `T' + commands even when wearing just one applicable item. all - turn on all of the above. - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use + By default, the pray choice is enabled, the others disabled. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 66 + + + + To disable it without setting any of the other choices, use "paranoid_confirmation:none". To keep it enabled while setting - any of the others, include it in the list, such as "para- + any of the others, include it in the list, such as "para- noid_confirmation:attack pray Remove". perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. petattr - Specifies one or more text highlighting attributes to use when - showing pets on the map. Effectively a superset of the + Specifies one or more text highlighting attributes to use when + showing pets on the map. Effectively a superset of the hilite_pet boolean option. Curses interface only; value is one or more of the following letters. @@ -4277,80 +4320,37 @@ l - Left line indicator r - Right line indicator - Some of those choices might not work, particularly the final - three, depending upon terminal hardware or terminal emulation + Some of those choices might not work, particularly the final + three, depending upon terminal hardware or terminal emulation software. - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 66 - - - - Currently multiple highlight-style letters can be combined by - simply stringing them together (for example, "bk"), but in the - future they might require being separated by plus signs (such - as "b+k", which works already). When using the `n' choice, it - should be specified on its own, not in combination with any of + Currently multiple highlight-style letters can be combined by + simply stringing them together (for example, "bk"), but in the + future they might require being separated by plus signs (such + as "b+k", which works already). When using the `n' choice, it + should be specified on its own, not in combination with any of the other letters. 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", + 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". If the choice is not allowed for the role - you are currently playing, it will be silently ignored. For - example, "horse" will only be honored when playing a knight. + you are currently playing, it will be silently ignored. For + example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. (Default `S'). Persistent. 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 an autopickup exception. Default is on. Persistent. - - pickup_types - Specify the object types to be picked up when autopickup is on. - Default is all types. You can use autopickup_exception config- - uration file lines to further refine autopickup behavior. Per- - sistent. - - 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 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. - - playmode - 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 it when not allowed or not possible re- - sults in explore mode instead. Default is normal play. - - pushweapon - Using the `w' (wield) command when already wielding something + If this option is on and autopickup is also on, try to pick up - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4360,63 +4360,63 @@ - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the + 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. + Default is all types. You can use autopickup_exception config- + uration file lines to further refine autopickup behavior. Per- + sistent. + + 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 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. + + playmode + 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 it when not allowed or not possible re- + sults in explore mode instead. Default is normal play. + + pushweapon + Using the `w' (wield) command when already wielding something + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. quick_farsight - When set, usually prevents the "you sense your surroundings" - message where play pauses to allow you to browse the map when- + When set, usually prevents the "you sense your surroundings" + message where play pauses to allow you to browse the map when- ever clairvoyance randomly activates. Some situations, such as - being underwater or engulfed, ignore this option. It does not + being underwater or engulfed, ignore this option. It does not affect the clairvoyance spell where pausing to examine revealed - objects or monsters is less intrusive. Default is off. Per- + objects or monsters is less intrusive. Default is off. Per- sistent. race Selects your race (for example, "race:human"). Default is ran- - dom. If you prefix the value with `!' or "no", you will ex- + dom. If you prefix the value with `!' or "no", you will ex- clude that race from being picked randomly. Cannot be set with the `O' command. Persistent. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (de- + Make the space bar a synonym for the `.' (#wait) command (de- fault off). Persistent. - role - Pick your type of character (for example "role:Samurai"); syn- - onym for "character". See "name" for an alternate method of - specifying your role. Normally only the first letter of the - value is examined; `r' is an exception with "Rogue", "Ranger", - and "random" values. If you prefix the value with `!' or "no", - you will exclude that role from being picked randomly. Cannot - be set with the `O' command. Persistent. - - roguesymset - This option may be used to select one of the named symbol sets - found within "symbols" to alter the symbols displayed on the - screen on the rogue level. - - rlecomp - 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 - control+direction and so forth, or via the travel command or - mouse click). The possible values are: - - teleport - update the map after movement has finished; - run - update the map after every seven or so steps; - 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 - NetHack 3.7 November 16, 2020 + + NetHack 3.7 November 30, 2020 @@ -4426,17 +4426,48 @@ - actual results of moving. The default is "run"; versions prior - to 3.4.1 used "teleport" only. Whether or not the effect is + role + Pick your type of character (for example "role:Samurai"); syn- + onym for "character". See "name" for an alternate method of + specifying your role. Normally only the first letter of the + value is examined; `r' is an exception with "Rogue", "Ranger", + and "random" values. If you prefix the value with `!' or "no", + you will exclude that role from being picked randomly. Cannot + be set with the `O' command. Persistent. + + roguesymset + This option may be used to select one of the named symbol sets + found within "symbols" to alter the symbols displayed on the + screen on the rogue level. + + rlecomp + 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 + control+direction and so forth, or via the travel command or + mouse click). The possible values are: + + teleport - update the map after movement has finished; + run - update the map after every seven or so steps; + 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 ac- + tual 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. Persistent. safe_pet - Prevent you from (knowingly) attacking your pets (default on). + Prevent you from (knowingly) attacking your pets (default on). Persistent. safe_wait - Prevents you from waiting or searching when next to a hostile + Prevents you from waiting or searching when next to a hostile monster (default on). Persistent. sanity_check @@ -4444,19 +4475,31 @@ 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 + 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. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 69 + + + showexp 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 af- - fects only the appearance of the display, not the way the game + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4468,87 +4511,44 @@ sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + 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, + 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. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 69 - - - sparkle Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- + hit by an attack to which it is resistant (default on). Per- sistent. standout Boldface monsters and "--More--" (default off). Persistent. statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. See "Configuring 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 + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (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 "symset:default" to explicitly select the default - symbols. - - time - Show the elapsed game time in turns on bottom line (default - off). Persistent. - - timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface - only; "X11" interface always uses a timer based delay. The de- - fault is on if configured into the program.) Persistent. - - tombstone - Draw a tombstone graphic upon your death (default on). Persis- - tent. - - toptenwin - Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around - after game end on a terminal or emulating window. - - travel - Allow the travel command via mouse click (default on). Turning - this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map - NetHack 3.7 November 16, 2020 + + NetHack 3.7 November 30, 2020 @@ -4558,17 +4558,49 @@ - window. Does not affect traveling via the `_' ("#travel") com- + 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 "symset:default" to explicitly select the default + symbols. + + time + Show the elapsed game time in turns on bottom line (default + off). Persistent. + + timed_delay + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface + only; "X11" interface always uses a timer based delay. The de- + fault is on if configured into the program.) Persistent. + + tombstone + Draw a tombstone graphic upon your death (default on). Persis- + tent. + + toptenwin + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around + after game end on a terminal or emulating window. + + travel + Allow the travel command via mouse click (default on). Turning + this option off will prevent the game from attempting unintend- + ed moves if you make inadvertent mouse clicks on the map win- + dow. Does not affect traveling via the `_' ("#travel") com- mand. Persistent. verbose - Provide more commentary during the game (default on). Persis- + Provide more commentary during the game (default on). Persis- tent. whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -4580,41 +4612,9 @@ 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 over- - ridden 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 possi- - ble 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 were last moving towards. - - Filtering can also be changed when getting a location with the - "getpos.filter" key. - - 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. (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 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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4624,13 +4624,45 @@ - depends on build-time settings; use "#version" to check). Can- - not be set with the `O' command. + and "/O" sub-commands of `/', where the "none" setting is over- + ridden with "map". - When used, it should be the first option set since its value - might enable or disable the availability of various other op- - tions. For multiple lines in a configuration file, that would - be the first non-comment line. For a comma-separated list in + whatis_filter + When getting a location on the map, and using the keys to cycle + through next and previous targets, allows filtering the possi- + ble 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 were last moving towards. + + Filtering can also be changed when getting a location with the + "getpos.filter" key. + + 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. (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 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 de- + pends 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 op- + tions. 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 option in the list. @@ -4639,48 +4671,16 @@ 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 + 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 can safely add any of these options to your - configuration file, and if the window port is capable of adjust- - ing 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. 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). - - ascii_map - If NetHack can, it should display an ascii character map if it - can. - - color - If NetHack can, it should display color if it can for different - monsters, objects, and dungeon features. - - eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to - your terminal (default off). - NetHack 3.7 November 16, 2020 + + + + NetHack 3.7 November 30, 2020 @@ -4690,12 +4690,52 @@ + 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 can safely add any of these options to your + configuration file, and if the window port is capable of adjust- + ing 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. 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). + + ascii_map + If NetHack can, it should display the map using simple charac- + ters (letters and punctuation) rather than tiles graphics. In + some cases, characters can be augmented with line-drawing sym- + bols; use the symset option to select a symbol set such as + DECgraphics or IBMgraphics if your display supports them. Set- + ting ascii_map to True forces tiled_map to be False. + + color + If NetHack can, it should display color if it can for different + monsters, objects, and dungeon features. + + eight_bit_tty + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to + your terminal (default off). + font_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 + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -4704,49 +4744,9 @@ font_status If NetHack can, it should use a font by the chosen name for the - status window. - - font_text - If NetHack can, it should use a font by the chosen name for - text windows. - - font_size_map - If NetHack can, it should use this size font for the map win- - dow. - - 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. - - font_size_text - If NetHack can, it should use this size font for text windows. - - fullscreen - If NetHack can, it should try and display on the entire screen - rather than in a window. - - guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- - terface only; default is on. - - large_font - If NetHack can, it should use a large font. - - map_mode - If NetHack can, it should display the map in the manner speci- - fied. - - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4756,8 +4756,48 @@ + status window. + + font_text + If NetHack can, it should use a font by the chosen name for + text windows. + + font_size_map + If NetHack can, it should use this size font for the map win- + dow. + + 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. + + font_size_text + If NetHack can, it should use this size font for text windows. + + fullscreen + If NetHack can, it should try and display on the entire screen + rather than in a window. + + guicolor + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- + terface only; default is on. + + large_font + If NetHack can, it should use a large font. + + map_mode + If NetHack can, it should display the map in the manner speci- + fied. + player_selection - If NetHack can, it should pop up dialog boxes, or use prompts + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog @@ -4765,54 +4805,14 @@ preload_tiles If NetHack can, it should preload tiles into memory. For exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. - scroll_amount - If NetHack can, it should scroll the display by this number of - cells when the hero reaches the scroll_margin. - - scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- - dow. - - selectsaved - If NetHack can, it should display a menu of existing saved - games for the player to choose from at game startup, if it can. - Not all ports support this option. - - softkeyboard - 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). - - statuslines - Number of lines for traditional below-the-map status display. - Acceptable values are 2 and 3 (default is 2). - - For 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 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 uses the statuslines value differently. A value of 3 ren- - ders 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 - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 @@ -4822,32 +4822,87 @@ - eliminate one whole line, reducing the height needed. For Qt, - statuslines can only be set in the configuration file or via + scroll_amount + If NetHack can, it should scroll the display by this number of + cells when the hero reaches the scroll_margin. + + scroll_margin + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- + dow. + + selectsaved + If NetHack can, it should display a menu of existing saved + games for the player to choose from at game startup, if it can. + Not all ports support this option. + + softkeyboard + 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). + + statuslines + Number of lines for traditional below-the-map status display. + Acceptable values are 2 and 3 (default is 2). + + For 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 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 uses the statuslines value differently. A value of 3 ren- + ders 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, reducing the height needed. For Qt, + statuslines can only be set in the configuration file or via NETHACKOPTIONS, not with the `O' command. term_cols and term_rows - Curses interface only. Number of columns and rows to use for + Curses interface only. Number of columns and rows to use for the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. + ified but will settle for smaller sizes if they are too big. Default is the current window size. - tiled_map - If NetHack can, it should display a tiled map if it can. - tile_file - Specify the name of an alternative tile file to override the + Specify the name of an alternative tile file to override the + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 75 + + + default. tile_height - Specify the preferred height of each tile in a tile capable + Specify the preferred height of each tile in a tile capable port. tile_width 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, possi- + bly 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). @@ -4876,18 +4931,6 @@ If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 75 - - - OPTION=windowcolors:wintype foreground/background where wintype is one of "menu", "message", "status", or @@ -4898,9 +4941,21 @@ silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one of Windows UI colors (activeborder, activecaption, appworkspace, background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- - text). + greytext, highlight, highlighttext, inactiveborder, + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 76 + + + + inactivecaption, menu, menutext, scrollbar, window, windowframe, + windowtext). wraptext If NetHack can, it should wrap long lines of text if they don't @@ -4942,18 +4997,6 @@ chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 76 - - - flush (default off, Amiga NetHack only). @@ -4964,11 +5007,23 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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. + Force raw (non-cbreak) mode for faster output and more + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 77 + + + + bulletproof input (MS-DOS sometimes treats `^P' as a printer + toggle without it) (default off, OS/2, PC, and ST NetHack on- + ly). 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 @@ -5007,23 +5062,11 @@ command. videoshades - Set the intensity level of the three gray scales available - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 77 - - - - (default dark normal light, PC NetHack only). If the game dis- - play is difficult to read, try adjusting these scales; if this - does not correct the problem, try !color. Cannot be set with - the `O' command. + Set the intensity level of the three gray scales available (de- + fault dark normal light, PC NetHack only). If the game display + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the + `O' command. 9.7. Regular Expressions @@ -5031,6 +5074,18 @@ pressions. It is possible to compile NetHack without regular ex- pression support on a platform where there is no regular expres- sion library. While this is not true of any modern platform, if + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 78 + + + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -5073,20 +5128,8 @@ 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 - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 78 - - - - exclusion of items known to be cursed from autopickup. + any corpse from autopickup. The last example results in the ex- + clusion of items known to be cursed from autopickup. 9.9. Changing Key Bindings @@ -5097,6 +5140,18 @@ key can be a single character ("x"), a control key ("^X", "C-x"), a meta key ("M-x"), or a three-digit decimal ASCII code. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 79 + + + For example: BIND=^X:getpos.autodescribe @@ -5139,19 +5194,6 @@ When asked for a direction, the key to show the help. Default is `?'. - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 79 - - - getdir.self When asked for a direction, the key to target yourself. De- fault is `.'. @@ -5164,6 +5206,18 @@ When asked for a location, the key to toggle autodescribe. De- fault is `#'. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 80 + + + getpos.all.next When asked for a location, the key to go to next closest inter- esting thing. Default is `a'. @@ -5205,19 +5259,6 @@ ous keys to cycle through targets, toggle showing a menu in- stead. Default is `!'. - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 80 - - - 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 @@ -5231,6 +5272,18 @@ getpos.pick When asked for a location, the key to choose the location, and + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 81 + + + possibly ask for more info. Default is `.'. getpos.pick.once @@ -5273,17 +5326,6 @@ nopickup Prefix key to move without picking up items. Default is `m'. - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 81 - - - redraw Key to redraw the screen. Default is `^R'. @@ -5297,6 +5339,17 @@ reqmenu Prefix key to request menu from some commands. Default is `m'. + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 82 + + + run Prefix key to run towards a direction. Default is `G'. @@ -5338,18 +5391,6 @@ MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 82 - - - specifies that whenever a message "You feel hungry" is shown, the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. @@ -5364,6 +5405,17 @@ when the line matches a user-defined pattern. At this time the tty, curses, win32tty and win32gui interfaces support this. + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 83 + + + In general, the configuration file entries to describe the menu color mappings look like this: @@ -5405,17 +5457,6 @@ uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 83 - - - Note that if you intend to have one or more color specifica- tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed @@ -5428,6 +5469,19 @@ to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 84 + + + The following configuration file entries are relevant to mapping user sounds to messages: @@ -5470,18 +5524,6 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 84 - - - For another example, the following line in your configura- tion file will cause wisdom to be displayed red if it drops and green if it rises: @@ -5494,6 +5536,18 @@ ground color on the display, which is not necessarily the same as black or white or any of the other colors. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 85 + + + Allowed attributes are none, bold, dim, underline, blink, and inverse. "Normal" is a synonym for "none"; they should not be used in combination with any of the other attributes. @@ -5537,17 +5591,6 @@ nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 85 - - - Allowed behaviors are "always", "up", "down", "changed", a per- centage or absolute number threshold, or text to match against. @@ -5559,6 +5602,18 @@ * "changed" sets the field attribute for when the field val- ue changes. This attribute times out after statushilites + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 86 + + + turns. (If a field has both a "changed" rule and an "up" or "down" rule which matches a change in the field's val- ue, the "up" or "down" one takes precedence.) @@ -5603,22 +5658,28 @@ The in-game options menu can help you determine the correct syntax for a configuration file. - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 86 - - - The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: + + + + + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 87 + + + OPTION=hilite_status: gold/up/yellow/down/brown OPTION=hilite_status: characteristics/up/green/down/red OPTION=hilite_status: hitpoints/100%/gray&normal @@ -5667,24 +5728,24 @@ ^ S_arrow_trap (arrow trap) 0 S_ball (iron ball) # S_bars (iron bars) - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 87 - - - B S_bat (bat or bird) ^ S_bear_trap (bear trap) - S_blcorn (bottom left corner) b S_blob (blob) + S_book (spellbook) + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 88 + + + ) S_boomleft (boomerang open left) ( S_boomright (boomerang open right) ` S_boulder (boulder) @@ -5733,24 +5794,24 @@ - S_hbeam (horizontal beam [zap animation]) # S_hcdbridge (horizontal raised drawbridge) + S_hcdoor (closed door in horizontal wall) - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 88 - - - . S_hodbridge (horizontal lowered drawbridge) | S_hodoor (open door in horizontal wall) ^ S_hole (hole) @ S_human (human or elf) h S_humanoid (humanoid) + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 89 + + + - S_hwall (horizontal wall) . S_ice (ice) i S_imp (imp or minor demon) @@ -5799,24 +5860,24 @@ # S_sink (sink) ^ S_sleeping_gas_trap (sleeping gas trap) S S_snake (snake) - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 89 - - - s S_spider (arachnid or centipede) ^ S_spiked_pit (spiked pit) ^ S_squeaky_board (squeaky board) 0 S_ss1 (magic shield 1 of 4) # S_ss2 (magic shield 2 of 4) + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 90 + + + @ S_ss3 (magic shield 3 of 4) * S_ss4 (magic shield 4 of 4) ^ S_statue_trap (statue trap) @@ -5865,24 +5926,24 @@ w S_worm (worm) ~ S_worm_tail (long worm tail) W S_wraith (wraith) - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 90 - - - x S_xan (xan or other extraordinary insect) X S_xorn (xorn) Y S_yeti (apelike creature) Z S_zombie (zombie) z S_zruty (zruty) + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 91 + + + S_pet_override (any pet if ACCESSIBILITY=1 is set) S_hero_override (hero if ACCESSIBILITY=1 is set) @@ -5931,24 +5992,24 @@ While it is not difficult for experienced users to edit the defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the "symbols" file of all - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 91 - - - - official distributions of NetHack is a symset called NHAccess. - Selecting that symset in your configuration file will cause the + somewhat daunting. Included within the "symbols" file of all of- + ficial distributions of NetHack is a symset called NHAccess. Se- + lecting that symset in your configuration file will cause the game to run in a manner accessible to the blind. After you have gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 92 + + + configuration file to better suit your preferences. See the pre- vious section for the special symbols S_pet_override to force a consistent symbol for all pets and S_hero_override to force a @@ -5997,24 +6058,24 @@ When targeting with cursor and using fast-move, skip the same glyphs instead of moving 8 units at a time. - - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 92 - - - nostatus_updates Prevent updates to the status lines at the bottom of the screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. + + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 93 + + + 9.16. Global Configuration for System Administrators If NetHack is compiled with the SYSCF option, a system ad- @@ -6065,21 +6126,22 @@ SEDUCE = 0 or 1 to disable or enable, respectively, the SEDUCE option. When disabled, incubi and succubi behave like nymphs. - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 93 - - - CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 94 + + + 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 @@ -6130,22 +6192,22 @@ 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 - - - NetHack 3.7 November 16, 2020 - - - - - - NetHack Guidebook 94 - - - 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. + + + NetHack 3.7 November 30, 2020 + + + + + + NetHack Guidebook 95 + + + 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 @@ -6198,13 +6260,17 @@ mode instead. - NetHack 3.7 November 16, 2020 + + + + + NetHack 3.7 November 30, 2020 - NetHack Guidebook 95 + NetHack Guidebook 96 @@ -6264,13 +6330,13 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 96 + NetHack Guidebook 97 @@ -6330,13 +6396,13 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 97 + NetHack Guidebook 98 @@ -6396,13 +6462,13 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 98 + NetHack Guidebook 99 @@ -6462,13 +6528,13 @@ dows CE port for 3.4.1. - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 99 + NetHack Guidebook 100 @@ -6528,13 +6594,13 @@ beloved community patches. Many bugs were fixed and some code was - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 100 + NetHack Guidebook 101 @@ -6594,13 +6660,13 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 101 + NetHack Guidebook 102 @@ -6660,13 +6726,13 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 - NetHack Guidebook 102 + NetHack Guidebook 103 @@ -6726,7 +6792,7 @@ - NetHack 3.7 November 16, 2020 + NetHack 3.7 November 30, 2020 From d79b5388cece6c9ba415b1c37380f413e519a23d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 22:18:44 +0200 Subject: [PATCH 478/708] Remove dealloc_obj b&c sanity checking --- src/mkobj.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mkobj.c b/src/mkobj.c index 4c1b810bb..07ec33b67 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -2173,10 +2173,6 @@ struct obj *obj; panic("dealloc_obj with nobj"); if (obj->cobj) panic("dealloc_obj with cobj"); - if (obj == uball || obj == uchain) - impossible("dealloc_obj called on %s, owornmask=%lx", - (obj == uball) ? "uball" : "uchain", - obj->owornmask); /* free up any timers attached to the object */ if (obj->timed) From 1360e636448854d322b30c1d003f54d0cc21753e Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 1 Dec 2020 21:32:52 -0800 Subject: [PATCH 479/708] Fix build issue when building project for the first time. --- win/win32/vs/afterdlb.proj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/win32/vs/afterdlb.proj b/win/win32/vs/afterdlb.proj index 807fdf7c7..56ea03350 100644 --- a/win/win32/vs/afterdlb.proj +++ b/win/win32/vs/afterdlb.proj @@ -4,8 +4,8 @@ - - + + From 4d6a140d34323af547cb790bb8ffc2c6d9b6d9b2 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 2 Dec 2020 06:29:58 -0800 Subject: [PATCH 480/708] saving vs ball&chain I started activating new program_state.saving and discovered that saving of ball and chain could access freed memory. The change for the former and fix for the latter are mixed together here (but easily distinguishable). The saving flag inhibits status updating and perm_invent updating, also map updating that goes through flush_screen(). That should fix the exception triggered after an impossible warning was issued during a save operation. impossible() goes through pline() which tries to bring the screen up to date before issuing a message. During save, data for that update can be in an inconsistent state. The code to save ball and/or chain when not on floor or in invent (I think swallowed is the only expected case) was examining the memory pointed to by uball and uchain even if saving the level had just freed floor objects and saving invent had just freed carried objects. So for the usual cases, stale pointer values for uball and uchain would be present and checking their obj->where field was not reliable. --- doc/fixes37.0 | 4 +- include/decl.h | 4 +- include/extern.h | 3 +- src/decl.c | 4 +- src/display.c | 6 ++- src/save.c | 121 ++++++++++++++++++++++++++++++++--------------- src/worn.c | 22 ++++++++- 7 files changed, 119 insertions(+), 45 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 0fc0401a4..4794c86ad 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.369 $ $NHDT-Date: 1606781767 2020/12/01 00:16:07 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.370 $ $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ General Fixes and Modified Features ----------------------------------- @@ -316,6 +316,8 @@ autodescribe when moving the cursor was erroneously honoring MSGTYPE=stop and potentially delivering sounds reduce the number of "seeXYZ" commands by renaming some: #seenv -> #wizseenv, #seespells -> #showspells, and #seetrap -> #showtrap +when saving while punished or game ends while punished, handling for ball and + chain might access freed memory with unpredictable consequences Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/decl.h b/include/decl.h index def2db1cb..6cc5f75bb 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1606765210 2020/11/30 19:40:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.246 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1103,6 +1103,8 @@ struct instance_globals { boolean havestate; unsigned ustuck_id; /* need to preserve during save */ unsigned usteed_id; /* need to preserve during save */ + struct obj *looseball; /* track uball during save and... */ + struct obj *loosechain; /* track uchain since saving might free it */ /* shk.c */ /* auto-response flag for/from "sell foo?" 'a' => 'y', 'q' => 'n' */ diff --git a/include/extern.h b/include/extern.h index 3be154e70..64df72baa 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.882 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.886 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3122,6 +3122,7 @@ E void FDECL(flip_worm_segs_horizontal, (struct monst *, int, int)); E void FDECL(setworn, (struct obj *, long)); E void FDECL(setnotworn, (struct obj *)); +E void NDECL(allunworn); E struct obj *FDECL(wearmask_to_obj, (long)); E long FDECL(wearslot, (struct obj *)); E void FDECL(mon_set_minvis, (struct monst *)); diff --git a/src/decl.c b/src/decl.c index 54d38ac6d..09e6d608a 100644 --- a/src/decl.c +++ b/src/decl.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.c $NHDT-Date: 1600468453 2020/09/18 22:34:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.218 $ */ +/* NetHack 3.7 decl.c $NHDT-Date: 1606919256 2020/12/02 14:27:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.221 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -611,6 +611,8 @@ const struct instance_globals g_init = { TRUE, /* havestate*/ 0, /* ustuck_id */ 0, /* usteed_id */ + (struct obj *) 0, /* looseball */ + (struct obj *) 0, /* loosechain */ /* shk.c */ 'a', /* sell_response */ diff --git a/src/display.c b/src/display.c index 1c4707b04..1e0ac89e7 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.c $NHDT-Date: 1597700875 2020/08/17 21:47:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ +/* NetHack 3.7 display.c $NHDT-Date: 1606919261 2020/12/02 14:27:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1691,6 +1691,10 @@ int cursor_on_u; static int delay_flushing = 0; register int x, y; + /* 3.7: don't update map, status, or perm_invent during save/restore */ + if (g.program_state.saving || g.program_state.restoring) + return; + if (cursor_on_u == -1) delay_flushing = !delay_flushing; if (delay_flushing) diff --git a/src/save.c b/src/save.c index 586ae177d..c8f1865da 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 save.c $NHDT-Date: 1596498207 2020/08/03 23:43:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.160 $ */ +/* NetHack 3.7 save.c $NHDT-Date: 1606919257 2020/12/02 14:27:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -29,7 +29,7 @@ static void FDECL(saveobj, (NHFILE *,struct obj *)); static void FDECL(savemon, (NHFILE *,struct monst *)); static void FDECL(savelevl, (NHFILE *,BOOLEAN_P)); static void FDECL(save_stairs, (NHFILE *)); -static void FDECL(saveobjchn, (NHFILE *,struct obj *)); +static void FDECL(saveobjchn, (NHFILE *,struct obj **)); static void FDECL(savemonchn, (NHFILE *,struct monst *)); static void FDECL(savetrapchn, (NHFILE *,struct trap *)); static void FDECL(savegamestate, (NHFILE *)); @@ -86,7 +86,9 @@ dosave0() d_level uz_save; char whynot[BUFSZ]; NHFILE *nhfp, *onhfp; + int res = 0; + g.program_state.saving++; /* inhibit status and perm_invent updates */ /* we may get here via hangup signal, in which case we want to fix up a few of things before saving so that they won't be restored in an improper state; these will be no-ops for normal save sequence */ @@ -99,9 +101,9 @@ dosave0() u.uburied = 1, iflags.save_uburied = 0; if (!g.program_state.something_worth_saving || !g.SAVEF[0]) - return 0; - fq_save = fqname(g.SAVEF, SAVEPREFIX, 1); /* level files take 0 */ + goto done; + fq_save = fqname(g.SAVEF, SAVEPREFIX, 1); /* level files take 0 */ #ifndef NO_SIGNAL #if defined(UNIX) || defined(VMS) sethanguphandler((void FDECL((*), (int) )) SIG_IGN); @@ -118,7 +120,7 @@ dosave0() There("seems to be an old save file."); if (yn("Overwrite the old file?") == 'n') { nh_compress(fq_save); - return 0; + goto done; } } } @@ -129,7 +131,7 @@ dosave0() if (!nhfp) { HUP pline("Cannot open save file."); (void) delete_savefile(); /* ab@unido */ - return 0; + goto done; } vision_recalc(2); /* shut down vision to prevent problems @@ -158,6 +160,15 @@ dosave0() store_plname_in_file(nhfp); g.ustuck_id = (u.ustuck ? u.ustuck->m_id : 0); g.usteed_id = (u.usteed ? u.usteed->m_id : 0); + /* savelev() might save uball and uchain, releasing their memory if + FREEING, so we need to check their status now; if hero is swallowed, + uball and uchain will persist beyond saving map floor and inventory + so these copies of their pointers will be valid and savegamestate() + will know to save them separately (from floor and invent); when not + swallowed, uchain will be stale by then, and uball will be too if + ball is on the floor rather than carried */ + g.looseball = BALL_IN_MON ? uball : 0; + g.loosechain = CHAIN_IN_MON ? uchain : 0; savelev(nhfp, ledger_no(&u.uz)); savegamestate(nhfp); @@ -197,7 +208,7 @@ dosave0() (void) delete_savefile(); HUP Strcpy(g.killer.name, whynot); HUP done(TRICKED); - return 0; + goto done; } minit(); /* ZEROCOMP */ getlev(onhfp, g.hackpid, ltmp); @@ -217,7 +228,11 @@ dosave0() nh_compress(fq_save); /* this should probably come sooner... */ g.program_state.something_worth_saving = 0; - return 1; + res = 1; + + done: + g.program_state.saving--; + return res; } static void @@ -225,7 +240,10 @@ savegamestate(nhfp) NHFILE *nhfp; { unsigned long uid; - struct obj * bc_objs = (struct obj *)0; + struct obj *bc_objs = (struct obj *)0; + + if (!g.program_state.saving) + impossible("savegamestate called when not saving or changing levels?"); uid = (unsigned long) getuid(); if (nhfp->structlevel) { @@ -251,27 +269,31 @@ NHFILE *nhfp; save_timers(nhfp, RANGE_GLOBAL); save_light_sources(nhfp, RANGE_GLOBAL); - saveobjchn(nhfp, g.invent); + /* when FREEING, deletes objects in invent and sets invent to Null; + pointers into invent (uwep, uarmg, uamul, &c) are set to Null too */ + saveobjchn(nhfp, &g.invent); - /* save ball and chain if they are currently dangling free (i.e. not on - floor or in inventory) */ - if (CHAIN_IN_MON) { - uchain->nobj = bc_objs; - bc_objs = uchain; + /* save ball and chain if they are currently dangling free (i.e. not + on floor or in inventory); 'looseball' and 'loosechain' have been + set up in caller because ball and chain will be gone by now if on + floor, or ball gone if carried; caveat: uball and uchain pointers + will be non-Null but stale (point to freed memory) in those cases */ + bc_objs = (struct obj *) 0; + if (g.loosechain) { + g.loosechain->nobj = bc_objs; /* uchain */ + bc_objs = g.loosechain; } - if (BALL_IN_MON) { - uball->nobj = bc_objs; - bc_objs = uball; + if (g.looseball) { + g.looseball->nobj = bc_objs; + bc_objs = g.looseball; } - saveobjchn(nhfp, bc_objs); + saveobjchn(nhfp, &bc_objs); /* frees objs in list, sets bc_objs to Null */ + g.looseball = g.loosechain = (struct obj *) 0; - saveobjchn(nhfp, g.migrating_objs); + saveobjchn(nhfp, &g.migrating_objs); /* frees objs and sets to Null */ savemonchn(nhfp, g.migrating_mons); - if (release_data(nhfp)) { - g.invent = 0; - g.migrating_objs = 0; - g.migrating_mons = 0; - } + if (release_data(nhfp)) + g.migrating_mons = (struct monst *) 0; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) g.mvitals, sizeof g.mvitals); save_dungeon(nhfp, (boolean) !!perform_bwrite(nhfp), @@ -329,6 +351,7 @@ savestateinlock() char whynot[BUFSZ]; NHFILE *nhfp; + g.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 * needs to be in the level.0 file, so it does not need to be @@ -356,16 +379,21 @@ savestateinlock() if (g.hackpid != hpid) { Sprintf(whynot, "Level #0 pid (%d) doesn't match ours (%d)!", hpid, g.hackpid); - pline1(whynot); - Strcpy(g.killer.name, whynot); - done(TRICKED); + goto giveup; } close_nhfile(nhfp); nhfp = create_levelfile(0, whynot); if (!nhfp) { pline1(whynot); + giveup: Strcpy(g.killer.name, whynot); + /* done(TRICKED) will return when running in wizard mode; + clear the display-update-suppression flag before rather + than after so that screen updating behaves normally; + game data shouldn't be inconsistent yet, unlike it would + become midway through saving */ + g.program_state.saving--; done(TRICKED); return; } @@ -384,10 +412,13 @@ savestateinlock() g.ustuck_id = (u.ustuck ? u.ustuck->m_id : 0); g.usteed_id = (u.usteed ? u.usteed->m_id : 0); + g.looseball = BALL_IN_MON ? uball : 0; + g.loosechain = CHAIN_IN_MON ? uchain : 0; savegamestate(nhfp); } close_nhfile(nhfp); } + g.program_state.saving--; g.havestate = flags.ins_chkpt; } #endif @@ -401,6 +432,7 @@ xchar lev; short tlev; #endif + g.program_state.saving++; /* even if current mode is FREEING */ /* * Level file contents: * version info (handled by caller); @@ -454,7 +486,8 @@ xchar lev; if (nhfp->mode == FREEING) /* see above */ goto skip_lots; - savelevl(nhfp, (boolean) ((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); + savelevl(nhfp, + (boolean) ((sfsaveinfo.sfi1 & SFI1_RLECOMP) == SFI1_RLECOMP)); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) g.lastseentyp, sizeof g.lastseentyp); bwrite(nhfp->fd, (genericptr_t) &g.monstermoves, sizeof g.monstermoves); @@ -475,9 +508,9 @@ xchar lev; savemonchn(nhfp, fmon); save_worm(nhfp); /* save worm information */ savetrapchn(nhfp, g.ftrap); - saveobjchn(nhfp, fobj); - saveobjchn(nhfp, g.level.buriedobjlist); - saveobjchn(nhfp, g.billobjs); + saveobjchn(nhfp, &fobj); + saveobjchn(nhfp, &g.level.buriedobjlist); + saveobjchn(nhfp, &g.billobjs); if (release_data(nhfp)) { int x,y; /* TODO: maybe use clear_level_structures() */ @@ -503,6 +536,7 @@ xchar lev; if (nhfp->structlevel) bflush(nhfp->fd); } + g.program_state.saving--; } static void @@ -695,11 +729,13 @@ NHFILE *nhfp; } static void -saveobjchn(nhfp, otmp) +saveobjchn(nhfp, obj_p) NHFILE *nhfp; -register struct obj *otmp; +struct obj **obj_p; { - register struct obj *otmp2; + register struct obj *otmp = *obj_p; + struct obj *otmp2; + boolean is_invent = (otmp && otmp == g.invent); int minusone = -1; while (otmp) { @@ -708,7 +744,7 @@ register struct obj *otmp; saveobj(nhfp, otmp); } if (Has_contents(otmp)) - saveobjchn(nhfp, otmp->cobj); + saveobjchn(nhfp, &otmp->cobj); if (release_data(nhfp)) { /* * If these are on the floor, the discarding could be @@ -733,6 +769,10 @@ register struct obj *otmp; otmp->cobj = NULL; /* contents handled above */ otmp->timed = 0; /* not timed any more */ otmp->lamplit = 0; /* caller handled lights */ + otmp->leashmon = 0; /* mon->mleashed could still be set; + * unfortunately, we can't clear that + * until after the monster is saved */ + otmp->owornmask = 0L; /* no longer care */ dealloc_obj(otmp); } otmp = otmp2; @@ -741,6 +781,11 @@ register struct obj *otmp; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &minusone, sizeof (int)); } + if (release_data(nhfp)) { + if (is_invent) + allunworn(); /* clear uwep, uarm, uball, &c pointers */ + *obj_p = (struct obj *) 0; + } } static void @@ -825,7 +870,7 @@ register struct monst *mtmp; savemon(nhfp, mtmp); } if (mtmp->minvent) - saveobjchn(nhfp, mtmp->minvent); + saveobjchn(nhfp, &mtmp->minvent); if (release_data(nhfp)) { if (mtmp == g.context.polearm.hitmon) { g.context.polearm.m_id = mtmp->m_id; @@ -1033,7 +1078,7 @@ freedynamicdata() tmp_at(DISP_FREEMEM, 0); /* temporary display effects */ #ifdef FREE_ALL_MEMORY #define free_current_level() savelev(&tnhfp, -1) -#define freeobjchn(X) (saveobjchn(&tnhfp, X), X = 0) +#define freeobjchn(X) (saveobjchn(&tnhfp, &X), X = 0) #define freemonchn(X) (savemonchn(&tnhfp, X), X = 0) #define freefruitchn() savefruitchn(&tnhfp) #define freenames() savenames(&tnhfp) diff --git a/src/worn.c b/src/worn.c index ad52e2474..f5c4c3a1d 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worn.c $NHDT-Date: 1596498231 2020/08/03 23:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.67 $ */ +/* NetHack 3.7 worn.c $NHDT-Date: 1606919259 2020/12/02 14:27:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.70 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -131,7 +131,7 @@ register struct obj *obj; is pending (via 'A' command for multiple items) */ cancel_doff(obj, wp->w_mask); - *(wp->w_obj) = 0; + *(wp->w_obj) = (struct obj *) 0; p = objects[obj->otyp].oc_oprop; u.uprops[p].extrinsic = u.uprops[p].extrinsic & ~wp->w_mask; obj->owornmask &= ~wp->w_mask; @@ -145,6 +145,24 @@ register struct obj *obj; update_inventory(); } +/* called when saving with FREEING flag set has just discarded inventory */ +void +allunworn() +{ + const struct worn *wp; + + u.twoweap = 0; /* uwep and uswapwep are going away */ + /* remove stale pointers; called after the objects have been freed + (without first being unworn) while saving invent during game save; + note: uball and uchain might not be freed yet but we clear them + here anyway (savegamestate() and its callers deal with them) */ + for (wp = worn; wp->w_mask; wp++) { + /* object is already gone so we don't/can't update is owornmask */ + *(wp->w_obj) = (struct obj *) 0; + } +} + + /* return item worn in slot indiciated by wornmask; needed by poly_obj() */ struct obj * wearmask_to_obj(wornmask) From 5e570b181fc6dcacbb4a9f9e91cb0007b353e773 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 2 Dec 2020 14:49:09 -0800 Subject: [PATCH 481/708] saving followup If attempting to checkpoint when changing levels discovered that the alock.0 or 123wizard.0 file was missing and the game was running in wizard mode, play continued after reporting trickery but screen updating was left disabled. An early return in savegamestateinlock() wasn't resetting the program_state.saving flag to revert to normal screen updates. I added a few return statements at the ends of void routines, where they're optional, because it makes searching for early returns easier. (Without these then when no early return is present between current point and end of routine, the search would move past the routine looking for 'return' later in the file.) save_stairs() was placed in between saveobj() and saveobjchn() so I've moved it. (Has no effect on the recently reported stair anomalies.) It was also accumulating the total stairway data size in 'len' and never using that for anything, so I got rid of it. (Ditto about anomalies.) --- src/save.c | 85 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 41 deletions(-) diff --git a/src/save.c b/src/save.c index c8f1865da..d1dcf15fd 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 save.c $NHDT-Date: 1606919257 2020/12/02 14:27:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.163 $ */ +/* NetHack 3.7 save.c $NHDT-Date: 1606949327 2020/12/02 22:48:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.164 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -21,15 +21,12 @@ int dotcnt, dotrow; /* also used in restore */ #endif static void FDECL(savelevchn, (NHFILE *)); -static void FDECL(savedamage, (NHFILE *)); -/* static void FDECL(saveobj, (NHFILE *,struct obj *)); */ -/* static void FDECL(savemon, (NHFILE *,struct monst *)); */ -/* static void FDECL(savelevl, (NHFILE *, BOOLEAN_P)); */ -static void FDECL(saveobj, (NHFILE *,struct obj *)); -static void FDECL(savemon, (NHFILE *,struct monst *)); static void FDECL(savelevl, (NHFILE *,BOOLEAN_P)); +static void FDECL(savedamage, (NHFILE *)); static void FDECL(save_stairs, (NHFILE *)); +static void FDECL(saveobj, (NHFILE *,struct obj *)); static void FDECL(saveobjchn, (NHFILE *,struct obj **)); +static void FDECL(savemon, (NHFILE *,struct monst *)); static void FDECL(savemonchn, (NHFILE *,struct monst *)); static void FDECL(savetrapchn, (NHFILE *,struct trap *)); static void FDECL(savegamestate, (NHFILE *)); @@ -214,7 +211,7 @@ dosave0() getlev(onhfp, g.hackpid, ltmp); close_nhfile(onhfp); if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) <mp, sizeof ltmp); /* level number*/ + bwrite(nhfp->fd, (genericptr_t) <mp, sizeof ltmp); /* lvl no. */ savelev(nhfp, ltmp); /* actual level*/ delete_levelfile(ltmp); } @@ -242,9 +239,7 @@ NHFILE *nhfp; unsigned long uid; struct obj *bc_objs = (struct obj *)0; - if (!g.program_state.saving) - impossible("savegamestate called when not saving or changing levels?"); - + g.program_state.saving++; /* caller should/did already set this... */ uid = (unsigned long) getuid(); if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) &uid, sizeof uid); @@ -326,8 +321,11 @@ NHFILE *nhfp; save_msghistory(nhfp); if (nhfp->structlevel) bflush(nhfp->fd); + g.program_state.saving--; + return; } +/* potentially called from goto_level(do.c) as well as savestateinlock() */ boolean tricked_fileremoved(nhfp, whynot) NHFILE *nhfp; @@ -371,8 +369,10 @@ savestateinlock() * readable by an external utility */ nhfp = open_levelfile(0, whynot); - if (tricked_fileremoved(nhfp, whynot)) + if (tricked_fileremoved(nhfp, whynot)) { + g.program_state.saving--; return; + } if (nhfp->structlevel) (void) read(nhfp->fd, (genericptr_t) &hpid, sizeof hpid); @@ -420,6 +420,7 @@ savestateinlock() } g.program_state.saving--; g.havestate = flags.ins_chkpt; + return; } #endif @@ -537,6 +538,7 @@ xchar lev; bflush(nhfp->fd); } g.program_state.saving--; + return; } static void @@ -598,6 +600,7 @@ boolean rlecomp; if (nhfp->structlevel) { bwrite(nhfp->fd, (genericptr_t) levl, sizeof levl); } + return; } /* used when saving a level and also when saving dungeon overview data */ @@ -656,6 +659,32 @@ NHFILE *nhfp; g.level.damagelist = 0; } +static void +save_stairs(nhfp) +NHFILE *nhfp; +{ + stairway *stway = g.stairs; + int buflen = (int) sizeof *stway; + + while (stway) { + if (perform_bwrite(nhfp)) { + if (nhfp->structlevel) { + bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); + bwrite(nhfp->fd, (genericptr_t) stway, sizeof *stway); + } + } + stway = stway->next; + } + if (perform_bwrite(nhfp)) { + if (nhfp->structlevel) { + buflen = -1; + bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); + } + } +} + +/* save one object; + caveat: this is only for perform_bwrite(); caller handles release_data() */ static void saveobj(nhfp, otmp) NHFILE *nhfp; @@ -694,40 +723,14 @@ struct obj *otmp; } /* omid used to be indirect via a pointer in oextra but has become part of oextra itself; 0 means not applicable and - gets saved/restored whenever any other oxtra components do */ + gets saved/restored whenever any other oextra components do */ if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &OMID(otmp), sizeof OMID(otmp)); } } -static void -save_stairs(nhfp) -NHFILE *nhfp; -{ - stairway *stway = g.stairs; - int buflen = (int) sizeof (stairway); - int len = 0; - - while (stway) { - if (perform_bwrite(nhfp)) { - if (nhfp->structlevel) { - len += sizeof(buflen); - bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); - len += sizeof(stairway); - bwrite(nhfp->fd, (genericptr_t) stway, sizeof(stairway)); - } - } - stway = stway->next; - } - if (perform_bwrite(nhfp)) { - if (nhfp->structlevel) { - buflen = -1; - len += sizeof(buflen); - bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); - } - } -} - +/* save an object chain; sets head of list to Null when done; + handles release_data() for each object in the list */ static void saveobjchn(nhfp, obj_p) NHFILE *nhfp; From 3e7283e8fd7df2aa0d2a5a8f0b9d9e3b6f30a27c Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 2 Dec 2020 16:11:53 -0800 Subject: [PATCH 482/708] Qt fix for typing "#version" The #version command is a leading substring of the #versionshort command and for Qt, it couldn't be executed by typing, only via mouse click or one of the Qt-specific menus. #version or #version now works for that. The #versionshort command ought to be renamed to something else. --- doc/fixes37.0 | 6 +++++- win/Qt/qt_xcmd.cpp | 34 ++++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 4794c86ad..d7fad4bb9 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.370 $ $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.371 $ $NHDT-Date: 1606954304 2020/12/03 00:11:44 $ General Fixes and Modified Features ----------------------------------- @@ -507,6 +507,10 @@ Qt: don't get stuck in a loop after choosing "play" while the character name field is empty in the character selection widget Qt: when a new message is issued, pan the message window to its left edge if player panned it horizontally then didn't manually scroll it back +Qt: there was no way to enter extended command "#version" by typing; command + name matching was waiting to disambiguate it from "#versionshort" + and the only way to that was to type #version but + explicitly triggered rejection, cancelling '#' processing Qt: {maybe just Qt+OSX:} when viewing a text window ('V' to look at 'history' for instance), clicking on [Search], entering a search target in the resulting popup and clicking on [Okay] or typing , the text diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index ce81fbb44..ed6f870d3 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -167,26 +167,40 @@ void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) if (promptstr != "#") prompt->setText(promptstr.left(promptstr.size() - 1)); enableButtons(); - /*} else if (uc == '\r' || uc == '\n'; || uc == ' ') {*/ - } else if (uc < ' ' || uc > std::max('z', 'Z')) { + } else if ((uc < ' ' && !(uc == '\n' || uc == '\r')) + || uc > std::max('z', 'Z')) { reject(); // done() } else { - promptstr += QChar(uc); // event()->text() + // is necessary if one command is a leading substring + // of another and superfluous otherwise + boolean checkexact = (uc == '\n' || uc == '\r' || uc == ' '); + if (!checkexact) + promptstr += QChar(uc); // event()->text() QString typedstr = promptstr.mid(1); // skip the '#' unsigned matches = 0; - unsigned match = 0; + unsigned matchindx = 0; for (unsigned i=0; extcmdlist[i].ef_txt; i++) { if (!interesting_command(i)) continue; - if (QString(extcmdlist[i].ef_txt).startsWith(typedstr)) { - ++matches; - if (matches >= 2) - break; - match = i; + QString cmdtxt = QString(extcmdlist[i].ef_txt); + if (cmdtxt.startsWith(typedstr)) { + if (checkexact) { + if (cmdtxt == typedstr) { + matchindx = i; + matches = 1; + break; + } + } else { + if (++matches >= 2) + break; + matchindx = i; + } } } if (matches == 1) - done(match+1); + done(matchindx + 1); + else if (checkexact) + reject(); else if (matches >= 2) prompt->setText(promptstr); enableButtons(); From cfc4612338385fd06257d5111411b7cc0e3a7a6c Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 2 Dec 2020 21:59:26 -0500 Subject: [PATCH 483/708] correct coding typo: nx instead of ny Prevented proper migration of obj dropped down the stairs. Also, don't include your attached chain when counting drop impacts. --- src/dokick.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/dokick.c b/src/dokick.c index 114a217b8..84d373421 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -18,7 +18,7 @@ static void FDECL(kick_monster, (struct monst *, XCHAR_P, XCHAR_P)); static int FDECL(kick_object, (XCHAR_P, XCHAR_P, char *)); static int FDECL(really_kick_object, (XCHAR_P, XCHAR_P)); static char *FDECL(kickstr, (char *, const char *)); -static void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long)); +static void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, BOOLEAN_P, long)); static void FDECL(drop_to, (coord *, SCHAR_P, XCHAR_P, XCHAR_P)); static const char kick_passes_thru[] = "kick passes harmlessly through"; @@ -1510,7 +1510,7 @@ boolean shop_floor_obj; coord cc; struct obj *obj; struct trap *t; - boolean nodrop, unpaid, container, impact = FALSE; + boolean nodrop, unpaid, container, impact = FALSE, chainthere = FALSE; long n = 0L; if (!otmp) @@ -1530,9 +1530,12 @@ boolean shop_floor_obj; unpaid = is_unpaid(otmp); if (OBJ_AT(x, y)) { - for (obj = g.level.objects[x][y]; obj; obj = obj->nexthere) - if (obj != otmp) + for (obj = g.level.objects[x][y]; obj; obj = obj->nexthere) { + if (obj == uchain) + chainthere = TRUE; + else if (obj != otmp) n += obj->quan; + } if (n) impact = TRUE; } @@ -1546,7 +1549,7 @@ boolean shop_floor_obj; } if (cansee(x, y)) - otransit_msg(otmp, nodrop, n); + otransit_msg(otmp, nodrop, chainthere, n); if (nodrop) { if (impact) @@ -1665,7 +1668,7 @@ boolean near_hero; case MIGR_SSTAIRS: if ((stway = stairway_find_from(&fromdlev, isladder)) != 0) { nx = stway->sx; - nx = stway->sy; + ny = stway->sy; } break; case MIGR_WITH_HERO: @@ -1766,9 +1769,9 @@ unsigned long deliverflags; } static void -otransit_msg(otmp, nodrop, num) +otransit_msg(otmp, nodrop, chainthere, num) register struct obj *otmp; -register boolean nodrop; +boolean nodrop, chainthere; long num; { char *optr = 0, obuf[BUFSZ], xbuf[BUFSZ]; @@ -1782,11 +1785,15 @@ long num; } Strcpy(obuf, optr); - if (num) { /* means: other objects are impacted */ + if (num || chainthere) { /* As of 3.6.2: use a separate buffer for the suffix to avoid risk of overrunning obuf[] (let pline() handle truncation if necessary) */ - Sprintf(xbuf, " %s %s object%s", otense(otmp, "hit"), - (num == 1L) ? "another" : "other", (num > 1L) ? "s" : ""); + if (num) { /* means: other objects are impacted */ + Sprintf(xbuf, " %s %s object%s", otense(otmp, "hit"), + (num == 1L) ? "another" : "other", (num > 1L) ? "s" : ""); + } else { /* chain-only msg */ + Sprintf(xbuf, " %s your chain", otense(otmp, "rattle")); + } if (nodrop) Sprintf(eos(xbuf), "."); else From cf888082853c206df429126d653c6995e52ac495 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 3 Dec 2020 16:38:17 +0200 Subject: [PATCH 484/708] Fix stairs on oracle level bones Recent change to the stairs structure now lets each stair keep the destination level number and dungeon where the stairs go to. When a level that can be on different depth (such as the Oracle) became a bones level, and it was loaded in another game at different depth, the stairs were still pointing to the old level number. Save it as relative to the current level instead of absolute. --- src/restore.c | 4 ++++ src/save.c | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/restore.c b/src/restore.c index 3622c02ab..e28648769 100644 --- a/src/restore.c +++ b/src/restore.c @@ -926,6 +926,10 @@ NHFILE *nhfp; if (nhfp->structlevel) { len += (int) sizeof (stairway); mread(nhfp->fd, (genericptr_t) &stway, sizeof (stairway)); + if (stway.tolev.dnum == u.uz.dnum) { + /* stairway dlevel is relative, make it absolute */ + stway.tolev.dlevel += u.uz.dlevel; + } } stairway_add(stway.sx, stway.sy, stway.up, stway.isladder, diff --git a/src/save.c b/src/save.c index d1dcf15fd..bc8def125 100644 --- a/src/save.c +++ b/src/save.c @@ -669,8 +669,16 @@ NHFILE *nhfp; while (stway) { if (perform_bwrite(nhfp)) { if (nhfp->structlevel) { + if (stway->tolev.dnum == u.uz.dnum) { + /* make dlevel relative to current level */ + stway->tolev.dlevel -= u.uz.dlevel; + } bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); bwrite(nhfp->fd, (genericptr_t) stway, sizeof *stway); + if (stway->tolev.dnum == u.uz.dnum) { + /* reset staiway dlevel back to absolute */ + stway->tolev.dlevel += u.uz.dlevel; + } } } stway = stway->next; From f5437636959d09d5dfdf02976442ec9edbfcbd47 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 3 Dec 2020 10:05:31 -0500 Subject: [PATCH 485/708] stairway save/restore bit The logic surrounding stairway saves and restores should not be within a block reserved for deliminating external file structure. --- src/restore.c | 11 +++++------ src/save.c | 18 +++++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/restore.c b/src/restore.c index e28648769..528d76a04 100644 --- a/src/restore.c +++ b/src/restore.c @@ -923,15 +923,14 @@ NHFILE *nhfp; if (buflen == -1) break; + len += (int) sizeof (stairway); if (nhfp->structlevel) { - len += (int) sizeof (stairway); mread(nhfp->fd, (genericptr_t) &stway, sizeof (stairway)); - if (stway.tolev.dnum == u.uz.dnum) { - /* stairway dlevel is relative, make it absolute */ - stway.tolev.dlevel += u.uz.dlevel; - } } - + if (stway.tolev.dnum == u.uz.dnum) { + /* stairway dlevel is relative, make it absolute */ + stway.tolev.dlevel += u.uz.dlevel; + } stairway_add(stway.sx, stway.sy, stway.up, stway.isladder, &(stway.tolev)); } diff --git a/src/save.c b/src/save.c index bc8def125..f463e8939 100644 --- a/src/save.c +++ b/src/save.c @@ -668,24 +668,24 @@ NHFILE *nhfp; while (stway) { if (perform_bwrite(nhfp)) { + if (stway->tolev.dnum == u.uz.dnum) { + /* make dlevel relative to current level */ + stway->tolev.dlevel -= u.uz.dlevel; + } if (nhfp->structlevel) { - if (stway->tolev.dnum == u.uz.dnum) { - /* make dlevel relative to current level */ - stway->tolev.dlevel -= u.uz.dlevel; - } bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); bwrite(nhfp->fd, (genericptr_t) stway, sizeof *stway); - if (stway->tolev.dnum == u.uz.dnum) { - /* reset staiway dlevel back to absolute */ - stway->tolev.dlevel += u.uz.dlevel; - } + } + if (stway->tolev.dnum == u.uz.dnum) { + /* reset staiway dlevel back to absolute */ + stway->tolev.dlevel += u.uz.dlevel; } } stway = stway->next; } if (perform_bwrite(nhfp)) { + buflen = -1; if (nhfp->structlevel) { - buflen = -1; bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); } } From 0d445a7a7cb4796909ef6e6d51106099aa3b749d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 19:08:59 +0200 Subject: [PATCH 486/708] Unify monster-hits-monster --- include/extern.h | 3 + include/monattk.h | 6 ++ src/mhitm.c | 158 +++++++++++++-------------- src/mhitu.c | 161 +++++++++++++--------------- src/uhitm.c | 268 ++++++++++++++++++++++++++++++++-------------- 5 files changed, 348 insertions(+), 248 deletions(-) diff --git a/include/extern.h b/include/extern.h index 64df72baa..78417eba6 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1282,6 +1282,7 @@ E void FDECL(rustm, (struct monst *, struct obj *)); /* ### mhitu.c ### */ +E void FDECL(hitmsg, (struct monst *, struct attack *)); E const char *FDECL(mpoisons_subj, (struct monst *, struct attack *)); E void NDECL(u_slow_down); E struct monst *NDECL(cloneu); @@ -2754,6 +2755,8 @@ E boolean FDECL(attack, (struct monst *)); E boolean FDECL(hmon, (struct monst *, struct obj *, int, int)); E boolean FDECL(shade_miss, (struct monst *, struct monst *, struct obj *, BOOLEAN_P, BOOLEAN_P)); +E void FDECL(mhitm_ad_rust, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/include/monattk.h b/include/monattk.h index a836f3eab..8f2d7c12f 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -86,6 +86,12 @@ #define AD_SAMU 252 /* hits, may steal Amulet (Wizard) */ #define AD_CURS 253 /* random curse (ex. gremlin) */ +struct mhitm_data { + int damage; + int hitflags; /* MM_DEF_DIED | MM_AGR_DIED | ... */ + boolean done; +}; + /* * Monster to monster attacks. When a monster attacks another (mattackm), * any or all of the following can be returned. See mattackm() for more diff --git a/src/mhitm.c b/src/mhitm.c index efed25f15..397673396 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -858,10 +858,11 @@ int dieroll; struct obj *obj; char buf[BUFSZ]; struct permonst *pa = magr->data, *pd = mdef->data; - int armpro, num, - tmp = d((int) mattk->damn, (int) mattk->damd), - res = MM_MISS; + int armpro, num; boolean cancelled; + struct mhitm_data mhm; + mhm.damage = d((int) mattk->damn, (int) mattk->damd); + mhm.hitflags = MM_MISS; if ((touch_petrifies(pd) /* or flesh_petrifies() */ || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA])) @@ -914,7 +915,7 @@ int dieroll; } if (flags.verbose && !Deaf) verbalize("Burrrrp!"); - tmp = mdef->mhp; + mhm.damage = mdef->mhp; /* Use up amulet of life saving */ if ((obj = mlifesaver(mdef)) != 0) m_useup(mdef, obj); @@ -955,7 +956,7 @@ int dieroll; goto physical; case AD_LEGS: if (magr->mcan) { - tmp = 0; + mhm.damage = 0; break; } goto physical; @@ -967,11 +968,11 @@ int dieroll; mwep = 0; if (shade_miss(magr, mdef, mwep, FALSE, TRUE)) { - tmp = 0; + mhm.damage = 0; } else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { /* [no 'kicking boots' check needed; monsters with kick attacks can't wear boots and monsters that wear boots don't kick] */ - tmp = 0; + mhm.damage = 0; } else if (mwep) { /* non-Null 'mwep' implies AT_WEAP || AT_CLAW */ struct obj *marmg; @@ -979,19 +980,19 @@ int dieroll; && touch_petrifies(&mons[mwep->corpsenm])) goto do_stone; - tmp += dmgval(mwep, mdef); + mhm.damage += dmgval(mwep, mdef); if ((marmg = which_armor(magr, W_ARMG)) != 0 && marmg->otyp == GAUNTLETS_OF_POWER) - tmp += rn1(4, 3); /* 3..6 */ - if (tmp < 1) /* is this necessary? mhitu.c has it... */ - tmp = 1; + mhm.damage += rn1(4, 3); /* 3..6 */ + if (mhm.damage < 1) /* is this necessary? mhitu.c has it... */ + mhm.damage = 1; if (mwep->oartifact) { /* when magr's weapon is an artifact, caller suppressed its usual 'hit' message in case artifact_hit() delivers one; now we'll know and might need to deliver skipped message (note: if there's no message there'll be no auxilliary damage so the message here isn't coming too late) */ - if (!artifact_hit(magr, mdef, mwep, &tmp, dieroll)) { + if (!artifact_hit(magr, mdef, mwep, &mhm.damage, dieroll)) { if (g.vis) pline("%s hits %s.", Monnam(magr), mon_nam_too(mdef, magr)); @@ -1003,20 +1004,20 @@ int dieroll; return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } - if (tmp) + if (mhm.damage) rustm(mdef, mwep); } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) { /* hack to enhance mm_aggression(); we don't want purple worm's bite attack to kill a shrieker because then it won't swallow the corpse; but if the target survives, the subsequent engulf attack should accomplish that */ - if (tmp >= mdef->mhp && mdef->mhp > 1) - tmp = mdef->mhp - 1; + if (mhm.damage >= mdef->mhp && mdef->mhp > 1) + mhm.damage = mdef->mhp - 1; } break; case AD_FIRE: if (cancelled) { - tmp = 0; + mhm.damage = 0; break; } if (g.vis && canseemon(mdef)) @@ -1033,22 +1034,22 @@ int dieroll; return 0; return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } - tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); - tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); + mhm.damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); + mhm.damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); if (resists_fire(mdef)) { if (g.vis && canseemon(mdef)) pline_The("fire doesn't seem to burn %s!", mon_nam(mdef)); shieldeff(mdef->mx, mdef->my); - golemeffects(mdef, AD_FIRE, tmp); - tmp = 0; + golemeffects(mdef, AD_FIRE, mhm.damage); + mhm.damage = 0; } /* only potions damage resistant players in destroy_item */ - tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); + mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); ignite_items(mdef->minvent); break; case AD_COLD: if (cancelled) { - tmp = 0; + mhm.damage = 0; break; } if (g.vis && canseemon(mdef)) @@ -1057,39 +1058,39 @@ int dieroll; if (g.vis && canseemon(mdef)) pline_The("frost doesn't seem to chill %s!", mon_nam(mdef)); shieldeff(mdef->mx, mdef->my); - golemeffects(mdef, AD_COLD, tmp); - tmp = 0; + golemeffects(mdef, AD_COLD, mhm.damage); + mhm.damage = 0; } - tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); + mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); break; case AD_ELEC: if (cancelled) { - tmp = 0; + mhm.damage = 0; break; } if (g.vis && canseemon(mdef)) pline("%s gets zapped!", Monnam(mdef)); - tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); + mhm.damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); if (resists_elec(mdef)) { if (g.vis && canseemon(mdef)) pline_The("zap doesn't shock %s!", mon_nam(mdef)); shieldeff(mdef->mx, mdef->my); - golemeffects(mdef, AD_ELEC, tmp); - tmp = 0; + golemeffects(mdef, AD_ELEC, mhm.damage); + mhm.damage = 0; } /* only rings damage resistant players in destroy_item */ - tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); + mhm.damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); break; case AD_ACID: if (magr->mcan) { - tmp = 0; + mhm.damage = 0; break; } if (resists_acid(mdef)) { if (g.vis && canseemon(mdef)) pline("%s is covered in %s, but it seems harmless.", Monnam(mdef), hliquid("acid")); - tmp = 0; + mhm.damage = 0; } else if (g.vis && canseemon(mdef)) { pline("%s is covered in %s!", Monnam(mdef), hliquid("acid")); pline("It burns %s!", mon_nam(mdef)); @@ -1100,27 +1101,14 @@ int dieroll; acid_damage(MON_WEP(mdef)); break; case AD_RUST: - if (magr->mcan) - break; - if (completelyrusts(pd)) { /* PM_IRON_GOLEM */ - if (g.vis && canseemon(mdef)) - pline("%s %s to pieces!", Monnam(mdef), - !mlifesaver(mdef) ? "falls" : "starts to fall"); - monkilled(mdef, (char *) 0, AD_RUST); - if (!DEADMONSTER(mdef)) - return 0; - return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - } - erode_armor(mdef, ERODE_RUST); - mdef->mstrategy &= ~STRAT_WAITFORU; - tmp = 0; + mhitm_ad_rust(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CORR: - if (magr->mcan) - break; - erode_armor(mdef, ERODE_CORRODE); - mdef->mstrategy &= ~STRAT_WAITFORU; - tmp = 0; + mhitm_ad_corr(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DCAY: if (magr->mcan) @@ -1138,7 +1126,7 @@ int dieroll; } erode_armor(mdef, ERODE_CORRODE); mdef->mstrategy &= ~STRAT_WAITFORU; - tmp = 0; + mhm.damage = 0; break; case AD_STON: if (magr->mcan) @@ -1149,7 +1137,7 @@ int dieroll; goto post_stone; if (poly_when_stoned(pd)) { mon_to_stone(mdef); - tmp = 0; + mhm.damage = 0; break; } if (!resists_ston(mdef)) { @@ -1163,10 +1151,10 @@ int dieroll; You(brief_feeling, "peculiarly sad"); return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } - tmp = (mattk->adtyp == AD_STON ? 0 : 1); + mhm.damage = (mattk->adtyp == AD_STON ? 0 : 1); break; case AD_TLPT: - if (!cancelled && tmp < mdef->mhp && !tele_restrict(mdef)) { + if (!cancelled && mhm.damage < mdef->mhp && !tele_restrict(mdef)) { char mdef_Monnam[BUFSZ]; boolean wasseen = canspotmon(mdef); @@ -1178,10 +1166,10 @@ int dieroll; (void) rloc(mdef, TRUE); if (g.vis && wasseen && !canspotmon(mdef) && mdef != u.usteed) pline("%s suddenly disappears!", mdef_Monnam); - if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */ + if (mhm.damage >= mdef->mhp) { /* see hitmu(mhitu.c) */ if (mdef->mhp == 1) ++mdef->mhp; - tmp = mdef->mhp - 1; + mhm.damage = mdef->mhp - 1; } } break; @@ -1240,7 +1228,7 @@ int dieroll; mdef->mcansee = 0; mdef->mstrategy &= ~STRAT_WAITFORU; } - tmp = 0; + mhm.damage = 0; break; case AD_HALU: if (!magr->mcan && haseyes(pd) && mdef->mcansee) { @@ -1250,7 +1238,7 @@ int dieroll; mdef->mconf = 1; mdef->mstrategy &= ~STRAT_WAITFORU; } - tmp = 0; + mhm.damage = 0; break; case AD_CURS: if (!night() && (pa == &mons[PM_GREMLIN])) @@ -1283,7 +1271,7 @@ int dieroll; } break; case AD_SGLD: - tmp = 0; + mhm.damage = 0; if (magr->mcan) break; /* technically incorrect; no check for stealing gold from @@ -1312,11 +1300,11 @@ int dieroll; break; case AD_DRLI: /* drain life */ if (!cancelled && !rn2(3) && !resists_drli(mdef)) { - tmp = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ + mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ if (g.vis && canspotmon(mdef)) pline("%s becomes weaker!", Monnam(mdef)); - if (mdef->mhpmax - tmp > (int) mdef->m_lev) { - mdef->mhpmax -= tmp; + if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) { + mdef->mhpmax -= mhm.damage; } else { /* limit floor of mhpmax reduction to current m_lev + 1; avoid increasing it if somehow already less than that */ @@ -1324,7 +1312,7 @@ int dieroll; mdef->mhpmax = (int) mdef->m_lev + 1; } if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */ - tmp = mdef->mhp; + mhm.damage = mdef->mhp; else mdef->m_lev--; @@ -1386,13 +1374,13 @@ int dieroll; pline("%s suddenly disappears!", buf); } } - tmp = 0; + mhm.damage = 0; break; case AD_DREN: if (!cancelled && !rn2(4)) xdrainenergym(mdef, (boolean) (g.vis && canspotmon(mdef) && mattk->aatyp != AT_ENGL)); - tmp = 0; + mhm.damage = 0; break; case AD_DRST: case AD_DRDX: @@ -1407,11 +1395,11 @@ int dieroll; mon_nam(mdef)); } else { if (rn2(10)) - tmp += rn1(10, 6); + mhm.damage += rn1(10, 6); else { if (g.vis && canspotmon(mdef)) pline_The("poison was deadly..."); - tmp = mdef->mhp; + mhm.damage = mdef->mhp; } } } @@ -1421,7 +1409,7 @@ int dieroll; if (g.vis && canspotmon(mdef)) pline("%s doesn't seem harmed.", Monnam(mdef)); /* Not clear what to do for green slimes */ - tmp = 0; + mhm.damage = 0; /* don't bother with additional DRIN attacks since they wouldn't be able to hit target on head either */ g.skipdrin = TRUE; /* affects mattackm()'s attack loop */ @@ -1435,7 +1423,7 @@ int dieroll; } break; } - res = eat_brains(magr, mdef, g.vis, &tmp); + mhm.hitflags = eat_brains(magr, mdef, g.vis, &mhm.damage); break; case AD_SLIM: if (cancelled) @@ -1446,41 +1434,41 @@ int dieroll; (boolean) (g.vis && canseemon(mdef)))) pd = mdef->data; mdef->mstrategy &= ~STRAT_WAITFORU; - res = MM_HIT; + mhm.hitflags = MM_HIT; } /* munslime attempt could have been fatal, potentially to multiple monsters (SCR_FIRE) */ if (DEADMONSTER(magr)) - res |= MM_AGR_DIED; + mhm.hitflags |= MM_AGR_DIED; if (DEADMONSTER(mdef)) - res |= MM_DEF_DIED; - tmp = 0; + mhm.hitflags |= MM_DEF_DIED; + mhm.damage = 0; } break; case AD_STCK: if (cancelled) - tmp = 0; + mhm.damage = 0; break; case AD_WRAP: /* monsters cannot grab one another, it's too hard */ if (magr->mcan) - tmp = 0; + mhm.damage = 0; break; case AD_ENCH: /* there's no msomearmor() function, so just do damage */ /* if (cancelled) break; */ break; case AD_POLY: - if (!magr->mcan && tmp < mdef->mhp) - tmp = mon_poly(magr, mdef, tmp); + if (!magr->mcan && mhm.damage < mdef->mhp) + mhm.damage = mon_poly(magr, mdef, mhm.damage); break; default: - tmp = 0; + mhm.damage = 0; break; } - if (!tmp) - return res; + if (!mhm.damage) + return mhm.hitflags; - if ((mdef->mhp -= tmp) < 1) { + if ((mdef->mhp -= mhm.damage) < 1) { if (m_at(mdef->mx, mdef->my) == magr) { /* see gulpmm() */ remove_monster(mdef->mx, mdef->my); mdef->mhp = 1; /* otherwise place_monster will complain */ @@ -1495,8 +1483,8 @@ int dieroll; monkilled(mdef, "", (int) mattk->adtyp); g.zombify = FALSE; /* reset */ if (!DEADMONSTER(mdef)) - return res; /* mdef lifesaved */ - else if (res == MM_AGR_DIED) + return mhm.hitflags; /* mdef lifesaved */ + else if (mhm.hitflags == MM_AGR_DIED) return (MM_DEF_DIED | MM_AGR_DIED); if (mattk->adtyp == AD_DGST) { @@ -1518,7 +1506,7 @@ int dieroll; return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); } - return (res == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT; + return (mhm.hitflags == MM_AGR_DIED) ? MM_AGR_DIED : MM_HIT; } int diff --git a/src/mhitu.c b/src/mhitu.c index b9df18ce7..767ed19e7 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -8,7 +8,6 @@ static NEARDATA struct obj *mon_currwep = (struct obj *) 0; -static void FDECL(hitmsg, (struct monst *, struct attack *)); static void FDECL(missmu, (struct monst *, BOOLEAN_P, struct attack *)); static void FDECL(mswings, (struct monst *, struct obj *)); static void FDECL(wildmiss, (struct monst *, struct attack *)); @@ -25,7 +24,7 @@ static int FDECL(passiveum, (struct permonst *, struct monst *, #define ld() ((yyyymmdd((time_t) 0) - (getyear() * 10000L)) == 0xe5) -static void +void hitmsg(mtmp, mattk) struct monst *mtmp; struct attack *mattk; @@ -970,10 +969,12 @@ register struct attack *mattk; { struct permonst *mdat = mtmp->data; int uncancelled, ptmp; - int dmg, armpro, permdmg, tmphp; + int armpro, permdmg, tmphp; char buf[BUFSZ]; struct permonst *olduasmon = g.youmonst.data; int res; + struct mhitm_data mhm; + mhm.hitflags = MM_MISS; if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); @@ -1002,9 +1003,9 @@ register struct attack *mattk; } /* First determine the base damage done */ - dmg = d((int) mattk->damn, (int) mattk->damd); + mhm.damage = d((int) mattk->damn, (int) mattk->damd); if ((is_undead(mdat) || is_vampshifter(mtmp)) && midnight()) - dmg += d((int) mattk->damn, (int) mattk->damd); /* extra damage */ + mhm.damage += d((int) mattk->damn, (int) mattk->damd); /* extra damage */ /* Next a cancellation factor. * Use uncancelled when cancellation factor takes into account certain @@ -1020,7 +1021,7 @@ register struct attack *mattk; if (mattk->aatyp == AT_HUGS && !sticks(g.youmonst.data)) { if (!u.ustuck && rn2(2)) { if (u_slip_free(mtmp, mattk)) { - dmg = 0; + mhm.damage = 0; } else { set_ustuck(mtmp); pline("%s grabs you!", Monnam(mtmp)); @@ -1040,22 +1041,22 @@ register struct attack *mattk; if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm])) { - dmg = 1; + mhm.damage = 1; pline("%s hits you with the %s corpse.", Monnam(mtmp), mons[otmp->corpsenm].mname); if (!Stoned) goto do_stone; } - dmg += dmgval(otmp, &g.youmonst); + mhm.damage += dmgval(otmp, &g.youmonst); if ((marmg = which_armor(mtmp, W_ARMG)) != 0 && marmg->otyp == GAUNTLETS_OF_POWER) - dmg += rn1(4, 3); /* 3..6 */ - if (dmg <= 0) - dmg = 1; + mhm.damage += rn1(4, 3); /* 3..6 */ + if (mhm.damage <= 0) + mhm.damage = 1; if (!(otmp->oartifact && artifact_hit(mtmp, &g.youmonst, otmp, - &dmg, g.mhitu_dieroll))) + &mhm.damage, g.mhitu_dieroll))) hitmsg(mtmp, mattk); - if (!dmg) + if (!mhm.damage) break; if (objects[otmp->otyp].oc_material == SILVER && Hate_silver) { @@ -1065,7 +1066,7 @@ register struct attack *mattk; /* this redundancy necessary because you have to take the damage _before_ being cloned; need to have at least 2 hp left to split */ - tmp = dmg; + tmp = mhm.damage; if (u.uac < 0) tmp -= rnd(-u.uac); if (tmp < 1) @@ -1081,12 +1082,12 @@ register struct attack *mattk; /* inflict damage now; we know it can't be fatal */ u.mh -= tmp; g.context.botl = 1; - dmg = 0; /* don't inflict more damage below */ + mhm.damage = 0; /* don't inflict more damage below */ if (cloneu()) You("divide as %s hits you!", mon_nam(mtmp)); } rustm(&g.youmonst, otmp); - } else if (mattk->aatyp != AT_TUCH || dmg != 0 + } else if (mattk->aatyp != AT_TUCH || mhm.damage != 0 || mtmp != u.ustuck) hitmsg(mtmp, mattk); } @@ -1094,7 +1095,7 @@ register struct attack *mattk; case AD_DISE: hitmsg(mtmp, mattk); if (!diseasemu(mdat)) - dmg = 0; + mhm.damage = 0; break; case AD_FIRE: hitmsg(mtmp, mattk); @@ -1107,7 +1108,7 @@ register struct attack *mattk; break; } else if (Fire_resistance) { pline_The("fire doesn't feel hot!"); - dmg = 0; + mhm.damage = 0; } if ((int) mtmp->m_lev > rn2(20)) destroy_item(SCROLL_CLASS, AD_FIRE); @@ -1119,7 +1120,7 @@ register struct attack *mattk; ignite_items(g.invent); burn_away_slime(); } else - dmg = 0; + mhm.damage = 0; break; case AD_COLD: hitmsg(mtmp, mattk); @@ -1127,12 +1128,12 @@ register struct attack *mattk; pline("You're covered in frost!"); if (Cold_resistance) { pline_The("frost doesn't seem cold!"); - dmg = 0; + mhm.damage = 0; } if ((int) mtmp->m_lev > rn2(20)) destroy_item(POTION_CLASS, AD_COLD); } else - dmg = 0; + mhm.damage = 0; break; case AD_ELEC: hitmsg(mtmp, mattk); @@ -1140,14 +1141,14 @@ register struct attack *mattk; You("get zapped!"); if (Shock_resistance) { pline_The("zap doesn't shock you!"); - dmg = 0; + mhm.damage = 0; } if ((int) mtmp->m_lev > rn2(20)) destroy_item(WAND_CLASS, AD_ELEC); if ((int) mtmp->m_lev > rn2(20)) destroy_item(RING_CLASS, AD_ELEC); } else - dmg = 0; + mhm.damage = 0; break; case AD_SLEE: hitmsg(mtmp, mattk); @@ -1165,11 +1166,11 @@ register struct attack *mattk; if (can_blnd(mtmp, &g.youmonst, mattk->aatyp, (struct obj *) 0)) { if (!Blind) pline("%s blinds you!", Monnam(mtmp)); - make_blinded(Blinded + (long) dmg, FALSE); + make_blinded(Blinded + (long) mhm.damage, FALSE); if (!Blind) Your1(vision_clears); } - dmg = 0; + mhm.damage = 0; break; case AD_DRST: ptmp = A_STR; @@ -1207,9 +1208,9 @@ register struct attack *mattk; } /* negative armor class doesn't reduce this damage */ if (Half_physical_damage) - dmg = (dmg + 1) / 2; - mdamageu(mtmp, dmg); - dmg = 0; /* don't inflict a second dose below */ + mhm.damage = (mhm.damage + 1) / 2; + mdamageu(mtmp, mhm.damage); + mhm.damage = 0; /* don't inflict a second dose below */ if (!uarmh || uarmh->otyp != DUNCE_CAP) { /* eat_brains() will miss if target is mindless (won't @@ -1260,11 +1261,11 @@ register struct attack *mattk; */ if ((u.usteed || Levitation || Flying) && !is_flyer(mtmp->data)) { pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg); - dmg = 0; + mhm.damage = 0; } else if (mtmp->mcan) { pline("%s nuzzles against your %s %s!", Monnam(mtmp), sidestr, leg); - dmg = 0; + mhm.damage = 0; } else { if (uarmf) { if (rn2(2) && (uarmf->otyp == LOW_BOOTS @@ -1277,7 +1278,7 @@ register struct attack *mattk; } else { pline("%s scratches your %s boot!", Monst_name, sidestr); - dmg = 0; + mhm.damage = 0; break; } } else @@ -1330,7 +1331,7 @@ register struct attack *mattk; if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(g.youmonst.data)) { if (!u.ustuck && !rn2(10)) { if (u_slip_free(mtmp, mattk)) { - dmg = 0; + mhm.damage = 0; } else { set_ustuck(mtmp); /* before message, for botl update */ pline("%s swings itself around you!", Monnam(mtmp)); @@ -1352,13 +1353,13 @@ register struct attack *mattk; You("are being crushed."); } } else { - dmg = 0; + mhm.damage = 0; if (flags.verbose) pline("%s brushes against your %s.", Monnam(mtmp), body_part(LEG)); } } else - dmg = 0; + mhm.damage = 0; break; case AD_WERE: hitmsg(mtmp, mattk); @@ -1462,16 +1463,16 @@ register struct attack *mattk; particularly if the teleportation had been controlled [applying the damage first and not teleporting if fatal is another alternative but it has its own complications] */ - if ((Half_physical_damage ? (dmg - 1) / 2 : dmg) + if ((Half_physical_damage ? (mhm.damage - 1) / 2 : mhm.damage) >= (tmphp = (Upolyd ? u.mh : u.uhp))) { - dmg = tmphp - 1; + mhm.damage = tmphp - 1; if (Half_physical_damage) - dmg *= 2; /* doesn't actually increase damage; we only + mhm.damage *= 2; /* doesn't actually increase damage; we only * get here if half the original damage would * would have been fatal, so double reduced * damage will be less than original damage */ - if (dmg < 1) { /* implies (tmphp <= 1) */ - dmg = 1; + if (mhm.damage < 1) { /* implies (tmphp <= 1) */ + mhm.damage = 1; /* this might increase current HP beyond maximum HP but it will be immediately reduced below, so that should be indistinguishable from zero damage; we don't drop @@ -1487,22 +1488,14 @@ register struct attack *mattk; } break; case AD_RUST: - hitmsg(mtmp, mattk); - if (mtmp->mcan) - break; - if (completelyrusts(g.youmonst.data)) { - You("rust!"); - /* KMH -- this is okay with unchanging */ - rehumanize(); - break; - } - erode_armor(&g.youmonst, ERODE_RUST); + mhitm_ad_rust(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CORR: - hitmsg(mtmp, mattk); - if (mtmp->mcan) - break; - erode_armor(&g.youmonst, ERODE_CORRODE); + mhitm_ad_corr(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DCAY: hitmsg(mtmp, mattk); @@ -1568,12 +1561,12 @@ register struct attack *mattk; monflee(mtmp, d(3, 6), TRUE, FALSE); return 3; } - dmg = 0; + mhm.damage = 0; } else { if (Role_if(PM_HEALER)) { if (!Deaf && !(g.moves % 5)) verbalize("Doc, I can't help you unless you cooperate."); - dmg = 0; + mhm.damage = 0; } else hitmsg(mtmp, mattk); } @@ -1601,8 +1594,8 @@ register struct attack *mattk; case AD_STUN: hitmsg(mtmp, mattk); if (!mtmp->mcan && !rn2(4)) { - make_stunned((HStun & TIMEOUT) + (long) dmg, TRUE); - dmg /= 2; + make_stunned((HStun & TIMEOUT) + (long) mhm.damage, TRUE); + mhm.damage /= 2; } break; case AD_ACID: @@ -1611,13 +1604,13 @@ register struct attack *mattk; if (Acid_resistance) { pline("You're covered in %s, but it seems harmless.", hliquid("acid")); - dmg = 0; + mhm.damage = 0; } else { pline("You're covered in %s! It burns!", hliquid("acid")); exercise(A_STR, FALSE); } else - dmg = 0; + mhm.damage = 0; break; case AD_SLOW: hitmsg(mtmp, mattk); @@ -1627,20 +1620,20 @@ register struct attack *mattk; case AD_DREN: hitmsg(mtmp, mattk); if (uncancelled && !rn2(4)) /* 25% chance */ - drain_en(dmg); - dmg = 0; + drain_en(mhm.damage); + mhm.damage = 0; break; case AD_CONF: hitmsg(mtmp, mattk); if (!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { - mtmp->mspec_used = mtmp->mspec_used + (dmg + rn2(6)); + mtmp->mspec_used = mtmp->mspec_used + (mhm.damage + rn2(6)); if (Confusion) You("are getting even more confused."); else You("are getting confused."); - make_confused(HConfusion + dmg, FALSE); + make_confused(HConfusion + mhm.damage, FALSE); } - dmg = 0; + mhm.damage = 0; break; case AD_DETH: pline("%s reaches out with its deadly touch.", Monnam(mtmp)); @@ -1657,7 +1650,7 @@ register struct attack *mattk; g.killer.format = KILLED_BY_AN; Strcpy(g.killer.name, "touch of death"); done(DIED); - dmg = 0; + mhm.damage = 0; break; } /*FALLTHRU*/ @@ -1673,7 +1666,7 @@ register struct attack *mattk; if (Antimagic) shieldeff(u.ux, u.uy); pline("Lucky for you, it didn't work!"); - dmg = 0; + mhm.damage = 0; break; } break; @@ -1694,11 +1687,11 @@ register struct attack *mattk; break; if (flaming(g.youmonst.data)) { pline_The("slime burns away!"); - dmg = 0; + mhm.damage = 0; } else if (Unchanging || noncorporeal(g.youmonst.data) || g.youmonst.data == &mons[PM_GREEN_SLIME]) { You("are unaffected."); - dmg = 0; + mhm.damage = 0; } else if (!Slimed) { You("don't feel very well."); make_slimed(10L, (char *) 0); @@ -1739,35 +1732,35 @@ register struct attack *mattk; } break; case AD_POLY: - if (uncancelled && Maybe_Half_Phys(dmg) < (Upolyd ? u.mh : u.uhp)) - dmg = mon_poly(mtmp, &g.youmonst, dmg); + if (uncancelled && Maybe_Half_Phys(mhm.damage) < (Upolyd ? u.mh : u.uhp)) + mhm.damage = mon_poly(mtmp, &g.youmonst, mhm.damage); break; default: - dmg = 0; + mhm.damage = 0; break; } if ((Upolyd ? u.mh : u.uhp) < 1) { /* already dead? call rehumanize() or done_in_by() as appropriate */ mdamageu(mtmp, 1); - dmg = 0; + mhm.damage = 0; } /* Negative armor class reduces damage done instead of fully protecting * against hits. */ - if (dmg && u.uac < 0) { - dmg -= rnd(-u.uac); - if (dmg < 1) - dmg = 1; + if (mhm.damage && u.uac < 0) { + mhm.damage -= rnd(-u.uac); + if (mhm.damage < 1) + mhm.damage = 1; } - if (dmg) { + if (mhm.damage) { if (Half_physical_damage /* Mitre of Holiness */ || (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) && (is_undead(mtmp->data) || is_demon(mtmp->data) || is_vampshifter(mtmp)))) - dmg = (dmg + 1) / 2; + mhm.damage = (mhm.damage + 1) / 2; if (permdmg) { /* Death's life force drain */ int lowerlimit, *hpmax_p; @@ -1780,13 +1773,13 @@ register struct attack *mattk; * otherwise 0..50% * Never reduces hpmax below 1 hit point per level. */ - permdmg = rn2(dmg / 2 + 1); + permdmg = rn2(mhm.damage / 2 + 1); if (Upolyd || u.uhpmax > 25 * u.ulevel) - permdmg = dmg; + permdmg = mhm.damage; else if (u.uhpmax > 10 * u.ulevel) - permdmg += dmg / 2; + permdmg += mhm.damage / 2; else if (u.uhpmax > 5 * u.ulevel) - permdmg += dmg / 4; + permdmg += mhm.damage / 4; if (Upolyd) { hpmax_p = &u.mhmax; @@ -1805,10 +1798,10 @@ register struct attack *mattk; g.context.botl = 1; } - mdamageu(mtmp, dmg); + mdamageu(mtmp, mhm.damage); } - if (dmg) + if (mhm.damage) res = passiveum(olduasmon, mtmp, mattk); else res = 1; diff --git a/src/uhitm.c b/src/uhitm.c index a9ebc349c..53ff72678 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1689,6 +1689,118 @@ struct attack *mattk; mpickobj(mdef, gold); } +void +mhitm_ad_rust(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (completelyrusts(pd)) { /* iron golem */ + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); + xkilled(mdef, XKILL_NOMSG); + mhm->hitflags |= MM_DEF_DIED; + } + erode_armor(mdef, ERODE_RUST); + mhm->damage = 0; /* damageum(), int tmp */ + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (magr->mcan) { + return; + } + if (completelyrusts(pd)) { + You("rust!"); + /* KMH -- this is okay with unchanging */ + rehumanize(); + return; + } + erode_armor(&g.youmonst, ERODE_RUST); + } else { + /* mhitm */ + if (magr->mcan) + return; + if (completelyrusts(pd)) { /* PM_IRON_GOLEM */ + if (g.vis && canseemon(mdef)) + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); + monkilled(mdef, (char *) 0, AD_RUST); + if (!DEADMONSTER(mdef)) { + mhm->hitflags = MM_MISS; + mhm->done = TRUE; + return; + } + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + mhm->done = TRUE; + return; + } + erode_armor(mdef, ERODE_RUST); + mdef->mstrategy &= ~STRAT_WAITFORU; + mhm->damage = 0; /* mdamagem(), int tmp */ + } +} + +void +mhitm_ad_corr(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + erode_armor(mdef, ERODE_CORRODE); + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (magr->mcan) + return; + erode_armor(mdef, ERODE_CORRODE); + } else { + /* mhitm */ + if (magr->mcan) + return; + erode_armor(mdef, ERODE_CORRODE); + mdef->mstrategy &= ~STRAT_WAITFORU; + mhm->damage = 0; + } +} + +/* Template for monster hits monster for AD_FOO. + - replace "break" with return + - replace "return" with mhm->done = TRUE +*/ +void +mhitm_ad_FOO(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + /* TODO */ + } else if (mdef == &g.youmonst) { + /* mhitu */ + /* TODO */ + } else { + /* mhitm */ + /* TODO */ + } +} + int damageum(mdef, mattk, specialdmg) register struct monst *mdef; @@ -1696,9 +1808,12 @@ register struct attack *mattk; int specialdmg; /* blessed and/or silver bonus against various things */ { register struct permonst *pd = mdef->data; - int armpro, tmp = d((int) mattk->damn, (int) mattk->damd); + int armpro; boolean negated; struct obj *mongold; + struct mhitm_data mhm; + mhm.damage = d((int) mattk->damn, (int) mattk->damd); + mhm.hitflags = MM_MISS; armpro = magic_negation(mdef); /* since hero can't be cancelled, only defender's armor applies */ @@ -1720,7 +1835,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ case AD_LEGS: #if 0 if (u.ucancelled) { - tmp = 0; + mhm.damage = 0; break; } #endif @@ -1730,39 +1845,39 @@ int specialdmg; /* blessed and/or silver bonus against various things */ case AD_PHYS: physical: if (pd == &mons[PM_SHADE]) { - tmp = 0; + mhm.damage = 0; if (!specialdmg) impossible("bad shade attack function flow?"); } - tmp += specialdmg; + mhm.damage += specialdmg; if (mattk->aatyp == AT_WEAP) { /* hmonas() uses known_hitum() to deal physical damage, then also damageum() for non-AD_PHYS; don't inflict extra physical damage for unusual damage types */ - tmp = 0; + mhm.damage = 0; } else if (mattk->aatyp == AT_KICK || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH || mattk->aatyp == AT_HUGS) { if (thick_skinned(pd)) - tmp = (mattk->aatyp == AT_KICK) ? 0 : (tmp + 1) / 2; + mhm.damage = (mattk->aatyp == AT_KICK) ? 0 : (mhm.damage + 1) / 2; /* add ring(s) of increase damage */ if (u.udaminc > 0) { /* applies even if damage was 0 */ - tmp += u.udaminc; - } else if (tmp > 0) { + mhm.damage += u.udaminc; + } else if (mhm.damage > 0) { /* ring(s) might be negative; avoid converting 0 to non-0 or positive to non-positive */ - tmp += u.udaminc; - if (tmp < 1) - tmp = 1; + mhm.damage += u.udaminc; + if (mhm.damage < 1) + mhm.damage = 1; } } break; case AD_FIRE: if (negated) { - tmp = 0; + mhm.damage = 0; break; } if (!Blind) @@ -1779,26 +1894,26 @@ int specialdmg; /* blessed and/or silver bonus against various things */ (pd == &mons[PM_PAPER_GOLEM]) ? " paper" : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : ""); xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE); - tmp = 0; + mhm.damage = 0; break; - /* Don't return yet; keep hp<1 and tmp=0 for pet msg */ + /* Don't return yet; keep hp<1 and mhm.damage=0 for pet msg */ } - tmp += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); - tmp += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); + mhm.damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); + mhm.damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); if (resists_fire(mdef)) { if (!Blind) pline_The("fire doesn't heat %s!", mon_nam(mdef)); - golemeffects(mdef, AD_FIRE, tmp); + golemeffects(mdef, AD_FIRE, mhm.damage); shieldeff(mdef->mx, mdef->my); - tmp = 0; + mhm.damage = 0; } /* only potions damage resistant players in destroy_item */ - tmp += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); + mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); ignite_items(mdef->minvent); break; case AD_COLD: if (negated) { - tmp = 0; + mhm.damage = 0; break; } if (!Blind) @@ -1807,43 +1922,43 @@ int specialdmg; /* blessed and/or silver bonus against various things */ shieldeff(mdef->mx, mdef->my); if (!Blind) pline_The("frost doesn't chill %s!", mon_nam(mdef)); - golemeffects(mdef, AD_COLD, tmp); - tmp = 0; + golemeffects(mdef, AD_COLD, mhm.damage); + mhm.damage = 0; } - tmp += destroy_mitem(mdef, POTION_CLASS, AD_COLD); + mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); break; case AD_ELEC: if (negated) { - tmp = 0; + mhm.damage = 0; break; } if (!Blind) pline("%s is zapped!", Monnam(mdef)); - tmp += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); + mhm.damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); if (resists_elec(mdef)) { if (!Blind) pline_The("zap doesn't shock %s!", mon_nam(mdef)); - golemeffects(mdef, AD_ELEC, tmp); + golemeffects(mdef, AD_ELEC, mhm.damage); shieldeff(mdef->mx, mdef->my); - tmp = 0; + mhm.damage = 0; } /* only rings damage resistant players in destroy_item */ - tmp += destroy_mitem(mdef, RING_CLASS, AD_ELEC); + mhm.damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); break; case AD_ACID: if (resists_acid(mdef)) - tmp = 0; + mhm.damage = 0; break; case AD_STON: if (!munstone(mdef, TRUE)) minstapetrify(mdef, TRUE); - tmp = 0; + mhm.damage = 0; break; case AD_SSEX: case AD_SEDU: case AD_SITM: steal_it(mdef, mattk); - tmp = 0; + mhm.damage = 0; break; case AD_SGLD: /* This you as a leprechaun, so steal @@ -1861,11 +1976,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } } exercise(A_DEX, TRUE); - tmp = 0; + mhm.damage = 0; break; case AD_TLPT: - if (tmp <= 0) - tmp = 1; + if (mhm.damage <= 0) + mhm.damage = 1; if (!negated) { char nambuf[BUFSZ]; boolean u_saw_mon = (canseemon(mdef) @@ -1876,10 +1991,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (u_teleport_mon(mdef, FALSE) && u_saw_mon && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef))) pline("%s suddenly disappears!", nambuf); - if (tmp >= mdef->mhp) { /* see hitmu(mhitu.c) */ + if (mhm.damage >= mdef->mhp) { /* see hitmu(mhitu.c) */ if (mdef->mhp == 1) ++mdef->mhp; - tmp = mdef->mhp - 1; + mhm.damage = mdef->mhp - 1; } } break; @@ -1888,12 +2003,12 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (!Blind && mdef->mcansee) pline("%s is blinded.", Monnam(mdef)); mdef->mcansee = 0; - tmp += mdef->mblinded; - if (tmp > 127) - tmp = 127; - mdef->mblinded = tmp; + mhm.damage += mdef->mblinded; + if (mhm.damage > 127) + mhm.damage = 127; + mdef->mblinded = mhm.damage; } - tmp = 0; + mhm.damage = 0; break; case AD_CURS: if (night() && !rn2(10) && !mdef->mcan) { @@ -1902,27 +2017,27 @@ int specialdmg; /* blessed and/or silver bonus against various things */ pline("Some writing vanishes from %s head!", s_suffix(mon_nam(mdef))); xkilled(mdef, XKILL_NOMSG); - /* Don't return yet; keep hp<1 and tmp=0 for pet msg */ + /* Don't return yet; keep hp<1 and mhm.damage=0 for pet msg */ } else { mdef->mcan = 1; You("chuckle."); } } - tmp = 0; + mhm.damage = 0; break; case AD_DRLI: /* drain life */ if (!negated && !rn2(3) && !resists_drli(mdef)) { - tmp = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ + mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ pline("%s becomes weaker!", Monnam(mdef)); - if (mdef->mhpmax - tmp > (int) mdef->m_lev) { - mdef->mhpmax -= tmp; + if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) { + mdef->mhpmax -= mhm.damage; } else { /* limit floor of mhpmax reduction to current m_lev + 1; avoid increasing it if somehow already less than that */ if (mdef->mhpmax > (int) mdef->m_lev) mdef->mhpmax = (int) mdef->m_lev + 1; } - mdef->mhp -= tmp; + mdef->mhp -= mhm.damage; /* !m_lev: level 0 monster is killed regardless of hit points rather than drop to level -1; note: some non-living creatures (golems, vortices) are subject to life-drain */ @@ -1932,26 +2047,21 @@ int specialdmg; /* blessed and/or silver bonus against various things */ xkilled(mdef, XKILL_NOMSG); } else mdef->m_lev--; - tmp = 0; /* damage has already been inflicted */ + mhm.damage = 0; /* damage has already been inflicted */ /* unlike hitting with Stormbringer, wounded hero doesn't heal any from the drained life */ } break; case AD_RUST: - if (completelyrusts(pd)) { /* iron golem */ - /* note: the life-saved case is hypothetical because - life-saving doesn't work for golems */ - pline("%s %s to pieces!", Monnam(mdef), - !mlifesaver(mdef) ? "falls" : "starts to fall"); - xkilled(mdef, XKILL_NOMSG); - } - erode_armor(mdef, ERODE_RUST); - tmp = 0; + mhitm_ad_rust(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CORR: - erode_armor(mdef, ERODE_CORRODE); - tmp = 0; + mhitm_ad_corr(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DCAY: if (completelyrots(pd)) { /* wood golem or leather golem */ @@ -1960,12 +2070,12 @@ int specialdmg; /* blessed and/or silver bonus against various things */ xkilled(mdef, XKILL_NOMSG); } erode_armor(mdef, ERODE_ROT); - tmp = 0; + mhm.damage = 0; break; case AD_DREN: if (!negated && !rn2(4)) xdrainenergym(mdef, TRUE); - tmp = 0; + mhm.damage = 0; break; case AD_DRST: case AD_DRDX: @@ -1977,9 +2087,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } else { if (!rn2(10)) { Your("poison was deadly..."); - tmp = mdef->mhp; + mhm.damage = mdef->mhp; } else - tmp += rn1(10, 6); + mhm.damage += rn1(10, 6); } } break; @@ -1992,7 +2102,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ because they'll be just as harmless as this one (and also to reduce verbosity) */ g.skipdrin = TRUE; - tmp = 0; + mhm.damage = 0; if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) { if (!Slimed) { You("suck in some slime and don't feel very well."); @@ -2011,7 +2121,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ break; } - (void) eat_brains(&g.youmonst, mdef, TRUE, &tmp); + (void) eat_brains(&g.youmonst, mdef, TRUE, &mhm.damage); break; } case AD_STCK: @@ -2022,7 +2132,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (!sticks(pd)) { if (!u.ustuck && !rn2(10)) { if (m_slips_free(mdef, mattk)) { - tmp = 0; + mhm.damage = 0; } else { You("swing yourself around %s!", mon_nam(mdef)); set_ustuck(mdef); @@ -2032,20 +2142,20 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (is_pool(u.ux, u.uy) && !is_swimmer(pd) && !amphibious(pd)) { You("drown %s...", mon_nam(mdef)); - tmp = mdef->mhp; + mhm.damage = mdef->mhp; } else if (mattk->aatyp == AT_HUGS) pline("%s is being crushed.", Monnam(mdef)); } else { - tmp = 0; + mhm.damage = 0; if (flags.verbose) You("brush against %s %s.", s_suffix(mon_nam(mdef)), mbodypart(mdef, LEG)); } } else - tmp = 0; + mhm.damage = 0; break; case AD_PLYS: - if (!negated && mdef->mcanmove && !rn2(3) && tmp < mdef->mhp) { + if (!negated && mdef->mcanmove && !rn2(3) && mhm.damage < mdef->mhp) { if (!Blind) pline("%s is frozen by you!", Monnam(mdef)); paralyze_monst(mdef, rnd(10)); @@ -2072,7 +2182,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ /* munslime attempt could have been fatal */ if (DEADMONSTER(mdef)) return 2; /* skip death message */ - tmp = 0; + mhm.damage = 0; } break; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ @@ -2096,26 +2206,26 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } break; case AD_POLY: - if (!negated && tmp < mdef->mhp) - tmp = mon_poly(&g.youmonst, mdef, tmp); + if (!negated && mhm.damage < mdef->mhp) + mhm.damage = mon_poly(&g.youmonst, mdef, mhm.damage); break; default: - tmp = 0; + mhm.damage = 0; break; } mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */ - mdef->mhp -= tmp; + mdef->mhp -= mhm.damage; if (DEADMONSTER(mdef)) { if (mdef->mtame && !cansee(mdef->mx, mdef->my)) { You_feel("embarrassed for a moment."); - if (tmp) - xkilled(mdef, XKILL_NOMSG); /* !tmp but hp<1: already killed */ + if (mhm.damage) + xkilled(mdef, XKILL_NOMSG); /* !mhm.damage but hp<1: already killed */ } else if (!flags.verbose) { You("destroy it!"); - if (tmp) + if (mhm.damage) xkilled(mdef, XKILL_NOMSG); - } else if (tmp) + } else if (mhm.damage) killed(mdef); return 2; } From 6436ea1532213d6ee5f8248dfc4b06034ff45b4c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 19:18:42 +0200 Subject: [PATCH 487/708] Unify ad_dcay --- include/extern.h | 1 + src/mhitm.c | 19 +++----------- src/mhitu.c | 13 +++------- src/uhitm.c | 66 +++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/include/extern.h b/include/extern.h index 78417eba6..e45fcdbd3 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2757,6 +2757,7 @@ E boolean FDECL(shade_miss, (struct monst *, struct monst *, struct obj *, BOOLEAN_P, BOOLEAN_P)); E void FDECL(mhitm_ad_rust, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 397673396..875884b37 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1111,22 +1111,9 @@ int dieroll; return mhm.hitflags; break; case AD_DCAY: - if (magr->mcan) - break; - if (completelyrots(pd)) { /* PM_WOOD_GOLEM || PM_LEATHER_GOLEM */ - /* note: the life-saved case is hypothetical because - life-saving doesn't work for golems */ - if (g.vis && canseemon(mdef)) - pline("%s %s to pieces!", Monnam(mdef), - !mlifesaver(mdef) ? "falls" : "starts to fall"); - monkilled(mdef, (char *) 0, AD_DCAY); - if (!DEADMONSTER(mdef)) - return 0; - return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - } - erode_armor(mdef, ERODE_CORRODE); - mdef->mstrategy &= ~STRAT_WAITFORU; - mhm.damage = 0; + mhitm_ad_dcay(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_STON: if (magr->mcan) diff --git a/src/mhitu.c b/src/mhitu.c index 767ed19e7..ec8988807 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1498,16 +1498,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_DCAY: - hitmsg(mtmp, mattk); - if (mtmp->mcan) - break; - if (completelyrots(g.youmonst.data)) { - You("rot!"); - /* KMH -- this is okay with unchanging */ - rehumanize(); - break; - } - erode_armor(&g.youmonst, ERODE_ROT); + mhitm_ad_dcay(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_HEAL: /* a cancelled nurse is just an ordinary monster, diff --git a/src/uhitm.c b/src/uhitm.c index 53ff72678..859122d6f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1776,6 +1776,62 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_dcay(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (completelyrots(pd)) { /* wood golem or leather golem */ + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); + xkilled(mdef, XKILL_NOMSG); + } + erode_armor(mdef, ERODE_ROT); + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (magr->mcan) + return; + if (completelyrots(pd)) { + You("rot!"); + /* KMH -- this is okay with unchanging */ + rehumanize(); + return; + } + erode_armor(mdef, ERODE_ROT); + } else { + /* mhitm */ + if (magr->mcan) + return; + if (completelyrots(pd)) { /* PM_WOOD_GOLEM || PM_LEATHER_GOLEM */ + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ + if (g.vis && canseemon(mdef)) + pline("%s %s to pieces!", Monnam(mdef), + !mlifesaver(mdef) ? "falls" : "starts to fall"); + monkilled(mdef, (char *) 0, AD_DCAY); + if (!DEADMONSTER(mdef)) { + mhm->done = TRUE; + mhm->hitflags = MM_MISS; + return; + } + mhm->done = TRUE; + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + return; + } + erode_armor(mdef, ERODE_CORRODE); + mdef->mstrategy &= ~STRAT_WAITFORU; + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2064,13 +2120,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_DCAY: - if (completelyrots(pd)) { /* wood golem or leather golem */ - pline("%s %s to pieces!", Monnam(mdef), - !mlifesaver(mdef) ? "falls" : "starts to fall"); - xkilled(mdef, XKILL_NOMSG); - } - erode_armor(mdef, ERODE_ROT); - mhm.damage = 0; + mhitm_ad_dcay(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DREN: if (!negated && !rn2(4)) From 518798d0d244741c6b6756e513156db49133eb3d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 19:32:53 +0200 Subject: [PATCH 488/708] Unify ad_dren --- include/extern.h | 1 + src/mhitm.c | 7 +++---- src/mhitu.c | 7 +++---- src/uhitm.c | 50 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/include/extern.h b/include/extern.h index e45fcdbd3..cf5f18597 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2758,6 +2758,7 @@ E boolean FDECL(shade_miss, (struct monst *, struct monst *, struct obj *, E void FDECL(mhitm_ad_rust, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 875884b37..90cf855e8 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1364,10 +1364,9 @@ int dieroll; mhm.damage = 0; break; case AD_DREN: - if (!cancelled && !rn2(4)) - xdrainenergym(mdef, (boolean) (g.vis && canspotmon(mdef) - && mattk->aatyp != AT_ENGL)); - mhm.damage = 0; + mhitm_ad_dren(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRST: case AD_DRDX: diff --git a/src/mhitu.c b/src/mhitu.c index ec8988807..c8567e114 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1611,10 +1611,9 @@ register struct attack *mattk; u_slow_down(); break; case AD_DREN: - hitmsg(mtmp, mattk); - if (uncancelled && !rn2(4)) /* 25% chance */ - drain_en(mhm.damage); - mhm.damage = 0; + mhitm_ad_dren(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CONF: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index 859122d6f..7bd27ee0a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1832,6 +1832,50 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_dren(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && !rn2(4)) + xdrainenergym(mdef, TRUE); + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + /* Next a cancellation factor. + * Use uncancelled when cancellation factor takes into account certain + * armor's special magic protection. Otherwise just use !mtmp->mcan. + */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && !rn2(4)) /* 25% chance */ + drain_en(mhm->damage); + mhm->damage = 0; + } else { + /* mhitm */ + /* cancellation factor is the same as when attacking the hero */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && !rn2(4)) + xdrainenergym(mdef, (boolean) (g.vis && canspotmon(mdef) + && mattk->aatyp != AT_ENGL)); + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2125,9 +2169,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_DREN: - if (!negated && !rn2(4)) - xdrainenergym(mdef, TRUE); - mhm.damage = 0; + mhitm_ad_dren(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRST: case AD_DRDX: From cfd819f1c178bdb622307329b821ef26cfc267c5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 19:43:16 +0200 Subject: [PATCH 489/708] Unify ad_drli --- include/extern.h | 1 + src/mhitm.c | 23 ++-------- src/mhitu.c | 10 ++--- src/uhitm.c | 114 ++++++++++++++++++++++++++++++++++------------- 4 files changed, 91 insertions(+), 57 deletions(-) diff --git a/include/extern.h b/include/extern.h index cf5f18597..2607c69b0 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2759,6 +2759,7 @@ E void FDECL(mhitm_ad_rust, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 90cf855e8..4850e3195 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1286,26 +1286,9 @@ int dieroll; } break; case AD_DRLI: /* drain life */ - if (!cancelled && !rn2(3) && !resists_drli(mdef)) { - mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ - if (g.vis && canspotmon(mdef)) - pline("%s becomes weaker!", Monnam(mdef)); - if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) { - mdef->mhpmax -= mhm.damage; - } else { - /* limit floor of mhpmax reduction to current m_lev + 1; - avoid increasing it if somehow already less than that */ - if (mdef->mhpmax > (int) mdef->m_lev) - mdef->mhpmax = (int) mdef->m_lev + 1; - } - if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */ - mhm.damage = mdef->mhp; - else - mdef->m_lev--; - - /* unlike hitting with Stormbringer, wounded attacker doesn't - heal any from the drained life */ - } + mhitm_ad_drli(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SSEX: case AD_SITM: /* for now these are the same */ diff --git a/src/mhitu.c b/src/mhitu.c index c8567e114..0c4dde885 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1242,13 +1242,9 @@ register struct attack *mattk; } break; case AD_DRLI: /* drain life */ - hitmsg(mtmp, mattk); - if (uncancelled && !rn2(3) && !Drain_resistance) { - losexp("life drainage"); - - /* unlike hitting with Stormbringer, wounded attacker doesn't - heal any from the drained life */ - } + mhitm_ad_drli(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_LEGS: { long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; diff --git a/src/uhitm.c b/src/uhitm.c index 7bd27ee0a..88ce1958b 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1852,10 +1852,6 @@ struct mhitm_data *mhm; mhm->damage = 0; } else if (mdef == &g.youmonst) { /* mhitu */ - /* Next a cancellation factor. - * Use uncancelled when cancellation factor takes into account certain - * armor's special magic protection. Otherwise just use !mtmp->mcan. - */ int armpro = magic_negation(mdef); boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); @@ -1876,6 +1872,87 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_drli(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && !rn2(3) && !resists_drli(mdef)) { + mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ + pline("%s becomes weaker!", Monnam(mdef)); + if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) { + mdef->mhpmax -= mhm->damage; + } else { + /* limit floor of mhpmax reduction to current m_lev + 1; + avoid increasing it if somehow already less than that */ + if (mdef->mhpmax > (int) mdef->m_lev) + mdef->mhpmax = (int) mdef->m_lev + 1; + } + mdef->mhp -= mhm->damage; + /* !m_lev: level 0 monster is killed regardless of hit points + rather than drop to level -1; note: some non-living creatures + (golems, vortices) are subject to life-drain */ + if (DEADMONSTER(mdef) || !mdef->m_lev) { + pline("%s %s!", Monnam(mdef), + nonliving(mdef->data) ? "expires" : "dies"); + xkilled(mdef, XKILL_NOMSG); + } else + mdef->m_lev--; + mhm->damage = 0; /* damage has already been inflicted */ + + /* unlike hitting with Stormbringer, wounded hero doesn't + heal any from the drained life */ + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && !rn2(3) && !Drain_resistance) { + losexp("life drainage"); + + /* unlike hitting with Stormbringer, wounded attacker doesn't + heal any from the drained life */ + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && !rn2(3) && !resists_drli(mdef)) { + mhm->damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ + if (g.vis && canspotmon(mdef)) + pline("%s becomes weaker!", Monnam(mdef)); + if (mdef->mhpmax - mhm->damage > (int) mdef->m_lev) { + mdef->mhpmax -= mhm->damage; + } else { + /* limit floor of mhpmax reduction to current m_lev + 1; + avoid increasing it if somehow already less than that */ + if (mdef->mhpmax > (int) mdef->m_lev) + mdef->mhpmax = (int) mdef->m_lev + 1; + } + if (mdef->m_lev == 0) /* automatic kill if drained past level 0 */ + mhm->damage = mdef->mhp; + else + mdef->m_lev--; + + /* unlike hitting with Stormbringer, wounded attacker doesn't + heal any from the drained life */ + } + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2126,32 +2203,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ mhm.damage = 0; break; case AD_DRLI: /* drain life */ - if (!negated && !rn2(3) && !resists_drli(mdef)) { - mhm.damage = d(2, 6); /* Stormbringer uses monhp_per_lvl(usually 1d8) */ - pline("%s becomes weaker!", Monnam(mdef)); - if (mdef->mhpmax - mhm.damage > (int) mdef->m_lev) { - mdef->mhpmax -= mhm.damage; - } else { - /* limit floor of mhpmax reduction to current m_lev + 1; - avoid increasing it if somehow already less than that */ - if (mdef->mhpmax > (int) mdef->m_lev) - mdef->mhpmax = (int) mdef->m_lev + 1; - } - mdef->mhp -= mhm.damage; - /* !m_lev: level 0 monster is killed regardless of hit points - rather than drop to level -1; note: some non-living creatures - (golems, vortices) are subject to life-drain */ - if (DEADMONSTER(mdef) || !mdef->m_lev) { - pline("%s %s!", Monnam(mdef), - nonliving(mdef->data) ? "expires" : "dies"); - xkilled(mdef, XKILL_NOMSG); - } else - mdef->m_lev--; - mhm.damage = 0; /* damage has already been inflicted */ - - /* unlike hitting with Stormbringer, wounded hero doesn't - heal any from the drained life */ - } + mhitm_ad_drli(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_RUST: mhitm_ad_rust(&g.youmonst, mattk, mdef, &mhm); From 67128768015834ea3dba7d91258ce1aa1f4fc8c5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 19:56:52 +0200 Subject: [PATCH 490/708] Unify ad_fire --- include/extern.h | 1 + src/mhitm.c | 33 +--------- src/mhitu.c | 26 +------- src/uhitm.c | 158 +++++++++++++++++++++++++++++++++++++---------- 4 files changed, 131 insertions(+), 87 deletions(-) diff --git a/include/extern.h b/include/extern.h index 2607c69b0..51a1544d6 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2760,6 +2760,7 @@ E void FDECL(mhitm_ad_corr, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_fire, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 4850e3195..5448e1359 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1016,36 +1016,9 @@ int dieroll; } break; case AD_FIRE: - if (cancelled) { - mhm.damage = 0; - break; - } - if (g.vis && canseemon(mdef)) - pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk)); - if (completelyburns(pd)) { /* paper golem or straw golem */ - /* note: the life-saved case is hypothetical because - life-saving doesn't work for golems */ - if (g.vis && canseemon(mdef)) - pline("%s %s!", Monnam(mdef), - !mlifesaver(mdef) ? "burns completely" - : "is totally engulfed in flames"); - monkilled(mdef, (char *) 0, AD_FIRE); - if (!DEADMONSTER(mdef)) - return 0; - return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - } - mhm.damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); - mhm.damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); - if (resists_fire(mdef)) { - if (g.vis && canseemon(mdef)) - pline_The("fire doesn't seem to burn %s!", mon_nam(mdef)); - shieldeff(mdef->mx, mdef->my); - golemeffects(mdef, AD_FIRE, mhm.damage); - mhm.damage = 0; - } - /* only potions damage resistant players in destroy_item */ - mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); - ignite_items(mdef->minvent); + mhitm_ad_fire(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_COLD: if (cancelled) { diff --git a/src/mhitu.c b/src/mhitu.c index 0c4dde885..5430d9f12 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1098,29 +1098,9 @@ register struct attack *mattk; mhm.damage = 0; break; case AD_FIRE: - hitmsg(mtmp, mattk); - if (uncancelled) { - pline("You're %s!", on_fire(g.youmonst.data, mattk)); - if (completelyburns(g.youmonst.data)) { /* paper or straw golem */ - You("go up in flames!"); - /* KMH -- this is okay with unchanging */ - rehumanize(); - break; - } else if (Fire_resistance) { - pline_The("fire doesn't feel hot!"); - mhm.damage = 0; - } - if ((int) mtmp->m_lev > rn2(20)) - destroy_item(SCROLL_CLASS, AD_FIRE); - if ((int) mtmp->m_lev > rn2(20)) - destroy_item(POTION_CLASS, AD_FIRE); - if ((int) mtmp->m_lev > rn2(25)) - destroy_item(SPBOOK_CLASS, AD_FIRE); - if ((int) mtmp->m_lev > rn2(20)) - ignite_items(g.invent); - burn_away_slime(); - } else - mhm.damage = 0; + mhitm_ad_fire(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_COLD: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index 88ce1958b..f1d64f07e 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1953,6 +1953,127 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_fire(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (negated) { + mhm->damage = 0; + return; + } + if (!Blind) + pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk)); + if (completelyburns(pd)) { /* paper golem or straw golem */ + if (!Blind) + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ + pline("%s %s!", Monnam(mdef), + !mlifesaver(mdef) ? "burns completely" + : "is totally engulfed in flames"); + else + You("smell burning%s.", + (pd == &mons[PM_PAPER_GOLEM]) ? " paper" + : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : ""); + xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE); + mhm->damage = 0; + return; + /* Don't return yet; keep hp<1 and mhm.damage=0 for pet msg */ + } + mhm->damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); + mhm->damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); + if (resists_fire(mdef)) { + if (!Blind) + pline_The("fire doesn't heat %s!", mon_nam(mdef)); + golemeffects(mdef, AD_FIRE, mhm->damage); + shieldeff(mdef->mx, mdef->my); + mhm->damage = 0; + } + /* only potions damage resistant players in destroy_item */ + mhm->damage += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); + ignite_items(mdef->minvent); + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled) { + pline("You're %s!", on_fire(pd, mattk)); + if (completelyburns(pd)) { /* paper or straw golem */ + You("go up in flames!"); + /* KMH -- this is okay with unchanging */ + rehumanize(); + return; + } else if (Fire_resistance) { + pline_The("fire doesn't feel hot!"); + mhm->damage = 0; + } + if ((int) magr->m_lev > rn2(20)) + destroy_item(SCROLL_CLASS, AD_FIRE); + if ((int) magr->m_lev > rn2(20)) + destroy_item(POTION_CLASS, AD_FIRE); + if ((int) magr->m_lev > rn2(25)) + destroy_item(SPBOOK_CLASS, AD_FIRE); + if ((int) magr->m_lev > rn2(20)) + ignite_items(g.invent); + burn_away_slime(); + } else + mhm->damage = 0; + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (cancelled) { + mhm->damage = 0; + return; + } + if (g.vis && canseemon(mdef)) + pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk)); + if (completelyburns(pd)) { /* paper golem or straw golem */ + /* note: the life-saved case is hypothetical because + life-saving doesn't work for golems */ + if (g.vis && canseemon(mdef)) + pline("%s %s!", Monnam(mdef), + !mlifesaver(mdef) ? "burns completely" + : "is totally engulfed in flames"); + monkilled(mdef, (char *) 0, AD_FIRE); + if (!DEADMONSTER(mdef)) { + mhm->hitflags = MM_MISS; + mhm->done = TRUE; + return; + } + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + mhm->done = TRUE; + return; + } + mhm->damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); + mhm->damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); + if (resists_fire(mdef)) { + if (g.vis && canseemon(mdef)) + pline_The("fire doesn't seem to burn %s!", mon_nam(mdef)); + shieldeff(mdef->mx, mdef->my); + golemeffects(mdef, AD_FIRE, mhm->damage); + mhm->damage = 0; + } + /* only potions damage resistant players in destroy_item */ + mhm->damage += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); + ignite_items(mdef->minvent); + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2053,40 +2174,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } break; case AD_FIRE: - if (negated) { - mhm.damage = 0; - break; - } - if (!Blind) - pline("%s is %s!", Monnam(mdef), on_fire(pd, mattk)); - if (completelyburns(pd)) { /* paper golem or straw golem */ - if (!Blind) - /* note: the life-saved case is hypothetical because - life-saving doesn't work for golems */ - pline("%s %s!", Monnam(mdef), - !mlifesaver(mdef) ? "burns completely" - : "is totally engulfed in flames"); - else - You("smell burning%s.", - (pd == &mons[PM_PAPER_GOLEM]) ? " paper" - : (pd == &mons[PM_STRAW_GOLEM]) ? " straw" : ""); - xkilled(mdef, XKILL_NOMSG | XKILL_NOCORPSE); - mhm.damage = 0; - break; - /* Don't return yet; keep hp<1 and mhm.damage=0 for pet msg */ - } - mhm.damage += destroy_mitem(mdef, SCROLL_CLASS, AD_FIRE); - mhm.damage += destroy_mitem(mdef, SPBOOK_CLASS, AD_FIRE); - if (resists_fire(mdef)) { - if (!Blind) - pline_The("fire doesn't heat %s!", mon_nam(mdef)); - golemeffects(mdef, AD_FIRE, mhm.damage); - shieldeff(mdef->mx, mdef->my); - mhm.damage = 0; - } - /* only potions damage resistant players in destroy_item */ - mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_FIRE); - ignite_items(mdef->minvent); + mhitm_ad_fire(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_COLD: if (negated) { From 6abfe7e548301192789ed9be6666eeee2c88f755 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 20:10:13 +0200 Subject: [PATCH 491/708] Unify ad_cold --- include/extern.h | 1 + src/mhitm.c | 17 ++-------- src/mhitu.c | 14 ++------ src/uhitm.c | 84 ++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 77 insertions(+), 39 deletions(-) diff --git a/include/extern.h b/include/extern.h index 51a1544d6..7e6fa7acf 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2761,6 +2761,7 @@ E void FDECL(mhitm_ad_dcay, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_fire, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_cold, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 5448e1359..f6c4b3abc 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1021,20 +1021,9 @@ int dieroll; return mhm.hitflags; break; case AD_COLD: - if (cancelled) { - mhm.damage = 0; - break; - } - if (g.vis && canseemon(mdef)) - pline("%s is covered in frost!", Monnam(mdef)); - if (resists_cold(mdef)) { - if (g.vis && canseemon(mdef)) - pline_The("frost doesn't seem to chill %s!", mon_nam(mdef)); - shieldeff(mdef->mx, mdef->my); - golemeffects(mdef, AD_COLD, mhm.damage); - mhm.damage = 0; - } - mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); + mhitm_ad_cold(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ELEC: if (cancelled) { diff --git a/src/mhitu.c b/src/mhitu.c index 5430d9f12..be4fb308b 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1103,17 +1103,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_COLD: - hitmsg(mtmp, mattk); - if (uncancelled) { - pline("You're covered in frost!"); - if (Cold_resistance) { - pline_The("frost doesn't seem cold!"); - mhm.damage = 0; - } - if ((int) mtmp->m_lev > rn2(20)) - destroy_item(POTION_CLASS, AD_COLD); - } else - mhm.damage = 0; + mhitm_ad_cold(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ELEC: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index f1d64f07e..c3e2fdff5 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2073,6 +2073,73 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_cold(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (negated) { + mhm->damage = 0; + return; + } + if (!Blind) + pline("%s is covered in frost!", Monnam(mdef)); + if (resists_cold(mdef)) { + shieldeff(mdef->mx, mdef->my); + if (!Blind) + pline_The("frost doesn't chill %s!", mon_nam(mdef)); + golemeffects(mdef, AD_COLD, mhm->damage); + mhm->damage = 0; + } + mhm->damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled) { + pline("You're covered in frost!"); + if (Cold_resistance) { + pline_The("frost doesn't seem cold!"); + mhm->damage = 0; + } + if ((int) magr->m_lev > rn2(20)) + destroy_item(POTION_CLASS, AD_COLD); + } else + mhm->damage = 0; + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (cancelled) { + mhm->damage = 0; + return; + } + if (g.vis && canseemon(mdef)) + pline("%s is covered in frost!", Monnam(mdef)); + if (resists_cold(mdef)) { + if (g.vis && canseemon(mdef)) + pline_The("frost doesn't seem to chill %s!", mon_nam(mdef)); + shieldeff(mdef->mx, mdef->my); + golemeffects(mdef, AD_COLD, mhm->damage); + mhm->damage = 0; + } + mhm->damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2179,20 +2246,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_COLD: - if (negated) { - mhm.damage = 0; - break; - } - if (!Blind) - pline("%s is covered in frost!", Monnam(mdef)); - if (resists_cold(mdef)) { - shieldeff(mdef->mx, mdef->my); - if (!Blind) - pline_The("frost doesn't chill %s!", mon_nam(mdef)); - golemeffects(mdef, AD_COLD, mhm.damage); - mhm.damage = 0; - } - mhm.damage += destroy_mitem(mdef, POTION_CLASS, AD_COLD); + mhitm_ad_cold(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ELEC: if (negated) { From 8a78c49feafd7e6d83713451997e6f99998c5861 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 20:15:13 +0200 Subject: [PATCH 492/708] Unify ad_elec --- include/extern.h | 1 + src/mhitm.c | 19 ++-------- src/mhitu.c | 16 ++------- src/uhitm.c | 92 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 83 insertions(+), 45 deletions(-) diff --git a/include/extern.h b/include/extern.h index 7e6fa7acf..c899cdc18 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2762,6 +2762,7 @@ E void FDECL(mhitm_ad_dren, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_fire, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_cold, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_elec, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index f6c4b3abc..f0f95fda8 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1026,22 +1026,9 @@ int dieroll; return mhm.hitflags; break; case AD_ELEC: - if (cancelled) { - mhm.damage = 0; - break; - } - if (g.vis && canseemon(mdef)) - pline("%s gets zapped!", Monnam(mdef)); - mhm.damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); - if (resists_elec(mdef)) { - if (g.vis && canseemon(mdef)) - pline_The("zap doesn't shock %s!", mon_nam(mdef)); - shieldeff(mdef->mx, mdef->my); - golemeffects(mdef, AD_ELEC, mhm.damage); - mhm.damage = 0; - } - /* only rings damage resistant players in destroy_item */ - mhm.damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); + mhitm_ad_elec(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ACID: if (magr->mcan) { diff --git a/src/mhitu.c b/src/mhitu.c index be4fb308b..3b146cd20 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1108,19 +1108,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_ELEC: - hitmsg(mtmp, mattk); - if (uncancelled) { - You("get zapped!"); - if (Shock_resistance) { - pline_The("zap doesn't shock you!"); - mhm.damage = 0; - } - if ((int) mtmp->m_lev > rn2(20)) - destroy_item(WAND_CLASS, AD_ELEC); - if ((int) mtmp->m_lev > rn2(20)) - destroy_item(RING_CLASS, AD_ELEC); - } else - mhm.damage = 0; + mhitm_ad_elec(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLEE: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index c3e2fdff5..2d78004ed 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2140,6 +2140,79 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_elec(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (negated) { + mhm->damage = 0; + return; + } + if (!Blind) + pline("%s is zapped!", Monnam(mdef)); + mhm->damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); + if (resists_elec(mdef)) { + if (!Blind) + pline_The("zap doesn't shock %s!", mon_nam(mdef)); + golemeffects(mdef, AD_ELEC, mhm->damage); + shieldeff(mdef->mx, mdef->my); + mhm->damage = 0; + } + /* only rings damage resistant players in destroy_item */ + mhm->damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled) { + You("get zapped!"); + if (Shock_resistance) { + pline_The("zap doesn't shock you!"); + mhm->damage = 0; + } + if ((int) magr->m_lev > rn2(20)) + destroy_item(WAND_CLASS, AD_ELEC); + if ((int) magr->m_lev > rn2(20)) + destroy_item(RING_CLASS, AD_ELEC); + } else + mhm->damage = 0; + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (cancelled) { + mhm->damage = 0; + return; + } + if (g.vis && canseemon(mdef)) + pline("%s gets zapped!", Monnam(mdef)); + mhm->damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); + if (resists_elec(mdef)) { + if (g.vis && canseemon(mdef)) + pline_The("zap doesn't shock %s!", mon_nam(mdef)); + shieldeff(mdef->mx, mdef->my); + golemeffects(mdef, AD_ELEC, mhm->damage); + mhm->damage = 0; + } + /* only rings damage resistant players in destroy_item */ + mhm->damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2251,22 +2324,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_ELEC: - if (negated) { - mhm.damage = 0; - break; - } - if (!Blind) - pline("%s is zapped!", Monnam(mdef)); - mhm.damage += destroy_mitem(mdef, WAND_CLASS, AD_ELEC); - if (resists_elec(mdef)) { - if (!Blind) - pline_The("zap doesn't shock %s!", mon_nam(mdef)); - golemeffects(mdef, AD_ELEC, mhm.damage); - shieldeff(mdef->mx, mdef->my); - mhm.damage = 0; - } - /* only rings damage resistant players in destroy_item */ - mhm.damage += destroy_mitem(mdef, RING_CLASS, AD_ELEC); + mhitm_ad_elec(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ACID: if (resists_acid(mdef)) From b7899ee014f8c3d39910d8c183cd513d59fb7afe Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 20:19:49 +0200 Subject: [PATCH 493/708] Unify ad_acid --- include/extern.h | 1 + src/mhitm.c | 20 +++--------------- src/mhitu.c | 15 +++----------- src/uhitm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/include/extern.h b/include/extern.h index c899cdc18..7d9907bab 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2763,6 +2763,7 @@ E void FDECL(mhitm_ad_drli, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_fire, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_cold, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_elec, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_acid, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index f0f95fda8..f5e15a533 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1031,23 +1031,9 @@ int dieroll; return mhm.hitflags; break; case AD_ACID: - if (magr->mcan) { - mhm.damage = 0; - break; - } - if (resists_acid(mdef)) { - if (g.vis && canseemon(mdef)) - pline("%s is covered in %s, but it seems harmless.", - Monnam(mdef), hliquid("acid")); - mhm.damage = 0; - } else if (g.vis && canseemon(mdef)) { - pline("%s is covered in %s!", Monnam(mdef), hliquid("acid")); - pline("It burns %s!", mon_nam(mdef)); - } - if (!rn2(30)) - erode_armor(mdef, ERODE_CORRODE); - if (!rn2(6)) - acid_damage(MON_WEP(mdef)); + mhitm_ad_acid(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_RUST: mhitm_ad_rust(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 3b146cd20..1e45dadcc 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1550,18 +1550,9 @@ register struct attack *mattk; } break; case AD_ACID: - hitmsg(mtmp, mattk); - if (!mtmp->mcan && !rn2(3)) - if (Acid_resistance) { - pline("You're covered in %s, but it seems harmless.", - hliquid("acid")); - mhm.damage = 0; - } else { - pline("You're covered in %s! It burns!", hliquid("acid")); - exercise(A_STR, FALSE); - } - else - mhm.damage = 0; + mhitm_ad_acid(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLOW: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index 2d78004ed..330342f7e 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2213,6 +2213,55 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_acid(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (resists_acid(mdef)) + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (!magr->mcan && !rn2(3)) + if (Acid_resistance) { + pline("You're covered in %s, but it seems harmless.", + hliquid("acid")); + mhm->damage = 0; + } else { + pline("You're covered in %s! It burns!", hliquid("acid")); + exercise(A_STR, FALSE); + } + else + mhm->damage = 0; + } else { + /* mhitm */ + if (magr->mcan) { + mhm->damage = 0; + return; + } + if (resists_acid(mdef)) { + if (g.vis && canseemon(mdef)) + pline("%s is covered in %s, but it seems harmless.", + Monnam(mdef), hliquid("acid")); + mhm->damage = 0; + } else if (g.vis && canseemon(mdef)) { + pline("%s is covered in %s!", Monnam(mdef), hliquid("acid")); + pline("It burns %s!", mon_nam(mdef)); + } + if (!rn2(30)) + erode_armor(mdef, ERODE_CORRODE); + if (!rn2(6)) + acid_damage(MON_WEP(mdef)); + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2329,8 +2378,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_ACID: - if (resists_acid(mdef)) - mhm.damage = 0; + mhitm_ad_acid(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_STON: if (!munstone(mdef, TRUE)) From bfe773812e41d9c6d7e3a8308c8e57eb9fc6fc9a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 20:32:38 +0200 Subject: [PATCH 494/708] Unify ad_sgld --- include/extern.h | 1 + src/mhitm.c | 29 ++-------------- src/mhitu.c | 8 ++--- src/uhitm.c | 88 ++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 78 insertions(+), 48 deletions(-) diff --git a/include/extern.h b/include/extern.h index 7d9907bab..8456059c1 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2764,6 +2764,7 @@ E void FDECL(mhitm_ad_fire, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_cold, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_elec, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_acid, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_sgld, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index f5e15a533..6b21059df 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1193,32 +1193,9 @@ int dieroll; } break; case AD_SGLD: - mhm.damage = 0; - if (magr->mcan) - break; - /* technically incorrect; no check for stealing gold from - * between mdef's feet... - */ - { - struct obj *gold = findgold(mdef->minvent); - - if (!gold) - break; - obj_extract_self(gold); - add_to_minv(magr, gold); - } - mdef->mstrategy &= ~STRAT_WAITFORU; - if (g.vis && canseemon(mdef)) { - Strcpy(buf, Monnam(magr)); - pline("%s steals some gold from %s.", buf, mon_nam(mdef)); - } - if (!tele_restrict(magr)) { - boolean couldspot = canspotmon(magr); - - (void) rloc(magr, TRUE); - if (g.vis && couldspot && !canspotmon(magr)) - pline("%s suddenly disappears!", buf); - } + mhitm_ad_sgld(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRLI: /* drain life */ mhitm_ad_drli(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 1e45dadcc..e012a7196 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1330,11 +1330,9 @@ register struct attack *mattk; } break; case AD_SGLD: - hitmsg(mtmp, mattk); - if (g.youmonst.data->mlet == mdat->mlet) - break; - if (!mtmp->mcan) - stealgold(mtmp); + mhitm_ad_sgld(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SSEX: diff --git a/src/uhitm.c b/src/uhitm.c index 330342f7e..176912b04 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2262,6 +2262,74 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_sgld(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + struct obj *mongold = findgold(mdef->minvent); + + if (mongold) { + obj_extract_self(mongold); + if (merge_choice(g.invent, mongold) || inv_cnt(FALSE) < 52) { + addinv(mongold); + Your("purse feels heavier."); + } else { + You("grab %s's gold, but find no room in your knapsack.", + mon_nam(mdef)); + dropy(mongold); + } + } + exercise(A_DEX, TRUE); + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (pd->mlet == pa->mlet) + return; + if (!magr->mcan) + stealgold(magr); + } else { + /* mhitm */ + char buf[BUFSZ]; + + mhm->damage = 0; + if (magr->mcan) + return; + /* technically incorrect; no check for stealing gold from + * between mdef's feet... + */ + { + struct obj *gold = findgold(mdef->minvent); + + if (!gold) + return; + obj_extract_self(gold); + add_to_minv(magr, gold); + } + mdef->mstrategy &= ~STRAT_WAITFORU; + if (g.vis && canseemon(mdef)) { + Strcpy(buf, Monnam(magr)); + pline("%s steals some gold from %s.", buf, mon_nam(mdef)); + } + if (!tele_restrict(magr)) { + boolean couldspot = canspotmon(magr); + + (void) rloc(magr, TRUE); + if (g.vis && couldspot && !canspotmon(magr)) + pline("%s suddenly disappears!", buf); + } + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2297,7 +2365,6 @@ int specialdmg; /* blessed and/or silver bonus against various things */ register struct permonst *pd = mdef->data; int armpro; boolean negated; - struct obj *mongold; struct mhitm_data mhm; mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = MM_MISS; @@ -2394,22 +2461,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ mhm.damage = 0; break; case AD_SGLD: - /* This you as a leprechaun, so steal - real gold only, no lesser coins */ - mongold = findgold(mdef->minvent); - if (mongold) { - obj_extract_self(mongold); - if (merge_choice(g.invent, mongold) || inv_cnt(FALSE) < 52) { - addinv(mongold); - Your("purse feels heavier."); - } else { - You("grab %s's gold, but find no room in your knapsack.", - mon_nam(mdef)); - dropy(mongold); - } - } - exercise(A_DEX, TRUE); - mhm.damage = 0; + mhitm_ad_sgld(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_TLPT: if (mhm.damage <= 0) From 607d1bcd96fb2b16c5f03c779f537b17f90a1c38 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 20:42:39 +0200 Subject: [PATCH 495/708] Unify ad_tlpt --- include/extern.h | 1 + src/mhitm.c | 21 ++------ src/mhitu.c | 40 ++------------- src/uhitm.c | 123 ++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 112 insertions(+), 73 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8456059c1..db195453d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2765,6 +2765,7 @@ E void FDECL(mhitm_ad_cold, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_elec, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_acid, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_sgld, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_tlpt, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 6b21059df..327222810 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1076,24 +1076,9 @@ int dieroll; mhm.damage = (mattk->adtyp == AD_STON ? 0 : 1); break; case AD_TLPT: - if (!cancelled && mhm.damage < mdef->mhp && !tele_restrict(mdef)) { - char mdef_Monnam[BUFSZ]; - boolean wasseen = canspotmon(mdef); - - /* save the name before monster teleports, otherwise - we'll get "it" in the suddenly disappears message */ - if (g.vis && wasseen) - Strcpy(mdef_Monnam, Monnam(mdef)); - mdef->mstrategy &= ~STRAT_WAITFORU; - (void) rloc(mdef, TRUE); - if (g.vis && wasseen && !canspotmon(mdef) && mdef != u.usteed) - pline("%s suddenly disappears!", mdef_Monnam); - if (mhm.damage >= mdef->mhp) { /* see hitmu(mhitu.c) */ - if (mdef->mhp == 1) - ++mdef->mhp; - mhm.damage = mdef->mhp - 1; - } - } + mhitm_ad_tlpt(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLEE: if (!cancelled && !mdef->msleeping diff --git a/src/mhitu.c b/src/mhitu.c index e012a7196..efea5a60d 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1405,43 +1405,9 @@ register struct attack *mattk; break; case AD_TLPT: - hitmsg(mtmp, mattk); - if (uncancelled) { - if (flags.verbose) - Your("position suddenly seems %suncertain!", - (Teleport_control && !Stunned && !unconscious()) ? "" - : "very "); - tele(); - /* As of 3.6.2: make sure damage isn't fatal; previously, it - was possible to be teleported and then drop dead at - the destination when QM's 1d4 damage gets applied below; - even though that wasn't "wrong", it seemed strange, - particularly if the teleportation had been controlled - [applying the damage first and not teleporting if fatal - is another alternative but it has its own complications] */ - if ((Half_physical_damage ? (mhm.damage - 1) / 2 : mhm.damage) - >= (tmphp = (Upolyd ? u.mh : u.uhp))) { - mhm.damage = tmphp - 1; - if (Half_physical_damage) - mhm.damage *= 2; /* doesn't actually increase damage; we only - * get here if half the original damage would - * would have been fatal, so double reduced - * damage will be less than original damage */ - if (mhm.damage < 1) { /* implies (tmphp <= 1) */ - mhm.damage = 1; - /* this might increase current HP beyond maximum HP but - it will be immediately reduced below, so that should - be indistinguishable from zero damage; we don't drop - damage all the way to zero because that inhibits any - passive counterattack if poly'd hero has one */ - if (Upolyd && u.mh == 1) - ++u.mh; - else if (!Upolyd && u.uhp == 1) - ++u.uhp; - /* [don't set context.botl here] */ - } - } - } + mhitm_ad_tlpt(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_RUST: mhitm_ad_rust(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 176912b04..9bdbd20ee 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2330,6 +2330,108 @@ struct mhitm_data *mhm; } +void +mhitm_ad_tlpt(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (mhm->damage <= 0) + mhm->damage = 1; + if (!negated) { + char nambuf[BUFSZ]; + boolean u_saw_mon = (canseemon(mdef) + || (u.uswallow && u.ustuck == mdef)); + + /* record the name before losing sight of monster */ + Strcpy(nambuf, Monnam(mdef)); + if (u_teleport_mon(mdef, FALSE) && u_saw_mon + && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef))) + pline("%s suddenly disappears!", nambuf); + if (mhm->damage >= mdef->mhp) { /* see hitmu(mhitu.c) */ + if (mdef->mhp == 1) + ++mdef->mhp; + mhm->damage = mdef->mhp - 1; + } + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + int tmphp; + + hitmsg(magr, mattk); + if (uncancelled) { + if (flags.verbose) + Your("position suddenly seems %suncertain!", + (Teleport_control && !Stunned && !unconscious()) ? "" + : "very "); + tele(); + /* As of 3.6.2: make sure damage isn't fatal; previously, it + was possible to be teleported and then drop dead at + the destination when QM's 1d4 damage gets applied below; + even though that wasn't "wrong", it seemed strange, + particularly if the teleportation had been controlled + [applying the damage first and not teleporting if fatal + is another alternative but it has its own complications] */ + if ((Half_physical_damage ? (mhm->damage - 1) / 2 : mhm->damage) + >= (tmphp = (Upolyd ? u.mh : u.uhp))) { + mhm->damage = tmphp - 1; + if (Half_physical_damage) + mhm->damage *= 2; /* doesn't actually increase damage; we only + * get here if half the original damage would + * would have been fatal, so double reduced + * damage will be less than original damage */ + if (mhm->damage < 1) { /* implies (tmphp <= 1) */ + mhm->damage = 1; + /* this might increase current HP beyond maximum HP but + it will be immediately reduced below, so that should + be indistinguishable from zero damage; we don't drop + damage all the way to zero because that inhibits any + passive counterattack if poly'd hero has one */ + if (Upolyd && u.mh == 1) + ++u.mh; + else if (!Upolyd && u.uhp == 1) + ++u.uhp; + /* [don't set context.botl here] */ + } + } + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && mhm->damage < mdef->mhp && !tele_restrict(mdef)) { + char mdef_Monnam[BUFSZ]; + boolean wasseen = canspotmon(mdef); + + /* save the name before monster teleports, otherwise + we'll get "it" in the suddenly disappears message */ + if (g.vis && wasseen) + Strcpy(mdef_Monnam, Monnam(mdef)); + mdef->mstrategy &= ~STRAT_WAITFORU; + (void) rloc(mdef, TRUE); + if (g.vis && wasseen && !canspotmon(mdef) && mdef != u.usteed) + pline("%s suddenly disappears!", mdef_Monnam); + if (mhm->damage >= mdef->mhp) { /* see hitmu(mhitu.c) */ + if (mdef->mhp == 1) + ++mdef->mhp; + mhm->damage = mdef->mhp - 1; + } + } + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2466,24 +2568,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_TLPT: - if (mhm.damage <= 0) - mhm.damage = 1; - if (!negated) { - char nambuf[BUFSZ]; - boolean u_saw_mon = (canseemon(mdef) - || (u.uswallow && u.ustuck == mdef)); - - /* record the name before losing sight of monster */ - Strcpy(nambuf, Monnam(mdef)); - if (u_teleport_mon(mdef, FALSE) && u_saw_mon - && !(canseemon(mdef) || (u.uswallow && u.ustuck == mdef))) - pline("%s suddenly disappears!", nambuf); - if (mhm.damage >= mdef->mhp) { /* see hitmu(mhitu.c) */ - if (mdef->mhp == 1) - ++mdef->mhp; - mhm.damage = mdef->mhp - 1; - } - } + mhitm_ad_tlpt(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_BLND: if (can_blnd(&g.youmonst, mdef, mattk->aatyp, (struct obj *) 0)) { From d325e2cc60cd25f5e8c7cfa33d3d7cff7747a914 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 21:12:18 +0200 Subject: [PATCH 496/708] Unify ad_blnd --- include/extern.h | 1 + src/mhitm.c | 16 +++---------- src/mhitu.c | 11 +++------ src/uhitm.c | 61 ++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 58 insertions(+), 31 deletions(-) diff --git a/include/extern.h b/include/extern.h index db195453d..40cbd2fab 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2766,6 +2766,7 @@ E void FDECL(mhitm_ad_elec, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_acid, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_sgld, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_tlpt, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_blnd, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 327222810..97fc90f6d 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1123,19 +1123,9 @@ int dieroll; } break; case AD_BLND: - if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { - register unsigned rnd_tmp; - - if (g.vis && mdef->mcansee && canspotmon(mdef)) - pline("%s is blinded.", Monnam(mdef)); - rnd_tmp = d((int) mattk->damn, (int) mattk->damd); - if ((rnd_tmp += mdef->mblinded) > 127) - rnd_tmp = 127; - mdef->mblinded = rnd_tmp; - mdef->mcansee = 0; - mdef->mstrategy &= ~STRAT_WAITFORU; - } - mhm.damage = 0; + mhitm_ad_blnd(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_HALU: if (!magr->mcan && haseyes(pd) && mdef->mcansee) { diff --git a/src/mhitu.c b/src/mhitu.c index efea5a60d..e0f3da06d 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1125,14 +1125,9 @@ register struct attack *mattk; } break; case AD_BLND: - if (can_blnd(mtmp, &g.youmonst, mattk->aatyp, (struct obj *) 0)) { - if (!Blind) - pline("%s blinds you!", Monnam(mtmp)); - make_blinded(Blinded + (long) mhm.damage, FALSE); - if (!Blind) - Your1(vision_clears); - } - mhm.damage = 0; + mhitm_ad_blnd(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRST: ptmp = A_STR; diff --git a/src/uhitm.c b/src/uhitm.c index 9bdbd20ee..2148d458b 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2432,6 +2432,54 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_blnd(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { + if (!Blind && mdef->mcansee) + pline("%s is blinded.", Monnam(mdef)); + mdef->mcansee = 0; + mhm->damage += mdef->mblinded; + if (mhm->damage > 127) + mhm->damage = 127; + mdef->mblinded = mhm->damage; + } + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { + if (!Blind) + pline("%s blinds you!", Monnam(magr)); + make_blinded(Blinded + (long) mhm->damage, FALSE); + if (!Blind) + Your1(vision_clears); + } + mhm->damage = 0; + } else { + /* mhitm */ + if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { + register unsigned rnd_tmp; + + if (g.vis && mdef->mcansee && canspotmon(mdef)) + pline("%s is blinded.", Monnam(mdef)); + rnd_tmp = d((int) mattk->damn, (int) mattk->damd); + if ((rnd_tmp += mdef->mblinded) > 127) + rnd_tmp = 127; + mdef->mblinded = rnd_tmp; + mdef->mcansee = 0; + mdef->mstrategy &= ~STRAT_WAITFORU; + } + mhm->damage = 0; + } +} /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2573,16 +2621,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_BLND: - if (can_blnd(&g.youmonst, mdef, mattk->aatyp, (struct obj *) 0)) { - if (!Blind && mdef->mcansee) - pline("%s is blinded.", Monnam(mdef)); - mdef->mcansee = 0; - mhm.damage += mdef->mblinded; - if (mhm.damage > 127) - mhm.damage = 127; - mdef->mblinded = mhm.damage; - } - mhm.damage = 0; + mhitm_ad_blnd(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CURS: if (night() && !rn2(10) && !mdef->mcan) { From dba9aaf424eba2a01ee3ca54c4b5d6d7c06bef80 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 21:22:58 +0200 Subject: [PATCH 497/708] Unify ad_curs --- include/extern.h | 1 + src/mhitm.c | 31 ++------------- src/mhitu.c | 21 ++-------- src/uhitm.c | 101 +++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 95 insertions(+), 59 deletions(-) diff --git a/include/extern.h b/include/extern.h index 40cbd2fab..8bfa0465f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2767,6 +2767,7 @@ E void FDECL(mhitm_ad_acid, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_sgld, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_tlpt, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_blnd, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_curs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 97fc90f6d..5a4bfa4bd 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1138,34 +1138,9 @@ int dieroll; mhm.damage = 0; break; case AD_CURS: - if (!night() && (pa == &mons[PM_GREMLIN])) - break; - if (!magr->mcan && !rn2(10)) { - mdef->mcan = 1; /* cancelled regardless of lifesave */ - mdef->mstrategy &= ~STRAT_WAITFORU; - if (is_were(pd) && pd->mlet != S_HUMAN) - were_change(mdef); - if (pd == &mons[PM_CLAY_GOLEM]) { - if (g.vis && canseemon(mdef)) { - pline("Some writing vanishes from %s head!", - s_suffix(mon_nam(mdef))); - pline("%s is destroyed!", Monnam(mdef)); - } - mondied(mdef); - if (!DEADMONSTER(mdef)) - return 0; - else if (mdef->mtame && !g.vis) - You(brief_feeling, "strangely sad"); - return (MM_DEF_DIED - | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - } - if (!Deaf) { - if (!g.vis) - You_hear("laughter."); - else if (canseemon(magr)) - pline("%s chuckles.", Monnam(magr)); - } - } + mhitm_ad_curs(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SGLD: mhitm_ad_sgld(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index e0f3da06d..d4d61a87f 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1482,24 +1482,9 @@ register struct attack *mattk; } break; case AD_CURS: - hitmsg(mtmp, mattk); - if (!night() && mdat == &mons[PM_GREMLIN]) - break; - if (!mtmp->mcan && !rn2(10)) { - if (!Deaf) { - if (Blind) - You_hear("laughter."); - else - pline("%s chuckles.", Monnam(mtmp)); - } - if (u.umonnum == PM_CLAY_GOLEM) { - pline("Some writing vanishes from your head!"); - /* KMH -- this is okay with unchanging */ - rehumanize(); - break; - } - attrcurse(); - } + mhitm_ad_curs(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_STUN: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index 2148d458b..eca8843b6 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -5,6 +5,9 @@ #include "hack.h" +static const char brief_feeling[] = + "have a %s feeling for a moment, then it passes."; + static boolean FDECL(known_hitum, (struct monst *, struct obj *, int *, int, int, struct attack *, int)); static boolean FDECL(theft_petrifies, (struct obj *)); @@ -2481,6 +2484,88 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_curs(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (night() && !rn2(10) && !mdef->mcan) { + if (pd == &mons[PM_CLAY_GOLEM]) { + if (!Blind) + pline("Some writing vanishes from %s head!", + s_suffix(mon_nam(mdef))); + xkilled(mdef, XKILL_NOMSG); + /* Don't return yet; keep hp<1 and mhm.damage=0 for pet msg */ + } else { + mdef->mcan = 1; + You("chuckle."); + } + } + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (!night() && pa == &mons[PM_GREMLIN]) + return; + if (!magr->mcan && !rn2(10)) { + if (!Deaf) { + if (Blind) + You_hear("laughter."); + else + pline("%s chuckles.", Monnam(magr)); + } + if (u.umonnum == PM_CLAY_GOLEM) { + pline("Some writing vanishes from your head!"); + /* KMH -- this is okay with unchanging */ + rehumanize(); + return; + } + attrcurse(); + } + } else { + /* mhitm */ + if (!night() && (pa == &mons[PM_GREMLIN])) + return; + if (!magr->mcan && !rn2(10)) { + mdef->mcan = 1; /* cancelled regardless of lifesave */ + mdef->mstrategy &= ~STRAT_WAITFORU; + if (is_were(pd) && pd->mlet != S_HUMAN) + were_change(mdef); + if (pd == &mons[PM_CLAY_GOLEM]) { + if (g.vis && canseemon(mdef)) { + pline("Some writing vanishes from %s head!", + s_suffix(mon_nam(mdef))); + pline("%s is destroyed!", Monnam(mdef)); + } + mondied(mdef); + if (!DEADMONSTER(mdef)) { + mhm->hitflags = MM_MISS; + mhm->done = TRUE; + return; + } + else if (mdef->mtame && !g.vis) + You(brief_feeling, "strangely sad"); + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + mhm->done = TRUE; + return; + } + if (!Deaf) { + if (!g.vis) + You_hear("laughter."); + else if (canseemon(magr)) + pline("%s chuckles.", Monnam(magr)); + } + } + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2626,19 +2711,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_CURS: - if (night() && !rn2(10) && !mdef->mcan) { - if (pd == &mons[PM_CLAY_GOLEM]) { - if (!Blind) - pline("Some writing vanishes from %s head!", - s_suffix(mon_nam(mdef))); - xkilled(mdef, XKILL_NOMSG); - /* Don't return yet; keep hp<1 and mhm.damage=0 for pet msg */ - } else { - mdef->mcan = 1; - You("chuckle."); - } - } - mhm.damage = 0; + mhitm_ad_curs(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRLI: /* drain life */ mhitm_ad_drli(&g.youmonst, mattk, mdef, &mhm); From 1ca0165bb978aab4e1546f4f5717c2e9101d0d58 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 21:41:28 +0200 Subject: [PATCH 498/708] Unify ad_drst --- include/extern.h | 1 + src/mhitm.c | 21 ++---------- src/mhitu.c | 15 ++------- src/uhitm.c | 87 +++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 82 insertions(+), 42 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8bfa0465f..6abcd8d1c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2768,6 +2768,7 @@ E void FDECL(mhitm_ad_sgld, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_tlpt, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_blnd, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_curs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_drst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 5a4bfa4bd..8361d5490 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1216,24 +1216,9 @@ int dieroll; case AD_DRST: case AD_DRDX: case AD_DRCO: - if (!cancelled && !rn2(8)) { - if (g.vis && canspotmon(magr)) - pline("%s %s was poisoned!", s_suffix(Monnam(magr)), - mpoisons_subj(magr, mattk)); - if (resists_poison(mdef)) { - if (g.vis && canspotmon(mdef) && canspotmon(magr)) - pline_The("poison doesn't seem to affect %s.", - mon_nam(mdef)); - } else { - if (rn2(10)) - mhm.damage += rn1(10, 6); - else { - if (g.vis && canspotmon(mdef)) - pline_The("poison was deadly..."); - mhm.damage = mdef->mhp; - } - } - } + mhitm_ad_drst(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRIN: if (g.notonhead || !has_head(pd)) { diff --git a/src/mhitu.c b/src/mhitu.c index d4d61a87f..8036df820 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1130,20 +1130,11 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_DRST: - ptmp = A_STR; - goto dopois; case AD_DRDX: - ptmp = A_DEX; - goto dopois; case AD_DRCO: - ptmp = A_CON; - dopois: - hitmsg(mtmp, mattk); - if (uncancelled && !rn2(8)) { - Sprintf(buf, "%s %s", s_suffix(Monnam(mtmp)), - mpoisons_subj(mtmp, mattk)); - poisoned(buf, ptmp, mdat->mname, 30, FALSE); - } + mhitm_ad_drst(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRIN: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index eca8843b6..d0b526e9f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2566,6 +2566,78 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_drst(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && !rn2(8)) { + Your("%s was poisoned!", mpoisons_subj(magr, mattk)); + if (resists_poison(mdef)) { + pline_The("poison doesn't seem to affect %s.", mon_nam(mdef)); + } else { + if (!rn2(10)) { + Your("poison was deadly..."); + mhm->damage = mdef->mhp; + } else + mhm->damage += rn1(10, 6); + } + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + int ptmp; + char buf[BUFSZ]; + + switch (mattk->adtyp) { + case AD_DRST: ptmp = A_STR; break; + case AD_DRDX: ptmp = A_DEX; break; + case AD_DRCO: ptmp = A_CON; break; + } + hitmsg(magr, mattk); + if (uncancelled && !rn2(8)) { + Sprintf(buf, "%s %s", s_suffix(Monnam(magr)), + mpoisons_subj(magr, mattk)); + poisoned(buf, ptmp, pa->mname, 30, FALSE); + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && !rn2(8)) { + if (g.vis && canspotmon(magr)) + pline("%s %s was poisoned!", s_suffix(Monnam(magr)), + mpoisons_subj(magr, mattk)); + if (resists_poison(mdef)) { + if (g.vis && canspotmon(mdef) && canspotmon(magr)) + pline_The("poison doesn't seem to affect %s.", + mon_nam(mdef)); + } else { + if (rn2(10)) + mhm->damage += rn1(10, 6); + else { + if (g.vis && canspotmon(mdef)) + pline_The("poison was deadly..."); + mhm->damage = mdef->mhp; + } + } + } + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2743,18 +2815,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ case AD_DRST: case AD_DRDX: case AD_DRCO: - if (!negated && !rn2(8)) { - Your("%s was poisoned!", mpoisons_subj(&g.youmonst, mattk)); - if (resists_poison(mdef)) { - pline_The("poison doesn't seem to affect %s.", mon_nam(mdef)); - } else { - if (!rn2(10)) { - Your("poison was deadly..."); - mhm.damage = mdef->mhp; - } else - mhm.damage += rn1(10, 6); - } - } + mhitm_ad_drst(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRIN: { struct obj *helmet; From b4ed25da46c212329c1b89db642ecf8474c604b4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 21:50:27 +0200 Subject: [PATCH 499/708] Unify ad_drin --- include/extern.h | 2 + src/mhitm.c | 22 ++------ src/mhitu.c | 40 ++------------ src/uhitm.c | 136 ++++++++++++++++++++++++++++++++++++----------- 4 files changed, 115 insertions(+), 85 deletions(-) diff --git a/include/extern.h b/include/extern.h index 6abcd8d1c..86d9b02b0 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1290,6 +1290,7 @@ E void FDECL(expels, (struct monst *, struct permonst *, BOOLEAN_P)); E struct attack *FDECL(getmattk, (struct monst *, struct monst *, int, int *, struct attack *)); E int FDECL(mattacku, (struct monst *)); +boolean FDECL(u_slip_free, (struct monst *, struct attack *)); E int FDECL(magic_negation, (struct monst *)); E boolean NDECL(gulp_blnd_check); E int FDECL(gazemu, (struct monst *, struct attack *)); @@ -2769,6 +2770,7 @@ E void FDECL(mhitm_ad_tlpt, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_blnd, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_curs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_drst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_drin, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 8361d5490..89626bc4b 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1221,25 +1221,9 @@ int dieroll; return mhm.hitflags; break; case AD_DRIN: - if (g.notonhead || !has_head(pd)) { - if (g.vis && canspotmon(mdef)) - pline("%s doesn't seem harmed.", Monnam(mdef)); - /* Not clear what to do for green slimes */ - mhm.damage = 0; - /* don't bother with additional DRIN attacks since they wouldn't - be able to hit target on head either */ - g.skipdrin = TRUE; /* affects mattackm()'s attack loop */ - break; - } - if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { - if (g.vis && canspotmon(magr) && canseemon(mdef)) { - Strcpy(buf, s_suffix(Monnam(mdef))); - pline("%s helmet blocks %s attack to %s head.", buf, - s_suffix(mon_nam(magr)), mhis(mdef)); - } - break; - } - mhm.hitflags = eat_brains(magr, mdef, g.vis, &mhm.damage); + mhitm_ad_drin(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLIM: if (cancelled) diff --git a/src/mhitu.c b/src/mhitu.c index 8036df820..61ed015a3 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -13,7 +13,6 @@ static void FDECL(mswings, (struct monst *, struct obj *)); static void FDECL(wildmiss, (struct monst *, struct attack *)); static void FDECL(summonmu, (struct monst *, BOOLEAN_P)); static boolean FDECL(diseasemu, (struct permonst *)); -static boolean FDECL(u_slip_free, (struct monst *, struct attack *)); static int FDECL(hitmu, (struct monst *, struct attack *)); static int FDECL(gulpmu, (struct monst *, struct attack *)); static int FDECL(explmu, (struct monst *, struct attack *, BOOLEAN_P)); @@ -869,7 +868,7 @@ struct permonst *mdat; } /* check whether slippery clothing protects from hug or wrap attack */ -static boolean +boolean u_slip_free(mtmp, mattk) struct monst *mtmp; struct attack *mattk; @@ -1137,40 +1136,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_DRIN: - hitmsg(mtmp, mattk); - if (defends(AD_DRIN, uwep) || !has_head(g.youmonst.data)) { - You("don't seem harmed."); - /* attacker should skip remaining AT_TENT+AD_DRIN attacks */ - g.skipdrin = TRUE; - /* Not clear what to do for green slimes */ - break; - } - if (u_slip_free(mtmp, mattk)) - break; - - if (uarmh && rn2(8)) { - /* not body_part(HEAD) */ - Your("%s blocks the attack to your head.", - helm_simple_name(uarmh)); - break; - } - /* negative armor class doesn't reduce this damage */ - if (Half_physical_damage) - mhm.damage = (mhm.damage + 1) / 2; - mdamageu(mtmp, mhm.damage); - mhm.damage = 0; /* don't inflict a second dose below */ - - if (!uarmh || uarmh->otyp != DUNCE_CAP) { - /* eat_brains() will miss if target is mindless (won't - happen here; hero is considered to retain his mind - regardless of current shape) or is noncorporeal - (can't happen here; no one can poly into a ghost - or shade) so this check for missing is academic */ - if (eat_brains(mtmp, &g.youmonst, TRUE, (int *) 0) == MM_MISS) - break; - } - /* adjattrib gives dunce cap message when appropriate */ - (void) adjattrib(A_INT, -rnd(2), FALSE); + mhitm_ad_drin(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_PLYS: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index d0b526e9f..53a5dd45f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2638,6 +2638,108 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_drin(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + struct obj *helmet; + + if (g.notonhead || !has_head(pd)) { + pline("%s doesn't seem harmed.", Monnam(mdef)); + /* hero should skip remaining AT_TENT+AD_DRIN attacks + because they'll be just as harmless as this one (and also + to reduce verbosity) */ + g.skipdrin = TRUE; + mhm->damage = 0; + if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) { + if (!Slimed) { + You("suck in some slime and don't feel very well."); + make_slimed(10L, (char *) 0); + } + } + return; + } + if (m_slips_free(mdef, mattk)) + return; + + if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) { + pline("%s %s blocks your attack to %s head.", + s_suffix(Monnam(mdef)), helm_simple_name(helmet), + mhis(mdef)); + return; + } + + (void) eat_brains(&g.youmonst, mdef, TRUE, &mhm->damage); + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (defends(AD_DRIN, uwep) || !has_head(pd)) { + You("don't seem harmed."); + /* attacker should skip remaining AT_TENT+AD_DRIN attacks */ + g.skipdrin = TRUE; + /* Not clear what to do for green slimes */ + return; + } + if (u_slip_free(magr, mattk)) + return; + + if (uarmh && rn2(8)) { + /* not body_part(HEAD) */ + Your("%s blocks the attack to your head.", + helm_simple_name(uarmh)); + return; + } + /* negative armor class doesn't reduce this damage */ + if (Half_physical_damage) + mhm->damage = (mhm->damage + 1) / 2; + mdamageu(magr, mhm->damage); + mhm->damage = 0; /* don't inflict a second dose below */ + + if (!uarmh || uarmh->otyp != DUNCE_CAP) { + /* eat_brains() will miss if target is mindless (won't + happen here; hero is considered to retain his mind + regardless of current shape) or is noncorporeal + (can't happen here; no one can poly into a ghost + or shade) so this check for missing is academic */ + if (eat_brains(magr, mdef, TRUE, (int *) 0) == MM_MISS) + return; + } + /* adjattrib gives dunce cap message when appropriate */ + (void) adjattrib(A_INT, -rnd(2), FALSE); + } else { + /* mhitm */ + char buf[BUFSZ]; + + if (g.notonhead || !has_head(pd)) { + if (g.vis && canspotmon(mdef)) + pline("%s doesn't seem harmed.", Monnam(mdef)); + /* Not clear what to do for green slimes */ + mhm->damage = 0; + /* don't bother with additional DRIN attacks since they wouldn't + be able to hit target on head either */ + g.skipdrin = TRUE; /* affects mattackm()'s attack loop */ + return; + } + if ((mdef->misc_worn_check & W_ARMH) && rn2(8)) { + if (g.vis && canspotmon(magr) && canseemon(mdef)) { + Strcpy(buf, s_suffix(Monnam(mdef))); + pline("%s helmet blocks %s attack to %s head.", buf, + s_suffix(mon_nam(magr)), mhis(mdef)); + } + return; + } + mhm->hitflags = eat_brains(magr, mdef, g.vis, &mhm->damage); + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -2819,37 +2921,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (mhm.done) return mhm.hitflags; break; - case AD_DRIN: { - struct obj *helmet; - - if (g.notonhead || !has_head(pd)) { - pline("%s doesn't seem harmed.", Monnam(mdef)); - /* hero should skip remaining AT_TENT+AD_DRIN attacks - because they'll be just as harmless as this one (and also - to reduce verbosity) */ - g.skipdrin = TRUE; - mhm.damage = 0; - if (!Unchanging && pd == &mons[PM_GREEN_SLIME]) { - if (!Slimed) { - You("suck in some slime and don't feel very well."); - make_slimed(10L, (char *) 0); - } - } - break; - } - if (m_slips_free(mdef, mattk)) - break; - - if ((helmet = which_armor(mdef, W_ARMH)) != 0 && rn2(8)) { - pline("%s %s blocks your attack to %s head.", - s_suffix(Monnam(mdef)), helm_simple_name(helmet), - mhis(mdef)); - break; - } - - (void) eat_brains(&g.youmonst, mdef, TRUE, &mhm.damage); + case AD_DRIN: + mhitm_ad_drin(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; - } case AD_STCK: if (!negated && !sticks(pd) && distu(mdef->mx, mdef->my) <= 2) u.ustuck = mdef; /* it's now stuck to you */ From bfb8931188dd3d33f139895e91303ee923f17391 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:00:35 +0200 Subject: [PATCH 500/708] Unify ad_stck --- include/extern.h | 1 + src/mhitm.c | 5 +++-- src/mhitu.c | 7 +++---- src/uhitm.c | 41 +++++++++++++++++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/include/extern.h b/include/extern.h index 86d9b02b0..cddedb6e2 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2771,6 +2771,7 @@ E void FDECL(mhitm_ad_blnd, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_curs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_drst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_drin, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_stck, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 89626bc4b..3502bd4c7 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1246,8 +1246,9 @@ int dieroll; } break; case AD_STCK: - if (cancelled) - mhm.damage = 0; + mhitm_ad_stck(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_WRAP: /* monsters cannot grab one another, it's too hard */ if (magr->mcan) diff --git a/src/mhitu.c b/src/mhitu.c index 61ed015a3..fe9b0257b 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1234,10 +1234,9 @@ register struct attack *mattk; } break; case AD_STCK: - hitmsg(mtmp, mattk); - if (uncancelled && !u.ustuck && !sticks(g.youmonst.data)) { - set_ustuck(mtmp); - } + mhitm_ad_stck(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_WRAP: if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(g.youmonst.data)) { diff --git a/src/uhitm.c b/src/uhitm.c index 53a5dd45f..567412b86 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2739,6 +2739,42 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_stck(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && !sticks(pd) && distu(mdef->mx, mdef->my) <= 2) + u.ustuck = mdef; /* it's now stuck to you */ + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && !u.ustuck && !sticks(pd)) { + set_ustuck(magr); + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (cancelled) + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2927,8 +2963,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_STCK: - if (!negated && !sticks(pd) && distu(mdef->mx, mdef->my) <= 2) - u.ustuck = mdef; /* it's now stuck to you */ + mhitm_ad_stck(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_WRAP: if (!sticks(pd)) { From 7914237fbfd6b0b5460f54164fc60e81ae718d99 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:06:53 +0200 Subject: [PATCH 501/708] Unify ad_wrap --- include/extern.h | 1 + src/mhitm.c | 7 ++-- src/mhitu.c | 35 ++-------------- src/uhitm.c | 103 ++++++++++++++++++++++++++++++++++++----------- 4 files changed, 87 insertions(+), 59 deletions(-) diff --git a/include/extern.h b/include/extern.h index cddedb6e2..b6c72b178 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2772,6 +2772,7 @@ E void FDECL(mhitm_ad_curs, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_drst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_drin, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_stck, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_wrap, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 3502bd4c7..95a096918 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1250,9 +1250,10 @@ int dieroll; if (mhm.done) return mhm.hitflags; break; - case AD_WRAP: /* monsters cannot grab one another, it's too hard */ - if (magr->mcan) - mhm.damage = 0; + case AD_WRAP: + mhitm_ad_wrap(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ENCH: /* there's no msomearmor() function, so just do damage */ diff --git a/src/mhitu.c b/src/mhitu.c index fe9b0257b..ad05ad186 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1239,38 +1239,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_WRAP: - if ((!mtmp->mcan || u.ustuck == mtmp) && !sticks(g.youmonst.data)) { - if (!u.ustuck && !rn2(10)) { - if (u_slip_free(mtmp, mattk)) { - mhm.damage = 0; - } else { - set_ustuck(mtmp); /* before message, for botl update */ - pline("%s swings itself around you!", Monnam(mtmp)); - } - } else if (u.ustuck == mtmp) { - if (is_pool(mtmp->mx, mtmp->my) && !Swimming && !Amphibious) { - boolean moat = (levl[mtmp->mx][mtmp->my].typ != POOL) - && (levl[mtmp->mx][mtmp->my].typ != WATER) - && !Is_medusa_level(&u.uz) - && !Is_waterlevel(&u.uz); - - pline("%s drowns you...", Monnam(mtmp)); - g.killer.format = KILLED_BY_AN; - Sprintf(g.killer.name, "%s by %s", - moat ? "moat" : "pool of water", - an(mtmp->data->mname)); - done(DROWNING); - } else if (mattk->aatyp == AT_HUGS) { - You("are being crushed."); - } - } else { - mhm.damage = 0; - if (flags.verbose) - pline("%s brushes against your %s.", Monnam(mtmp), - body_part(LEG)); - } - } else - mhm.damage = 0; + mhitm_ad_wrap(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_WERE: hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index 567412b86..3950f4c7b 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2775,6 +2775,82 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_wrap(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (!sticks(pd)) { + if (!u.ustuck && !rn2(10)) { + if (m_slips_free(mdef, mattk)) { + mhm->damage = 0; + } else { + You("swing yourself around %s!", mon_nam(mdef)); + set_ustuck(mdef); + } + } else if (u.ustuck == mdef) { + /* Monsters don't wear amulets of magical breathing */ + if (is_pool(u.ux, u.uy) && !is_swimmer(pd) + && !amphibious(pd)) { + You("drown %s...", mon_nam(mdef)); + mhm->damage = mdef->mhp; + } else if (mattk->aatyp == AT_HUGS) + pline("%s is being crushed.", Monnam(mdef)); + } else { + mhm->damage = 0; + if (flags.verbose) + You("brush against %s %s.", s_suffix(mon_nam(mdef)), + mbodypart(mdef, LEG)); + } + } else + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + if ((!magr->mcan || u.ustuck == magr) && !sticks(pd)) { + if (!u.ustuck && !rn2(10)) { + if (u_slip_free(magr, mattk)) { + mhm->damage = 0; + } else { + set_ustuck(magr); /* before message, for botl update */ + pline("%s swings itself around you!", Monnam(magr)); + } + } else if (u.ustuck == magr) { + if (is_pool(magr->mx, magr->my) && !Swimming && !Amphibious) { + boolean moat = (levl[magr->mx][magr->my].typ != POOL) + && (levl[magr->mx][magr->my].typ != WATER) + && !Is_medusa_level(&u.uz) + && !Is_waterlevel(&u.uz); + + pline("%s drowns you...", Monnam(magr)); + g.killer.format = KILLED_BY_AN; + Sprintf(g.killer.name, "%s by %s", + moat ? "moat" : "pool of water", + an(magr->data->mname)); + done(DROWNING); + } else if (mattk->aatyp == AT_HUGS) { + You("are being crushed."); + } + } else { + mhm->damage = 0; + if (flags.verbose) + pline("%s brushes against your %s.", Monnam(magr), + body_part(LEG)); + } + } else + mhm->damage = 0; + } else { + /* mhitm */ + if (magr->mcan) + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2968,30 +3044,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_WRAP: - if (!sticks(pd)) { - if (!u.ustuck && !rn2(10)) { - if (m_slips_free(mdef, mattk)) { - mhm.damage = 0; - } else { - You("swing yourself around %s!", mon_nam(mdef)); - set_ustuck(mdef); - } - } else if (u.ustuck == mdef) { - /* Monsters don't wear amulets of magical breathing */ - if (is_pool(u.ux, u.uy) && !is_swimmer(pd) - && !amphibious(pd)) { - You("drown %s...", mon_nam(mdef)); - mhm.damage = mdef->mhp; - } else if (mattk->aatyp == AT_HUGS) - pline("%s is being crushed.", Monnam(mdef)); - } else { - mhm.damage = 0; - if (flags.verbose) - You("brush against %s %s.", s_suffix(mon_nam(mdef)), - mbodypart(mdef, LEG)); - } - } else - mhm.damage = 0; + mhitm_ad_wrap(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_PLYS: if (!negated && mdef->mcanmove && !rn2(3) && mhm.damage < mdef->mhp) { From 654220f84054a5fe130256588a01b4972224e576 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:25:37 +0200 Subject: [PATCH 502/708] Unify ad_plys --- include/extern.h | 1 + src/mhitm.c | 10 ++----- src/mhitu.c | 18 ++---------- src/uhitm.c | 75 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 77 insertions(+), 27 deletions(-) diff --git a/include/extern.h b/include/extern.h index b6c72b178..748921103 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2773,6 +2773,7 @@ E void FDECL(mhitm_ad_drst, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_drin, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_stck, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_wrap, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_plys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 95a096918..bb183bd64 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1092,13 +1092,9 @@ int dieroll; } break; case AD_PLYS: - if (!cancelled && mdef->mcanmove) { - if (g.vis && canspotmon(mdef)) { - Strcpy(buf, Monnam(mdef)); - pline("%s is frozen by %s.", buf, mon_nam(magr)); - } - paralyze_monst(mdef, rnd(10)); - } + mhitm_ad_plys(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLOW: if (!cancelled && mdef->mspeed != MSLOW) { diff --git a/src/mhitu.c b/src/mhitu.c index ad05ad186..57c159e71 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1141,21 +1141,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_PLYS: - hitmsg(mtmp, mattk); - if (uncancelled && g.multi >= 0 && !rn2(3)) { - if (Free_action) { - You("momentarily stiffen."); - } else { - if (Blind) - You("are frozen!"); - else - You("are frozen by %s!", mon_nam(mtmp)); - g.nomovemsg = You_can_move_again; - nomul(-rnd(10)); - g.multi_reason = "paralyzed by a monster"; - exercise(A_DEX, FALSE); - } - } + mhitm_ad_plys(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DRLI: /* drain life */ mhitm_ad_drli(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 3950f4c7b..548eba081 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2851,6 +2851,63 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_plys(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && mdef->mcanmove && !rn2(3) && mhm->damage < mdef->mhp) { + if (!Blind) + pline("%s is frozen by you!", Monnam(mdef)); + paralyze_monst(mdef, rnd(10)); + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && g.multi >= 0 && !rn2(3)) { + if (Free_action) { + You("momentarily stiffen."); + } else { + if (Blind) + You("are frozen!"); + else + You("are frozen by %s!", mon_nam(magr)); + g.nomovemsg = You_can_move_again; + nomul(-rnd(10)); + g.multi_reason = "paralyzed by a monster"; + exercise(A_DEX, FALSE); + } + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && mdef->mcanmove) { + if (g.vis && canspotmon(mdef)) { + char buf[BUFSZ]; + Strcpy(buf, Monnam(mdef)); + pline("%s is frozen by %s.", buf, mon_nam(magr)); + } + paralyze_monst(mdef, rnd(10)); + } + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -2867,12 +2924,22 @@ struct mhitm_data *mhm; if (magr == &g.youmonst) { /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + /* TODO */ } else if (mdef == &g.youmonst) { /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + /* TODO */ } else { /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + /* TODO */ } } @@ -3049,11 +3116,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_PLYS: - if (!negated && mdef->mcanmove && !rn2(3) && mhm.damage < mdef->mhp) { - if (!Blind) - pline("%s is frozen by you!", Monnam(mdef)); - paralyze_monst(mdef, rnd(10)); - } + mhitm_ad_plys(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLEE: if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) { From eb5508ba5880b51af73312b64253a96ce9b3fe2d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:32:50 +0200 Subject: [PATCH 503/708] Unify ad_slee --- include/extern.h | 1 + src/mhitm.c | 12 +++------- src/mhitu.c | 13 +++-------- src/uhitm.c | 61 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/include/extern.h b/include/extern.h index 748921103..17bde2525 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2774,6 +2774,7 @@ E void FDECL(mhitm_ad_drin, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_stck, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_wrap, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_plys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_slee, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index bb183bd64..c242af935 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1081,15 +1081,9 @@ int dieroll; return mhm.hitflags; break; case AD_SLEE: - if (!cancelled && !mdef->msleeping - && sleep_monst(mdef, rnd(10), -1)) { - if (g.vis && canspotmon(mdef)) { - Strcpy(buf, Monnam(mdef)); - pline("%s is put to sleep by %s.", buf, mon_nam(magr)); - } - mdef->mstrategy &= ~STRAT_WAITFORU; - slept_monst(mdef); - } + mhitm_ad_slee(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_PLYS: mhitm_ad_plys(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 57c159e71..0f05f7550 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1112,16 +1112,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_SLEE: - hitmsg(mtmp, mattk); - if (uncancelled && g.multi >= 0 && !rn2(5)) { - if (Sleep_resistance) - break; - fall_asleep(-rnd(10), TRUE); - if (Blind) - You("are put to sleep!"); - else - You("are put to sleep by %s!", mon_nam(mtmp)); - } + mhitm_ad_slee(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_BLND: mhitm_ad_blnd(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 548eba081..6db992626 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2907,6 +2907,59 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_slee(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) { + if (!Blind) + pline("%s is put to sleep by you!", Monnam(mdef)); + slept_monst(mdef); + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && g.multi >= 0 && !rn2(5)) { + if (Sleep_resistance) + return; + fall_asleep(-rnd(10), TRUE); + if (Blind) + You("are put to sleep!"); + else + You("are put to sleep by %s!", mon_nam(magr)); + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && !mdef->msleeping + && sleep_monst(mdef, rnd(10), -1)) { + if (g.vis && canspotmon(mdef)) { + char buf[BUFSZ]; + Strcpy(buf, Monnam(mdef)); + pline("%s is put to sleep by %s.", buf, mon_nam(magr)); + } + mdef->mstrategy &= ~STRAT_WAITFORU; + slept_monst(mdef); + } + } +} + /* Template for monster hits monster for AD_FOO. @@ -3121,11 +3174,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_SLEE: - if (!negated && !mdef->msleeping && sleep_monst(mdef, rnd(10), -1)) { - if (!Blind) - pline("%s is put to sleep by you!", Monnam(mdef)); - slept_monst(mdef); - } + mhitm_ad_slee(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLIM: if (negated) From 96a4d14a36973817c15349e7c2c06ade3b38455d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:40:38 +0200 Subject: [PATCH 504/708] Unify ad_slim --- include/extern.h | 1 + src/mhitm.c | 21 ++--------- src/mhitu.c | 19 ++-------- src/uhitm.c | 97 ++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 89 insertions(+), 49 deletions(-) diff --git a/include/extern.h b/include/extern.h index 17bde2525..68dfa2166 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2775,6 +2775,7 @@ E void FDECL(mhitm_ad_stck, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_wrap, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_plys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_slee, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_slim, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index c242af935..24315f5ff 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1216,24 +1216,9 @@ int dieroll; return mhm.hitflags; break; case AD_SLIM: - if (cancelled) - break; /* physical damage only */ - if (!rn2(4) && !slimeproof(pd)) { - if (!munslime(mdef, FALSE) && !DEADMONSTER(mdef)) { - if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, - (boolean) (g.vis && canseemon(mdef)))) - pd = mdef->data; - mdef->mstrategy &= ~STRAT_WAITFORU; - mhm.hitflags = MM_HIT; - } - /* munslime attempt could have been fatal, - potentially to multiple monsters (SCR_FIRE) */ - if (DEADMONSTER(magr)) - mhm.hitflags |= MM_AGR_DIED; - if (DEADMONSTER(mdef)) - mhm.hitflags |= MM_DEF_DIED; - mhm.damage = 0; - } + mhitm_ad_slim(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_STCK: mhitm_ad_stck(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 0f05f7550..1151fb164 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1477,22 +1477,9 @@ register struct attack *mattk; /* plus the normal damage */ break; case AD_SLIM: - hitmsg(mtmp, mattk); - if (!uncancelled) - break; - if (flaming(g.youmonst.data)) { - pline_The("slime burns away!"); - mhm.damage = 0; - } else if (Unchanging || noncorporeal(g.youmonst.data) - || g.youmonst.data == &mons[PM_GREEN_SLIME]) { - You("are unaffected."); - mhm.damage = 0; - } else if (!Slimed) { - You("don't feel very well."); - make_slimed(10L, (char *) 0); - delayed_killer(SLIMED, KILLED_BY_AN, mtmp->data->mname); - } else - pline("Yuck!"); + mhitm_ad_slim(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ hitmsg(mtmp, mattk); diff --git a/src/uhitm.c b/src/uhitm.c index 6db992626..e04d6261f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2960,6 +2960,85 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_slim(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (negated) + return; /* physical damage only */ + if (!rn2(4) && !slimeproof(pd)) { + if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) { + /* this assumes newcham() won't fail; since hero has + a slime attack, green slimes haven't been geno'd */ + You("turn %s into slime.", mon_nam(mdef)); + if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE)) + pd = mdef->data; + } + /* munslime attempt could have been fatal */ + if (DEADMONSTER(mdef)) { + mhm->hitflags = MM_DEF_DIED; /* skip death message */ + mhm->done = TRUE; + return; + } + mhm->damage = 0; + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (!uncancelled) + return; + if (flaming(pd)) { + pline_The("slime burns away!"); + mhm->damage = 0; + } else if (Unchanging || noncorporeal(pd) + || pd == &mons[PM_GREEN_SLIME]) { + You("are unaffected."); + mhm->damage = 0; + } else if (!Slimed) { + You("don't feel very well."); + make_slimed(10L, (char *) 0); + delayed_killer(SLIMED, KILLED_BY_AN, magr->data->mname); + } else + pline("Yuck!"); + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (cancelled) + return; /* physical damage only */ + if (!rn2(4) && !slimeproof(pd)) { + if (!munslime(mdef, FALSE) && !DEADMONSTER(mdef)) { + if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, + (boolean) (g.vis && canseemon(mdef)))) + pd = mdef->data; + mdef->mstrategy &= ~STRAT_WAITFORU; + mhm->hitflags = MM_HIT; + } + /* munslime attempt could have been fatal, + potentially to multiple monsters (SCR_FIRE) */ + if (DEADMONSTER(magr)) + mhm->hitflags |= MM_AGR_DIED; + if (DEADMONSTER(mdef)) + mhm->hitflags |= MM_DEF_DIED; + mhm->damage = 0; + } + } +} /* Template for monster hits monster for AD_FOO. @@ -3179,21 +3258,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_SLIM: - if (negated) - break; /* physical damage only */ - if (!rn2(4) && !slimeproof(pd)) { - if (!munslime(mdef, TRUE) && !DEADMONSTER(mdef)) { - /* this assumes newcham() won't fail; since hero has - a slime attack, green slimes haven't been geno'd */ - You("turn %s into slime.", mon_nam(mdef)); - if (newcham(mdef, &mons[PM_GREEN_SLIME], FALSE, FALSE)) - pd = mdef->data; - } - /* munslime attempt could have been fatal */ - if (DEADMONSTER(mdef)) - return 2; /* skip death message */ - mhm.damage = 0; - } + mhitm_ad_slim(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ /* there's no msomearmor() function, so just do damage */ From b80c30bcf1a474d2569f124514ec9cb93b66094c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:46:59 +0200 Subject: [PATCH 505/708] Unify ad_ench --- include/extern.h | 1 + src/mhitm.c | 5 ++-- src/mhitu.c | 33 +++------------------------ src/uhitm.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 63 insertions(+), 35 deletions(-) diff --git a/include/extern.h b/include/extern.h index 68dfa2166..161e17258 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2776,6 +2776,7 @@ E void FDECL(mhitm_ad_wrap, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_plys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_slee, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_slim, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_ench, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 24315f5ff..db2dfa4ee 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1231,8 +1231,9 @@ int dieroll; return mhm.hitflags; break; case AD_ENCH: - /* there's no msomearmor() function, so just do damage */ - /* if (cancelled) break; */ + mhitm_ad_ench(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_POLY: if (!magr->mcan && mhm.damage < mdef->mhp) diff --git a/src/mhitu.c b/src/mhitu.c index 1151fb164..cb26e2cb0 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1482,36 +1482,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ - hitmsg(mtmp, mattk); - /* uncancelled is sufficient enough; please - don't make this attack less frequent */ - if (uncancelled) { - struct obj *obj = some_armor(&g.youmonst); - - if (!obj) { - /* some rings are susceptible; - amulets and blindfolds aren't (at present) */ - switch (rn2(5)) { - case 0: - break; - case 1: - obj = uright; - break; - case 2: - obj = uleft; - break; - case 3: - obj = uamul; - break; - case 4: - obj = ublindf; - break; - } - } - if (drain_item(obj, FALSE)) { - pline("%s less effective.", Yobjnam2(obj, "seem")); - } - } + mhitm_ad_ench(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_POLY: if (uncancelled && Maybe_Half_Phys(mhm.damage) < (Upolyd ? u.mh : u.uhp)) diff --git a/src/uhitm.c b/src/uhitm.c index e04d6261f..171ea78ea 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3040,6 +3040,58 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_ench(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + /* there's no msomearmor() function, so just do damage */ + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + /* uncancelled is sufficient enough; please + don't make this attack less frequent */ + if (uncancelled) { + struct obj *obj = some_armor(mdef); + + if (!obj) { + /* some rings are susceptible; + amulets and blindfolds aren't (at present) */ + switch (rn2(5)) { + case 0: + break; + case 1: + obj = uright; + break; + case 2: + obj = uleft; + break; + case 3: + obj = uamul; + break; + case 4: + obj = ublindf; + break; + } + } + if (drain_item(obj, FALSE)) { + pline("%s less effective.", Yobjnam2(obj, "seem")); + } + } + } else { + /* mhitm */ + /* there's no msomearmor() function, so just do damage */ + } +} /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -3262,9 +3314,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (mhm.done) return mhm.hitflags; break; - case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ - /* there's no msomearmor() function, so just do damage */ - /* if (negated) break; */ + case AD_ENCH: + mhitm_ad_ench(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLOW: if (!negated && mdef->mspeed != MSLOW) { From 558ec78b3a7474532931ce24bd28a8e09bb1b94f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:50:56 +0200 Subject: [PATCH 506/708] Unify ad_slow --- include/extern.h | 1 + src/mhitm.c | 11 +++------- src/mhitu.c | 6 ++--- src/uhitm.c | 57 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/include/extern.h b/include/extern.h index 161e17258..414e1d0f8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2777,6 +2777,7 @@ E void FDECL(mhitm_ad_plys, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_slee, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_slim, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_ench, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_slow, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index db2dfa4ee..ffb11fe1f 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1091,14 +1091,9 @@ int dieroll; return mhm.hitflags; break; case AD_SLOW: - if (!cancelled && mdef->mspeed != MSLOW) { - unsigned int oldspeed = mdef->mspeed; - - mon_adjust_speed(mdef, -1, (struct obj *) 0); - mdef->mstrategy &= ~STRAT_WAITFORU; - if (mdef->mspeed != oldspeed && g.vis && canspotmon(mdef)) - pline("%s slows down.", Monnam(mdef)); - } + mhitm_ad_slow(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CONF: /* Since confusing another monster doesn't have a real time diff --git a/src/mhitu.c b/src/mhitu.c index cb26e2cb0..dcee2988d 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1409,9 +1409,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_SLOW: - hitmsg(mtmp, mattk); - if (uncancelled && HFast && !defends(AD_SLOW, uwep) && !rn2(4)) - u_slow_down(); + mhitm_ad_slow(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DREN: mhitm_ad_dren(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 171ea78ea..16bf66c34 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3093,6 +3093,53 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_slow(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && mdef->mspeed != MSLOW) { + unsigned int oldspeed = mdef->mspeed; + + mon_adjust_speed(mdef, -1, (struct obj *) 0); + if (mdef->mspeed != oldspeed && canseemon(mdef)) + pline("%s slows down.", Monnam(mdef)); + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && HFast && !defends(AD_SLOW, uwep) && !rn2(4)) + u_slow_down(); + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!cancelled && mdef->mspeed != MSLOW) { + unsigned int oldspeed = mdef->mspeed; + + mon_adjust_speed(mdef, -1, (struct obj *) 0); + mdef->mstrategy &= ~STRAT_WAITFORU; + if (mdef->mspeed != oldspeed && g.vis && canspotmon(mdef)) + pline("%s slows down.", Monnam(mdef)); + } + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3320,13 +3367,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_SLOW: - if (!negated && mdef->mspeed != MSLOW) { - unsigned int oldspeed = mdef->mspeed; - - mon_adjust_speed(mdef, -1, (struct obj *) 0); - if (mdef->mspeed != oldspeed && canseemon(mdef)) - pline("%s slows down.", Monnam(mdef)); - } + mhitm_ad_slow(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CONF: if (!mdef->mconf) { From fda63d145b08425f14f4701210d1f913fd94c17c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:55:26 +0200 Subject: [PATCH 507/708] Unify ad_conf --- include/extern.h | 1 + src/mhitm.c | 13 +++---------- src/mhitu.c | 13 +++---------- src/uhitm.c | 50 +++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 52 insertions(+), 25 deletions(-) diff --git a/include/extern.h b/include/extern.h index 414e1d0f8..28292037c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2778,6 +2778,7 @@ E void FDECL(mhitm_ad_slee, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_slim, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_ench, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_slow, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_conf, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index ffb11fe1f..88a29c9a2 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1096,16 +1096,9 @@ int dieroll; return mhm.hitflags; break; case AD_CONF: - /* Since confusing another monster doesn't have a real time - * limit, setting spec_used would not really be right (though - * we still should check for it). - */ - if (!magr->mcan && !mdef->mconf && !magr->mspec_used) { - if (g.vis && canseemon(mdef)) - pline("%s looks confused.", Monnam(mdef)); - mdef->mconf = 1; - mdef->mstrategy &= ~STRAT_WAITFORU; - } + mhitm_ad_conf(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_BLND: mhitm_ad_blnd(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index dcee2988d..4213609b4 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1419,16 +1419,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_CONF: - hitmsg(mtmp, mattk); - if (!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { - mtmp->mspec_used = mtmp->mspec_used + (mhm.damage + rn2(6)); - if (Confusion) - You("are getting even more confused."); - else - You("are getting confused."); - make_confused(HConfusion + mhm.damage, FALSE); - } - mhm.damage = 0; + mhitm_ad_conf(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DETH: pline("%s reaches out with its deadly touch.", Monnam(mtmp)); diff --git a/src/uhitm.c b/src/uhitm.c index 16bf66c34..2d745667e 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3139,6 +3139,48 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_conf(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (!mdef->mconf) { + if (canseemon(mdef)) + pline("%s looks confused.", Monnam(mdef)); + mdef->mconf = 1; + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (!magr->mcan && !rn2(4) && !magr->mspec_used) { + magr->mspec_used = magr->mspec_used + (mhm->damage + rn2(6)); + if (Confusion) + You("are getting even more confused."); + else + You("are getting confused."); + make_confused(HConfusion + mhm->damage, FALSE); + } + mhm->damage = 0; + } else { + /* mhitm */ + /* Since confusing another monster doesn't have a real time + * limit, setting spec_used would not really be right (though + * we still should check for it). + */ + if (!magr->mcan && !mdef->mconf && !magr->mspec_used) { + if (g.vis && canseemon(mdef)) + pline("%s looks confused.", Monnam(mdef)); + mdef->mconf = 1; + mdef->mstrategy &= ~STRAT_WAITFORU; + } + } +} /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -3372,11 +3414,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_CONF: - if (!mdef->mconf) { - if (canseemon(mdef)) - pline("%s looks confused.", Monnam(mdef)); - mdef->mconf = 1; - } + mhitm_ad_conf(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_POLY: if (!negated && mhm.damage < mdef->mhp) From 618feabd8831a848e9d3764f1d76ae86fb5de202 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 22:59:06 +0200 Subject: [PATCH 508/708] Unify ad_poly --- include/extern.h | 1 + src/mhitm.c | 5 +++-- src/mhitu.c | 5 +++-- src/uhitm.c | 39 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/include/extern.h b/include/extern.h index 28292037c..856cfd0cf 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2779,6 +2779,7 @@ E void FDECL(mhitm_ad_slim, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_ench, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_slow, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_conf, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_poly, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 88a29c9a2..69ba4405c 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1224,8 +1224,9 @@ int dieroll; return mhm.hitflags; break; case AD_POLY: - if (!magr->mcan && mhm.damage < mdef->mhp) - mhm.damage = mon_poly(magr, mdef, mhm.damage); + mhitm_ad_poly(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; default: mhm.damage = 0; diff --git a/src/mhitu.c b/src/mhitu.c index 4213609b4..9957e0d3e 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1480,8 +1480,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_POLY: - if (uncancelled && Maybe_Half_Phys(mhm.damage) < (Upolyd ? u.mh : u.uhp)) - mhm.damage = mon_poly(mtmp, &g.youmonst, mhm.damage); + mhitm_ad_poly(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; default: mhm.damage = 0; diff --git a/src/uhitm.c b/src/uhitm.c index 2d745667e..83bdaa7e1 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3182,6 +3182,40 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_poly(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (!negated && mhm->damage < mdef->mhp) + mhm->damage = mon_poly(magr, mdef, mhm->damage); + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + if (uncancelled && Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) + mhm->damage = mon_poly(magr, mdef, mhm->damage); + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!magr->mcan && mhm->damage < mdef->mhp) + mhm->damage = mon_poly(magr, mdef, mhm->damage); + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3419,8 +3453,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_POLY: - if (!negated && mhm.damage < mdef->mhp) - mhm.damage = mon_poly(&g.youmonst, mdef, mhm.damage); + mhitm_ad_poly(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; default: mhm.damage = 0; From cb55d7c30fbab91ba47879cda49b371990004c6f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 23:05:01 +0200 Subject: [PATCH 509/708] Unify ad_famn --- include/extern.h | 1 + src/mhitu.c | 8 +++----- src/uhitm.c | 25 +++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 856cfd0cf..81fbef7a5 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2780,6 +2780,7 @@ E void FDECL(mhitm_ad_ench, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_slow, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_conf, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_poly, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_famn, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitu.c b/src/mhitu.c index 9957e0d3e..7791176b8 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1463,11 +1463,9 @@ register struct attack *mattk; (void) diseasemu(mdat); /* plus the normal damage */ break; case AD_FAMN: - pline("%s reaches out, and your body shrivels.", Monnam(mtmp)); - exercise(A_CON, FALSE); - if (!is_fainted()) - morehungry(rn1(40, 40)); - /* plus the normal damage */ + mhitm_ad_famn(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SLIM: mhitm_ad_slim(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 83bdaa7e1..9167326c8 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3216,6 +3216,31 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_famn(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + pline("%s reaches out, and your body shrivels.", Monnam(magr)); + exercise(A_CON, FALSE); + if (!is_fainted()) + morehungry(rn1(40, 40)); + /* plus the normal damage */ + } else { + /* mhitm */ + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE From 29992333324fc3530294baad66a741bca8ca91e8 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 23:09:05 +0200 Subject: [PATCH 510/708] Unify ad_pest --- include/extern.h | 2 ++ src/mhitu.c | 8 ++++---- src/uhitm.c | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/extern.h b/include/extern.h index 81fbef7a5..44f3f2523 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1290,6 +1290,7 @@ E void FDECL(expels, (struct monst *, struct permonst *, BOOLEAN_P)); E struct attack *FDECL(getmattk, (struct monst *, struct monst *, int, int *, struct attack *)); E int FDECL(mattacku, (struct monst *)); +boolean FDECL(diseasemu, (struct permonst *)); boolean FDECL(u_slip_free, (struct monst *, struct attack *)); E int FDECL(magic_negation, (struct monst *)); E boolean NDECL(gulp_blnd_check); @@ -2781,6 +2782,7 @@ E void FDECL(mhitm_ad_slow, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_conf, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_poly, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_famn, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_pest, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitu.c b/src/mhitu.c index 7791176b8..d38c76b0a 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -12,7 +12,6 @@ static void FDECL(missmu, (struct monst *, BOOLEAN_P, struct attack *)); static void FDECL(mswings, (struct monst *, struct obj *)); static void FDECL(wildmiss, (struct monst *, struct attack *)); static void FDECL(summonmu, (struct monst *, BOOLEAN_P)); -static boolean FDECL(diseasemu, (struct permonst *)); static int FDECL(hitmu, (struct monst *, struct attack *)); static int FDECL(gulpmu, (struct monst *, struct attack *)); static int FDECL(explmu, (struct monst *, struct attack *, BOOLEAN_P)); @@ -853,7 +852,7 @@ boolean youseeit; } /* were creature */ } -static boolean +boolean diseasemu(mdat) struct permonst *mdat; { @@ -1459,8 +1458,9 @@ register struct attack *mattk; } break; case AD_PEST: - pline("%s reaches out, and you feel fever and chills.", Monnam(mtmp)); - (void) diseasemu(mdat); /* plus the normal damage */ + mhitm_ad_pest(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_FAMN: mhitm_ad_famn(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 9167326c8..e71050b67 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3241,6 +3241,30 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_pest(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + pline("%s reaches out, and you feel fever and chills.", Monnam(magr)); + (void) diseasemu(pa); + /* plus the normal damage */ + } else { + /* mhitm */ + mhm->damage = 0; + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE From 36bb52466d2b25d7eb304b024e15945316db5951 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 23:20:09 +0200 Subject: [PATCH 511/708] Unify ad_deth --- include/extern.h | 1 + include/monattk.h | 1 + src/mhitm.c | 1 + src/mhitu.c | 54 +++++++++++------------------------------------ src/uhitm.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 42 deletions(-) diff --git a/include/extern.h b/include/extern.h index 44f3f2523..6082a1537 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2783,6 +2783,7 @@ E void FDECL(mhitm_ad_conf, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_poly, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_famn, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_pest, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_deth, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/include/monattk.h b/include/monattk.h index 8f2d7c12f..0ea507b21 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -90,6 +90,7 @@ struct mhitm_data { int damage; int hitflags; /* MM_DEF_DIED | MM_AGR_DIED | ... */ boolean done; + boolean permdmg; }; /* diff --git a/src/mhitm.c b/src/mhitm.c index 69ba4405c..9d35199a6 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -863,6 +863,7 @@ int dieroll; struct mhitm_data mhm; mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = MM_MISS; + mhm.permdmg = 0; if ((touch_petrifies(pd) /* or flesh_petrifies() */ || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA])) diff --git a/src/mhitu.c b/src/mhitu.c index d38c76b0a..614b3d9de 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -967,12 +967,13 @@ register struct attack *mattk; { struct permonst *mdat = mtmp->data; int uncancelled, ptmp; - int armpro, permdmg, tmphp; + int armpro, tmphp; char buf[BUFSZ]; struct permonst *olduasmon = g.youmonst.data; int res; struct mhitm_data mhm; mhm.hitflags = MM_MISS; + mhm.permdmg = 0; if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); @@ -1012,7 +1013,6 @@ register struct attack *mattk; armpro = magic_negation(&g.youmonst); uncancelled = !mtmp->mcan && (rn2(10) >= 3 * armpro); - permdmg = 0; /* Now, adjust damages via resistances or specific attacks */ switch (mattk->adtyp) { case AD_PHYS: @@ -1423,39 +1423,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_DETH: - pline("%s reaches out with its deadly touch.", Monnam(mtmp)); - if (is_undead(g.youmonst.data)) { - /* Still does normal damage */ - pline("Was that the touch of death?"); - break; - } - switch (rn2(20)) { - case 19: - case 18: - case 17: - if (!Antimagic) { - g.killer.format = KILLED_BY_AN; - Strcpy(g.killer.name, "touch of death"); - done(DIED); - mhm.damage = 0; - break; - } - /*FALLTHRU*/ - default: /* case 16: ... case 5: */ - You_feel("your life force draining away..."); - permdmg = 1; /* actual damage done below */ - break; - case 4: - case 3: - case 2: - case 1: - case 0: - if (Antimagic) - shieldeff(u.ux, u.uy); - pline("Lucky for you, it didn't work!"); - mhm.damage = 0; - break; - } + mhitm_ad_deth(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_PEST: mhitm_ad_pest(mtmp, mattk, &g.youmonst, &mhm); @@ -1509,7 +1479,7 @@ register struct attack *mattk; || is_vampshifter(mtmp)))) mhm.damage = (mhm.damage + 1) / 2; - if (permdmg) { /* Death's life force drain */ + if (mhm.permdmg) { /* Death's life force drain */ int lowerlimit, *hpmax_p; /* * Apply some of the damage to permanent hit points: @@ -1520,13 +1490,13 @@ register struct attack *mattk; * otherwise 0..50% * Never reduces hpmax below 1 hit point per level. */ - permdmg = rn2(mhm.damage / 2 + 1); + mhm.permdmg = rn2(mhm.damage / 2 + 1); if (Upolyd || u.uhpmax > 25 * u.ulevel) - permdmg = mhm.damage; + mhm.permdmg = mhm.damage; else if (u.uhpmax > 10 * u.ulevel) - permdmg += mhm.damage / 2; + mhm.permdmg += mhm.damage / 2; else if (u.uhpmax > 5 * u.ulevel) - permdmg += mhm.damage / 4; + mhm.permdmg += mhm.damage / 4; if (Upolyd) { hpmax_p = &u.mhmax; @@ -1536,8 +1506,8 @@ register struct attack *mattk; hpmax_p = &u.uhpmax; lowerlimit = u.ulevel; } - if (*hpmax_p - permdmg > lowerlimit) - *hpmax_p -= permdmg; + if (*hpmax_p - mhm.permdmg > lowerlimit) + *hpmax_p -= mhm.permdmg; else if (*hpmax_p > lowerlimit) *hpmax_p = lowerlimit; /* else unlikely... diff --git a/src/uhitm.c b/src/uhitm.c index e71050b67..4f5ead337 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3264,6 +3264,59 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_deth(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + pline("%s reaches out with its deadly touch.", Monnam(magr)); + if (is_undead(pd)) { + /* Still does normal damage */ + pline("Was that the touch of death?"); + return; + } + switch (rn2(20)) { + case 19: + case 18: + case 17: + if (!Antimagic) { + g.killer.format = KILLED_BY_AN; + Strcpy(g.killer.name, "touch of death"); + done(DIED); + mhm->damage = 0; + return; + } + /*FALLTHRU*/ + default: /* case 16: ... case 5: */ + You_feel("your life force draining away..."); + mhm->permdmg = 1; /* actual damage done below */ + return; + case 4: + case 3: + case 2: + case 1: + case 0: + if (Antimagic) + shieldeff(u.ux, u.uy); + pline("Lucky for you, it didn't work!"); + mhm->damage = 0; + return; + } + } else { + /* mhitm */ + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -3312,6 +3365,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ struct mhitm_data mhm; mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = MM_MISS; + mhm.permdmg = 0; armpro = magic_negation(mdef); /* since hero can't be cancelled, only defender's armor applies */ From ac5822fe69f83da0634fd6709f603ec66fe7b3ca Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 30 Nov 2020 23:28:13 +0200 Subject: [PATCH 512/708] Unify ad_halu --- include/extern.h | 1 + src/mhitm.c | 11 +++-------- src/uhitm.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/extern.h b/include/extern.h index 6082a1537..4f4b9a2a3 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2784,6 +2784,7 @@ E void FDECL(mhitm_ad_poly, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_famn, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_pest, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_deth, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_halu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/src/mhitm.c b/src/mhitm.c index 9d35199a6..9c9e89bec 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1107,14 +1107,9 @@ int dieroll; return mhm.hitflags; break; case AD_HALU: - if (!magr->mcan && haseyes(pd) && mdef->mcansee) { - if (g.vis && canseemon(mdef)) - pline("%s looks %sconfused.", Monnam(mdef), - mdef->mconf ? "more " : ""); - mdef->mconf = 1; - mdef->mstrategy &= ~STRAT_WAITFORU; - } - mhm.damage = 0; + mhitm_ad_halu(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CURS: mhitm_ad_curs(magr, mattk, mdef, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 4f5ead337..3213c8ff5 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3317,6 +3317,36 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_halu(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + mhm->damage = 0; + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + + if (!magr->mcan && haseyes(pd) && mdef->mcansee) { + if (g.vis && canseemon(mdef)) + pline("%s looks %sconfused.", Monnam(mdef), + mdef->mconf ? "more " : ""); + mdef->mconf = 1; + mdef->mstrategy &= ~STRAT_WAITFORU; + } + mhm->damage = 0; + } +} /* Template for monster hits monster for AD_FOO. - replace "break" with return From 20b6ea602bf3982ea88484b164aefef5ce71de9f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 09:07:44 +0200 Subject: [PATCH 513/708] Unify ad_phys --- include/extern.h | 3 + include/monattk.h | 2 + src/mhitm.c | 79 ++----------- src/mhitu.c | 95 +-------------- src/uhitm.c | 286 +++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 275 insertions(+), 190 deletions(-) diff --git a/include/extern.h b/include/extern.h index 4f4b9a2a3..59982f230 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2785,6 +2785,9 @@ E void FDECL(mhitm_ad_famn, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_pest, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_deth, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_halu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_phys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E boolean FDECL(do_stone_u, (struct monst *)); +E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, diff --git a/include/monattk.h b/include/monattk.h index 0ea507b21..b78ec6fe6 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -91,6 +91,8 @@ struct mhitm_data { int hitflags; /* MM_DEF_DIED | MM_AGR_DIED | ... */ boolean done; boolean permdmg; + int specialdmg; + int dieroll; }; /* diff --git a/src/mhitm.c b/src/mhitm.c index 9c9e89bec..d7f9a6dbe 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -864,6 +864,8 @@ int dieroll; mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = MM_MISS; mhm.permdmg = 0; + mhm.specialdmg = 0; + mhm.dieroll = dieroll; if ((touch_petrifies(pd) /* or flesh_petrifies() */ || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA])) @@ -965,56 +967,9 @@ int dieroll; case AD_HEAL: case AD_PHYS: physical: - if (mattk->aatyp != AT_WEAP && mattk->aatyp != AT_CLAW) - mwep = 0; - - if (shade_miss(magr, mdef, mwep, FALSE, TRUE)) { - mhm.damage = 0; - } else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { - /* [no 'kicking boots' check needed; monsters with kick attacks - can't wear boots and monsters that wear boots don't kick] */ - mhm.damage = 0; - } else if (mwep) { /* non-Null 'mwep' implies AT_WEAP || AT_CLAW */ - struct obj *marmg; - - if (mwep->otyp == CORPSE - && touch_petrifies(&mons[mwep->corpsenm])) - goto do_stone; - - mhm.damage += dmgval(mwep, mdef); - if ((marmg = which_armor(magr, W_ARMG)) != 0 - && marmg->otyp == GAUNTLETS_OF_POWER) - mhm.damage += rn1(4, 3); /* 3..6 */ - if (mhm.damage < 1) /* is this necessary? mhitu.c has it... */ - mhm.damage = 1; - if (mwep->oartifact) { - /* when magr's weapon is an artifact, caller suppressed its - usual 'hit' message in case artifact_hit() delivers one; - now we'll know and might need to deliver skipped message - (note: if there's no message there'll be no auxilliary - damage so the message here isn't coming too late) */ - if (!artifact_hit(magr, mdef, mwep, &mhm.damage, dieroll)) { - if (g.vis) - pline("%s hits %s.", Monnam(magr), - mon_nam_too(mdef, magr)); - } - /* artifact_hit updates 'tmp' but doesn't inflict any - damage; however, it might cause carried items to be - destroyed and they might do so */ - if (DEADMONSTER(mdef)) - return (MM_DEF_DIED - | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - } - if (mhm.damage) - rustm(mdef, mwep); - } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) { - /* hack to enhance mm_aggression(); we don't want purple - worm's bite attack to kill a shrieker because then it - won't swallow the corpse; but if the target survives, - the subsequent engulf attack should accomplish that */ - if (mhm.damage >= mdef->mhp && mdef->mhp > 1) - mhm.damage = mdef->mhp - 1; - } + mhitm_ad_phys(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_FIRE: mhitm_ad_fire(magr, mattk, mdef, &mhm); @@ -1054,27 +1009,9 @@ int dieroll; case AD_STON: if (magr->mcan) break; - do_stone: - /* may die from the acid if it eats a stone-curing corpse */ - if (munstone(mdef, FALSE)) - goto post_stone; - if (poly_when_stoned(pd)) { - mon_to_stone(mdef); - mhm.damage = 0; - break; - } - if (!resists_ston(mdef)) { - if (g.vis && canseemon(mdef)) - pline("%s turns to stone!", Monnam(mdef)); - monstone(mdef); - post_stone: - if (!DEADMONSTER(mdef)) - return 0; - else if (mdef->mtame && !g.vis) - You(brief_feeling, "peculiarly sad"); - return (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - } - mhm.damage = (mattk->adtyp == AD_STON ? 0 : 1); + do_stone_mon(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_TLPT: mhitm_ad_tlpt(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 614b3d9de..5a3e69e42 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -974,6 +974,7 @@ register struct attack *mattk; struct mhitm_data mhm; mhm.hitflags = MM_MISS; mhm.permdmg = 0; + mhm.specialdmg = 0; if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); @@ -1016,79 +1017,9 @@ register struct attack *mattk; /* Now, adjust damages via resistances or specific attacks */ switch (mattk->adtyp) { case AD_PHYS: - if (mattk->aatyp == AT_HUGS && !sticks(g.youmonst.data)) { - if (!u.ustuck && rn2(2)) { - if (u_slip_free(mtmp, mattk)) { - mhm.damage = 0; - } else { - set_ustuck(mtmp); - pline("%s grabs you!", Monnam(mtmp)); - } - } else if (u.ustuck == mtmp) { - exercise(A_STR, FALSE); - You("are being %s.", (mtmp->data == &mons[PM_ROPE_GOLEM]) - ? "choked" - : "crushed"); - } - } else { /* hand to hand weapon */ - struct obj *otmp = mon_currwep; - - if (mattk->aatyp == AT_WEAP && otmp) { - struct obj *marmg; - int tmp; - - if (otmp->otyp == CORPSE - && touch_petrifies(&mons[otmp->corpsenm])) { - mhm.damage = 1; - pline("%s hits you with the %s corpse.", Monnam(mtmp), - mons[otmp->corpsenm].mname); - if (!Stoned) - goto do_stone; - } - mhm.damage += dmgval(otmp, &g.youmonst); - if ((marmg = which_armor(mtmp, W_ARMG)) != 0 - && marmg->otyp == GAUNTLETS_OF_POWER) - mhm.damage += rn1(4, 3); /* 3..6 */ - if (mhm.damage <= 0) - mhm.damage = 1; - if (!(otmp->oartifact && artifact_hit(mtmp, &g.youmonst, otmp, - &mhm.damage, g.mhitu_dieroll))) - hitmsg(mtmp, mattk); - if (!mhm.damage) - break; - if (objects[otmp->otyp].oc_material == SILVER - && Hate_silver) { - pline_The("silver sears your flesh!"); - exercise(A_CON, FALSE); - } - /* this redundancy necessary because you have - to take the damage _before_ being cloned; - need to have at least 2 hp left to split */ - tmp = mhm.damage; - if (u.uac < 0) - tmp -= rnd(-u.uac); - if (tmp < 1) - tmp = 1; - if (u.mh - tmp > 1 - && (objects[otmp->otyp].oc_material == IRON - /* relevant 'metal' objects are scalpel and tsurugi */ - || objects[otmp->otyp].oc_material == METAL) - && (u.umonnum == PM_BLACK_PUDDING - || u.umonnum == PM_BROWN_PUDDING)) { - if (tmp > 1) - exercise(A_STR, FALSE); - /* inflict damage now; we know it can't be fatal */ - u.mh -= tmp; - g.context.botl = 1; - mhm.damage = 0; /* don't inflict more damage below */ - if (cloneu()) - You("divide as %s hits you!", mon_nam(mtmp)); - } - rustm(&g.youmonst, otmp); - } else if (mattk->aatyp != AT_TUCH || mhm.damage != 0 - || mtmp != u.ustuck) - hitmsg(mtmp, mattk); - } + mhitm_ad_phys(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DISE: hitmsg(mtmp, mattk); @@ -1193,22 +1124,8 @@ register struct attack *mattk; You_hear("%s hissing!", s_suffix(mon_nam(mtmp))); if (!rn2(10) || (flags.moonphase == NEW_MOON && !have_lizard())) { - do_stone: - if (!Stoned && !Stone_resistance - && !(poly_when_stoned(g.youmonst.data) - && polymon(PM_STONE_GOLEM))) { - int kformat = KILLED_BY_AN; - const char *kname = mtmp->data->mname; - - if (mtmp->data->geno & G_UNIQ) { - if (!type_is_pname(mtmp->data)) - kname = the(kname); - kformat = KILLED_BY; - } - make_stoned(5L, (char *) 0, kformat, kname); - return 1; - /* done_in_by(mtmp, STONING); */ - } + if (do_stone_u(mtmp)) + return MM_HIT; } } } diff --git a/src/uhitm.c b/src/uhitm.c index 3213c8ff5..b377a5f35 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3348,6 +3348,258 @@ struct mhitm_data *mhm; } } +boolean +do_stone_u(mtmp) +struct monst *mtmp; +{ + if (!Stoned && !Stone_resistance + && !(poly_when_stoned(g.youmonst.data) + && polymon(PM_STONE_GOLEM))) { + int kformat = KILLED_BY_AN; + const char *kname = mtmp->data->mname; + + if (mtmp->data->geno & G_UNIQ) { + if (!type_is_pname(mtmp->data)) + kname = the(kname); + kformat = KILLED_BY; + } + make_stoned(5L, (char *) 0, kformat, kname); + return 1; + /* done_in_by(mtmp, STONING); */ + } + return 0; +} + +void +do_stone_mon(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + /* may die from the acid if it eats a stone-curing corpse */ + if (munstone(mdef, FALSE)) + goto post_stone; + if (poly_when_stoned(pd)) { + mon_to_stone(mdef); + mhm->damage = 0; + return; + } + if (!resists_ston(mdef)) { + if (g.vis && canseemon(mdef)) + pline("%s turns to stone!", Monnam(mdef)); + monstone(mdef); + post_stone: + if (!DEADMONSTER(mdef)) { + mhm->hitflags = MM_MISS; + mhm->done = TRUE; + return; + } + else if (mdef->mtame && !g.vis) + You(brief_feeling, "peculiarly sad"); + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + mhm->done = TRUE; + return; + } + mhm->damage = (mattk->adtyp == AD_STON ? 0 : 1); +} + +void +mhitm_ad_phys(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + int armpro = magic_negation(mdef); + /* since hero can't be cancelled, only defender's armor applies */ + boolean negated = !(rn2(10) >= 3 * armpro); + + if (pd == &mons[PM_SHADE]) { + mhm->damage = 0; + if (!mhm->specialdmg) + impossible("bad shade attack function flow?"); + } + mhm->damage += mhm->specialdmg; + + if (mattk->aatyp == AT_WEAP) { + /* hmonas() uses known_hitum() to deal physical damage, + then also damageum() for non-AD_PHYS; don't inflict + extra physical damage for unusual damage types */ + mhm->damage = 0; + } else if (mattk->aatyp == AT_KICK + || mattk->aatyp == AT_CLAW + || mattk->aatyp == AT_TUCH + || mattk->aatyp == AT_HUGS) { + if (thick_skinned(pd)) + mhm->damage = (mattk->aatyp == AT_KICK) ? 0 : (mhm->damage + 1) / 2; + /* add ring(s) of increase damage */ + if (u.udaminc > 0) { + /* applies even if damage was 0 */ + mhm->damage += u.udaminc; + } else if (mhm->damage > 0) { + /* ring(s) might be negative; avoid converting + 0 to non-0 or positive to non-positive */ + mhm->damage += u.udaminc; + if (mhm->damage < 1) + mhm->damage = 1; + } + } + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + if (mattk->aatyp == AT_HUGS && !sticks(pd)) { + if (!u.ustuck && rn2(2)) { + if (u_slip_free(magr, mattk)) { + mhm->damage = 0; + } else { + set_ustuck(magr); + pline("%s grabs you!", Monnam(magr)); + } + } else if (u.ustuck == magr) { + exercise(A_STR, FALSE); + You("are being %s.", (magr->data == &mons[PM_ROPE_GOLEM]) + ? "choked" + : "crushed"); + } + } else { /* hand to hand weapon */ + struct obj *otmp = MON_WEP(magr); + + if (mattk->aatyp == AT_WEAP && otmp) { + struct obj *marmg; + int tmp; + + if (otmp->otyp == CORPSE + && touch_petrifies(&mons[otmp->corpsenm])) { + mhm->damage = 1; + pline("%s hits you with the %s corpse.", Monnam(magr), + mons[otmp->corpsenm].mname); + if (!Stoned) { + if (do_stone_u(magr)) { + mhm->hitflags = MM_HIT; + mhm->done = 1; + return; + } + } + } + mhm->damage += dmgval(otmp, mdef); + if ((marmg = which_armor(magr, W_ARMG)) != 0 + && marmg->otyp == GAUNTLETS_OF_POWER) + mhm->damage += rn1(4, 3); /* 3..6 */ + if (mhm->damage <= 0) + mhm->damage = 1; + if (!(otmp->oartifact && artifact_hit(magr, mdef, otmp, + &mhm->damage, g.mhitu_dieroll))) + hitmsg(magr, mattk); + if (!mhm->damage) + return; + if (objects[otmp->otyp].oc_material == SILVER + && Hate_silver) { + pline_The("silver sears your flesh!"); + exercise(A_CON, FALSE); + } + /* this redundancy necessary because you have + to take the damage _before_ being cloned; + need to have at least 2 hp left to split */ + tmp = mhm->damage; + if (u.uac < 0) + tmp -= rnd(-u.uac); + if (tmp < 1) + tmp = 1; + if (u.mh - tmp > 1 + && (objects[otmp->otyp].oc_material == IRON + /* relevant 'metal' objects are scalpel and tsurugi */ + || objects[otmp->otyp].oc_material == METAL) + && (u.umonnum == PM_BLACK_PUDDING + || u.umonnum == PM_BROWN_PUDDING)) { + if (tmp > 1) + exercise(A_STR, FALSE); + /* inflict damage now; we know it can't be fatal */ + u.mh -= tmp; + g.context.botl = 1; + mhm->damage = 0; /* don't inflict more damage below */ + if (cloneu()) + You("divide as %s hits you!", mon_nam(magr)); + } + rustm(&g.youmonst, otmp); + } else if (mattk->aatyp != AT_TUCH || mhm->damage != 0 + || magr != u.ustuck) + hitmsg(magr, mattk); + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + struct obj *mwep = MON_WEP(magr); + + if (mattk->aatyp != AT_WEAP && mattk->aatyp != AT_CLAW) + mwep = 0; + + if (shade_miss(magr, mdef, mwep, FALSE, TRUE)) { + mhm->damage = 0; + } else if (mattk->aatyp == AT_KICK && thick_skinned(pd)) { + /* [no 'kicking boots' check needed; monsters with kick attacks + can't wear boots and monsters that wear boots don't kick] */ + mhm->damage = 0; + } else if (mwep) { /* non-Null 'mwep' implies AT_WEAP || AT_CLAW */ + struct obj *marmg; + + if (mwep->otyp == CORPSE + && touch_petrifies(&mons[mwep->corpsenm])) { + do_stone_mon(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } + + mhm->damage += dmgval(mwep, mdef); + if ((marmg = which_armor(magr, W_ARMG)) != 0 + && marmg->otyp == GAUNTLETS_OF_POWER) + mhm->damage += rn1(4, 3); /* 3..6 */ + if (mhm->damage < 1) /* is this necessary? mhitu.c has it... */ + mhm->damage = 1; + if (mwep->oartifact) { + /* when magr's weapon is an artifact, caller suppressed its + usual 'hit' message in case artifact_hit() delivers one; + now we'll know and might need to deliver skipped message + (note: if there's no message there'll be no auxilliary + damage so the message here isn't coming too late) */ + if (!artifact_hit(magr, mdef, mwep, &mhm->damage, mhm->dieroll)) { + if (g.vis) + pline("%s hits %s.", Monnam(magr), + mon_nam_too(mdef, magr)); + } + /* artifact_hit updates 'tmp' but doesn't inflict any + damage; however, it might cause carried items to be + destroyed and they might do so */ + if (DEADMONSTER(mdef)) { + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + mhm->done = TRUE; + return; + } + } + if (mhm->damage) + rustm(mdef, mwep); + } else if (pa == &mons[PM_PURPLE_WORM] && pd == &mons[PM_SHRIEKER]) { + /* hack to enhance mm_aggression(); we don't want purple + worm's bite attack to kill a shrieker because then it + won't swallow the corpse; but if the target survives, + the subsequent engulf attack should accomplish that */ + if (mhm->damage >= mdef->mhp && mdef->mhp > 1) + mhm->damage = mdef->mhp - 1; + } + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3396,6 +3648,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ mhm.damage = d((int) mattk->damn, (int) mattk->damd); mhm.hitflags = MM_MISS; mhm.permdmg = 0; + mhm.specialdmg = specialdmg; armpro = magic_negation(mdef); /* since hero can't be cancelled, only defender's armor applies */ @@ -3426,36 +3679,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ case AD_HEAL: /* likewise */ case AD_PHYS: physical: - if (pd == &mons[PM_SHADE]) { - mhm.damage = 0; - if (!specialdmg) - impossible("bad shade attack function flow?"); - } - mhm.damage += specialdmg; - - if (mattk->aatyp == AT_WEAP) { - /* hmonas() uses known_hitum() to deal physical damage, - then also damageum() for non-AD_PHYS; don't inflict - extra physical damage for unusual damage types */ - mhm.damage = 0; - } else if (mattk->aatyp == AT_KICK - || mattk->aatyp == AT_CLAW - || mattk->aatyp == AT_TUCH - || mattk->aatyp == AT_HUGS) { - if (thick_skinned(pd)) - mhm.damage = (mattk->aatyp == AT_KICK) ? 0 : (mhm.damage + 1) / 2; - /* add ring(s) of increase damage */ - if (u.udaminc > 0) { - /* applies even if damage was 0 */ - mhm.damage += u.udaminc; - } else if (mhm.damage > 0) { - /* ring(s) might be negative; avoid converting - 0 to non-0 or positive to non-positive */ - mhm.damage += u.udaminc; - if (mhm.damage < 1) - mhm.damage = 1; - } - } + mhitm_ad_phys(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_FIRE: mhitm_ad_fire(&g.youmonst, mattk, mdef, &mhm); From a6a676f720b979356e7bb7b6d46a995eb2c8a752 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 10:44:15 +0200 Subject: [PATCH 514/708] Unify ad_ston --- include/extern.h | 1 + src/mhitm.c | 4 +--- src/mhitu.c | 20 ++++--------------- src/uhitm.c | 50 +++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/include/extern.h b/include/extern.h index 59982f230..4de281ec0 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2786,6 +2786,7 @@ E void FDECL(mhitm_ad_pest, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_deth, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_halu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_phys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index d7f9a6dbe..236e4d83a 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1007,9 +1007,7 @@ int dieroll; return mhm.hitflags; break; case AD_STON: - if (magr->mcan) - break; - do_stone_mon(magr, mattk, mdef, &mhm); + mhitm_ad_ston(magr, mattk, mdef, &mhm); if (mhm.done) return mhm.hitflags; break; diff --git a/src/mhitu.c b/src/mhitu.c index 5a3e69e42..a08ce6ce7 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1113,22 +1113,10 @@ register struct attack *mattk; } break; } - case AD_STON: /* cockatrice */ - hitmsg(mtmp, mattk); - if (!rn2(3)) { - if (mtmp->mcan) { - if (!Deaf) - You_hear("a cough from %s!", mon_nam(mtmp)); - } else { - if (!Deaf) - You_hear("%s hissing!", s_suffix(mon_nam(mtmp))); - if (!rn2(10) - || (flags.moonphase == NEW_MOON && !have_lizard())) { - if (do_stone_u(mtmp)) - return MM_HIT; - } - } - } + case AD_STON: + mhitm_ad_ston(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_STCK: mhitm_ad_stck(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index b377a5f35..e0d1d30d0 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3600,6 +3600,50 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_ston(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (!munstone(mdef, TRUE)) + minstapetrify(mdef, TRUE); + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (!rn2(3)) { + if (magr->mcan) { + if (!Deaf) + You_hear("a cough from %s!", mon_nam(magr)); + } else { + if (!Deaf) + You_hear("%s hissing!", s_suffix(mon_nam(magr))); + if (!rn2(10) + || (flags.moonphase == NEW_MOON && !have_lizard())) { + if (do_stone_u(magr)) { + mhm->hitflags = MM_HIT; + mhm->done = TRUE; + return; + } + } + } + } + } else { + /* mhitm */ + if (magr->mcan) + return; + do_stone_mon(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3704,9 +3748,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_STON: - if (!munstone(mdef, TRUE)) - minstapetrify(mdef, TRUE); - mhm.damage = 0; + mhitm_ad_ston(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SSEX: case AD_SEDU: From 4901c8027c88cd94f0e10f3747dc4424a16640c3 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 10:51:19 +0200 Subject: [PATCH 515/708] Unify ad_were --- include/extern.h | 1 + src/mhitm.c | 4 ++++ src/mhitu.c | 11 +++-------- src/uhitm.c | 42 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/include/extern.h b/include/extern.h index 4de281ec0..70d8298d9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2787,6 +2787,7 @@ E void FDECL(mhitm_ad_deth, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_halu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_phys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index 236e4d83a..b743a2fe3 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -964,6 +964,10 @@ int dieroll; } goto physical; case AD_WERE: + mhitm_ad_were(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_HEAL: case AD_PHYS: physical: diff --git a/src/mhitu.c b/src/mhitu.c index a08ce6ce7..8000454e3 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1129,14 +1129,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_WERE: - hitmsg(mtmp, mattk); - if (uncancelled && !rn2(4) && u.ulycn == NON_PM - && !Protection_from_shape_changers && !defends(AD_WERE, uwep)) { - You_feel("feverish."); - exercise(A_CON, FALSE); - set_ulycn(monsndx(mdat)); - retouch_equipment(2); - } + mhitm_ad_were(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SGLD: mhitm_ad_sgld(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index e0d1d30d0..d4281ac2f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3644,6 +3644,42 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_were(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhitm_ad_phys(&g.youmonst, mattk, mdef, mhm); + if (mhm->done) + return; + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + hitmsg(magr, mattk); + if (uncancelled && !rn2(4) && u.ulycn == NON_PM + && !Protection_from_shape_changers && !defends(AD_WERE, uwep)) { + You_feel("feverish."); + exercise(A_CON, FALSE); + set_ulycn(monsndx(pa)); + retouch_equipment(2); + } + } else { + /* mhitm */ + mhitm_ad_phys(&g.youmonst, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3719,7 +3755,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } #endif goto physical; - case AD_WERE: /* no special effect on monsters */ + case AD_WERE: + mhitm_ad_were(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_HEAL: /* likewise */ case AD_PHYS: physical: From 12ee14493663c2d4d475c6e90335332cdd9f74d3 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 10:58:51 +0200 Subject: [PATCH 516/708] Unify ad_heal --- include/extern.h | 1 + src/mhitm.c | 4 ++ src/mhitu.c | 63 ++--------------------------- src/uhitm.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 106 insertions(+), 63 deletions(-) diff --git a/include/extern.h b/include/extern.h index 70d8298d9..94f3d8a0d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2788,6 +2788,7 @@ E void FDECL(mhitm_ad_halu, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_phys, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index b743a2fe3..e638a97b0 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -969,6 +969,10 @@ int dieroll; return mhm.hitflags; break; case AD_HEAL: + mhitm_ad_heal(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_PHYS: physical: mhitm_ad_phys(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 8000454e3..1e630dfd6 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1229,66 +1229,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_HEAL: - /* a cancelled nurse is just an ordinary monster, - * nurses don't heal those that cause petrification */ - if (mtmp->mcan || (Upolyd && touch_petrifies(g.youmonst.data))) { - hitmsg(mtmp, mattk); - break; - } - /* weapon check should match the one in sounds.c for MS_NURSE */ - if (!(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) - && !uarmu && !uarm && !uarmc - && !uarms && !uarmg && !uarmf && !uarmh) { - boolean goaway = FALSE; - - pline("%s hits! (I hope you don't mind.)", Monnam(mtmp)); - if (Upolyd) { - u.mh += rnd(7); - if (!rn2(7)) { - /* no upper limit necessary; effect is temporary */ - u.mhmax++; - if (!rn2(13)) - goaway = TRUE; - } - if (u.mh > u.mhmax) - u.mh = u.mhmax; - } else { - u.uhp += rnd(7); - if (!rn2(7)) { - /* hard upper limit via nurse care: 25 * ulevel */ - if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10)) - u.uhpmax++; - if (!rn2(13)) - goaway = TRUE; - } - if (u.uhp > u.uhpmax) - u.uhp = u.uhpmax; - } - if (!rn2(3)) - exercise(A_STR, TRUE); - if (!rn2(3)) - exercise(A_CON, TRUE); - if (Sick) - make_sick(0L, (char *) 0, FALSE, SICK_ALL); - g.context.botl = 1; - if (goaway) { - mongone(mtmp); - return 2; - } else if (!rn2(33)) { - if (!tele_restrict(mtmp)) - (void) rloc(mtmp, TRUE); - monflee(mtmp, d(3, 6), TRUE, FALSE); - return 3; - } - mhm.damage = 0; - } else { - if (Role_if(PM_HEALER)) { - if (!Deaf && !(g.moves % 5)) - verbalize("Doc, I can't help you unless you cooperate."); - mhm.damage = 0; - } else - hitmsg(mtmp, mattk); - } + mhitm_ad_heal(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_CURS: mhitm_ad_curs(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index d4281ac2f..56e6bc2c5 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3656,7 +3656,7 @@ struct mhitm_data *mhm; if (magr == &g.youmonst) { /* uhitm */ - mhitm_ad_phys(&g.youmonst, mattk, mdef, mhm); + mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; } else if (mdef == &g.youmonst) { @@ -3674,7 +3674,98 @@ struct mhitm_data *mhm; } } else { /* mhitm */ - mhitm_ad_phys(&g.youmonst, mattk, mdef, mhm); + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + +void +mhitm_ad_heal(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + /* a cancelled nurse is just an ordinary monster, + * nurses don't heal those that cause petrification */ + if (magr->mcan || (Upolyd && touch_petrifies(pd))) { + hitmsg(magr, mattk); + return; + } + /* weapon check should match the one in sounds.c for MS_NURSE */ + if (!(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))) + && !uarmu && !uarm && !uarmc + && !uarms && !uarmg && !uarmf && !uarmh) { + boolean goaway = FALSE; + + pline("%s hits! (I hope you don't mind.)", Monnam(magr)); + if (Upolyd) { + u.mh += rnd(7); + if (!rn2(7)) { + /* no upper limit necessary; effect is temporary */ + u.mhmax++; + if (!rn2(13)) + goaway = TRUE; + } + if (u.mh > u.mhmax) + u.mh = u.mhmax; + } else { + u.uhp += rnd(7); + if (!rn2(7)) { + /* hard upper limit via nurse care: 25 * ulevel */ + if (u.uhpmax < 5 * u.ulevel + d(2 * u.ulevel, 10)) + u.uhpmax++; + if (!rn2(13)) + goaway = TRUE; + } + if (u.uhp > u.uhpmax) + u.uhp = u.uhpmax; + } + if (!rn2(3)) + exercise(A_STR, TRUE); + if (!rn2(3)) + exercise(A_CON, TRUE); + if (Sick) + make_sick(0L, (char *) 0, FALSE, SICK_ALL); + g.context.botl = 1; + if (goaway) { + mongone(magr); + mhm->done = TRUE; + mhm->hitflags = MM_DEF_DIED; /* return 2??? */ + return; + } else if (!rn2(33)) { + if (!tele_restrict(magr)) + (void) rloc(magr, TRUE); + monflee(magr, d(3, 6), TRUE, FALSE); + mhm->done = TRUE; + mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + return; + } + mhm->damage = 0; + } else { + if (Role_if(PM_HEALER)) { + if (!Deaf && !(g.moves % 5)) + verbalize("Doc, I can't help you unless you cooperate."); + mhm->damage = 0; + } else + hitmsg(magr, mattk); + } + } else { + /* mhitm */ + mhitm_ad_phys(magr, mattk, mdef, mhm); if (mhm->done) return; } @@ -3760,7 +3851,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */ if (mhm.done) return mhm.hitflags; break; - case AD_HEAL: /* likewise */ + case AD_HEAL: + mhitm_ad_heal(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_PHYS: physical: mhitm_ad_phys(&g.youmonst, mattk, mdef, &mhm); From 337e7da049718cae352f3d5c83f4e83de79da926 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 11:05:14 +0200 Subject: [PATCH 517/708] Unify ad_stun --- include/extern.h | 1 + src/mhitm.c | 11 ++++------- src/mhitu.c | 8 +++----- src/uhitm.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 51 insertions(+), 17 deletions(-) diff --git a/include/extern.h b/include/extern.h index 94f3d8a0d..f4d5c0fcf 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2789,6 +2789,7 @@ E void FDECL(mhitm_ad_phys, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_stun, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index e638a97b0..decb034b8 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -950,13 +950,10 @@ int dieroll; } break; case AD_STUN: - if (magr->mcan) - break; - if (canseemon(mdef)) - pline("%s %s for a moment.", Monnam(mdef), - makeplural(stagger(pd, "stagger"))); - mdef->mstun = 1; - goto physical; + mhitm_ad_stun(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_LEGS: if (magr->mcan) { mhm.damage = 0; diff --git a/src/mhitu.c b/src/mhitu.c index 1e630dfd6..a67f78e38 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1239,11 +1239,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_STUN: - hitmsg(mtmp, mattk); - if (!mtmp->mcan && !rn2(4)) { - make_stunned((HStun & TIMEOUT) + (long) mhm.damage, TRUE); - mhm.damage /= 2; - } + mhitm_ad_stun(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_ACID: mhitm_ad_acid(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 56e6bc2c5..7824e6ac2 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3771,6 +3771,45 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_stun(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + if (!Blind) + pline("%s %s for a moment.", Monnam(mdef), + makeplural(stagger(pd, "stagger"))); + mdef->mstun = 1; + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (!magr->mcan && !rn2(4)) { + make_stunned((HStun & TIMEOUT) + (long) mhm->damage, TRUE); + mhm->damage /= 2; + } + } else { + /* mhitm */ + if (magr->mcan) + return; + if (canseemon(mdef)) + pline("%s %s for a moment.", Monnam(mdef), + makeplural(stagger(pd, "stagger"))); + mdef->mstun = 1; + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3833,11 +3872,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ } switch (mattk->adtyp) { case AD_STUN: - if (!Blind) - pline("%s %s for a moment.", Monnam(mdef), - makeplural(stagger(pd, "stagger"))); - mdef->mstun = 1; - goto physical; + mhitm_ad_stun(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_LEGS: #if 0 if (u.ucancelled) { From e777bd9670c07bb0f0f5512378de53db3c15593a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 11:10:54 +0200 Subject: [PATCH 518/708] Unify ad_legs --- include/extern.h | 1 + src/mhitm.c | 9 +++-- src/mhitu.c | 43 +++--------------------- src/uhitm.c | 85 ++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 87 insertions(+), 51 deletions(-) diff --git a/include/extern.h b/include/extern.h index f4d5c0fcf..b72d73296 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2790,6 +2790,7 @@ E void FDECL(mhitm_ad_ston, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_stun, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_legs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index decb034b8..b892e56c3 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -955,11 +955,10 @@ int dieroll; return mhm.hitflags; break; case AD_LEGS: - if (magr->mcan) { - mhm.damage = 0; - break; - } - goto physical; + mhitm_ad_legs(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_WERE: mhitm_ad_were(magr, mattk, mdef, &mhm); if (mhm.done) diff --git a/src/mhitu.c b/src/mhitu.c index a67f78e38..030c98ee9 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1073,46 +1073,11 @@ register struct attack *mattk; if (mhm.done) return mhm.hitflags; break; - case AD_LEGS: { - long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; - const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", - *Monst_name = Monnam(mtmp), *leg = body_part(LEG); - - /* This case is too obvious to ignore, but Nethack is not in - * general very good at considering height--most short monsters - * still _can_ attack you when you're flying or mounted. - */ - if ((u.usteed || Levitation || Flying) && !is_flyer(mtmp->data)) { - pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg); - mhm.damage = 0; - } else if (mtmp->mcan) { - pline("%s nuzzles against your %s %s!", Monnam(mtmp), - sidestr, leg); - mhm.damage = 0; - } else { - if (uarmf) { - if (rn2(2) && (uarmf->otyp == LOW_BOOTS - || uarmf->otyp == IRON_SHOES)) { - pline("%s pricks the exposed part of your %s %s!", - Monst_name, sidestr, leg); - } else if (!rn2(5)) { - pline("%s pricks through your %s boot!", Monst_name, - sidestr); - } else { - pline("%s scratches your %s boot!", Monst_name, - sidestr); - mhm.damage = 0; - break; - } - } else - pline("%s pricks your %s %s!", Monst_name, sidestr, leg); - - set_wounded_legs(side, rnd(60 - ACURR(A_DEX))); - exercise(A_STR, FALSE); - exercise(A_DEX, FALSE); - } + case AD_LEGS: + mhitm_ad_legs(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; - } case AD_STON: mhitm_ad_ston(mtmp, mattk, &g.youmonst, &mhm); if (mhm.done) diff --git a/src/uhitm.c b/src/uhitm.c index 7824e6ac2..9c33c959a 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3810,6 +3810,80 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_legs(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ +#if 0 + if (u.ucancelled) { + mhm->damage = 0; + return; + } +#endif + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + + long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; + const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", + *Monst_name = Monnam(magr), *leg = body_part(LEG); + + /* This case is too obvious to ignore, but Nethack is not in + * general very good at considering height--most short monsters + * still _can_ attack you when you're flying or mounted. + */ + if ((u.usteed || Levitation || Flying) && !is_flyer(magr->data)) { + pline("%s tries to reach your %s %s!", Monst_name, sidestr, leg); + mhm->damage = 0; + } else if (magr->mcan) { + pline("%s nuzzles against your %s %s!", Monnam(magr), + sidestr, leg); + mhm->damage = 0; + } else { + if (uarmf) { + if (rn2(2) && (uarmf->otyp == LOW_BOOTS + || uarmf->otyp == IRON_SHOES)) { + pline("%s pricks the exposed part of your %s %s!", + Monst_name, sidestr, leg); + } else if (!rn2(5)) { + pline("%s pricks through your %s boot!", Monst_name, + sidestr); + } else { + pline("%s scratches your %s boot!", Monst_name, + sidestr); + mhm->damage = 0; + return; + } + } else + pline("%s pricks your %s %s!", Monst_name, sidestr, leg); + + set_wounded_legs(side, rnd(60 - ACURR(A_DEX))); + exercise(A_STR, FALSE); + exercise(A_DEX, FALSE); + } + } else { + /* mhitm */ + if (magr->mcan) { + mhm->damage = 0; + return; + } + mhitm_ad_phys(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE @@ -3877,13 +3951,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_LEGS: -#if 0 - if (u.ucancelled) { - mhm.damage = 0; - break; - } -#endif - goto physical; + mhitm_ad_legs(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_WERE: mhitm_ad_were(&g.youmonst, mattk, mdef, &mhm); if (mhm.done) From d4625266a77bd61f71882d312eb25c9fb08999fb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 11:12:43 +0200 Subject: [PATCH 519/708] Remove unused goto label --- src/mhitm.c | 1 - src/uhitm.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/mhitm.c b/src/mhitm.c index b892e56c3..9ac86fee3 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -970,7 +970,6 @@ int dieroll; return mhm.hitflags; break; case AD_PHYS: - physical: mhitm_ad_phys(magr, mattk, mdef, &mhm); if (mhm.done) return mhm.hitflags; diff --git a/src/uhitm.c b/src/uhitm.c index 9c33c959a..4843c747f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3966,7 +3966,6 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_PHYS: - physical: mhitm_ad_phys(&g.youmonst, mattk, mdef, &mhm); if (mhm.done) return mhm.hitflags; From d679d3a029b8c009b216354004f8bfdbe523d519 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 11:24:52 +0200 Subject: [PATCH 520/708] Unify ad_dgst --- include/extern.h | 1 + src/mhitm.c | 51 ++------------------------------ src/uhitm.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 48 deletions(-) diff --git a/include/extern.h b/include/extern.h index b72d73296..97fdb46e3 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2791,6 +2791,7 @@ E void FDECL(mhitm_ad_were, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_stun, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_legs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_dgst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index 9ac86fee3..fea621491 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -900,54 +900,9 @@ int dieroll; switch (mattk->adtyp) { case AD_DGST: - /* eating a Rider or its corpse is fatal */ - if (is_rider(pd)) { - if (g.vis && canseemon(magr)) - pline("%s %s!", Monnam(magr), - (pd == &mons[PM_FAMINE]) - ? "belches feebly, shrivels up and dies" - : (pd == &mons[PM_PESTILENCE]) - ? "coughs spasmodically and collapses" - : "vomits violently and drops dead"); - mondied(magr); - if (!DEADMONSTER(magr)) - return 0; /* lifesaved */ - else if (magr->mtame && !g.vis) - You(brief_feeling, "queasy"); - return MM_AGR_DIED; - } - if (flags.verbose && !Deaf) - verbalize("Burrrrp!"); - mhm.damage = mdef->mhp; - /* Use up amulet of life saving */ - if ((obj = mlifesaver(mdef)) != 0) - m_useup(mdef, obj); - - /* Is a corpse for nutrition possible? It may kill magr */ - if (!corpse_chance(mdef, magr, TRUE) || DEADMONSTER(magr)) - break; - - /* Pets get nutrition from swallowing monster whole. - * No nutrition from G_NOCORPSE monster, eg, undead. - * DGST monsters don't die from undead corpses - */ - num = monsndx(pd); - if (magr->mtame && !magr->isminion - && !(g.mvitals[num].mvflags & G_NOCORPSE)) { - struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE); - int nutrit; - - set_corpsenm(virtualcorpse, num); - nutrit = dog_nutrition(magr, virtualcorpse); - dealloc_obj(virtualcorpse); - - /* only 50% nutrition, 25% of normal eating time */ - if (magr->meating > 1) - magr->meating = (magr->meating + 3) / 4; - if (nutrit > 1) - nutrit /= 2; - EDOG(magr)->hungrytime += nutrit; - } + mhitm_ad_dgst(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_STUN: mhitm_ad_stun(magr, mattk, mdef, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 4843c747f..57bced509 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3884,6 +3884,81 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_dgst(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + mhm->damage = 0; + } else { + /* mhitm */ + int num; + struct obj *obj; + + /* eating a Rider or its corpse is fatal */ + if (is_rider(pd)) { + if (g.vis && canseemon(magr)) + pline("%s %s!", Monnam(magr), + (pd == &mons[PM_FAMINE]) + ? "belches feebly, shrivels up and dies" + : (pd == &mons[PM_PESTILENCE]) + ? "coughs spasmodically and collapses" + : "vomits violently and drops dead"); + mondied(magr); + if (!DEADMONSTER(magr)) { + mhm->hitflags = MM_MISS; /* lifesaved */ + mhm->done = TRUE; + return; + } else if (magr->mtame && !g.vis) + You(brief_feeling, "queasy"); + mhm->hitflags = MM_AGR_DIED; + mhm->done = TRUE; + return; + } + if (flags.verbose && !Deaf) + verbalize("Burrrrp!"); + mhm->damage = mdef->mhp; + /* Use up amulet of life saving */ + if ((obj = mlifesaver(mdef)) != 0) + m_useup(mdef, obj); + + /* Is a corpse for nutrition possible? It may kill magr */ + if (!corpse_chance(mdef, magr, TRUE) || DEADMONSTER(magr)) + return; + + /* Pets get nutrition from swallowing monster whole. + * No nutrition from G_NOCORPSE monster, eg, undead. + * DGST monsters don't die from undead corpses + */ + num = monsndx(pd); + if (magr->mtame && !magr->isminion + && !(g.mvitals[num].mvflags & G_NOCORPSE)) { + struct obj *virtualcorpse = mksobj(CORPSE, FALSE, FALSE); + int nutrit; + + set_corpsenm(virtualcorpse, num); + nutrit = dog_nutrition(magr, virtualcorpse); + dealloc_obj(virtualcorpse); + + /* only 50% nutrition, 25% of normal eating time */ + if (magr->meating > 1) + magr->meating = (magr->meating + 3) / 4; + if (nutrit > 1) + nutrit /= 2; + EDOG(magr)->hungrytime += nutrit; + } + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE From 4118a7ea44cb927df983674bd24374c7cc07b0bf Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 11:28:41 +0200 Subject: [PATCH 521/708] Unify ad_samu --- include/extern.h | 1 + src/mhitu.c | 10 +++------- src/uhitm.c | 27 +++++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/include/extern.h b/include/extern.h index 97fdb46e3..914265912 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2792,6 +2792,7 @@ E void FDECL(mhitm_ad_heal, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_stun, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_legs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dgst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_samu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitu.c b/src/mhitu.c index 030c98ee9..d061dd9b1 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1165,14 +1165,10 @@ register struct attack *mattk; break; case AD_SAMU: - hitmsg(mtmp, mattk); - /* when the Wizard or quest nemesis hits, there's a 1/20 chance - to steal a quest artifact (any, not just the one for the hero's - own role) or the Amulet or one of the invocation tools */ - if (!rn2(20)) - stealamulet(mtmp); + mhitm_ad_samu(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; - case AD_TLPT: mhitm_ad_tlpt(mtmp, mattk, &g.youmonst, &mhm); if (mhm.done) diff --git a/src/uhitm.c b/src/uhitm.c index 57bced509..59362b6bb 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3959,6 +3959,33 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_samu(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + /* when the Wizard or quest nemesis hits, there's a 1/20 chance + to steal a quest artifact (any, not just the one for the hero's + own role) or the Amulet or one of the invocation tools */ + if (!rn2(20)) + stealamulet(magr); + } else { + /* mhitm */ + mhm->damage = 0; + } +} + + /* Template for monster hits monster for AD_FOO. - replace "break" with return - replace "return" with mhm->done = TRUE From 376593dad5eddf7aa25217e19238ce7a71d09497 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 11:41:35 +0200 Subject: [PATCH 522/708] Unify ad_dise --- include/extern.h | 1 + src/mhitu.c | 6 +++--- src/uhitm.c | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/include/extern.h b/include/extern.h index 914265912..95cf72f08 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2793,6 +2793,7 @@ E void FDECL(mhitm_ad_stun, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_legs, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dgst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_samu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_dise, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitu.c b/src/mhitu.c index d061dd9b1..fee3a3230 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1022,9 +1022,9 @@ register struct attack *mattk; return mhm.hitflags; break; case AD_DISE: - hitmsg(mtmp, mattk); - if (!diseasemu(mdat)) - mhm.damage = 0; + mhitm_ad_dise(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_FIRE: mhitm_ad_fire(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 59362b6bb..41c97e7c4 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -3985,6 +3985,30 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_dise(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + hitmsg(magr, mattk); + if (!diseasemu(pa)) + mhm->damage = 0; + } else { + /* mhitm */ + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return From 1696019361f88682ba4300b2389896f219c74cbe Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 15:56:32 +0200 Subject: [PATCH 523/708] Unify ad_sedu --- include/extern.h | 1 + src/mhitm.c | 55 +----------------- src/mhitu.c | 52 +---------------- src/uhitm.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 151 insertions(+), 104 deletions(-) diff --git a/include/extern.h b/include/extern.h index 95cf72f08..13122a575 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2794,6 +2794,7 @@ E void FDECL(mhitm_ad_legs, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_dgst, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_samu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dise, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_sedu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index fea621491..fab8bbba0 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1022,58 +1022,9 @@ int dieroll; case AD_SSEX: case AD_SITM: /* for now these are the same */ case AD_SEDU: - if (magr->mcan) - break; - /* find an object to steal, non-cursed if magr is tame */ - for (obj = mdef->minvent; obj; obj = obj->nobj) - if (!magr->mtame || !obj->cursed) - break; - - if (obj) { - char onambuf[BUFSZ], mdefnambuf[BUFSZ]; - - /* make a special x_monnam() call that never omits - the saddle, and save it for later messages */ - Strcpy(mdefnambuf, - x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE)); - - if (u.usteed == mdef && obj == which_armor(mdef, W_SADDLE)) - /* "You can no longer ride ." */ - dismount_steed(DISMOUNT_POLY); - obj_extract_self(obj); - if (obj->owornmask) { - mdef->misc_worn_check &= ~obj->owornmask; - if (obj->owornmask & W_WEP) - mwepgone(mdef); - obj->owornmask = 0L; - update_mon_intrinsics(mdef, obj, FALSE, FALSE); - /* give monster a chance to wear other equipment on its next - move instead of waiting until it picks something up */ - mdef->misc_worn_check |= I_SPECIAL; - } - /* add_to_minv() might free 'obj' [if it merges] */ - if (g.vis) - Strcpy(onambuf, doname(obj)); - (void) add_to_minv(magr, obj); - if (g.vis && canseemon(mdef)) { - Strcpy(buf, Monnam(magr)); - pline("%s steals %s from %s!", buf, onambuf, mdefnambuf); - } - possibly_unwield(mdef, FALSE); - mdef->mstrategy &= ~STRAT_WAITFORU; - mselftouch(mdef, (const char *) 0, FALSE); - if (DEADMONSTER(mdef)) - return (MM_DEF_DIED - | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); - if (pa->mlet == S_NYMPH && !tele_restrict(magr)) { - boolean couldspot = canspotmon(magr); - - (void) rloc(magr, TRUE); - if (g.vis && couldspot && !canspotmon(magr)) - pline("%s suddenly disappears!", buf); - } - } - mhm.damage = 0; + mhitm_ad_sedu(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_DREN: mhitm_ad_dren(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index fee3a3230..31d903541 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1114,56 +1114,10 @@ register struct attack *mattk; /*FALLTHRU*/ case AD_SITM: /* for now these are the same */ case AD_SEDU: - if (is_animal(mtmp->data)) { - hitmsg(mtmp, mattk); - if (mtmp->mcan) - break; - /* Continue below */ - } else if (dmgtype(g.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(g.youmonst.data, AD_SSEX)) { - pline("%s %s.", Monnam(mtmp), - Deaf ? "says something but you can't hear it" - : mtmp->minvent - ? "brags about the goods some dungeon explorer provided" - : "makes some remarks about how difficult theft is lately"); - if (!tele_restrict(mtmp)) - (void) rloc(mtmp, TRUE); - return 3; - } else if (mtmp->mcan) { - if (!Blind) - pline("%s tries to %s you, but you seem %s.", - Adjmonnam(mtmp, "plain"), - flags.female ? "charm" : "seduce", - flags.female ? "unaffected" : "uninterested"); - if (rn2(3)) { - if (!tele_restrict(mtmp)) - (void) rloc(mtmp, TRUE); - return 3; - } - break; - } - buf[0] = '\0'; - switch (steal(mtmp, buf)) { - case -1: - return 2; - case 0: - break; - default: - if (!is_animal(mtmp->data) && !tele_restrict(mtmp)) - (void) rloc(mtmp, TRUE); - if (is_animal(mtmp->data) && *buf) { - if (canseemon(mtmp)) - pline("%s tries to %s away with %s.", Monnam(mtmp), - locomotion(mtmp->data, "run"), buf); - } - monflee(mtmp, 0, FALSE, FALSE); - return 3; - } + mhitm_ad_sedu(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; break; - case AD_SAMU: mhitm_ad_samu(mtmp, mattk, &g.youmonst, &mhm); if (mhm.done) diff --git a/src/uhitm.c b/src/uhitm.c index 41c97e7c4..211316e54 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4009,6 +4009,146 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_sedu(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + struct permonst *pa = magr->data; + struct permonst *pd = mdef->data; + + if (magr == &g.youmonst) { + /* uhitm */ + steal_it(mdef, mattk); + mhm->damage = 0; + } else if (mdef == &g.youmonst) { + /* mhitu */ + int armpro = magic_negation(mdef); + boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); + char buf[BUFSZ]; + + if (is_animal(magr->data)) { + hitmsg(magr, mattk); + if (magr->mcan) + return; + /* Continue below */ + } else if (dmgtype(g.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(g.youmonst.data, AD_SSEX)) { + pline("%s %s.", Monnam(magr), + Deaf ? "says something but you can't hear it" + : magr->minvent + ? "brags about the goods some dungeon explorer provided" + : "makes some remarks about how difficult theft is lately"); + if (!tele_restrict(magr)) + (void) rloc(magr, TRUE); + mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->done = TRUE; + return; + } else if (magr->mcan) { + if (!Blind) + pline("%s tries to %s you, but you seem %s.", + Adjmonnam(magr, "plain"), + flags.female ? "charm" : "seduce", + flags.female ? "unaffected" : "uninterested"); + if (rn2(3)) { + if (!tele_restrict(magr)) + (void) rloc(magr, TRUE); + mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->done = TRUE; + return; + } + return; + } + buf[0] = '\0'; + switch (steal(magr, buf)) { + case -1: + mhm->hitflags = MM_DEF_DIED; /* return 2??? */ + mhm->done = TRUE; + return; + case 0: + return; + default: + if (!is_animal(magr->data) && !tele_restrict(magr)) + (void) rloc(magr, TRUE); + if (is_animal(magr->data) && *buf) { + if (canseemon(magr)) + pline("%s tries to %s away with %s.", Monnam(magr), + locomotion(magr->data, "run"), buf); + } + monflee(magr, 0, FALSE, FALSE); + mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->done = TRUE; + return; + } + } else { + /* mhitm */ + int armpro = magic_negation(mdef); + boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); + struct obj *obj; + + if (magr->mcan) + return; + /* find an object to steal, non-cursed if magr is tame */ + for (obj = mdef->minvent; obj; obj = obj->nobj) + if (!magr->mtame || !obj->cursed) + return; + + if (obj) { + char buf[BUFSZ]; + char onambuf[BUFSZ], mdefnambuf[BUFSZ]; + + /* make a special x_monnam() call that never omits + the saddle, and save it for later messages */ + Strcpy(mdefnambuf, + x_monnam(mdef, ARTICLE_THE, (char *) 0, 0, FALSE)); + + if (u.usteed == mdef && obj == which_armor(mdef, W_SADDLE)) + /* "You can no longer ride ." */ + dismount_steed(DISMOUNT_POLY); + obj_extract_self(obj); + if (obj->owornmask) { + mdef->misc_worn_check &= ~obj->owornmask; + if (obj->owornmask & W_WEP) + mwepgone(mdef); + obj->owornmask = 0L; + update_mon_intrinsics(mdef, obj, FALSE, FALSE); + /* give monster a chance to wear other equipment on its next + move instead of waiting until it picks something up */ + mdef->misc_worn_check |= I_SPECIAL; + } + /* add_to_minv() might free 'obj' [if it merges] */ + if (g.vis) + Strcpy(onambuf, doname(obj)); + (void) add_to_minv(magr, obj); + if (g.vis && canseemon(mdef)) { + Strcpy(buf, Monnam(magr)); + pline("%s steals %s from %s!", buf, onambuf, mdefnambuf); + } + possibly_unwield(mdef, FALSE); + mdef->mstrategy &= ~STRAT_WAITFORU; + mselftouch(mdef, (const char *) 0, FALSE); + if (DEADMONSTER(mdef)) { + mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + mhm->done = TRUE; + return; + } + if (pa->mlet == S_NYMPH && !tele_restrict(magr)) { + boolean couldspot = canspotmon(magr); + + (void) rloc(magr, TRUE); + if (g.vis && couldspot && !canspotmon(magr)) + pline("%s suddenly disappears!", buf); + } + } + mhm->damage = 0; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -4122,10 +4262,11 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_SSEX: - case AD_SEDU: case AD_SITM: - steal_it(mdef, mattk); - mhm.damage = 0; + case AD_SEDU: + mhitm_ad_sedu(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; break; case AD_SGLD: mhitm_ad_sgld(&g.youmonst, mattk, mdef, &mhm); From 88e333a3a880e5f220621ee52e500e03669b67f0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 16:05:25 +0200 Subject: [PATCH 524/708] Unify ad_ssex --- include/extern.h | 1 + src/mhitm.c | 4 ++++ src/mhitu.c | 11 ++++------- src/uhitm.c | 38 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/include/extern.h b/include/extern.h index 13122a575..8b4bd149c 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2795,6 +2795,7 @@ E void FDECL(mhitm_ad_dgst, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_samu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_dise, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_sedu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_ad_ssex, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index fab8bbba0..0cb813803 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -1020,6 +1020,10 @@ int dieroll; return mhm.hitflags; break; case AD_SSEX: + mhitm_ad_ssex(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_SITM: /* for now these are the same */ case AD_SEDU: mhitm_ad_sedu(magr, mattk, mdef, &mhm); diff --git a/src/mhitu.c b/src/mhitu.c index 31d903541..3fce4da9e 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1105,13 +1105,10 @@ register struct attack *mattk; break; case AD_SSEX: - if (SYSOPT_SEDUCE) { - if (could_seduce(mtmp, &g.youmonst, mattk) == 1 && !mtmp->mcan) - if (doseduce(mtmp)) - return 3; - break; - } - /*FALLTHRU*/ + mhitm_ad_ssex(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_SITM: /* for now these are the same */ case AD_SEDU: mhitm_ad_sedu(mtmp, mattk, &g.youmonst, &mhm); diff --git a/src/uhitm.c b/src/uhitm.c index 211316e54..012f1cfdb 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4149,6 +4149,40 @@ struct mhitm_data *mhm; } } +void +mhitm_ad_ssex(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + if (magr == &g.youmonst) { + /* uhitm */ + mhitm_ad_sedu(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } else if (mdef == &g.youmonst) { + /* mhitu */ + if (SYSOPT_SEDUCE) { + if (could_seduce(magr, mdef, mattk) == 1 && !magr->mcan) + if (doseduce(magr)) { + mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->done = TRUE; + return; + } + return; + } + mhitm_ad_sedu(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } else { + /* mhitm */ + mhitm_ad_sedu(magr, mattk, mdef, mhm); + if (mhm->done) + return; + } +} + /* Template for monster hits monster for AD_FOO. - replace "break" with return @@ -4262,6 +4296,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ return mhm.hitflags; break; case AD_SSEX: + mhitm_ad_ssex(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + break; case AD_SITM: case AD_SEDU: mhitm_ad_sedu(&g.youmonst, mattk, mdef, &mhm); From 3ef3b425ad1288d8f3a3ca602f515578dc819dfb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 16:28:28 +0200 Subject: [PATCH 525/708] Unify the ad type switches --- include/extern.h | 1 + src/mhitm.c | 182 +------------------------------------ src/mhitu.c | 197 +--------------------------------------- src/uhitm.c | 227 ++++++++++++----------------------------------- 4 files changed, 67 insertions(+), 540 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8b4bd149c..fb348d6da 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2796,6 +2796,7 @@ E void FDECL(mhitm_ad_samu, (struct monst *, struct attack *, struct monst *, st E void FDECL(mhitm_ad_dise, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_sedu, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E void FDECL(mhitm_ad_ssex, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); +E void FDECL(mhitm_adtyping, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); diff --git a/src/mhitm.c b/src/mhitm.c index 0cb813803..7c0b2c913 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -898,184 +898,10 @@ int dieroll; armpro = magic_negation(mdef); cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - switch (mattk->adtyp) { - case AD_DGST: - mhitm_ad_dgst(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STUN: - mhitm_ad_stun(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_LEGS: - mhitm_ad_legs(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_WERE: - mhitm_ad_were(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_HEAL: - mhitm_ad_heal(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_PHYS: - mhitm_ad_phys(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_FIRE: - mhitm_ad_fire(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_COLD: - mhitm_ad_cold(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ELEC: - mhitm_ad_elec(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ACID: - mhitm_ad_acid(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_RUST: - mhitm_ad_rust(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CORR: - mhitm_ad_corr(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DCAY: - mhitm_ad_dcay(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STON: - mhitm_ad_ston(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_TLPT: - mhitm_ad_tlpt(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLEE: - mhitm_ad_slee(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_PLYS: - mhitm_ad_plys(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLOW: - mhitm_ad_slow(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CONF: - mhitm_ad_conf(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_BLND: - mhitm_ad_blnd(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_HALU: - mhitm_ad_halu(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CURS: - mhitm_ad_curs(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SGLD: - mhitm_ad_sgld(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRLI: /* drain life */ - mhitm_ad_drli(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SSEX: - mhitm_ad_ssex(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SITM: /* for now these are the same */ - case AD_SEDU: - mhitm_ad_sedu(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DREN: - mhitm_ad_dren(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRST: - case AD_DRDX: - case AD_DRCO: - mhitm_ad_drst(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRIN: - mhitm_ad_drin(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLIM: - mhitm_ad_slim(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STCK: - mhitm_ad_stck(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_WRAP: - mhitm_ad_wrap(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ENCH: - mhitm_ad_ench(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_POLY: - mhitm_ad_poly(magr, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - default: - mhm.damage = 0; - break; - } + mhitm_adtyping(magr, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; + if (!mhm.damage) return mhm.hitflags; diff --git a/src/mhitu.c b/src/mhitu.c index 3fce4da9e..84cab3e91 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -1014,201 +1014,10 @@ register struct attack *mattk; armpro = magic_negation(&g.youmonst); uncancelled = !mtmp->mcan && (rn2(10) >= 3 * armpro); - /* Now, adjust damages via resistances or specific attacks */ - switch (mattk->adtyp) { - case AD_PHYS: - mhitm_ad_phys(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DISE: - mhitm_ad_dise(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_FIRE: - mhitm_ad_fire(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_COLD: - mhitm_ad_cold(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ELEC: - mhitm_ad_elec(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLEE: - mhitm_ad_slee(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_BLND: - mhitm_ad_blnd(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRST: - case AD_DRDX: - case AD_DRCO: - mhitm_ad_drst(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRIN: - mhitm_ad_drin(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_PLYS: - mhitm_ad_plys(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRLI: /* drain life */ - mhitm_ad_drli(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_LEGS: - mhitm_ad_legs(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STON: - mhitm_ad_ston(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STCK: - mhitm_ad_stck(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_WRAP: - mhitm_ad_wrap(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_WERE: - mhitm_ad_were(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SGLD: - mhitm_ad_sgld(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; + mhitm_adtyping(mtmp, mattk, &g.youmonst, &mhm); + if (mhm.done) + return mhm.hitflags; - case AD_SSEX: - mhitm_ad_ssex(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SITM: /* for now these are the same */ - case AD_SEDU: - mhitm_ad_sedu(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SAMU: - mhitm_ad_samu(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_TLPT: - mhitm_ad_tlpt(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_RUST: - mhitm_ad_rust(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CORR: - mhitm_ad_corr(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DCAY: - mhitm_ad_dcay(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_HEAL: - mhitm_ad_heal(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CURS: - mhitm_ad_curs(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STUN: - mhitm_ad_stun(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ACID: - mhitm_ad_acid(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLOW: - mhitm_ad_slow(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DREN: - mhitm_ad_dren(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CONF: - mhitm_ad_conf(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DETH: - mhitm_ad_deth(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_PEST: - mhitm_ad_pest(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_FAMN: - mhitm_ad_famn(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLIM: - mhitm_ad_slim(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ - mhitm_ad_ench(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_POLY: - mhitm_ad_poly(mtmp, mattk, &g.youmonst, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - default: - mhm.damage = 0; - break; - } if ((Upolyd ? u.mh : u.uhp) < 1) { /* already dead? call rehumanize() or done_in_by() as appropriate */ mdamageu(mtmp, 1); diff --git a/src/uhitm.c b/src/uhitm.c index 012f1cfdb..6adf232ed 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4219,6 +4219,61 @@ struct mhitm_data *mhm; } } +void +mhitm_adtyping(magr, mattk, mdef, mhm) +struct monst *magr; +struct attack *mattk; +struct monst *mdef; +struct mhitm_data *mhm; +{ + switch (mattk->adtyp) { + case AD_STUN: mhitm_ad_stun(magr, mattk, mdef, mhm); break; + case AD_LEGS: mhitm_ad_legs(magr, mattk, mdef, mhm); break; + case AD_WERE: mhitm_ad_were(magr, mattk, mdef, mhm); break; + case AD_HEAL: mhitm_ad_heal(magr, mattk, mdef, mhm); break; + case AD_PHYS: mhitm_ad_phys(magr, mattk, mdef, mhm); break; + case AD_FIRE: mhitm_ad_fire(magr, mattk, mdef, mhm); break; + case AD_COLD: mhitm_ad_cold(magr, mattk, mdef, mhm); break; + case AD_ELEC: mhitm_ad_elec(magr, mattk, mdef, mhm); break; + case AD_ACID: mhitm_ad_acid(magr, mattk, mdef, mhm); break; + case AD_STON: mhitm_ad_ston(magr, mattk, mdef, mhm); break; + case AD_SSEX: mhitm_ad_ssex(magr, mattk, mdef, mhm); break; + case AD_SITM: + case AD_SEDU: mhitm_ad_sedu(magr, mattk, mdef, mhm); break; + case AD_SGLD: mhitm_ad_sgld(magr, mattk, mdef, mhm); break; + case AD_TLPT: mhitm_ad_tlpt(magr, mattk, mdef, mhm); break; + case AD_BLND: mhitm_ad_blnd(magr, mattk, mdef, mhm); break; + case AD_CURS: mhitm_ad_curs(magr, mattk, mdef, mhm); break; + case AD_DRLI: mhitm_ad_drli(magr, mattk, mdef, mhm); break; + case AD_RUST: mhitm_ad_rust(magr, mattk, mdef, mhm); break; + case AD_CORR: mhitm_ad_corr(magr, mattk, mdef, mhm); break; + case AD_DCAY: mhitm_ad_dcay(magr, mattk, mdef, mhm); break; + case AD_DREN: mhitm_ad_dren(magr, mattk, mdef, mhm); break; + case AD_DRST: + case AD_DRDX: + case AD_DRCO: mhitm_ad_drst(magr, mattk, mdef, mhm); break; + case AD_DRIN: mhitm_ad_drin(magr, mattk, mdef, mhm); break; + case AD_STCK: mhitm_ad_stck(magr, mattk, mdef, mhm); break; + case AD_WRAP: mhitm_ad_wrap(magr, mattk, mdef, mhm); break; + case AD_PLYS: mhitm_ad_plys(magr, mattk, mdef, mhm); break; + case AD_SLEE: mhitm_ad_slee(magr, mattk, mdef, mhm); break; + case AD_SLIM: mhitm_ad_slim(magr, mattk, mdef, mhm); break; + case AD_ENCH: mhitm_ad_ench(magr, mattk, mdef, mhm); break; + case AD_SLOW: mhitm_ad_slow(magr, mattk, mdef, mhm); break; + case AD_CONF: mhitm_ad_conf(magr, mattk, mdef, mhm); break; + case AD_POLY: mhitm_ad_poly(magr, mattk, mdef, mhm); break; + case AD_DISE: mhitm_ad_dise(magr, mattk, mdef, mhm); break; + case AD_SAMU: mhitm_ad_samu(magr, mattk, mdef, mhm); break; + case AD_DETH: mhitm_ad_deth(magr, mattk, mdef, mhm); break; + case AD_PEST: mhitm_ad_pest(magr, mattk, mdef, mhm); break; + case AD_FAMN: mhitm_ad_famn(magr, mattk, mdef, mhm); break; + case AD_DGST: mhitm_ad_dgst(magr, mattk, mdef, mhm); break; + case AD_HALU: mhitm_ad_halu(magr, mattk, mdef, mhm); break; + default: + mhm->damage = 0; + } +} + int damageum(mdef, mattk, specialdmg) register struct monst *mdef; @@ -4244,174 +4299,10 @@ int specialdmg; /* blessed and/or silver bonus against various things */ demonpet(); return 0; } - switch (mattk->adtyp) { - case AD_STUN: - mhitm_ad_stun(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_LEGS: - mhitm_ad_legs(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_WERE: - mhitm_ad_were(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_HEAL: - mhitm_ad_heal(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_PHYS: - mhitm_ad_phys(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_FIRE: - mhitm_ad_fire(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_COLD: - mhitm_ad_cold(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ELEC: - mhitm_ad_elec(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ACID: - mhitm_ad_acid(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STON: - mhitm_ad_ston(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SSEX: - mhitm_ad_ssex(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SITM: - case AD_SEDU: - mhitm_ad_sedu(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SGLD: - mhitm_ad_sgld(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_TLPT: - mhitm_ad_tlpt(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_BLND: - mhitm_ad_blnd(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CURS: - mhitm_ad_curs(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRLI: /* drain life */ - mhitm_ad_drli(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_RUST: - mhitm_ad_rust(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CORR: - mhitm_ad_corr(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DCAY: - mhitm_ad_dcay(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DREN: - mhitm_ad_dren(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRST: - case AD_DRDX: - case AD_DRCO: - mhitm_ad_drst(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_DRIN: - mhitm_ad_drin(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_STCK: - mhitm_ad_stck(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_WRAP: - mhitm_ad_wrap(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_PLYS: - mhitm_ad_plys(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLEE: - mhitm_ad_slee(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLIM: - mhitm_ad_slim(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_ENCH: - mhitm_ad_ench(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_SLOW: - mhitm_ad_slow(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_CONF: - mhitm_ad_conf(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - case AD_POLY: - mhitm_ad_poly(&g.youmonst, mattk, mdef, &mhm); - if (mhm.done) - return mhm.hitflags; - break; - default: - mhm.damage = 0; - break; - } + + mhitm_adtyping(&g.youmonst, mattk, mdef, &mhm); + if (mhm.done) + return mhm.hitflags; mdef->mstrategy &= ~STRAT_WAITFORU; /* in case player is very fast */ mdef->mhp -= mhm.damage; From b797baba7a96d45d4eb3b26712830ebaead72cd4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 19:17:26 +0200 Subject: [PATCH 526/708] Make return values use defines --- include/extern.h | 2 +- include/monattk.h | 1 + src/mhitm.c | 18 ++++---- src/mhitu.c | 60 ++++++++++++------------ src/mthrowu.c | 22 ++++----- src/uhitm.c | 114 ++++++++++++++++------------------------------ 6 files changed, 92 insertions(+), 125 deletions(-) diff --git a/include/extern.h b/include/extern.h index fb348d6da..b8b73c1ff 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2801,7 +2801,7 @@ E boolean FDECL(do_stone_u, (struct monst *)); E void FDECL(do_stone_mon, (struct monst *, struct attack *, struct monst *, struct mhitm_data *)); E int FDECL(damageum, (struct monst *, struct attack *, int)); E void FDECL(missum, (struct monst *, struct attack *, BOOLEAN_P)); -E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, int, +E int FDECL(passive, (struct monst *, struct obj *, BOOLEAN_P, BOOLEAN_P, UCHAR_P, BOOLEAN_P)); E void FDECL(passive_obj, (struct monst *, struct obj *, struct attack *)); E void FDECL(stumble_onto_mimic, (struct monst *)); diff --git a/include/monattk.h b/include/monattk.h index b78ec6fe6..98975e5db 100644 --- a/include/monattk.h +++ b/include/monattk.h @@ -104,5 +104,6 @@ struct mhitm_data { #define MM_HIT 0x1 /* aggressor hit defender */ #define MM_DEF_DIED 0x2 /* defender died */ #define MM_AGR_DIED 0x4 /* aggressor died */ +#define MM_AGR_DONE 0x8 /* aggressor is done with their turn */ #endif /* MONATTK_H */ diff --git a/src/mhitm.c b/src/mhitm.c index 7c0b2c913..5c3b5a43a 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -267,6 +267,7 @@ boolean quietly; * / / / * x x x * + * 0x8 MM_AGR_DONE * 0x4 MM_AGR_DIED * 0x2 MM_DEF_DIED * 0x1 MM_HIT @@ -367,7 +368,7 @@ register struct monst *magr, *mdef; case AT_WEAP: /* "hand to hand" attacks */ if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1) { /* D: Do a ranged attack here! */ - strike = thrwmm(magr, mdef); + strike = (thrwmm(magr, mdef) == MM_MISS) ? 0 : 1; if (strike) /* don't really know if we hit or not; pretend we did */ res[i] |= MM_HIT; @@ -380,7 +381,7 @@ register struct monst *magr, *mdef; if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) { magr->weapon_check = NEED_HTH_WEAPON; if (mon_wield_item(magr) != 0) - return 0; + return MM_MISS; } possibly_unwield(magr, FALSE); if ((mwep = MON_WEP(magr)) != 0) { @@ -489,7 +490,7 @@ register struct monst *magr, *mdef; case AT_BREA: if (!monnear(magr, mdef->mx, mdef->my)) { - strike = breamm(magr, mattk, mdef); + strike = (breamm(magr, mattk, mdef) == MM_MISS) ? 0 : 1; /* We don't really know if we hit or not; pretend we did. */ if (strike) @@ -505,7 +506,7 @@ register struct monst *magr, *mdef; case AT_SPIT: if (!monnear(magr, mdef->mx, mdef->my)) { - strike = spitmm(magr, mattk, mdef); + strike = (spitmm(magr, mattk, mdef) == MM_MISS) ? 0 : 1; /* We don't really know if we hit or not; pretend we did. */ if (strike) @@ -1107,9 +1108,9 @@ struct obj *otemp; * handled above. Returns same values as mattackm. */ static int -passivemm(magr, mdef, mhit, mdead, mwep) +passivemm(magr, mdef, mhitb, mdead, mwep) register struct monst *magr, *mdef; -boolean mhit; +boolean mhitb; int mdead; struct obj *mwep; { @@ -1117,6 +1118,7 @@ struct obj *mwep; register struct permonst *madat = magr->data; char buf[BUFSZ]; int i, tmp; + int mhit = mhitb ? MM_HIT : MM_MISS; for (i = 0;; i++) { if (i >= NATTK) @@ -1134,7 +1136,7 @@ struct obj *mwep; /* These affect the enemy even if defender killed */ switch (mddat->mattk[i].adtyp) { case AD_ACID: - if (mhit && !rn2(2)) { + if (mhitb && !rn2(2)) { Strcpy(buf, Monnam(magr)); if (canseemon(magr)) pline("%s is splashed by %s %s!", buf, @@ -1152,7 +1154,7 @@ struct obj *mwep; acid_damage(MON_WEP(magr)); goto assess_dmg; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ - if (mhit && !mdef->mcan && mwep) { + if (mhitb && !mdef->mcan && mwep) { (void) drain_item(mwep, FALSE); /* No message */ } diff --git a/src/mhitu.c b/src/mhitu.c index 84cab3e91..6bbbb7d25 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -285,7 +285,7 @@ struct attack *alt_attk_buf; /* prevent a monster with two consecutive disease or hunger attacks from hitting with both of them on the same turn; if the first has already hit, switch to a stun attack for the second */ - if (indx > 0 && prev_result[indx - 1] > 0 + if (indx > 0 && prev_result[indx - 1] > MM_MISS && (attk->adtyp == AD_DISE || attk->adtyp == AD_PEST || attk->adtyp == AD_FAMN) && attk->adtyp == mptr->mattk[indx - 1].adtyp) { @@ -622,7 +622,7 @@ register struct monst *mtmp; g.skipdrin = FALSE; /* [see mattackm(mhitm.c)] */ for (i = 0; i < NATTK; i++) { - sum[i] = 0; + sum[i] = MM_MISS; if (i > 0 && foundyou /* previous attack might have moved hero */ && (mtmp->mux != u.ux || mtmp->muy != u.uy)) continue; /* fill in sum[] with 'miss' but skip other actions */ @@ -763,15 +763,15 @@ register struct monst *mtmp; if (g.context.botl) bot(); /* give player a chance of waking up before dying -kaa */ - if (sum[i] == 1) { /* successful attack */ + if (sum[i] == MM_HIT) { /* successful attack */ if (u.usleep && u.usleep < g.monstermoves && !rn2(10)) { g.multi = -1; g.nomovemsg = "The combat suddenly awakens you."; } } - if (sum[i] == 2) + if ((sum[i] & MM_AGR_DIED)) return 1; /* attacker dead */ - if (sum[i] == 3) + if ((sum[i] & MM_AGR_DONE)) break; /* attacker teleported, no more attacks */ /* sum[i] == 0: unsuccessful attack */ } @@ -956,10 +956,8 @@ struct monst *mon; /* * hitmu: monster hits you - * returns 2 if monster dies (e.g. "yellow light"), 1 otherwise - * 3 if the monster lives but teleported/paralyzed, so it can't keep - * attacking you - */ + * returns MM_ flags +*/ static int hitmu(mtmp, mattk) register struct monst *mtmp; @@ -1083,7 +1081,7 @@ register struct attack *mattk; if (mhm.damage) res = passiveum(olduasmon, mtmp, mattk); else - res = 1; + res = MM_HIT; stop_occupation(); return res; } @@ -1123,9 +1121,9 @@ struct attack *mattk; int omx = mtmp->mx, omy = mtmp->my; if (!engulf_target(mtmp, &g.youmonst)) - return 0; + return MM_MISS; if ((t && is_pit(t->ttyp)) && sobj_at(BOULDER, u.ux, u.uy)) - return 0; + return MM_MISS; if (Punished) unplacebc(); /* ball&chain go away */ @@ -1176,7 +1174,7 @@ struct attack *mattk; if (Punished) placebc(); set_ustuck((struct monst *) 0); - return (!DEADMONSTER(mtmp)) ? 0 : 2; + return (!DEADMONSTER(mtmp)) ? MM_MISS : MM_AGR_DIED; } display_nhwindow(WIN_MESSAGE, FALSE); @@ -1207,7 +1205,7 @@ struct attack *mattk; } if (mtmp != u.ustuck) - return 0; + return MM_MISS; if (Punished) { /* ball&chain are in limbo while swallowed; update their internal location to be at swallower's spot */ @@ -1362,7 +1360,7 @@ struct attack *mattk; pline("Obviously %s doesn't like your taste.", mon_nam(mtmp)); expels(mtmp, mtmp->data, FALSE); } - return 1; + return MM_HIT; } /* monster explodes in your face */ @@ -1375,7 +1373,7 @@ boolean ufound; boolean physical_damage = TRUE, kill_agr = TRUE; if (mtmp->mcan) - return 0; + return MM_MISS; if (!ufound) { pline("%s explodes at a spot in %s!", @@ -1467,7 +1465,7 @@ boolean ufound; if (kill_agr) mondead(mtmp); wake_nearto(mtmp->mx, mtmp->my, 7 * 7); - return (!DEADMONSTER(mtmp)) ? 0 : 2; + return (!DEADMONSTER(mtmp)) ? MM_MISS : MM_AGR_DIED; } /* monster gazes at you */ @@ -1535,7 +1533,7 @@ struct attack *mattk; if (!DEADMONSTER(mtmp)) break; - return 2; + return MM_AGR_DIED; } if (canseemon(mtmp) && couldsee(mtmp->mx, mtmp->my) && !Stone_resistance) { @@ -1685,7 +1683,7 @@ struct attack *mattk; : (!rn2(2) ? "a bit " : "somewhat "), reactions[react]); } - return 0; + return MM_MISS; } /* mtmp hits you for n points damage */ @@ -2141,7 +2139,7 @@ struct attack *mattk; */ for (i = 0; !oldu_mattk; i++) { if (i >= NATTK) - return 1; + return MM_HIT; if (olduasmon->mattk[i].aatyp == AT_NONE || olduasmon->mattk[i].aatyp == AT_BOOM) oldu_mattk = &olduasmon->mattk[i]; @@ -2194,10 +2192,10 @@ struct attack *mattk; g.stoned = 1; xkilled(mtmp, XKILL_NOMSG); if (!DEADMONSTER(mtmp)) - return 1; - return 2; + return MM_HIT; + return MM_AGR_DIED; } - return 1; + return MM_HIT; } case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ if (mon_currwep) { @@ -2206,12 +2204,12 @@ struct attack *mattk; (void) drain_item(mon_currwep, TRUE); /* No message */ } - return 1; + return MM_HIT; default: break; } if (!Upolyd) - return 1; + return MM_HIT; /* These affect the enemy only if you are still a monster */ if (rn2(3)) @@ -2241,15 +2239,15 @@ struct attack *mattk; return 1; pline("%s is frozen by your gaze!", Monnam(mtmp)); paralyze_monst(mtmp, tmp); - return 3; + return MM_AGR_DONE; } } } else { /* gelatinous cube */ pline("%s is frozen by you.", Monnam(mtmp)); paralyze_monst(mtmp, tmp); - return 3; + return MM_AGR_DONE; } - return 1; + return MM_HIT; case AD_COLD: /* Brown mold or blue jelly */ if (resists_cold(mtmp)) { shieldeff(mtmp->mx, mtmp->my); @@ -2305,10 +2303,10 @@ struct attack *mattk; pline("%s dies!", Monnam(mtmp)); xkilled(mtmp, XKILL_NOMSG); if (!DEADMONSTER(mtmp)) - return 1; - return 2; + return MM_HIT; + return MM_AGR_DIED; } - return 1; + return MM_HIT; } struct monst * diff --git a/src/mthrowu.c b/src/mthrowu.c index 66ef9d949..55cc3c92a 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -704,13 +704,13 @@ struct monst *mtmp, *mtarg; mtmp->weapon_check = NEED_RANGED_WEAPON; /* mon_wield_item resets weapon_check as appropriate */ if (mon_wield_item(mtmp) != 0) - return 0; + return MM_MISS; } /* Pick a weapon */ otmp = select_rwep(mtmp); if (!otmp) - return 0; + return MM_MISS; ispole = is_pole(otmp); x = mtmp->mx; @@ -725,17 +725,17 @@ struct monst *mtmp, *mtarg; if (ammo_and_launcher(otmp, mwep) && dist2(mtmp->mx, mtmp->my, mtarg->mx, mtarg->my) > PET_MISSILE_RANGE2) - return 0; /* Out of range */ + return MM_MISS; /* Out of range */ /* Set target monster */ g.mtarget = mtarg; g.marcher = mtmp; monshoot(mtmp, otmp, mwep); /* multishot shooting or throwing */ g.marcher = g.mtarget = (struct monst *) 0; nomul(0); - return 1; + return MM_HIT; } } - return 0; + return MM_MISS; } /* monster spits substance at monster */ @@ -750,7 +750,7 @@ struct attack *mattk; if (!Deaf) pline("A dry rattle comes from %s throat.", s_suffix(mon_nam(mtmp))); - return 0; + return MM_MISS; } if (m_lined_up(mtarg, mtmp)) { switch (mattk->adtyp) { @@ -784,10 +784,10 @@ struct attack *mattk; dog->hungrytime -= 5; } - return 1; + return MM_HIT; } } - return 0; + return MM_MISS; } /* monster breathes at monster (ranged) */ @@ -807,7 +807,7 @@ struct attack *mattk; else You_hear("a cough."); } - return 0; + return MM_MISS; } if (!mtmp->mspec_used && rn2(3)) { if ((typ >= AD_MAGM) && (typ <= AD_ACID)) { @@ -836,9 +836,9 @@ struct attack *mattk; } } else impossible("Breath weapon %d used", typ-1); } else - return 0; + return MM_MISS; } - return 1; + return MM_HIT; } diff --git a/src/uhitm.c b/src/uhitm.c index 6adf232ed..998408e18 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4046,7 +4046,7 @@ struct mhitm_data *mhm; : "makes some remarks about how difficult theft is lately"); if (!tele_restrict(magr)) (void) rloc(magr, TRUE); - mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->hitflags = MM_AGR_DONE; /* return 3??? */ mhm->done = TRUE; return; } else if (magr->mcan) { @@ -4058,7 +4058,7 @@ struct mhitm_data *mhm; if (rn2(3)) { if (!tele_restrict(magr)) (void) rloc(magr, TRUE); - mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->hitflags = MM_AGR_DONE; /* return 3??? */ mhm->done = TRUE; return; } @@ -4067,7 +4067,7 @@ struct mhitm_data *mhm; buf[0] = '\0'; switch (steal(magr, buf)) { case -1: - mhm->hitflags = MM_DEF_DIED; /* return 2??? */ + mhm->hitflags = MM_AGR_DIED; /* return 2??? */ mhm->done = TRUE; return; case 0: @@ -4081,7 +4081,7 @@ struct mhitm_data *mhm; locomotion(magr->data, "run"), buf); } monflee(magr, 0, FALSE, FALSE); - mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->hitflags = MM_AGR_DONE; /* return 3??? */ mhm->done = TRUE; return; } @@ -4166,7 +4166,7 @@ struct mhitm_data *mhm; if (SYSOPT_SEDUCE) { if (could_seduce(magr, mdef, mattk) == 1 && !magr->mcan) if (doseduce(magr)) { - mhm->hitflags = MM_HIT | MM_DEF_DIED; /* return 3??? */ + mhm->hitflags = MM_AGR_DONE; mhm->done = TRUE; return; } @@ -4183,42 +4183,6 @@ struct mhitm_data *mhm; } } - -/* Template for monster hits monster for AD_FOO. - - replace "break" with return - - replace "return" with mhm->done = TRUE -*/ -void -mhitm_ad_FOO(magr, mattk, mdef, mhm) -struct monst *magr; -struct attack *mattk; -struct monst *mdef; -struct mhitm_data *mhm; -{ - struct permonst *pd = mdef->data; - - if (magr == &g.youmonst) { - /* uhitm */ - int armpro = magic_negation(mdef); - /* since hero can't be cancelled, only defender's armor applies */ - boolean negated = !(rn2(10) >= 3 * armpro); - - /* TODO */ - } else if (mdef == &g.youmonst) { - /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - - /* TODO */ - } else { - /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - - /* TODO */ - } -} - void mhitm_adtyping(magr, mattk, mdef, mhm) struct monst *magr; @@ -4297,7 +4261,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS && u.umonnum != PM_BALROG) { demonpet(); - return 0; + return MM_MISS; } mhitm_adtyping(&g.youmonst, mattk, mdef, &mhm); @@ -4317,9 +4281,9 @@ int specialdmg; /* blessed and/or silver bonus against various things */ xkilled(mdef, XKILL_NOMSG); } else if (mhm.damage) killed(mdef); - return 2; + return MM_DEF_DIED; } - return 1; + return MM_HIT; } static int @@ -4359,7 +4323,7 @@ register struct attack *mattk; mdef->mhp -= tmp; if (DEADMONSTER(mdef)) { killed(mdef); - return 2; + return MM_DEF_DIED; } } else { shieldeff(mdef->mx, mdef->my); @@ -4372,7 +4336,7 @@ register struct attack *mattk; default: break; } - return 1; + return MM_HIT; } static void @@ -4423,7 +4387,7 @@ register struct attack *mattk; */ if (!engulf_target(&g.youmonst, mdef)) - return 0; + return MM_MISS; if (u.uhunger < 1500 && !u.uswallow) { for (otmp = mdef->minvent; otmp; otmp = otmp->nobj) @@ -4438,7 +4402,7 @@ register struct attack *mattk; pline("It turns into %s.", a_monnam(mdef)); else map_invisible(mdef->mx, mdef->my); - return 1; + return MM_HIT; } /* engulfing a cockatrice or digesting a Rider or Medusa */ @@ -4471,7 +4435,7 @@ register struct attack *mattk; pd->mname); g.killer.format = NO_KILLER_PREFIX; done(DIED); - return 0; /* lifesaved */ + return MM_MISS; /* lifesaved */ } if (Slow_digestion) { @@ -4527,7 +4491,7 @@ register struct attack *mattk; exercise(A_CON, TRUE); } end_engulf(); - return 2; + return MM_DEF_DIED; case AD_PHYS: if (g.youmonst.data == &mons[PM_FOG_CLOUD]) { pline("%s is laden with your moisture.", Monnam(mdef)); @@ -4603,7 +4567,7 @@ register struct attack *mattk; if (DEADMONSTER(mdef)) { killed(mdef); if (DEADMONSTER(mdef)) /* not lifesaved */ - return 2; + return MM_DEF_DIED; } You("%s %s!", is_animal(g.youmonst.data) ? "regurgitate" : "expel", mon_nam(mdef)); @@ -4613,7 +4577,7 @@ register struct attack *mattk; } } } - return 0; + return MM_MISS; } void @@ -4643,14 +4607,14 @@ register struct monst *mon; struct attack *mattk, alt_attk; struct obj *weapon, **originalweapon; boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE; - int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0; + int i, tmp, armorpenalty, sum[NATTK], nsum = MM_MISS, dhit = 0, attknum = 0; int dieroll, multi_claw = 0; /* with just one touch/claw/weapon attack, both rings matter; with more than one, alternate right and left when checking whether silver ring causes successful hit */ for (i = 0; i < NATTK; i++) { - sum[i] = 0; + sum[i] = MM_MISS; mattk = getmattk(&g.youmonst, mon, i, sum, &alt_attk); if (mattk->aatyp == AT_WEAP || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH) @@ -4661,7 +4625,7 @@ register struct monst *mon; g.skipdrin = FALSE; /* [see mattackm(mhitm.c)] */ for (i = 0; i < NATTK; i++) { - /* sum[i] = 0; -- now done above */ + /* sum[i] = MM_MISS; -- now done above */ mattk = getmattk(&g.youmonst, mon, i, sum, &alt_attk); if (g.skipdrin && mattk->aatyp == AT_TENT && mattk->adtyp == AD_DRIN) continue; @@ -4675,7 +4639,7 @@ register struct monst *mon; get to make another weapon attack (note: monsters who use weapons do not have this restriction, but they also never have the opportunity to use two weapons) */ - if (weapon_used && sum[i - 1] && uwep && bimanual(uwep)) + if (weapon_used && (sum[i - 1] > MM_MISS) && uwep && bimanual(uwep)) continue; /* Certain monsters don't use weapons when encountered as enemies, * but players who polymorph into them have hands or claws and @@ -4724,10 +4688,10 @@ register struct monst *mon; if (!known_hitum(mon, weapon, &dhit, tmp, armorpenalty, mattk, dieroll)) { /* enemy dead, before any special abilities used */ - sum[i] = 2; + sum[i] = MM_DEF_DIED; break; } else - sum[i] = dhit; + sum[i] = dhit ? MM_HIT : MM_MISS; /* originalweapon points to an equipment slot which might now be empty if the weapon was destroyed during the hit; passive(,weapon,...) won't call passive_obj() in that case */ @@ -4924,7 +4888,7 @@ register struct monst *mon; if (silverhit && flags.verbose) silver_sears(&g.youmonst, mon, silverhit); sum[i] = damageum(mon, mattk, specialdmg); - } else if (i >= 2 && sum[i - 1] && sum[i - 2]) { + } else if (i >= 2 && (sum[i - 1] > MM_MISS) && (sum[i - 2] > MM_MISS)) { /* in case we're hugging a new target while already holding something else; yields feedback " is no longer in your clutches" */ @@ -4954,7 +4918,7 @@ register struct monst *mon; Your("attempt to surround %s is harmless.", mon_nam(mon)); else { sum[i] = gulpum(mon, mattk); - if (sum[i] == 2 && (mon->data->mlet == S_ZOMBIE + if (sum[i] == MM_DEF_DIED && (mon->data->mlet == S_ZOMBIE || mon->data->mlet == S_MUMMY) && rn2(5) && !Sick_resistance) { You_feel("%ssick.", (Sick) ? "very " : ""); @@ -4994,12 +4958,12 @@ register struct monst *mon; u.mh = -1; /* dead in the current form */ rehumanize(); } - if (sum[i] == 2) { + if (sum[i] == MM_DEF_DIED) { /* defender dead */ (void) passive(mon, weapon, 1, 0, mattk->aatyp, FALSE); - nsum = 0; /* return value below used to be 'nsum > 0' */ + nsum = MM_MISS; /* return value below used to be 'nsum > 0' */ } else { - (void) passive(mon, weapon, sum[i], 1, mattk->aatyp, FALSE); + (void) passive(mon, weapon, (sum[i] != MM_MISS), 1, mattk->aatyp, FALSE); nsum |= sum[i]; } @@ -5029,16 +4993,18 @@ register struct monst *mon; /* Special (passive) attacks on you by monsters done here. */ int -passive(mon, weapon, mhit, malive, aatyp, wep_was_destroyed) +passive(mon, weapon, mhitb, maliveb, aatyp, wep_was_destroyed) struct monst *mon; struct obj *weapon; /* uwep or uswapwep or uarmg or uarmf or Null */ -boolean mhit; -int malive; +boolean mhitb; +boolean maliveb; uchar aatyp; boolean wep_was_destroyed; { register struct permonst *ptr = mon->data; register int i, tmp; + int mhit = mhitb ? MM_HIT : MM_MISS; + int malive = maliveb ? MM_HIT : MM_MISS; for (i = 0;; i++) { if (i >= NATTK) @@ -5058,7 +5024,7 @@ boolean wep_was_destroyed; */ switch (ptr->mattk[i].adtyp) { case AD_FIRE: - if (mhit && !mon->mcan && weapon) { + if (mhitb && !mon->mcan && weapon) { if (aatyp == AT_KICK) { if (uarmf && !rn2(6)) (void) erode_obj(uarmf, xname(uarmf), ERODE_BURN, @@ -5069,7 +5035,7 @@ boolean wep_was_destroyed; } break; case AD_ACID: - if (mhit && rn2(2)) { + if (mhitb && rn2(2)) { if (Blind || !flags.verbose) You("are splashed!"); else @@ -5081,7 +5047,7 @@ boolean wep_was_destroyed; if (!rn2(30)) erode_armor(&g.youmonst, ERODE_CORRODE); } - if (mhit && weapon) { + if (mhitb && weapon) { if (aatyp == AT_KICK) { if (uarmf && !rn2(6)) (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE, @@ -5093,7 +5059,7 @@ boolean wep_was_destroyed; exercise(A_STR, FALSE); break; case AD_STON: - if (mhit) { /* successful attack */ + if (mhitb) { /* successful attack */ long protector = attk_protection((int) aatyp); /* hero using monsters' AT_MAGC attack is hitting hand to @@ -5111,13 +5077,13 @@ boolean wep_was_destroyed; && !(poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM))) { done_in_by(mon, STONING); /* "You turn to stone..." */ - return 2; + return MM_DEF_DIED; } } } break; case AD_RUST: - if (mhit && !mon->mcan && weapon) { + if (mhitb && !mon->mcan && weapon) { if (aatyp == AT_KICK) { if (uarmf) (void) erode_obj(uarmf, xname(uarmf), ERODE_RUST, @@ -5128,7 +5094,7 @@ boolean wep_was_destroyed; } break; case AD_CORR: - if (mhit && !mon->mcan && weapon) { + if (mhitb && !mon->mcan && weapon) { if (aatyp == AT_KICK) { if (uarmf) (void) erode_obj(uarmf, xname(uarmf), ERODE_CORRODE, @@ -5149,7 +5115,7 @@ boolean wep_was_destroyed; } break; case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */ - if (mhit) { + if (mhitb) { if (aatyp == AT_KICK) { if (!weapon) break; From 4fb370ee79394d2c764ac2886248f44736fffc39 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 19:32:06 +0200 Subject: [PATCH 527/708] Remove unused variables --- src/mhitm.c | 4 +--- src/mhitu.c | 5 ++-- src/uhitm.c | 67 ----------------------------------------------------- 3 files changed, 3 insertions(+), 73 deletions(-) diff --git a/src/mhitm.c b/src/mhitm.c index 5c3b5a43a..6b182d093 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -856,10 +856,8 @@ struct attack *mattk; struct obj *mwep; int dieroll; { - struct obj *obj; - char buf[BUFSZ]; struct permonst *pa = magr->data, *pd = mdef->data; - int armpro, num; + int armpro; boolean cancelled; struct mhitm_data mhm; mhm.damage = d((int) mattk->damn, (int) mattk->damd); diff --git a/src/mhitu.c b/src/mhitu.c index 6bbbb7d25..ba628651b 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -964,9 +964,8 @@ register struct monst *mtmp; register struct attack *mattk; { struct permonst *mdat = mtmp->data; - int uncancelled, ptmp; - int armpro, tmphp; - char buf[BUFSZ]; + int uncancelled; + int armpro; struct permonst *olduasmon = g.youmonst.data; int res; struct mhitm_data mhm; diff --git a/src/uhitm.c b/src/uhitm.c index 998408e18..c78032972 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1757,8 +1757,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ erode_armor(mdef, ERODE_CORRODE); @@ -1842,8 +1840,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -1882,8 +1878,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -2083,8 +2077,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -2150,8 +2142,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -2223,8 +2213,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ if (resists_acid(mdef)) @@ -2340,8 +2328,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -2442,8 +2428,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ if (can_blnd(magr, mdef, mattk->aatyp, (struct obj *) 0)) { @@ -2574,7 +2558,6 @@ struct monst *mdef; struct mhitm_data *mhm; { struct permonst *pa = magr->data; - struct permonst *pd = mdef->data; if (magr == &g.youmonst) { /* uhitm */ @@ -2858,8 +2841,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -2914,8 +2895,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -3047,8 +3026,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ /* there's no msomearmor() function, so just do damage */ @@ -3100,8 +3077,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -3146,8 +3121,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ if (!mdef->mconf) { @@ -3189,8 +3162,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -3208,9 +3179,6 @@ struct mhitm_data *mhm; mhm->damage = mon_poly(magr, mdef, mhm->damage); } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - if (!magr->mcan && mhm->damage < mdef->mhp) mhm->damage = mon_poly(magr, mdef, mhm->damage); } @@ -3223,8 +3191,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ mhm->damage = 0; @@ -3334,9 +3300,6 @@ struct mhitm_data *mhm; mhm->damage = 0; } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); - if (!magr->mcan && haseyes(pd) && mdef->mcansee) { if (g.vis && canseemon(mdef)) pline("%s looks %sconfused.", Monnam(mdef), @@ -3377,7 +3340,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pa = magr->data; struct permonst *pd = mdef->data; /* may die from the acid if it eats a stone-curing corpse */ @@ -3419,10 +3381,6 @@ struct mhitm_data *mhm; if (magr == &g.youmonst) { /* uhitm */ - int armpro = magic_negation(mdef); - /* since hero can't be cancelled, only defender's armor applies */ - boolean negated = !(rn2(10) >= 3 * armpro); - if (pd == &mons[PM_SHADE]) { mhm->damage = 0; if (!mhm->specialdmg) @@ -3455,9 +3413,6 @@ struct mhitm_data *mhm; } } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - if (mattk->aatyp == AT_HUGS && !sticks(pd)) { if (!u.ustuck && rn2(2)) { if (u_slip_free(magr, mattk)) { @@ -3538,8 +3493,6 @@ struct mhitm_data *mhm; } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); struct obj *mwep = MON_WEP(magr); if (mattk->aatyp != AT_WEAP && mattk->aatyp != AT_CLAW) @@ -3607,8 +3560,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ if (!munstone(mdef, TRUE)) @@ -3652,7 +3603,6 @@ struct monst *mdef; struct mhitm_data *mhm; { struct permonst *pa = magr->data; - struct permonst *pd = mdef->data; if (magr == &g.youmonst) { /* uhitm */ @@ -3696,9 +3646,6 @@ struct mhitm_data *mhm; return; } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - /* a cancelled nurse is just an ordinary monster, * nurses don't heal those that cause petrification */ if (magr->mcan || (Upolyd && touch_petrifies(pd))) { @@ -3817,8 +3764,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ #if 0 @@ -3832,9 +3777,6 @@ struct mhitm_data *mhm; return; } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; const char *sidestr = (side == RIGHT_SIDE) ? "right" : "left", *Monst_name = Monnam(magr), *leg = body_part(LEG); @@ -3966,8 +3908,6 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { - struct permonst *pd = mdef->data; - if (magr == &g.youmonst) { /* uhitm */ mhm->damage = 0; @@ -3993,7 +3933,6 @@ struct monst *mdef; struct mhitm_data *mhm; { struct permonst *pa = magr->data; - struct permonst *pd = mdef->data; if (magr == &g.youmonst) { /* uhitm */ @@ -4017,7 +3956,6 @@ struct monst *mdef; struct mhitm_data *mhm; { struct permonst *pa = magr->data; - struct permonst *pd = mdef->data; if (magr == &g.youmonst) { /* uhitm */ @@ -4025,8 +3963,6 @@ struct mhitm_data *mhm; mhm->damage = 0; } else if (mdef == &g.youmonst) { /* mhitu */ - int armpro = magic_negation(mdef); - boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); char buf[BUFSZ]; if (is_animal(magr->data)) { @@ -4087,8 +4023,6 @@ struct mhitm_data *mhm; } } else { /* mhitm */ - int armpro = magic_negation(mdef); - boolean cancelled = magr->mcan || !(rn2(10) >= 3 * armpro); struct obj *obj; if (magr->mcan) @@ -4244,7 +4178,6 @@ register struct monst *mdef; register struct attack *mattk; int specialdmg; /* blessed and/or silver bonus against various things */ { - register struct permonst *pd = mdef->data; int armpro; boolean negated; struct mhitm_data mhm; From 1f6a7a5eef2e964d229fbe7f44ea8693438bc3c7 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 1 Dec 2020 19:36:19 +0200 Subject: [PATCH 528/708] Init the done variable to false --- src/mhitm.c | 1 + src/mhitu.c | 1 + src/uhitm.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/mhitm.c b/src/mhitm.c index 6b182d093..f86843035 100644 --- a/src/mhitm.c +++ b/src/mhitm.c @@ -865,6 +865,7 @@ int dieroll; mhm.permdmg = 0; mhm.specialdmg = 0; mhm.dieroll = dieroll; + mhm.done = FALSE; if ((touch_petrifies(pd) /* or flesh_petrifies() */ || (mattk->adtyp == AD_DGST && pd == &mons[PM_MEDUSA])) diff --git a/src/mhitu.c b/src/mhitu.c index ba628651b..89d77dd2d 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -972,6 +972,7 @@ register struct attack *mattk; mhm.hitflags = MM_MISS; mhm.permdmg = 0; mhm.specialdmg = 0; + mhm.done = FALSE; if (!canspotmon(mtmp)) map_invisible(mtmp->mx, mtmp->my); diff --git a/src/uhitm.c b/src/uhitm.c index c78032972..470bb02cb 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -4185,6 +4185,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ mhm.hitflags = MM_MISS; mhm.permdmg = 0; mhm.specialdmg = specialdmg; + mhm.done = FALSE; armpro = magic_negation(mdef); /* since hero can't be cancelled, only defender's armor applies */ From d28489e55d58ccb78744a1cca6331872abbe756c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 4 Dec 2020 09:49:24 +0200 Subject: [PATCH 529/708] Fixes bit for mhitm/uhitm/mhitu unification --- doc/fixes37.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d7fad4bb9..3943ad444 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -748,5 +748,7 @@ rework stairs structure into a linked list move 'restoring' to the program_state struct; add corresponding 'saving'; both used to enforce no updating of status lines or of persistent inventory when the relevant activity is in progress +unify special attack damages from separate you-hit-monster, monster-hits-you, + and monster-hits-monster into functions by damage type From 6056799e2219e48eff424df5c791dad0daffc9a1 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 4 Dec 2020 02:11:53 -0800 Subject: [PATCH 530/708] XhitX unification - unused function parameters --- src/uhitm.c | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/src/uhitm.c b/src/uhitm.c index 470bb02cb..0b64ff8fe 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 uhitm.c $NHDT-Date: 1606558760 2020/11/28 10:19:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.244 $ */ +/* NetHack 3.7 uhitm.c $NHDT-Date: 1607076540 2020/12/04 10:09:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -9,13 +9,12 @@ static const char brief_feeling[] = "have a %s feeling for a moment, then it passes."; static boolean FDECL(known_hitum, (struct monst *, struct obj *, int *, - int, int, struct attack *, int)); + int, int, struct attack *, int)); static boolean FDECL(theft_petrifies, (struct obj *)); static void FDECL(steal_it, (struct monst *, struct attack *)); static boolean FDECL(hitum_cleave, (struct monst *, struct attack *)); static boolean FDECL(hitum, (struct monst *, struct attack *)); -static boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int, - int)); +static boolean FDECL(hmon_hitmon, (struct monst *, struct obj *, int, int)); static int FDECL(joust, (struct monst *, struct obj *)); static void NDECL(demonpet); static boolean FDECL(m_slips_free, (struct monst *, struct attack *)); @@ -2533,10 +2532,11 @@ struct mhitm_data *mhm; mhm->hitflags = MM_MISS; mhm->done = TRUE; return; - } - else if (mdef->mtame && !g.vis) + } else if (mdef->mtame && !g.vis) { You(brief_feeling, "strangely sad"); - mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + } + mhm->hitflags = (MM_DEF_DIED + | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); mhm->done = TRUE; return; } @@ -2609,9 +2609,9 @@ struct mhitm_data *mhm; pline_The("poison doesn't seem to affect %s.", mon_nam(mdef)); } else { - if (rn2(10)) + if (rn2(10)) { mhm->damage += rn1(10, 6); - else { + } else { if (g.vis && canspotmon(mdef)) pline_The("poison was deadly..."); mhm->damage = mdef->mhp; @@ -2895,6 +2895,8 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { + mhm->damage = 0; /* no HP damage */ + if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -3026,6 +3028,8 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { + mhm->damage = 0; /* no HP damage */ + if (magr == &g.youmonst) { /* uhitm */ /* there's no msomearmor() function, so just do damage */ @@ -3077,6 +3081,8 @@ struct attack *mattk; struct monst *mdef; struct mhitm_data *mhm; { + mhm->damage = 0; /* no HP damage */ + if (magr == &g.youmonst) { /* uhitm */ int armpro = magic_negation(mdef); @@ -3158,7 +3164,7 @@ struct mhitm_data *mhm; void mhitm_ad_poly(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; /* implied */ struct monst *mdef; struct mhitm_data *mhm; { @@ -3175,7 +3181,8 @@ struct mhitm_data *mhm; int armpro = magic_negation(mdef); boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - if (uncancelled && Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) + if (uncancelled + && Maybe_Half_Phys(mhm->damage) < (Upolyd ? u.mh : u.uhp)) mhm->damage = mon_poly(magr, mdef, mhm->damage); } else { /* mhitm */ @@ -3187,7 +3194,7 @@ struct mhitm_data *mhm; void mhitm_ad_famn(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; struct monst *mdef; struct mhitm_data *mhm; { @@ -3210,7 +3217,7 @@ struct mhitm_data *mhm; void mhitm_ad_pest(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; struct monst *mdef; struct mhitm_data *mhm; { @@ -3233,7 +3240,7 @@ struct mhitm_data *mhm; void mhitm_ad_deth(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; struct monst *mdef; struct mhitm_data *mhm; { @@ -3286,7 +3293,7 @@ struct mhitm_data *mhm; void mhitm_ad_halu(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; struct monst *mdef; struct mhitm_data *mhm; { @@ -3336,7 +3343,7 @@ struct monst *mtmp; void do_stone_mon(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; struct monst *mdef; struct mhitm_data *mhm; { @@ -3359,10 +3366,11 @@ struct mhitm_data *mhm; mhm->hitflags = MM_MISS; mhm->done = TRUE; return; - } - else if (mdef->mtame && !g.vis) + } else if (mdef->mtame && !g.vis) { You(brief_feeling, "peculiarly sad"); - mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); + } + mhm->hitflags = (MM_DEF_DIED + | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); mhm->done = TRUE; return; } @@ -3829,7 +3837,7 @@ struct mhitm_data *mhm; void mhitm_ad_dgst(magr, mattk, mdef, mhm) struct monst *magr; -struct attack *mattk; +struct attack *mattk UNUSED; struct monst *mdef; struct mhitm_data *mhm; { @@ -4848,9 +4856,9 @@ register struct monst *mon; &attknum, &armorpenalty); if ((dhit = (tmp > rnd(20 + i)))) { wakeup(mon, TRUE); - if (mon->data == &mons[PM_SHADE]) + if (mon->data == &mons[PM_SHADE]) { Your("attempt to surround %s is harmless.", mon_nam(mon)); - else { + } else { sum[i] = gulpum(mon, mattk); if (sum[i] == MM_DEF_DIED && (mon->data->mlet == S_ZOMBIE || mon->data->mlet == S_MUMMY) From 0ba41842061aed78664696ce17ec6587d8e86ae7 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 4 Dec 2020 02:58:03 -0800 Subject: [PATCH 531/708] couple more command tweaks Rename "seegold" to "showgold". The character to invoke it ('$') is similar to those for the various "seeXYZ" commands ('[','=',&c) but unlike them, it isn't part of "seeall" ('*'). Expand or replace the one-line description of several commands (shell, showgold, showtrap, suspend, versionshort). --- doc/fixes37.0 | 4 ++-- src/cmd.c | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3943ad444..ca4cb5939 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.371 $ $NHDT-Date: 1606954304 2020/12/03 00:11:44 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ $NHDT-Date: 1607079461 2020/12/04 10:57:41 $ General Fixes and Modified Features ----------------------------------- @@ -315,7 +315,7 @@ try to fix message sequencing for tame golems that "roast/rot/rust in peace" autodescribe when moving the cursor was erroneously honoring MSGTYPE=stop and potentially delivering sounds reduce the number of "seeXYZ" commands by renaming some: #seenv -> #wizseenv, - #seespells -> #showspells, and #seetrap -> #showtrap + #seegold -> #showgold, #seespells -> #showspells, #seetrap -> #showtrap when saving while punished or game ends while punished, handling for ball and chain might access freed memory with unpredictable consequences diff --git a/src/cmd.c b/src/cmd.c index d4d999ef7..ea0879b7b 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1606781767 2020/12/01 00:16:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.426 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607079461 2020/12/04 10:57:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.427 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1873,26 +1873,29 @@ struct ext_func_tab extcmdlist[] = { dopramulet, IFBURIED }, { ARMOR_SYM, "seearmor", "show the armor currently worn", doprarm, IFBURIED }, - { GOLD_SYM, "seegold", "count your gold", doprgold, IFBURIED }, { RING_SYM, "seerings", "show the ring(s) currently worn", doprring, IFBURIED }, { TOOL_SYM, "seetools", "show the tools currently in use", doprtool, IFBURIED }, { WEAPON_SYM, "seeweapon", "show the weapon currently wielded", doprwep, IFBURIED }, - { '!', "shell", "do a shell escape", + { '!', "shell", "leave game to enter a sub-shell ('exit' to come back)", dosh_core, IFBURIED | GENERALCMD #ifndef SHELL | CMD_NOT_AVAILABLE #endif /* SHELL */ }, + /* $ is like ),=,&c but is not included with *, so not called "seegold" */ + { GOLD_SYM, "showgold", "show gold, possibly shop credit or debt", + doprgold, IFBURIED }, { SPBOOK_SYM, "showspells", "list and reorder known spells", dovspell, IFBURIED }, - { '^', "showtrap", "show the type of adjacent trap", doidtrap, IFBURIED }, + { '^', "showtrap", "describe an adjacent, discovered trap", + doidtrap, IFBURIED }, { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE }, { '\0', "stats", "show memory statistics", wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, - { C('z'), "suspend", "suspend the game", + { C('z'), "suspend", "push game to background ('fg' to come back)", dosuspend_core, IFBURIED | GENERALCMD #ifndef SUSPEND | CMD_NOT_AVAILABLE @@ -1922,7 +1925,8 @@ struct ext_func_tab extcmdlist[] = { { M('v'), "version", "list compile time options for this version of NetHack", doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD }, - { 'v', "versionshort", "show version", doversion, IFBURIED | GENERALCMD }, + { 'v', "versionshort", "show version and date/time program was built", + doversion, IFBURIED | GENERALCMD }, { '\0', "vision", "show vision array", wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '.', "wait", "rest one move while doing nothing", From 5b3632249f8119427d7e4645f641be2d7baafe3a Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 4 Dec 2020 08:21:53 -0500 Subject: [PATCH 532/708] add a couple of optional fetching targets to sys/winnt/Makefile.msc --- sys/winnt/Makefile.msc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 6bbcee59e..259b1010a 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1192,6 +1192,32 @@ $(O)envchk.tag: $(O)obj.tag #========================================== #=========== SECONDARY TARGETS ============ #========================================== +fetch-lua: fetch-actual-Lua + +fetch-Lua: fetch-actual-Lua + +fetch-actual-Lua: + @if not exist ..\lib\*.* mkdir ..\lib + cd ..\lib + curl -R -O http://www.lua.org/ftp/lua-$(LUAVER).tar.gz + tar zxf lua-$(LUAVER).tar.gz + if exist lua-$(LUAVER).tar.gz del lua-$(LUAVER).tar.gz + if exist lua-$(LUAVER).tar del lua-$(LUAVER).tar + cd ..\src + @echo Lua has been fetched into ..\lib\lua-$(LUAVER) + +fetch-pdcurses: + @if not exist ..\lib\*.* mkdir ..\lib + cd ..\lib + curl -L -R https://codeload.github.com/wmcbrine/PDCurses/zip/master -o pdcurses.zip + powershell -command "Expand-Archive -Path .\pdcurses.zip -DestinationPath ./pdcurses-temp" + if exist .\pdcurses\* rd .\pdcurses /s /Q + move .\pdcurses-temp\PDCurses-master . + ren PDCurses-master pdcurses + if exist .\pdcurses-temp\* rd .\pdcurses-temp /s /Q + if exist .\pdcurses.zip del .\pdcurses.zip + cd ..\src + @echo pdcurses has been fetched into ..\lib\pdcurses #========================================== # DLB utility and nhdatNNN file creation From efbd92b906f8ea2a350745a34e7836877cb67da5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 4 Dec 2020 08:25:52 -0500 Subject: [PATCH 533/708] a couple of space-indents to tabs-indents in sys/winnt/Makefile.msc --- sys/winnt/Makefile.msc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 259b1010a..3a2d0749a 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -1212,8 +1212,8 @@ fetch-pdcurses: curl -L -R https://codeload.github.com/wmcbrine/PDCurses/zip/master -o pdcurses.zip powershell -command "Expand-Archive -Path .\pdcurses.zip -DestinationPath ./pdcurses-temp" if exist .\pdcurses\* rd .\pdcurses /s /Q - move .\pdcurses-temp\PDCurses-master . - ren PDCurses-master pdcurses + move .\pdcurses-temp\PDCurses-master . + ren PDCurses-master pdcurses if exist .\pdcurses-temp\* rd .\pdcurses-temp /s /Q if exist .\pdcurses.zip del .\pdcurses.zip cd ..\src From 55b49463056742ab3842b8a4ea49d7ee6306e2f5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 4 Dec 2020 19:00:16 +0200 Subject: [PATCH 534/708] Fix AD_DCAY mhitm armor erosion type --- doc/fixes37.0 | 2 ++ src/uhitm.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index ca4cb5939..8e52f52c2 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -318,6 +318,8 @@ reduce the number of "seeXYZ" commands by renaming some: #seenv -> #wizseenv, #seegold -> #showgold, #seespells -> #showspells, #seetrap -> #showtrap when saving while punished or game ends while punished, handling for ball and chain might access freed memory with unpredictable consequences +brown pudding monster hitting another monster with decay attack corroded armor + instead of rotting it Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/uhitm.c b/src/uhitm.c index 0b64ff8fe..5f2018078 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1826,7 +1826,7 @@ struct mhitm_data *mhm; mhm->hitflags = (MM_DEF_DIED | (grow_up(magr, mdef) ? 0 : MM_AGR_DIED)); return; } - erode_armor(mdef, ERODE_CORRODE); + erode_armor(mdef, ERODE_ROT); mdef->mstrategy &= ~STRAT_WAITFORU; mhm->damage = 0; } From 44920d46502465a938af7bb878e1c6b4b56f23d4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 5 Dec 2020 19:00:19 +0200 Subject: [PATCH 535/708] Remove duplicate lines --- src/mon.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/mon.c b/src/mon.c index 76ed3b28e..e203e71d7 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1586,17 +1586,11 @@ struct monst *mtmp; /* unicorn may not be able to avoid hero on a noteleport level */ if (is_unicorn(mtmp->data) && !noteleport_level(mtmp)) allowflags |= NOTONL; - if (passes_walls(mtmp->data)) - allowflags |= (ALLOW_WALL | ALLOW_ROCK); - if (passes_bars(mtmp->data)) - allowflags |= ALLOW_BARS; if (is_human(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR]) allowflags |= ALLOW_SSM; if ((is_undead(mtmp->data) && mtmp->data->mlet != S_GHOST) || is_vampshifter(mtmp)) allowflags |= NOGARLIC; - if (throws_rocks(mtmp->data)) - allowflags |= ALLOW_ROCK; return allowflags; } From 0462a2088c5937a8fb3ea0fdecdd4326cf180ef1 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 5 Dec 2020 19:38:16 +0200 Subject: [PATCH 536/708] Increment EDITLEVEL Forgot to increment EDITLEVEL when I did the stairs change, and again after fixing the Oracle bones stairs. Lets do it now. --- include/patchlevel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/patchlevel.h b/include/patchlevel.h index d240f2245..47f5d5235 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 27 +#define EDITLEVEL 28 /* * Development status possibilities. From edefa148349221238eb4c95f43e708dadf33030c Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 5 Dec 2020 12:29:38 -0800 Subject: [PATCH 537/708] readable conical hats Let tourists read cornuthaum ("WIZZARD") and dunce cap ("DUNCE"). One out of three will have those words, the other two will yield "you can't find anything to read on this ___" where ___ is either "conical hat" or "cornuthaum" or "dunce cap" depending upon hat type and discovery status. Even when a dunce cap says "DUNCE" it won't become discovered, just offer the player an opportunity to apply a name. Other roles still fall through to the "That's a silly thing to read" feedback. Not intended to be logical... --- doc/fixes37.0 | 3 +- src/read.c | 85 +++++++++++++++++++++++++++++++++++---------------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 8e52f52c2..393121815 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.373 $ $NHDT-Date: 1607079461 2020/12/04 10:57:41 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.375 $ $NHDT-Date: 1607200174 2020/12/05 20:29:34 $ General Fixes and Modified Features ----------------------------------- @@ -640,6 +640,7 @@ render the color names in the corresponding color when using the pick-a-color reading blessed scroll of teleportation confers one-shot teleport control mild zombie apocalypse list lamps and lanterns in charging prompt +let tourists read conical hats Platform- and/or Interface-Specific New Features diff --git a/src/read.c b/src/read.c index bd208a9d6..49bc07ce7 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1600468453 2020/09/18 22:34:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.202 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1607200174 2020/12/05 20:29:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.204 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -214,8 +214,10 @@ struct obj *obj; int doread() { + static const char find_any_braille[] = "feel any Braille writing."; register struct obj *scroll; boolean confused, nodisappear; + int otyp; /* * Reading while blind is allowed in most cases, including the @@ -241,9 +243,10 @@ doread() scroll = getobj(readable, "read"); if (!scroll) return 0; + otyp = scroll->otyp; /* outrumor has its own blindness check */ - if (scroll->otyp == FORTUNE_COOKIE) { + if (otyp == FORTUNE_COOKIE) { if (flags.verbose) You("break up the cookie and throw away the pieces."); outrumor(bcsign(scroll), BY_COOKIE); @@ -251,16 +254,16 @@ doread() u.uconduct.literate++; useup(scroll); return 1; - } else if (scroll->otyp == T_SHIRT || scroll->otyp == ALCHEMY_SMOCK) { + } else if (otyp == T_SHIRT || otyp == ALCHEMY_SMOCK) { char buf[BUFSZ], *mesg; const char *endpunct; if (Blind) { - You_cant("feel any Braille writing."); + You_cant(find_any_braille); return 0; } /* can't read shirt worn under suit (under cloak is ok though) */ - if (scroll->otyp == T_SHIRT && uarm && scroll == uarmu) { + if (otyp == T_SHIRT && uarm && scroll == uarmu) { pline("%s shirt is obscured by %s%s.", scroll->unpaid ? "That" : "Your", shk_your(buf, uarm), suit_simple_name(uarm)); @@ -268,8 +271,8 @@ doread() } u.uconduct.literate++; /* populate 'buf[]' */ - mesg = (scroll->otyp == T_SHIRT) ? tshirt_text(scroll, buf) - : apron_text(scroll, buf); + mesg = (otyp == T_SHIRT) ? tshirt_text(scroll, buf) + : apron_text(scroll, buf); endpunct = ""; if (flags.verbose) { int ln = (int) strlen(mesg); @@ -281,7 +284,37 @@ doread() } pline("\"%s\"%s", mesg, endpunct); return 1; - } else if (scroll->otyp == CREDIT_CARD) { + } else if ((otyp == DUNCE_CAP || otyp == CORNUTHAUM) + /* note: "DUNCE" isn't directly connected to tourists but + if everyone could read it, they would always be able to + trivially distinguish between the two types of conical hat; + limiting this to tourists is better than rejecting it */ + && Role_if(PM_TOURIST)) { + /* another note: the misspelling, "wizzard", is correct; + that's what is written on Rincewind's pointy hat from + Pratchett's Discworld series, along with a lot of stars; + rather than inked on or painted on, treat them as stitched + or even separate pieces of fabric which have been attached + (don't recall whether the books mention anything like that...) */ + const char *cap_text = (otyp == DUNCE_CAP) ? "DUNCE" : "WIZZARD"; + + if (scroll->o_id % 3) { + /* no need to vary this when blind; "on this ___" is important + because it suggests that there might be something on others */ + You_cant("find anything to read on this %s.", + simpleonames(scroll)); + return 0; + } + pline("%s on the %s. It reads: %s.", + !Blind ? "There is writing" : "You feel lettering", + simpleonames(scroll), cap_text); + u.uconduct.literate++; + /* yet another note: despite the fact that player will recognize + the object type, don't make it become a discovery for hero */ + if (!objects[otyp].oc_name_known && !objects[otyp].oc_uname) + docall(scroll); + return 1; + } else if (otyp == CREDIT_CARD) { static const char *card_msgs[] = { "Leprechaun Gold Tru$t - Shamrock Card", "Magic Memory Vault Charge Card", @@ -320,12 +353,12 @@ doread() (flags.verbose || Blind) ? "." : ""); u.uconduct.literate++; return 1; - } else if (scroll->otyp == CAN_OF_GREASE) { + } else if (otyp == CAN_OF_GREASE) { pline("This %s has no label.", singular(scroll, xname)); return 0; - } else if (scroll->otyp == MAGIC_MARKER) { + } else if (otyp == MAGIC_MARKER) { if (Blind) { - You_cant("feel any Braille writing."); + You_cant(find_any_braille); return 0; } if (flags.verbose) @@ -349,11 +382,11 @@ doread() pline("\"Odin.\""); u.uconduct.literate++; return 1; - } else if (scroll->otyp == CANDY_BAR) { + } else if (otyp == CANDY_BAR) { const char *wrapper = candy_wrapper_text(scroll); if (Blind) { - You_cant("feel any Braille writing."); + You_cant(find_any_braille); return 0; } if (!*wrapper) { @@ -367,10 +400,10 @@ doread() && scroll->oclass != SPBOOK_CLASS) { pline(silly_thing_to, "read"); return 0; - } else if (Blind && (scroll->otyp != SPE_BOOK_OF_THE_DEAD)) { + } else if (Blind && otyp != SPE_BOOK_OF_THE_DEAD) { const char *what = 0; - if (scroll->otyp == SPE_NOVEL) + if (otyp == SPE_NOVEL) /* unseen novels are already distinguishable from unseen spellbooks so this isn't revealing any extra information */ what = "words"; @@ -386,7 +419,7 @@ doread() confused = (Confusion != 0); #ifdef MAIL - if (scroll->otyp == SCR_MAIL) { + if (otyp == SCR_MAIL) { confused = FALSE; /* override */ /* reading mail is a convenience for the player and takes place outside the game, so shouldn't affect gameplay; @@ -405,24 +438,22 @@ doread() #endif /* Actions required to win the game aren't counted towards conduct */ - /* Novel conduct is handled in read_tribute so exclude it too*/ - if (scroll->otyp != SPE_BOOK_OF_THE_DEAD - && scroll->otyp != SPE_BLANK_PAPER && scroll->otyp != SCR_BLANK_PAPER - && scroll->otyp != SPE_NOVEL) + /* Novel conduct is handled in read_tribute so exclude it too */ + if (otyp != SPE_BOOK_OF_THE_DEAD && otyp != SPE_NOVEL + && otyp != SPE_BLANK_PAPER && otyp != SCR_BLANK_PAPER) u.uconduct.literate++; if (scroll->oclass == SPBOOK_CLASS) { return study_book(scroll); } scroll->in_use = TRUE; /* scroll, not spellbook, now being read */ - if (scroll->otyp != SCR_BLANK_PAPER) { + if (otyp != SCR_BLANK_PAPER) { boolean silently = !can_chant(&g.youmonst); /* a few scroll feedback messages describe something happening to the scroll itself, so avoid "it disappears" for those */ - nodisappear = (scroll->otyp == SCR_FIRE - || (scroll->otyp == SCR_REMOVE_CURSE - && scroll->cursed)); + nodisappear = (otyp == SCR_FIRE + || (otyp == SCR_REMOVE_CURSE && scroll->cursed)); if (Blind) pline(nodisappear ? "You %s the formula on the scroll." @@ -440,14 +471,14 @@ doread() } } if (!seffects(scroll)) { - if (!objects[scroll->otyp].oc_name_known) { + if (!objects[otyp].oc_name_known) { if (g.known) learnscroll(scroll); - else if (!objects[scroll->otyp].oc_uname) + else if (!objects[otyp].oc_uname) docall(scroll); } scroll->in_use = FALSE; - if (scroll->otyp != SCR_BLANK_PAPER) + if (otyp != SCR_BLANK_PAPER) useup(scroll); } return 1; From 9e33d658a4a8f6b24684807a5225fb6db262d6d6 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 5 Dec 2020 12:32:52 -0800 Subject: [PATCH 538/708] conflicting 'bullets' This was pointed out several years ago. Since tho different 'static bullets[]' contain different values, give them distinct names. --- src/dothrow.c | 11 ++++++----- src/wield.c | 6 +++--- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dothrow.c b/src/dothrow.c index f3015bfd1..f0ed6546e 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dothrow.c $NHDT-Date: 1606343578 2020/11/25 22:32:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ +/* NetHack 3.7 dothrow.c $NHDT-Date: 1607200366 2020/12/05 20:32:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -23,8 +23,9 @@ static boolean FDECL(mhurtle_step, (genericptr_t, int, int)); static NEARDATA const char toss_objs[] = { ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, WEAPON_CLASS, 0 }; /* different default choices when wielding a sling (gold must be included) */ -static NEARDATA const char bullets[] = { ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, - GEM_CLASS, 0 }; +static NEARDATA const char t_bullets[] = { + ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, GEM_CLASS, 0 +}; /* g.thrownobj (decl.c) tracks an object until it lands */ @@ -295,7 +296,7 @@ dothrow() if (!ok_to_throw(&shotlimit)) return 0; - obj = getobj(uslinging() ? bullets : toss_objs, "throw"); + obj = getobj(uslinging() ? t_bullets : toss_objs, "throw"); /* it is also possible to throw food */ /* (or jewels, or iron balls... ) */ @@ -407,7 +408,7 @@ dofire() use direction of previous throw as getobj()'s choice here */ g.in_doagain = 0; /* choose something from inventory, then usually quiver it */ - obj = getobj(uslinging() ? bullets : toss_objs, "throw"); + obj = getobj(uslinging() ? t_bullets : toss_objs, "throw"); /* Q command doesn't allow gold in quiver */ if (obj && !obj->owornmask && obj->oclass != COIN_CLASS) setuqwep(obj); /* demi-autoquiver */ diff --git a/src/wield.c b/src/wield.c index 5d5b04b94..b5f2dbac8 100644 --- a/src/wield.c +++ b/src/wield.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 wield.c $NHDT-Date: 1596498228 2020/08/03 23:43:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */ +/* NetHack 3.7 wield.c $NHDT-Date: 1607200367 2020/12/05 20:32:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -275,7 +275,7 @@ static NEARDATA const char wield_objs[] = { static NEARDATA const char ready_objs[] = { ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, ALLOW_NONE, WEAPON_CLASS, 0 }; -static NEARDATA const char bullets[] = { /* (note: different from dothrow.c) */ +static NEARDATA const char w_bullets[] = { /* (different from dothrow.c) */ ALLOW_COUNT, COIN_CLASS, ALL_CLASSES, ALLOW_NONE, GEM_CLASS, WEAPON_CLASS, 0 }; @@ -455,7 +455,7 @@ dowieldquiver() quivee_types = (uslinging() || (uswapwep && objects[uswapwep->otyp].oc_skill == P_SLING)) - ? bullets + ? w_bullets : ready_objs; newquiver = getobj(quivee_types, "ready"); From 1d8503a9129f551db9635588e0c13b1effa67a4b Mon Sep 17 00:00:00 2001 From: Patric Mueller Date: Sun, 6 Dec 2020 00:27:56 +0100 Subject: [PATCH 539/708] Typo in impossible message in spitmm --- src/mthrowu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mthrowu.c b/src/mthrowu.c index 55cc3c92a..ab96ee0b7 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -759,7 +759,7 @@ struct attack *mattk; otmp = mksobj(BLINDING_VENOM, TRUE, FALSE); break; default: - impossible("bad attack type in spitmu"); + impossible("bad attack type in spitmm"); /*FALLTHRU*/ case AD_ACID: otmp = mksobj(ACID_VENOM, TRUE, FALSE); From 13aa5e74803f2d54bb8e8eff8eddfb2004c1191b Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 5 Dec 2020 17:31:59 -0800 Subject: [PATCH 540/708] Adding Azure pipeline YAML. --- azure-pipelines.yml | 73 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 azure-pipelines.yml diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..a2348072a --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,73 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +strategy: + matrix: + linux: + imageName: 'ubuntu-20.04' + mac: + imageName: 'macOS-10.15' + windows: + imageName: 'windows-latest' + +pool: + vmImage: $(imageName) + +resources: + repositories: + - repository: luarepo + type: github + name: lua/lua + ref: refs/tags/v5.4.1 + endpoint: github.com_barthouse + +steps: +- checkout: git://NetHack/NHsource@NetHack-3.7 # $(Agent.BuildDirectory)\s\NHsource +- checkout: luarepo # $(Agent.BuildDirectory)\s\lua + +- task: DownloadSecureFile@1 + name: storeKey + displayName: 'Store Key Download' + inputs: + secureFile: 'NetHackPackage_StoreKey.pfx' + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + +- task: CopyFiles@2 + inputs: + contents: NetHackPackage_StoreKey.pfx + SourceFolder: $(Agent.TempDirectory) + TargetFolder: $(Agent.BuildDirectory)\s\NHsource\win\win32\vs + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + +- task: CopyFiles@2 + inputs: + SourceFolder: $(Agent.BuildDirectory)\s\lua + TargetFolder: $(Agent.BuildDirectory)\s\NHsource\lib\lua-5.4.1\src + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + +- task: MSBuild@1 + inputs: + solution: $(Agent.BuildDirectory)\s\NHsource\win\win32\vs\NetHack.sln + platform: Win32 + configuration: Debug + condition: eq( variables['Agent.OS'], 'Windows_NT' ) + +- bash: | + cd NHsource/sys/unix + sh setup.sh hints/linux.2020 + cd ../.. + make fetch-lua + make all + condition: eq( variables['Agent.OS'], 'Linux' ) + displayName: 'Linux Build' + +- bash: | + cd NHsource/sys/unix + sh setup.sh hints/macosx10.14 + cd ../.. + make fetch-lua + make all + condition: eq( variables['Agent.OS'], 'Darwin' ) + displayName: 'Mac Build' From 6bfd1c7e621bf98f3c25dca704042bb8edea0627 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 5 Dec 2020 19:37:03 -0800 Subject: [PATCH 541/708] Qt's window menus Qt on OSX is inserting "Search [_____]" as the first entry in the Help dropdown menu (the one in the toolbar at the top of the desttop). While trying--and failing--to figure out how to get rid of that, I cleaned up a little bit of the old menu hackery (that tries to workaround the fact that Qt on OSX insists that some menu actions--based solely on their names--should go into the appication menu rather than whichever menu the program is trying to insert them into). The only observeable difference is that 'About NetHack-Qt' will be at the top (actually second because of that Search one) of the Help dropdown, where it is on non-OSX builds, rather than last. This tries to make the program name consistent too, changing several instances of "Qt NetHack" to be "NetHack-Qt". The latter is the name being set up as ApplicationName in qt_bind.cpp that gets used when Qt stashes the Qt-specific settings wherever it stashes them. It also makes another tweak in formatting of 'About NetHack-Qt', inserting one explicit line break to avoid some poor looking line wrapping. I still haven't figured out how to control that popup's size. --- win/Qt/Qt-issues.txt | 6 ++++ win/Qt/qt_main.cpp | 69 +++++++++++++++++++++++--------------------- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index c38fca661..98c4621a6 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -26,6 +26,12 @@ around by giving focus to some other application (which will put up its own menu bar) and then back to nethack (thereby reloading nethack's menu bar). +On OSX, a "Search [______]" action is inserted as the first entry of +the dropdown Help menu on the toolbar. NetHack has no control over +what it does or where it looks, so it should be eliminated somehow. +(It is not releated to nethack's search command, nor the interception +of an attempt to insert "Search" into the dropdown Action menu.) + Sometimes scrolling a menu leaves the displayed text not matching what nethack thinks is displayed, so making a selection by mouse click may occasionally pick the wrong item. There's usually a visual clue when diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index b4f3822f9..a8bbebed8 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -454,10 +454,12 @@ aboutMsg() but we're using it mid-sentence so strip period off */ if ((p = strrchr(getversionstring(vbuf), '.')) != 0 && *(p + 1) == '\0') *p = '\0'; + /* it's also long; break it into two pieces */ + (void) strsubst(vbuf, " - ", "\n- "); QString msg; msg.sprintf( // format - "Qt NetHack is a version of NetHack built using" // no newline + "NetHack-Qt is a version of NetHack built using" // no newline #ifdef KDE " KDE and" // ditto #endif @@ -527,7 +529,7 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : addToolBar(toolbar); menubar = menuBar(); - setWindowTitle("Qt NetHack"); + setWindowTitle("NetHack-Qt"); setWindowIcon(QIcon(QPixmap(qt_compact_mode ? nh_icon_small : nh_icon))); #ifdef MACOSX @@ -672,26 +674,42 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { 0, 0, 0 } }; - int i; - - game->addAction( + QAction *actn; #ifndef MACOSX - "Qt settings...", + (void) game->addAction("Qt settings...", this, SLOT(doQtSettings(bool))); #else - /* on OSX, put this in the application menu by using - a name that Qt will move to that menu */ - "Preferences...", + /* on OSX, put this in the application menu instead of the game menu; + Qt would change the action name behind our backs; do it explicitly */ + actn = game->addAction("Preferences...", this, SLOT(doQtSettings(bool))); + actn->setMenuRole(QWidgetAction::PreferencesRole); + /* we also want a "Quit NetHack" entry in the application menu; + when "_Quit-without-saving" was called "Quit" it got intercepted + for that, but now this needs to be added separately; we'll use a + handy menu and let the interception put it in the intended place; + unlike About, it is not a duplicate; _Quit-without-saving runs + nethack's #quit command with "really quit?" prompt, this quit--with + Command+q as shortcut--pops up a dialog to choose between quit or + cancel-and-resume-playing */ + actn = game->addAction("Quit NetHack-Qt", this, SLOT(doQuit(bool))); + actn->setMenuRole(QWidgetAction::QuitRole); +#endif + + actn = help->addAction("About NetHack-Qt", this, SLOT(doAbout(bool))); +#ifdef MACOSX + actn->setMenuRole(QWidgetAction::AboutRole); + /* for OSX, the preceding "About" went into the application menu; + now add another duplicate one to the Help dropdown menu */ + actn = help->addAction("About NetHack-Qt", this, SLOT(doAbout(bool))); + actn->setMenuRole(QWidgetAction::NoRole); +#else + nhUse(actn); #endif - this, SLOT(doQtSettings(bool))); - /* on OSX, 'about' will end up in the application menu rather than - the help menu (this had trailing "..." but that conflicts with - the convention that an elipsis indicates the choice will bring - up its own sub-menu) */ - help->addAction("About Qt NetHack", this, SLOT(doAbout(bool))); - //help->addAction("NetHack Guidebook", this, SLOT(doGuidebook(bool))); help->addSeparator(); - for (i=0; item[i].menu; i++) { + //help->addAction("NetHack Guidebook", this, SLOT(doGuidebook(bool))); + //help->addSeparator(); + + for (int i = 0; item[i].menu; ++i) { if ( item[i].flags & (qt_compact_mode ? 1 : 2) ) { if (item[i].name) { char actchar[32]; @@ -766,21 +784,6 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : help->setTitle("Help"); menubar->addMenu(help); } -#ifdef MACOSX - /* for OSX, the attempt above to add "About Qt NetHack" went into - the application menu instead of the help menu; we'll add it to - the latter now and have two ways to access it; without the - leading underscore (or some other spelling variation such as - "'bout"), this one would get intercepted too and then evidently - be discarded as a duplicate */ - help->addSeparator(); - help->addAction("_About_Qt_NetHack_", this, SLOT(doAbout(bool))); - /* we also want a "Quit NetHack" entry in the application menu; - when "_Quit-without-saving" was called "Quit" it got intercepted - for that, but now it needs to be added separately; we'll use a - handy menu and let the interception put it in the intended place */ - game->addAction("Quit NetHack", this, SLOT(doQuit(bool))); -#endif // order changed: was Again, Get, Kick, Throw, Fire, Drop, Eat, Rest // now Again, PickUp, Drop, Kick, Throw, Fire, Eat, Rest @@ -952,7 +955,7 @@ void NetHackQtMainWindow::doQtSettings(bool) void NetHackQtMainWindow::doAbout(bool) { - QMessageBox::about(this, "About Qt NetHack", aboutMsg()); + QMessageBox::about(this, "About NetHack-Qt", aboutMsg()); } // on OSX, "quit nethack" has been selected in the application menu or From 197d8130d0149f61407fd153fccf0c6b78cf15b5 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 6 Dec 2020 02:58:05 -0800 Subject: [PATCH 542/708] Qt extended commands enhancement For Qt's pick-an-exetended-command dialog, allow a player to toggle the grid layout from column-oriented to row-oriented and vice versa and when in wizard mode to cycle the set of shown (and typable) commands from 'all' to 'normal mode-only' to 'wizard mode-only' back to 'all'. The most recent values are saved by Qt along with tile size, font size, and some other stuff. The extended command dialog has a Reset button to force them (the two extended command values) back to their defaults. The dialog layout has a slight change to conserve screen space as well as three additional control buttons: Was Now | [ Cancel ] | [Cancel] [Filter][Layout][Reset ] |# |# Grid Title | Grid title | [cmd 1] [cmd R+1] [cmd 2*R+1] ... | [cmd 1] [cmd R+1] [cmd 2*R+1] ... | [cmd 2] [cmd R+2] | [cmd 2] [cmd R+2] |... |... | [cmd R] [cmd 2*R] | [cmd R] [cmd 2*R] '#' is the prompt where typed text gets echoed and 'R' is the number of rows in the grid and varies by the set of commands from the current filter. Grid dimensions have been adjusted: 'all' is 13x9, 'normal' is 13x7, and 'wizard' is 7x4 or 4x7 depending on layout orientation. The wizard mode-only filter setting probably isn't very useful because you can only type--or click on--commands which are visible. So when set to wizard mode-only, you can't #quit for instance. (Via extended command; there are still menu choices for that particular action. And it's trivial to change filter.) --- doc/fixes37.0 | 8 +- win/Qt/qt_set.cpp | 17 ++ win/Qt/qt_set.h | 5 + win/Qt/qt_xcmd.cpp | 489 +++++++++++++++++++++++++++++++++++++-------- win/Qt/qt_xcmd.h | 27 ++- 5 files changed, 466 insertions(+), 80 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 393121815..16a14abe6 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.375 $ $NHDT-Date: 1607200174 2020/12/05 20:29:34 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.376 $ $NHDT-Date: 1607252278 2020/12/06 10:57:58 $ General Fixes and Modified Features ----------------------------------- @@ -662,6 +662,12 @@ Qt: clicking on the paper doll runs the #seeall command (inventory of wielded Qt: clicking on the status window runs the #attributes command (^X) Qt: add a Search button to the toolbar Qt: support the 'hitpointbar' option +Qt: add Filter, Layout, and Reset buttons to the extended command selector; + Filter is only useful in wizard mode, allowing changing the set of + extended commands between "all", "normal mode only", "extra wizard + mode only"; Layout redisplays the grid of command buttons, toggling + from down columns to across rows or vice versa; Reset puts both back + to their default settings and clears any pending typed input NetHack Community Patches (or Variation) Included diff --git a/win/Qt/qt_set.cpp b/win/Qt/qt_set.cpp index e3e0295b5..2f6655417 100644 --- a/win/Qt/qt_set.cpp +++ b/win/Qt/qt_set.cpp @@ -20,6 +20,7 @@ extern "C" { #include "qt_glyph.h" #include "qt_main.h" #include "qt_bind.h" +#include "qt_xcmd.h" #include "qt_str.h" // Dialog box accessed via "Qt Settings..." in the games menu (non-OSX) @@ -108,6 +109,12 @@ NetHackQtSettings::NetHackQtSettings() : #endif default_fontsize = settings.value("fontsize", 2).toInt(); + // these aren't currently part of the settings dialog; they're managed + // by the extended commands menu ('#' command) and updateXcmd() below + // but are included in qt_settings to be remembered across play sessions + xcmd_by_row = settings.value("xcmdByRow", false).toBool(); + xcmd_set = settings.value("xcmdSet", all_cmds).toInt(); + // Tile/font sizes read from .nethackrc if (qt_tilewidth != NULL) { tilewidth.setValue(atoi(qt_tilewidth)); @@ -274,6 +281,16 @@ void NetHackQtSettings::setDollShown(bool on_off) } #endif +// called from NetHackQtExtCmdRequestor::Retry() +void NetHackQtSettings::updateXcmd(bool by_row, int which_set) +{ + // update 'settings' to have Qt store the revised values for next session + xcmd_by_row = by_row; + settings.setValue("xcmdByRow", QVariant(xcmd_by_row)); + xcmd_set = which_set; + settings.setValue("xcmdSet", xcmd_set); +} + const QFont& NetHackQtSettings::normalFont() { static int size[]={ 18, 14, 12, 10, 8 }; diff --git a/win/Qt/qt_set.h b/win/Qt/qt_set.h index 36f9c0ac3..14ec92c02 100644 --- a/win/Qt/qt_set.h +++ b/win/Qt/qt_set.h @@ -24,9 +24,14 @@ public: int dollWidth = 32, dollHeight = 32; bool doll_is_shown = true; #endif + bool xcmd_by_row = false; + int xcmd_set = 0; // all_cmds + // dialog box for Qt-specific settings NetHackQtSettings(); + void updateXcmd(bool by_row, int which_set); + NetHackQtGlyphs& glyphs(); const QFont& normalFont(); const QFont& normalFixedFont(); diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index ed6f870d3..283517beb 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -5,13 +5,78 @@ // qt_xcmd.cpp -- extended command widget // // TODO: -// Add button that toggles the grid of command names from column-oriented -// to row-oriented and vice versa. -// Add another button to filter out commands that can be invoked by a -// 'normal' keystroke (not Meta) with current key bindings. -// If not those, move the [cancel] button from being absurdly wide at the -// top of the popup to being ordinary width, right justified on same -// line as the prompt where user's typed characters are shown. +// Maybe extend filtering to be able to omit commands that can be invoked +// by a 'normal' keystroke (not Meta) with current key bindings, or to +// exclude commands which don't autocomplete to match '#?'. +// Either disable [Layout] when prompt has a partial response, or +// preserve that partial response across widget tear-down/rebuild. +// Maybe make the number of grid columns user settable? Or a way to +// specify a different font (smaller might be necessary for some folks; +// the font set up in "Qt settings" or "Preferences" applies to the +// message and status windows but not to extended command choosing). +// + +// +// Widget appearance (excluding window title bar): +// +----------------------------------------------------+ +// | [Cancel] [Filter] [Layout] [Reset] | control buttons +// |# Extended commands | text entry & title +// +----------------------------------------------------+ +// | [cmmnd_1] [cmnd_14] ... [cmnd_92] [cmd_105] | boxed grid of... +// | [cmmnd_2] [cmnd_15] ... [cmnd_93] [cmd_106] | ...command buttons +// ... +// | [cmnd_13] [cmnd_26] ... [cmd_104] blank | +// +----------------------------------------------------+ +// +// Typed input gets appended to "#". When enough to be unambiguous has +// accumulated, the matching command is immediately chosen (except for +// the prefix special case mentioned for [Cancel]); +// Title is centered and describes which [sub]set of commands are shown. +// It shares the prompt line to conserve vertical space. +// [Cancel] is highlighted as the default and applies if is typed, +// with special handling when player has typed up to the end of one +// command which is a prefix of another; there, or is +// used to select the shorter while still providing opportunity to type +// more of the longer command; (there are several such cases: +// "#drop[type]", "#known[class]", "#takeoff[all]", "#version[short]"); +// button is left justitied (prior to addition of the filter/layout/reset +// buttons, [Cancel] stretched all the way across the top of the widget); +// [Filter] is grayed out when outside wizard mode; when in wizard mode, +// it cycles through "all commands", "normal mode commands only", and +// "wizard mode extra commands only"; [if it ever gets extended to do +// anything in normal play, it will need a more substantial interface +// than repeated clicks but those seem adequate for present wizard +// mode-only usage]; +// [Layout] toggles between displaying the command buttons down columns +// (as shown above) versus across rows ([cmd_1][cmd_2]...[cmd_9], &c); +// [Reset] clears typed partial response, if any, and sets filtering back +// to "all commands" and/or toggles layout back to by-column if either +// of those differ from their defaults; +// [cmd_N] are buttons labelled with command names; clicking returns the +// index for the name. +// +// Changing filter or layout returns 0 to caller who then calls us again +// (current filter and layout are kept in qt_settings so persist); +// much simpler than reorganizing the button grid's contents on the fly. +// [TODO: perform '0 => retry' handling in qt_get_ext_cmd() rather than +// relying on the core to maintain that behavior.] +// Current grid size with SHELL and SUSPEND enabled is 13x9 for all +// commands, 13x7 for normal mode commands, and 7x4 (when by-column) or +// 4x7 (if by-row) for wizard mode commands. Column counts are hardcoded +// and row counts are adjusted to fit (the command list, not the screen). +// Maybe move prompt and title above control buttons? However, menus have +// their count entry feedback positioned between control buttons and the +// rest of the information--current layout matches that. +// The popup is displayed as full-fledged window but the window title bar +// is blank (at least on OSX). +// If clicking on [Filter] or [Layout] (or [Reset], but there isn't any +// particular reason to try to run it twice in a row) places the pointer +// inside any button, clicking again won't do anything unless the pointer +// is moved (again, at least on OSX); a single pixel probably suffices. +// Possibly because despite not moving it has effectively gone into a +// whole new window since the old one gets torn down and is replaced by +// a new one that uses revised filter or layout settings. +// extern "C" { #include "hack.h" @@ -30,8 +95,16 @@ extern "C" { #include "qt_set.h" #include "qt_str.h" +// temporary +extern int qt_compact_mode; +// end temporary + namespace nethack_qt_ { +/* 'wizard' is #undef'd above (now in qt_pre.h) because a Qt header uses + that token, so create our own based on knowledge of 'wizard's internals */ +#define WizardMode (::flags.debug) + extern uchar keyValue(QKeyEvent *key_event); // from qt_menu.cpp // temporary @@ -39,84 +112,195 @@ void centerOnMain(QWidget *); // end temporary static inline bool -interesting_command(unsigned indx) +interesting_command(unsigned indx, int cmds) { - return (!(extcmdlist[indx].flags & CMD_NOT_AVAILABLE) - /* 'wizard' is #undef'd above because Qt uses that token - so rely on its internals */ - && (flags.debug || !(extcmdlist[indx].flags & WIZMODECMD))); + if (!WizardMode) + cmds = normal_cmds; + + // entry 0 is a no-op; don't bother displaying it in the command grid + if (indx == 0 && !strcmp("#", extcmdlist[indx].ef_txt)) + return false; + // some commands might have been compiled-out; don't show them + if ((extcmdlist[indx].flags & CMD_NOT_AVAILABLE) != 0) + return false; + // if picking from normal mode-only don't show wizard mode commands + // or if picking from wizard mode-only don't show normal commands + if ((cmds == normal_cmds && (extcmdlist[indx].flags & WIZMODECMD) != 0) + || (cmds == wizard_cmds && (extcmdlist[indx].flags & WIZMODECMD) == 0)) + return false; + // if we've gotten here, this command isn't filtered away, so show it + return true; } NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : - QDialog(parent) + QDialog(parent), + prompt(new QLabel("#", this)), + cancel_btn(new QPushButton("Cancel", this)), + byRow(qt_settings->xcmd_by_row), + set(qt_settings->xcmd_set), + butoffset(0), + exactmatchindx(xcmdNoMatch) { - QVBoxLayout *l = new QVBoxLayout(this); + if (!WizardMode) + set = normal_cmds; // {all,wizard}_cmds are wizard mode only - QPushButton *can = new QPushButton("Cancel", this); - can->setDefault(true); - can->setMinimumSize(can->sizeHint()); - l->addWidget(can); + QVBoxLayout *xl = new QVBoxLayout(this); // overall xcmd layout + int butw = 50; // initial button width; will be increased if too small + // should probably use the qt_settings font size as a spacing hint; + // tiny font, tiny internal margins; small font, small margins; + // medium or bigger, default margins (9 or 11?) + int spacing = qt_compact_mode ? 3 : -1; // 0 would abut; -1 gives default - prompt = new QLabel("#", this); - l->addWidget(prompt); + // first, the popup's controls: a row of buttons along the top; + // the two padding widgets make the control buttons line up better + // with the grid of xcmd choice buttons (closer but not exactly) + QHBoxLayout *ctrls = new QHBoxLayout(); + ctrls->setSpacing(spacing); // only seems to affect horizontal, not vert. + ctrls->addWidget(new QLabel(" ")); // padding + // Cancel, created during constructor setup (accessed in other routines) + DefaultActionIsCancel(true); /* cancel_btn->setDefault(true); */ + cancel_btn->setMinimumSize(cancel_btn->sizeHint()); + butw = std::max(butw, cancel_btn->width()); + ctrls->addWidget(cancel_btn); + ctrls->addStretch(0); // Cancel will be left justified, others far right + // Filter: change the [sub]set of commands that get shown; + // presently only useful when running in wizard mode + QPushButton *filter_btn = new QPushButton("Filter", this); + if (!WizardMode) { // nothing to filter if not in wizard mode + filter_btn->setEnabled(false); // gray the [Filter] button out +#if 0 /* This works but makes [Reset] seem to be redundant. */ + // graying out may not be adequate; conceal [Filter] so that + // players without access to wizard mode won't become concerned + // about something that seems to them to always be disabled + filter_btn->hide(); +#endif + } + filter_btn->setMinimumSize(filter_btn->sizeHint()); + butw = std::max(butw, filter_btn->width()); + ctrls->addWidget(filter_btn); + // Layout: switch from by-column grid to by-row grid or vice versa + QPushButton *layout_btn = new QPushButton("Layout", this); + layout_btn->setMinimumSize(layout_btn->sizeHint()); + butw = std::max(butw, layout_btn->width()); + ctrls->addWidget(layout_btn); + // Reset: switch filter back to all commands and layout back to by-column + QPushButton *reset__btn = new QPushButton("Reset", this); + reset__btn->setMinimumSize(reset__btn->sizeHint()); + butw = std::max(butw, reset__btn->width()); + ctrls->addWidget(reset__btn); + ctrls->addWidget(new QLabel(" ")); // padding + xl->addLayout(ctrls); - QButtonGroup *group=new QButtonGroup(this); - QGroupBox *grid=new QGroupBox("Extended commands",this); - l->addWidget(grid); + // text entry takes place below the row of control buttons and above + // the grid of command buttons; show typed text in fixed-width font + prompt->setFont(qt_settings->normalFixedFont()); + + // grid title rather than overall popup title + const char *ctitle = ((set == all_cmds) + ? "All extended commands" + : (set == normal_cmds) + ? (WizardMode ? "Normal mode extended commands" + : "Extended commands") + : (set == wizard_cmds) + ? "Debug mode extended commands" + : "(unknown)"); // won't happen + const QString &qtitle = QString(ctitle); + // rectangular grid to hold a button for each extended command name + QGroupBox *grid = new QGroupBox(); /* new QGroupBox(title, this); */ + // used to connect the buttons with their click handling routine + QButtonGroup *group = new QButtonGroup(this); + + // put grid title on same line as prompt (the padding simplifies centering) + QHBoxLayout *pl = new QHBoxLayout(); // prompt line + pl->addWidget(prompt); + QLabel *tt = new QLabel(qtitle); + tt->setAlignment(Qt::AlignHCenter); // center title horizontally + pl->addWidget(tt); + pl->addWidget(new QLabel(" ")); // padding to balance prompt + xl->addLayout(pl); + xl->addWidget(grid); + + // having the controls in the same button group as the extended command + // choices means that they use the same click callback [a holdover from + // when Cancel was the only one; using a separate group and separate + // click callback would eliminate the need for butoffset in Button()] + group->addButton(cancel_btn, butoffset), ++butoffset; // (,0), 1 + group->addButton(filter_btn, butoffset), ++butoffset; // (,1), 2 + group->addButton(layout_btn, butoffset), ++butoffset; // (,2), 3 + group->addButton(reset__btn, butoffset), ++butoffset; // (,3), 4 unsigned i, j, ncmds = 0; - int butw = 50; QFontMetrics fm = fontMetrics(); + // count the number of commands in current [sub]set and find the size of + // the widest choice button; starting size is from widest control button for (i = 0; extcmdlist[i].ef_txt; ++i) { - if (interesting_command(i)) { + if (interesting_command(i, set)) { ++ncmds; butw = std::max(butw, 30 + fm.width(extcmdlist[i].ef_txt)); } } + // if any of the choice buttons were bigger than the control buttons, + // make the control buttons bigger to match + if (cancel_btn->width() < butw) + cancel_btn->setMinimumWidth(butw); + if (filter_btn->width() < butw) + filter_btn->setMinimumWidth(butw); + if (layout_btn->width() < butw) + layout_btn->setMinimumWidth(butw); + if (reset__btn->width() < butw) + reset__btn->setMinimumWidth(butw); - /* 'ncols' should be calculated to fit (or enable a vertical scrollbar + QVBoxLayout *bl = new QVBoxLayout(grid); + QGridLayout *gl = new QGridLayout(); + // for qt_compact_mode, put buttons closer together + gl->setSpacing(spacing); + bl->addLayout(gl); + // could grow the buttons[] vector one element at a time but since we + // know the ultimate size, grow to that in one operation + buttons.resize((int) ncmds); + + /* 'ncols' could be calculated to fit (or enable a vertical scrollbar when resulting 'nrows' is too big, if GroupBox supports that); it used to be hardcoded 4 but after every command became accessible as an extended command, that resulted in so many rows that some of - the buttons were chopped off at the bottom of the grid */ - unsigned ncols = !flags.debug ? 6 : 8, - nrows = (ncmds + ncols - 1) / ncols; + the grid was chopped off at the bottom of the screen and the buttons + in that portion were out of reach */ + unsigned ncols = (set == all_cmds) ? 9 + : (set == normal_cmds) ? 7 + : (set == wizard_cmds) ? (byRow ? 7 : 4) + : 1; // can't happen + unsigned nrows = (ncmds + ncols - 1) / ncols; /* - * Choose grid layout. This ought to selected via a button that can - * be used to toggle the setting back and forth. + * Grid layout: by-column is the default. Can be toggled by clicking + * on the [Layout] control button. * - * by row vs by column - * a b a e - * c d b f - * e f c g - * g d - * - * Prior to 3.7, it was always by-row, but by-column is more natural - * for an alphabetized list. + * by-row vs by-column + * a b c a e i + * d e f b f j + * g h i c g - + * j - - d h - */ - bool by_column = true; - - QVBoxLayout *bl = new QVBoxLayout(grid); - bl->addSpacing(fm.height()); - QGridLayout *gl = new QGridLayout(); - bl->addLayout(gl); for (i = j = 0; extcmdlist[i].ef_txt; ++i) { - if (interesting_command(i)) { - QPushButton *pb = new QPushButton(extcmdlist[i].ef_txt, grid); + if (interesting_command(i, set)) { + QString btn_lbl = extcmdlist[i].ef_txt; + if (btn_lbl == "wait") + btn_lbl += " (rest)"; + QPushButton *pb = new QPushButton(btn_lbl, grid); pb->setMinimumSize(butw, pb->sizeHint().height()); // force the button to have fixed width or it can move around a // pixel or two (tiny but visibly noticeable) when enableButtons() // hides whole columns [see stretch comment below] pb->setMaximumSize(pb->minimumSize()); - group->addButton(pb, i + 1); + // i+butoffset is value that will be passed to the click handler + group->addButton(pb, i + butoffset); /* - * by_column: + * by column: xcmd_by_row==false, the default * 0..R-1 down first column, R..2*R-1 down second column, ... - * otherwise: + * otherwise: by row * 0..C-1 across first row, C..2*C-1 across second row, ... */ - int row = by_column ? j % nrows : j / ncols; - int col = by_column ? j / nrows : j % ncols; + unsigned row = !byRow ? j % nrows : j / ncols; + unsigned col = !byRow ? j / nrows : j % ncols; gl->addWidget(pb, row, col); // these stretch settings prevent the grid from becoming very // ugly when enableButtons() disables whole rows and/or columns @@ -126,42 +310,156 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : if (col == 0) gl->setRowStretch(row, 1); - buttons.append(pb); + // buttons[] vector is used by enableButtons() + buttons[j] = pb; // buttons.append(pb); ++j; } } - group->addButton(can, 0); - connect(group,SIGNAL(buttonPressed(int)),this,SLOT(done(int))); + + connect(group, SIGNAL(buttonPressed(int)), this, SLOT(Button(int))); bl->activate(); - l->activate(); + xl->activate(); resize(1,1); } -void NetHackQtExtCmdRequestor::cancel() +// Click handler for the ExtCmdRequestor widget +int NetHackQtExtCmdRequestor::Button(int butnum) +{ + // 0..3 are control buttons, 4..N+3 are choice buttons. + // Widget return value is -1 for cancel (via reject), + // 0 for filter, layout, reset (via accept if circumstances warrant), + // 1..N for command choices (choice 0 is '#' and it isn't shown as + // a candidate since picking it is not useful). + switch (butnum) { + case 0: + Cancel(); + /*NOTREACHED*/ + break; + case 1: + Filter(); + break; + case 2: + Layout(); + break; + case 3: + Reset(); + break; + default: + // 4..N-3 are the extended commands + done(butnum - butoffset + 1); + /*NOTREACHED*/ + break; + } + return 0; +} + +// Respond to a click on the [Cancel] button +void NetHackQtExtCmdRequestor::Cancel() { reject(); + /*NOTREACHED*/ +} + +// Respond to a click on the [Filter] button +void NetHackQtExtCmdRequestor::Filter() +{ + // TEMP: step from one [sub]set to the next, then wrap back to the first. + if (++set > std::max(std::max(all_cmds, normal_cmds), wizard_cmds)) + set = std::min(std::min(all_cmds, normal_cmds), wizard_cmds); + + // TODO: put up a popup--dialog or maybe simple pick-one menu--that + // has player choose between all_cmds, normal_cmds, wizard_cmds. + // Only meaningful for wizard mode so maybe the temp version suffices. + + if (set != qt_settings->xcmd_set) { + Retry(); + /*NOTREACHED*/ + } + return; +} + +// Respond to a click on the [Layout] button +void NetHackQtExtCmdRequestor::Layout() +{ + byRow = !byRow; + Retry(); + /*NOTREACHED*/ +} + +// Respond to a click on the [Reset] button +void NetHackQtExtCmdRequestor::Reset() +{ + // clear any typed text first (in case future changes are made to + // remember it across accept (retry); that would be intended for the + // [Layout] case rather than for [Reset]) + bool clearprompt = (prompt->text() != "#"); + if (clearprompt) + prompt->setText("#"); + + int teardown = 0; + if (set != (WizardMode ? all_cmds : normal_cmds)) + set = all_cmds, ++teardown; + if (byRow) + byRow = false, ++teardown; + if (teardown) { + Retry(); + /*NOTREACHED*/ + } + + if (clearprompt) { // was a subset, now need to show full set + DefaultActionIsCancel(true); // in case keyPressEvent cleared it + enableButtons(); // redraws the grid after discarding typed text above + } +} + +// Return to ExtCmdRequestor::get()'s caller in order to be called back +void NetHackQtExtCmdRequestor::Retry() +{ + // remember the current settings; they'll persist until changed again + qt_settings->updateXcmd(byRow, set); + + // result 0 means that caller in core will call get_ext_cmd() again; + // current selection grid will be torn down, then new one created; + // TODO: have qt_get_ext_cmd() handle it instead of relying on core + setResult(0); + accept(); } #define Ctrl(c) (0x1f & (c)) /* ASCII */ // Note: we don't necessarily have access to a terminal to query // it for user's preferred kill character, so use hardcoded ^U. +// Player who prefers something else can cope by using ESC instead. #define KILL_CHAR Ctrl('u') +// Receive the next character of typed input void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) { + /* + * This will select a command outright--as soon as enough chars + * to not be ambiguous are entered--but also narrows down visible + * choices [via enableButtons()] in the grid of clickable command + * buttons as the text-so-far makes many become impossible to match. + * Use of backspace/delete or ESC/kill restores suppressed choices + * to the grid as they become matchable again. + */ + + unsigned saveexactmatchindx = exactmatchindx; + // if previous KeyPressEvent cleared default, restore it now + DefaultActionIsCancel(true); QString promptstr = prompt->text(); uchar uc = keyValue(event); + if (!uc) { // shift or control or meta, another character should be coming QWidget::keyPressEvent(event); } else if (uc == '\033' || uc == KILL_CHAR) { - // Escape when some response is already present kills that text - // but keeps prompting; escape when response is empty cancels. - // Kill gets rid of current text, if any, and always re-prompts. + // when partial response is present kills that text + // but keeps prompting; when response is empty cancels. + // Kill gets rid of pending text, if any, and always re-prompts. if (uc == '\033' && promptstr == "#") reject(); // cancel() if ESC used when string is empty - prompt->setText("#"); + prompt->setText("#"); // reset to empty ('#' is always present) enableButtons(); } else if (uc == '\b' || uc == '\177') { if (promptstr != "#") @@ -171,57 +469,92 @@ void NetHackQtExtCmdRequestor::keyPressEvent(QKeyEvent *event) || uc > std::max('z', 'Z')) { reject(); // done() } else { - // is necessary if one command is a leading substring - // of another and superfluous otherwise - boolean checkexact = (uc == '\n' || uc == '\r' || uc == ' '); - if (!checkexact) - promptstr += QChar(uc); // event()->text() + /* + * or is necessary if one command is a + * leading substring of another and superfluous otherwise. + * (When a command is not a prefix of another, it will have + * been selected before reaching its last letter.) + * + * If we got an exact match with the last key, we're expecting + * a or to explicitly choose it now but might + * get next letter of the longer command (or get a backspace). + * + * If we get an exact match this time, then stop showing + * [Cancel] as the default action for . + * (That's a visual cue for the player, not a requirement to + * prevent from triggering the default action.) + * If it's not the default action upon the next key press, + * we'll change that back (done above). + * + * TODO? + * Implement support: if promptstr matches multiple + * commands but they all have the next one or more letters in + * common, allow to add the common letters to promptstr. + */ + bool checkexact = (uc == '\n' || uc == '\r' || uc == ' '); + if (!checkexact) { + // force lower case instead of rejecting upper case + if (isupper(uc)) + uc = tolower(uc); + promptstr += QChar(uc); // add new char to typed text + } QString typedstr = promptstr.mid(1); // skip the '#' unsigned matches = 0; unsigned matchindx = 0; - for (unsigned i=0; extcmdlist[i].ef_txt; i++) { - if (!interesting_command(i)) + for (unsigned i = 0; extcmdlist[i].ef_txt; ++i) { + if (!interesting_command(i, set)) continue; - QString cmdtxt = QString(extcmdlist[i].ef_txt); + const QString &cmdtxt = QString(extcmdlist[i].ef_txt); if (cmdtxt.startsWith(typedstr)) { + bool is_exact = (cmdtxt == typedstr); if (checkexact) { - if (cmdtxt == typedstr) { + if (is_exact) { matchindx = i; matches = 1; break; } } else { + if (is_exact) + DefaultActionIsCancel(false, i); // clear default if (++matches >= 2) break; matchindx = i; } } } - if (matches == 1) + if (matches == 1) { done(matchindx + 1); - else if (checkexact) + } else if (checkexact) { + // or without a pending exact match; cancel reject(); - else if (matches >= 2) + } else if (matches >= 2) { + // update the text-so-far prompt->setText(promptstr); + } else if (saveexactmatchindx != xcmdNoMatch) { + // had a pending exact match but typed something other than + // which didn't yield another match; prompt string + // hasn't been updated so still have a pending exact match + DefaultActionIsCancel(false, saveexactmatchindx); + } enableButtons(); } } +// Actual widget execution, used after calling NetHackQtExtCmdRequestor(). int NetHackQtExtCmdRequestor::get() { - const int none = -10; resize(1,1); // pack centerOnMain(this); // Add any keys presently buffered to the prompt - setResult(none); - while (NetHackQtBind::qt_kbhit() && result() == none) { + setResult(xcmdNone); + while (NetHackQtBind::qt_kbhit() && result() == xcmdNone) { int ch = NetHackQtBind::qt_nhgetch(); QKeyEvent event(QEvent::KeyPress, 0, Qt::NoModifier, QChar(ch)); keyPressEvent(&event); } - if (result() == none) + if (result() == xcmdNone) exec(); - return result()-1; + return result() - 1; } // Enable only buttons that match the current prompt string diff --git a/win/Qt/qt_xcmd.h b/win/Qt/qt_xcmd.h index fe8b027a6..52df63a52 100644 --- a/win/Qt/qt_xcmd.h +++ b/win/Qt/qt_xcmd.h @@ -9,6 +9,9 @@ namespace nethack_qt_ { +enum xcmdSets { all_cmds = 0, normal_cmds = 1, wizard_cmds = 2 }; +enum xcmdMisc { xcmdNone = -10, xcmdNoMatch = 9999 }; + class NetHackQtExtCmdRequestor : public QDialog { Q_OBJECT @@ -21,11 +24,33 @@ public: private: QLabel *prompt; + QPushButton *cancel_btn; QVector buttons; + bool byRow; // local copy of qt_settings->xcmd_by_row; + int set; // local copy of qt_settings->xcmd_set; + int butoffset; // number of control buttons (cancel, filter, &c) + unsigned exactmatchindx; + void enableButtons(); + void Cancel(); // not selecting a command after all + void Filter(); // choose command set (all, normal mode, wizard mode) + void Layout(); // by-column vs by-row for button grid + void Reset(); // go back to default filter and layout + + void Retry(); // returns to caller in order to be called back... + // ...and restart with revised settings + + inline void DefaultActionIsCancel(bool make_it_so, + unsigned matchindx = xcmdNoMatch) + { + if (!make_it_so ^ !cancel_btn->isDefault()) { + cancel_btn->setDefault(make_it_so); + exactmatchindx = matchindx; + } + } private slots: - void cancel(); + int Button(int); // click handler }; } // namespace nethack_qt_ From 452dc3da261a2400b2c51254aaff1326f8df6e88 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 6 Dec 2020 13:57:50 +0200 Subject: [PATCH 543/708] Unify spitmu and spitmm --- src/mthrowu.c | 50 ++++++++++++-------------------------------------- 1 file changed, 12 insertions(+), 38 deletions(-) diff --git a/src/mthrowu.c b/src/mthrowu.c index ab96ee0b7..2f21e543e 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -753,6 +753,10 @@ struct attack *mattk; return MM_MISS; } if (m_lined_up(mtarg, mtmp)) { + boolean utarg = (mtarg == &g.youmonst); + xchar tx = utarg ? mtmp->mux : mtarg->mx; + xchar ty = utarg ? mtmp->muy : mtarg->my; + switch (mattk->adtyp) { case AD_BLND: case AD_DRST: @@ -765,12 +769,13 @@ struct attack *mattk; otmp = mksobj(ACID_VENOM, TRUE, FALSE); break; } - if (!rn2(BOLT_LIM-distmin(mtmp->mx,mtmp->my,mtarg->mx,mtarg->my))) { + if (!rn2(BOLT_LIM-distmin(mtmp->mx,mtmp->my,tx,ty))) { if (canseemon(mtmp)) pline("%s spits venom!", Monnam(mtmp)); - g.mtarget = mtarg; + if (!utarg) + g.mtarget = mtarg; m_throw(mtmp, mtmp->mx, mtmp->my, sgn(g.tbx), sgn(g.tby), - distmin(mtmp->mx,mtmp->my,mtarg->mx,mtarg->my), otmp); + distmin(mtmp->mx,mtmp->my,tx,ty), otmp); g.mtarget = (struct monst *)0; nomul(0); @@ -785,6 +790,9 @@ struct attack *mattk; } return MM_HIT; + } else { + obj_extract_self(otmp); + obfree(otmp, (struct obj *) 0); } } return MM_MISS; @@ -949,41 +957,7 @@ spitmu(mtmp, mattk) struct monst *mtmp; struct attack *mattk; { - struct obj *otmp; - - if (mtmp->mcan) { - if (!Deaf) - pline("A dry rattle comes from %s throat.", - s_suffix(mon_nam(mtmp))); - return 0; - } - if (lined_up(mtmp)) { - switch (mattk->adtyp) { - case AD_BLND: - case AD_DRST: - otmp = mksobj(BLINDING_VENOM, TRUE, FALSE); - break; - default: - impossible("bad attack type in spitmu"); - /* fall through */ - case AD_ACID: - otmp = mksobj(ACID_VENOM, TRUE, FALSE); - break; - } - if (!rn2(BOLT_LIM - - distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy))) { - if (canseemon(mtmp)) - pline("%s spits venom!", Monnam(mtmp)); - m_throw(mtmp, mtmp->mx, mtmp->my, sgn(g.tbx), sgn(g.tby), - distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy), otmp); - nomul(0); - return 0; - } else { - obj_extract_self(otmp); - obfree(otmp, (struct obj *) 0); - } - } - return 0; + return spitmm(mtmp, mattk, &g.youmonst); } /* monster breathes at you (ranged) */ From b63e7bf5271f94ed4c84614327a4e8759e6a19ac Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sat, 5 Dec 2020 21:24:07 -0500 Subject: [PATCH 544/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Files b/Files index 7d456a19c..a7cfe86b1 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 .travis.yml Cross-compiling Files -Porting README +.clang-format .travis.yml Cross-compiling +Files Porting README +azure-pipelines.yml DEVEL: (files for people developing changes to NetHack) From 13359648dd31931313e1c4f06acc6281d05a5842 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 6 Dec 2020 18:36:37 +0200 Subject: [PATCH 545/708] Remove duplicate wallify_map code --- include/extern.h | 1 + src/mkmap.c | 26 +------------------------- src/sp_lev.c | 3 +-- 3 files changed, 3 insertions(+), 27 deletions(-) diff --git a/include/extern.h b/include/extern.h index b8b73c1ff..4fc957d30 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2495,6 +2495,7 @@ E boolean FDECL(create_room, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, E void FDECL(create_secret_door, (struct mkroom *, XCHAR_P)); E boolean FDECL(dig_corridor, (coord *, coord *, BOOLEAN_P, SCHAR_P, SCHAR_P)); E void FDECL(fill_special_room, (struct mkroom *)); +E void FDECL(wallify_map, (int, int, int, int)); E boolean FDECL(load_special, (const char *)); E xchar FDECL(selection_getpoint, (int, int, struct selectionvar *)); E struct selectionvar *NDECL(selection_new); diff --git a/src/mkmap.c b/src/mkmap.c index 14f7973d8..8100394ca 100644 --- a/src/mkmap.c +++ b/src/mkmap.c @@ -14,7 +14,6 @@ static schar FDECL(get_map, (int, int, SCHAR_P)); static void FDECL(pass_one, (SCHAR_P, SCHAR_P)); static void FDECL(pass_two, (SCHAR_P, SCHAR_P)); static void FDECL(pass_three, (SCHAR_P, SCHAR_P)); -static void NDECL(wallify_map); static void FDECL(join_map, (SCHAR_P, SCHAR_P)); static void FDECL(finish_map, (SCHAR_P, SCHAR_P, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); @@ -247,29 +246,6 @@ boolean anyroom; g.max_ry = sy; } -/* - * If we have drawn a map without walls, this allows us to - * auto-magically wallify it. Taken from lev_main.c. - */ -static void -wallify_map() -{ - int x, y, xx, yy; - - for (x = 1; x < COLNO; x++) - for (y = 0; y < ROWNO; y++) - if (levl[x][y].typ == STONE) { - for (yy = y - 1; yy <= y + 1; yy++) - for (xx = x - 1; xx <= x + 1; xx++) - if (isok(xx, yy) && levl[xx][yy].typ == ROOM) { - if (yy != y) - levl[x][y].typ = HWALL; - else - levl[x][y].typ = VWALL; - } - } -} - static void join_map(bg_typ, fg_typ) schar bg_typ, fg_typ; @@ -351,7 +327,7 @@ boolean lit, walled, icedpools; int i, j; if (walled) - wallify_map(); + wallify_map(1, 0, COLNO-1, ROWNO-1); if (lit) { for (i = 1; i < COLNO; i++) diff --git a/src/sp_lev.c b/src/sp_lev.c index a21fc72ab..6d64c182c 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -63,7 +63,6 @@ static boolean FDECL(search_door, (struct mkroom *, static void FDECL(create_corridor, (corridor *)); static struct mkroom *FDECL(build_room, (room *, struct mkroom *)); static void FDECL(light_region, (region *)); -static void FDECL(wallify_map, (int, int, int, int)); static void FDECL(maze1xy, (coord *, int)); static void NDECL(fill_empty_maze); static void FDECL(splev_initlev, (lev_init *)); @@ -2740,7 +2739,7 @@ region *tmpregion; } } -static void +void wallify_map(x1, y1, x2, y2) int x1, y1, x2, y2; { From 123b6c38a6b0eb0022ae95f3e01b8d37a0f16b79 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 7 Dec 2020 01:05:37 -0800 Subject: [PATCH 546/708] Qt extended commands: menu teardown and rebuild Change qt_get_ext_cmd() to handle calling the extended command selection menu again after player clicks on Filter/Layout/Reset instead of relying on the core to do that. (In order to change the menu, instead of attempting to reconfigure that on the fly it returns to caller and then puts up a new menu with different settings when called back. Initial checkin relied on the core for the call back; this maintains full control for that within the Qt interface code.) --- win/Qt/qt_bind.cpp | 11 +++++++++-- win/Qt/qt_xcmd.cpp | 20 +++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 7969fa5e8..f355bcd31 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -790,10 +790,17 @@ void NetHackQtBind::qt_getlin(const char *prompt, char *line) NetHackQtBind::qt_clear_nhwindow(WIN_MESSAGE); } +// User has typed '#' to begin entering an extended command; core calls us. int NetHackQtBind::qt_get_ext_cmd() { - NetHackQtExtCmdRequestor requestor(mainWidget()); - return requestor.get(); + NetHackQtExtCmdRequestor *xcmd; + int result; + do { + xcmd = new NetHackQtExtCmdRequestor(mainWidget()); + result = xcmd->get(); + delete xcmd; + } while (result == xcmdNoMatch); + return result; } void NetHackQtBind::qt_number_pad(int) diff --git a/win/Qt/qt_xcmd.cpp b/win/Qt/qt_xcmd.cpp index 283517beb..686ce0490 100644 --- a/win/Qt/qt_xcmd.cpp +++ b/win/Qt/qt_xcmd.cpp @@ -55,11 +55,10 @@ // [cmd_N] are buttons labelled with command names; clicking returns the // index for the name. // -// Changing filter or layout returns 0 to caller who then calls us again -// (current filter and layout are kept in qt_settings so persist); +// Changing filter or layout returns xcmdNoMatch to qt_get_ext_cmd() which +// then calls us again (current filter and layout are kept in qt_settings +// so persist, not just through return and call back but across games); // much simpler than reorganizing the button grid's contents on the fly. -// [TODO: perform '0 => retry' handling in qt_get_ext_cmd() rather than -// relying on the core to maintain that behavior.] // Current grid size with SHELL and SUSPEND enabled is 13x9 for all // commands, 13x7 for normal mode commands, and 7x4 (when by-column) or // 4x7 (if by-row) for wizard mode commands. Column counts are hardcoded @@ -120,6 +119,9 @@ interesting_command(unsigned indx, int cmds) // entry 0 is a no-op; don't bother displaying it in the command grid if (indx == 0 && !strcmp("#", extcmdlist[indx].ef_txt)) return false; + // treat '?' as both normal mode and debug mode + if (!strcmp("?", extcmdlist[indx].ef_txt)) + return true; // some commands might have been compiled-out; don't show them if ((extcmdlist[indx].flags & CMD_NOT_AVAILABLE) != 0) return false; @@ -327,8 +329,8 @@ NetHackQtExtCmdRequestor::NetHackQtExtCmdRequestor(QWidget *parent) : int NetHackQtExtCmdRequestor::Button(int butnum) { // 0..3 are control buttons, 4..N+3 are choice buttons. - // Widget return value is -1 for cancel (via reject), - // 0 for filter, layout, reset (via accept if circumstances warrant), + // Widget return value is -1 for cancel (via reject), xcmdNoMatch + // for filter, layout, reset (via accept if circumstances warrant), // 1..N for command choices (choice 0 is '#' and it isn't shown as // a candidate since picking it is not useful). switch (butnum) { @@ -419,11 +421,11 @@ void NetHackQtExtCmdRequestor::Retry() // remember the current settings; they'll persist until changed again qt_settings->updateXcmd(byRow, set); - // result 0 means that caller in core will call get_ext_cmd() again; + // return to qt_get_ext_cmd() and have it run ExtCmdRequestor again; // current selection grid will be torn down, then new one created; - // TODO: have qt_get_ext_cmd() handle it instead of relying on core - setResult(0); + setResult(xcmdNoMatch); accept(); + /*NOTREACHED*/ } #define Ctrl(c) (0x1f & (c)) /* ASCII */ From 76b1b0f2561ccbe87a0aa8a289f2002b40fd4b28 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 7 Dec 2020 03:08:32 -0800 Subject: [PATCH 547/708] extended command help The two or three (wizard mode) menu choices at the start of the '# ?' help menu look enough like headers that it can be confusing. They're asking about changing the view of commands to what those entries describe, but if considered as headers they're describing the opposite of what is currently displayed. Make them more verbose to try to clarify the situation. This also moves the 'm' flag in front of the 'A' in the middle column (of name, flag(s), description) when they both apply. --- src/cmd.c | 66 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index ea0879b7b..df38ac840 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607079461 2020/12/04 10:57:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.427 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607339290 2020/12/07 11:08:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.428 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -186,8 +186,7 @@ static int FDECL(ch2spkeys, (CHAR_P, int, int)); static boolean FDECL(prefix_cmd, (CHAR_P)); static int NDECL((*timed_occ_fn)); -static char *FDECL(doc_extcmd_flagstr, (winid, const struct ext_func_tab *, - BOOLEAN_P)); +static char *FDECL(doc_extcmd_flagstr, (winid, const struct ext_func_tab *)); static const char *readchar_queue = ""; /* for rejecting attempts to use wizard mode commands */ @@ -340,34 +339,43 @@ doextcmd(VOID_ARGS) return retval; } +/* format extended command flags for display */ static char * -doc_extcmd_flagstr(menuwin, efp, doc) +doc_extcmd_flagstr(menuwin, efp) winid menuwin; -const struct ext_func_tab *efp; -boolean doc; +const struct ext_func_tab *efp; /* if Null, add a footnote to the menu */ { - static char buf[BUFSZ]; + static char Abuf[10]; /* 5 would suffice: {'[','m','A',']','\0'} */ - if (doc) { + /* note: tag shown for menu prefix is 'm' even if m-prefix action + has been bound to some other key */ + if (!efp) { + char qbuf[QBUFSZ]; anything any = cg.zeroany; add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "[A] Command autocompletes", MENU_ITEMFLAGS_NONE); - Sprintf(buf, "[m] Command accepts '%c' prefix", + Sprintf(qbuf, "[m] Command accepts '%c' prefix", g.Cmd.spkeys[NHKF_REQMENU]); - add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, qbuf, MENU_ITEMFLAGS_NONE); return (char *) 0; } else { - buf[0] = '\0'; - Sprintf(&buf[1], "%s%s", - (efp->flags & AUTOCOMPLETE) ? "A" : "", - accept_menu_prefix(efp->ef_funct) ? "m" : ""); - if (buf[1]) { - buf[0] = '['; - Strcat(buf, "]"); + boolean mprefix = accept_menu_prefix(efp->ef_funct), + autocomplete = (efp->flags & AUTOCOMPLETE) != 0; + char *p = Abuf; + + /* "" or "[m]" or "[A]" or "[mA]" */ + if (mprefix || autocomplete) { + *p++ = '['; + if (mprefix) + *p++ = 'm'; + if (autocomplete) + *p++ = 'A'; + *p++ = ']'; } - return buf; + *p = '\0'; + return Abuf; } } @@ -400,10 +408,8 @@ doextlist(VOID_ARGS) add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_ITEMFLAGS_NONE); - Strcpy(buf, menumode ? "Show" : "Hide"); - Strcat(buf, " commands that don't autocomplete"); - if (!menumode) - Strcat(buf, " (those not marked with [A])"); + Sprintf(buf, "Switch to %s commands that don't autocomplete", + menumode ? "including" : "excluding"); any.a_int = 1; add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf, MENU_ITEMFLAGS_NONE); @@ -419,7 +425,7 @@ doextlist(VOID_ARGS) "Search extended commands", MENU_ITEMFLAGS_NONE); } else { - Strcpy(buf, "Show all, clear search"); + Strcpy(buf, "Switch back from search"); if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ) Sprintf(eos(buf), " (\"%s\")", searchbuf); any.a_int = 3; @@ -434,8 +440,8 @@ doextlist(VOID_ARGS) if (wizard) { any.a_int = 4; add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE, - onelist ? "Show debugging commands in separate section" - : "Show all alphabetically, including debugging commands", + onelist ? "Switch to showing debugging commands in separate section" + : "Switch to showing all alphabetically, including debugging commands", MENU_ITEMFLAGS_NONE); } any = cg.zeroany; @@ -486,10 +492,10 @@ doextlist(VOID_ARGS) MENU_ITEMFLAGS_NONE); menushown[pass] = 1; } - Sprintf(buf, " %-14s %-4s %s", - efp->ef_txt, - doc_extcmd_flagstr(menuwin, efp, FALSE), - efp->ef_desc); + /* 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), efp->ef_desc); add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_ITEMFLAGS_NONE); ++n; @@ -502,7 +508,7 @@ doextlist(VOID_ARGS) add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "no matches", MENU_ITEMFLAGS_NONE); else - (void) doc_extcmd_flagstr(menuwin, efp, TRUE); + (void) doc_extcmd_flagstr(menuwin, (struct ext_func_tab *) 0); end_menu(menuwin, (char *) 0); n = select_menu(menuwin, PICK_ONE, &selected); From 99980376b28d4b105439d770852da01e6882031d Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 7 Dec 2020 08:00:30 -0500 Subject: [PATCH 548/708] minor corrections to Cross-compiling doc --- Cross-compiling | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cross-compiling b/Cross-compiling index b0c673dea..f09be14b7 100644 --- a/Cross-compiling +++ b/Cross-compiling @@ -1,4 +1,4 @@ -Cross-compiling NetHack 3.7 Last edit: October 6, 2020 +Cross-compiling NetHack 3.7 Last edit: December 7, 2020 The NetHack 3.7 build process differs from the build process of previous versions in some important ways that make it possible to use a cross-compiler @@ -18,7 +18,7 @@ Part B Contents: B3. What needs to be built for the TARGET? B4. Case sample: msdos B5. Case sample: amiga (started but incomplete) - B6. Case sample: Web Assembly, libnethack + B6. Case sample: Web Assembly, libnh -------------------------------------------------------------------------------- Part A - Cross-compiling NetHack @@ -668,7 +668,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html make CROSS_TO_WASM=1 - You can build src/nethacklib.a from pull request 385 as follows: + You can build src/libnh.a from pull request 385 as follows: make WANT_LIBNH=1 @@ -679,7 +679,7 @@ Cross-compiler url: https://emscripten.org/docs/getting_started/downloads.html from pull request 385. Result: As mentioned, the wasm cross-compile will end up in - targets/wasm and the nethacklib.a will end up + targets/wasm and the nethacklib.a will end up in src. The cross-compiler hints additions are enclosed inside ifdef sections From 87818188e1960031fe3cd832784501342e4877a2 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 7 Dec 2020 12:46:46 -0800 Subject: [PATCH 549/708] fix #3120,#3122 - dwarf pass_wall without digging I couldn't reproduce this so can't confirm that this fix works, but inspection of the code reveals that something was missing in the unified mon movement flags code. I think what has been happening is that a dwarf without a pick-axe might not bother wielding that but movement behaved as if it had, then digging decided it wasn't. --- doc/fixes37.0 | 3 ++- src/dogmove.c | 6 ++++-- src/mon.c | 13 ++++++++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 16a14abe6..3194adae7 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.376 $ $NHDT-Date: 1607252278 2020/12/06 10:57:58 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.377 $ $NHDT-Date: 1607373999 2020/12/07 20:46:39 $ General Fixes and Modified Features ----------------------------------- @@ -411,6 +411,7 @@ options help ('? g') listed all boolean options, then repeated them among the compound options; on OSX they showed a description of "(null)" but for other sprintf implementations they might cause a crash change name of #wizlevelflip to #wizfliplevel +dwarves could sometimes pass through walls without digging their way curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/dogmove.c b/src/dogmove.c index e4f8f4513..363bbcd5c 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dogmove.c $NHDT-Date: 1596498159 2020/08/03 23:42:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.91 $ */ +/* NetHack 3.7 dogmove.c $NHDT-Date: 1607374000 2020/12/07 20:46:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.94 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1311,7 +1311,9 @@ xchar mx, my, fx, fy; if (dist2(i, j, fx, fy) >= dist) continue; if (IS_ROCK(levl[i][j].typ) && !passes_walls(mon->data) - && (!may_dig(i, j) || !tunnels(mon->data))) + && (!may_dig(i, j) || !tunnels(mon->data) + /* tunnelling monsters can't do that on the rogue level */ + || Is_rogue_level(&u.uz))) continue; if (IS_DOOR(levl[i][j].typ) && (levl[i][j].doormask & (D_CLOSED | D_LOCKED))) diff --git a/src/mon.c b/src/mon.c index e203e71d7..06a00a4a3 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1606623308 2020/11/29 04:15:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.357 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1607374002 2020/12/07 20:46:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.359 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1551,6 +1551,14 @@ struct monst *mtmp; boolean can_unlock = ((can_open && monhaskey(mtmp, TRUE)) || mtmp->iswiz || is_rider(mtmp->data)); boolean doorbuster = is_giant(mtmp->data); + /* don't tunnel if on rogue level or if hostile and close enough + to prefer a weapon; same criteria as in m_move() */ + boolean can_tunnel = (tunnels(mtmp->data) && !Is_rogue_level(&u.uz)); + + if (can_tunnel && needspick(mtmp->data) + && ((!mtmp->mpeaceful || Conflict) + && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8)) + can_tunnel = FALSE; if (mtmp->mtame) allowflags |= ALLOW_M | ALLOW_TRAPS | ALLOW_SANCT | ALLOW_SSM; @@ -1568,8 +1576,7 @@ struct monst *mtmp; allowflags |= (ALLOW_ROCK | ALLOW_WALL); if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK; - if (tunnels(mtmp->data) - && !Is_rogue_level(&u.uz)) /* same restriction as m_move() */ + if (can_tunnel) allowflags |= ALLOW_DIG; if (doorbuster) allowflags |= BUSTDOOR; From 3d7a3fcc724c0192a4df9b225f253de3ca9f65d7 Mon Sep 17 00:00:00 2001 From: k21971 Date: Mon, 7 Dec 2020 20:53:01 +0000 Subject: [PATCH 550/708] Fix: genetic engineers dropping Schroedinger's cat box. Only quantum mechanics are supposed to have a chance of death-dropping the Schroedinger's cat box. Slash'Em already had this but it was missed when Genetic engineers were ported over. --- doc/fixes37.0 | 1 + src/makemon.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3194adae7..c424affbc 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -412,6 +412,7 @@ options help ('? g') listed all boolean options, then repeated them among but for other sprintf implementations they might cause a crash change name of #wizlevelflip to #wizfliplevel dwarves could sometimes pass through walls without digging their way +fix genetic engineers dropping Schroedinger's cat box curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/makemon.c b/src/makemon.c index 11725b94c..b9bb36d5f 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -755,7 +755,7 @@ register struct monst *mtmp; (void) mongets(mtmp, MUMMY_WRAPPING); break; case S_QUANTMECH: - if (!rn2(20)) { + if (!rn2(20) && ptr == &mons[PM_QUANTUM_MECHANIC]) { struct obj *catcorpse; otmp = mksobj(LARGE_BOX, FALSE, FALSE); From 2a181c395545583bf96802ebd25d1544b40fb57f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 8 Dec 2020 17:08:57 +0200 Subject: [PATCH 551/708] Detection map redisplay routine code deduplication --- src/detect.c | 61 ++++++++++++++++------------------------------------ 1 file changed, 19 insertions(+), 42 deletions(-) diff --git a/src/detect.c b/src/detect.c index 575082e20..4bf7e0a0b 100644 --- a/src/detect.c +++ b/src/detect.c @@ -13,6 +13,7 @@ static boolean NDECL(unconstrain_map); static void NDECL(reconstrain_map); +static void NDECL(map_redisplay); static void FDECL(browse_map, (int, const char *)); static void FDECL(map_monst, (struct monst *, BOOLEAN_P)); static void FDECL(do_dknown_of, (struct obj *)); @@ -52,6 +53,17 @@ reconstrain_map() u.uswallow = iflags.save_uswallow, iflags.save_uswallow = 0; } +static void +map_redisplay() +{ + reconstrain_map(); + docrt(); /* redraw the screen to remove unseen traps from the map */ + if (Underwater) + under_water(2); + if (u.uburied) + under_ground(2); +} + /* use getpos()'s 'autodescribe' to view whatever is currently shown on map */ static void browse_map(ter_typ, ter_explain) @@ -440,12 +452,7 @@ register struct obj *sobj; browse_map(ter_typ, "gold"); - reconstrain_map(); - docrt(); - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); return 0; } @@ -564,12 +571,7 @@ register struct obj *sobj; browse_map(ter_typ, "food"); - reconstrain_map(); - docrt(); - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); } return 0; } @@ -765,12 +767,7 @@ int class; /* an object class, 0 for all */ else browse_map(ter_typ, "object"); - reconstrain_map(); - docrt(); /* this will correctly reset vision */ - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); return 0; } @@ -844,12 +841,7 @@ int mclass; /* monster class, 0 for all */ EDetect_monsters &= ~I_SPECIAL; } - reconstrain_map(); - docrt(); /* redraw the screen to remove unseen monsters from map */ - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); } return 0; } @@ -1032,12 +1024,7 @@ struct obj *sobj; /* null if crystal ball, *scroll if gold detection scroll */ browse_map(ter_typ, "trap of interest"); - reconstrain_map(); - docrt(); /* redraw the screen to remove unseen traps from the map */ - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); return 0; } @@ -1082,12 +1069,7 @@ furniture_detect() browse_map(TER_DETECT | TER_MAP | TER_TRP | TER_OBJ | TER_MON, "location"); - reconstrain_map(); - docrt(); /* redraw everything */ - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); return 0; } @@ -2108,12 +2090,7 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */ which_subset |= TER_MAP; /* guarantee non-zero */ browse_map(which_subset, "anything of interest"); - reconstrain_map(); - docrt(); /* redraw the screen, restoring regular map */ - if (Underwater) - under_water(2); - if (u.uburied) - under_ground(2); + map_redisplay(); } return; } From 00955f50e578675ee895ec8185ad0fd8389b9dd5 Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 8 Dec 2020 10:27:30 -0800 Subject: [PATCH 552/708] Update to azure pipeline. --- azure-pipelines.yml | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a2348072a..02d614c8f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,8 +1,3 @@ -# Starter pipeline -# Start with a minimal pipeline that you can customize to build and deploy your code. -# Add steps that build, run tests, deploy, and more: -# https://aka.ms/yaml - strategy: matrix: linux: @@ -24,7 +19,7 @@ resources: endpoint: github.com_barthouse steps: -- checkout: git://NetHack/NHsource@NetHack-3.7 # $(Agent.BuildDirectory)\s\NHsource +- checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack - checkout: luarepo # $(Agent.BuildDirectory)\s\lua - task: DownloadSecureFile@1 @@ -38,34 +33,37 @@ steps: inputs: contents: NetHackPackage_StoreKey.pfx SourceFolder: $(Agent.TempDirectory) - TargetFolder: $(Agent.BuildDirectory)\s\NHsource\win\win32\vs + TargetFolder: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs condition: eq( variables['Agent.OS'], 'Windows_NT' ) - task: CopyFiles@2 inputs: SourceFolder: $(Agent.BuildDirectory)\s\lua - TargetFolder: $(Agent.BuildDirectory)\s\NHsource\lib\lua-5.4.1\src + TargetFolder: $(Agent.BuildDirectory)\s\NetHack\lib\lua-5.4.1\src condition: eq( variables['Agent.OS'], 'Windows_NT' ) - task: MSBuild@1 inputs: - solution: $(Agent.BuildDirectory)\s\NHsource\win\win32\vs\NetHack.sln + solution: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs\NetHack.sln platform: Win32 configuration: Debug condition: eq( variables['Agent.OS'], 'Windows_NT' ) - bash: | - cd NHsource/sys/unix + sudo apt-get -qq -y update + sudo apt-get -qq -y install libncurses5-dev + sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools + cd NetHack/sys/unix sh setup.sh hints/linux.2020 cd ../.. make fetch-lua - make all + make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all condition: eq( variables['Agent.OS'], 'Linux' ) displayName: 'Linux Build' - bash: | - cd NHsource/sys/unix - sh setup.sh hints/macosx10.14 + cd NetHack/sys/unix + sh setup.sh hints/macos.2020 cd ../.. make fetch-lua make all From 9f79ad56d9245f1151dad999c0a2adc78f10dc06 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Dec 2020 12:58:36 -0800 Subject: [PATCH 553/708] NOSUSPEND Provide a hook to inhibit unixconf.h from defining SUSPEND without the need to modify it: #define NOSUSPEND in config.h or add -DNOSUSPEND to CFLAGS. Similar to long-standing NOSHELL for inhibiting SHELL. --- doc/fixes37.0 | 4 +++- include/unixconf.h | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c424affbc..dcc080db7 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.377 $ $NHDT-Date: 1607373999 2020/12/07 20:46:39 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.379 $ $NHDT-Date: 1607461111 2020/12/08 20:58:31 $ General Fixes and Modified Features ----------------------------------- @@ -670,6 +670,8 @@ Qt: add Filter, Layout, and Reset buttons to the extended command selector; mode only"; Layout redisplays the grid of command buttons, toggling from down columns to across rows or vice versa; Reset puts both back to their default settings and clears any pending typed input +Unix: can define NOSUSPEND in config.h or src/Makefile's CFLAGS to prevent + unixconf.h from enabling SUSPEND without need to modify unixconf.h NetHack Community Patches (or Variation) Included diff --git a/include/unixconf.h b/include/unixconf.h index e97481d7d..698adfc56 100644 --- a/include/unixconf.h +++ b/include/unixconf.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 unixconf.h $NHDT-Date: 1596498567 2020/08/03 23:49:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.47 $ */ +/* NetHack 3.7 unixconf.h $NHDT-Date: 1607461111 2020/12/08 20:58:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -273,8 +273,11 @@ #endif #endif #endif + +#ifndef NOSUSPEND #if defined(BSD_JOB_CONTROL) || defined(POSIX_JOB_CONTROL) || defined(AUX) -#define SUSPEND /* let ^Z suspend the game */ +#define SUSPEND /* let ^Z suspend the game (push to background) */ +#endif #endif /* From 1bec4a66cd8eff41263a2e3a8ff59dc7eceff113 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Dec 2020 15:58:02 -0800 Subject: [PATCH 554/708] keylist help (? i) fixes I was implementing a routine to show all the key bindings when I discovered that we already have one. This fixes a few small problems: 'n' prefix for number entry was missing for number_pad mode. Meta+ for running in number_pad mode was missing too. ^A was present but being suppressed by lack of #define for obsolete #if REDO. And ^C was shown as ^c while all other ^ characters appear in upper case. Once ^A appeared as the line before it, the inconsistency stood out. I also changed the slightly verbose "Shift-" and "Ctrl-" entries below the direction grid to use plus instead of minus signs. Plus emphasizes that two things are combined so seems more intuitive. (I left "M-c" alone.) --- doc/fixes37.0 | 4 +++- src/cmd.c | 38 +++++++++++++++++++++++++++----------- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index dcc080db7..c36d0c43e 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.379 $ $NHDT-Date: 1607461111 2020/12/08 20:58:31 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.380 $ $NHDT-Date: 1607471879 2020/12/08 23:57:59 $ General Fixes and Modified Features ----------------------------------- @@ -320,6 +320,8 @@ when saving while punished or game ends while punished, handling for ball and chain might access freed memory with unpredictable consequences brown pudding monster hitting another monster with decay attack corroded armor instead of rotting it + -> omitted 'n' prefix and M-digit for number_pad mode, + and ^A/re-do was suppressed due lack of obsolete '#define REDO' Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/cmd.c b/src/cmd.c index df38ac840..bd348ae8d 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607339290 2020/12/07 11:08:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.428 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607471879 2020/12/08 23:57:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.429 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2161,7 +2161,7 @@ dokeylist(VOID_ARGS) { char buf[BUFSZ], buf2[BUFSZ]; uchar key; - boolean keys_used[256] = {0}; + boolean keys_used[256]; winid datawin; int i; static const char @@ -2186,12 +2186,14 @@ dokeylist(VOID_ARGS) "Prefix: run without picking up objects/fighting", FALSE }, { NHKF_DOINV, "view inventory", TRUE }, { NHKF_REQMENU, "Prefix: request a menu", FALSE }, -#ifdef REDO + { NHKF_COUNT, + "Prefix: for digits when prefixing a command with a count", TRUE }, { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE }, -#endif { 0, (const char *) 0, FALSE } }; + (void) memset((genericptr_t) keys_used, 0, sizeof keys_used); + datawin = create_nhwindow(NHW_TEXT); putstr(datawin, 0, ""); putstr(datawin, 0, " Full Current Key Bindings List"); @@ -2226,12 +2228,24 @@ dokeylist(VOID_ARGS) = keys_used[(uchar) C(g.Cmd.move_SE)] = TRUE; putstr(datawin, 0, ""); putstr(datawin, 0, - "Shift- will move in specified direction until you hit"); - putstr(datawin, 0, " a wall or run into something."); - putstr(datawin, 0, - "Ctrl- will run in specified direction until something"); - putstr(datawin, 0, " very interesting is seen."); + "Ctrl+ will run in specified direction until something very"); + Sprintf(buf, "%8s %s", "", "interesting is seen."); + putstr(datawin, 0, buf); + Strcpy(buf, "Shift"); + } else { + /* num_pad */ + keys_used[(uchar) M('1')] = keys_used[(uchar) M('2')] + = keys_used[(uchar) M('3')] = keys_used[(uchar) M('4')] + = keys_used[(uchar) M('6')] = keys_used[(uchar) M('7')] + = keys_used[(uchar) M('8')] = keys_used[(uchar) M('9')] = TRUE; + putstr(datawin, 0, ""); + Strcpy(buf, "Meta"); } + Strcat(buf, + "+ will run in specified direction until you encounter"); + putstr(datawin, 0, buf); + Sprintf(buf, "%8s %s", "", "an obstacle."); + putstr(datawin, 0, buf); putstr(datawin, 0, ""); putstr(datawin, 0, "Miscellaneous keys:"); @@ -2245,8 +2259,10 @@ dokeylist(VOID_ARGS) } } #ifndef NO_SIGNAL - putstr(datawin, 0, "^c break out of NetHack (SIGINT)"); keys_used[(uchar) C('c')] = TRUE; + Sprintf(buf, "%-8s %s", key2txt(C('c'), buf2), + "break out of NetHack (SIGINT)"); + putstr(datawin, 0, buf); #endif putstr(datawin, 0, ""); @@ -2778,7 +2794,7 @@ wiz_migrate_mons() } #endif -struct { +static struct { int nhkf; char key; const char *name; From e1406a8c087d164e9355cb124410145b2109d686 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 9 Dec 2020 16:52:54 -0800 Subject: [PATCH 555/708] txt2key() - parsing key binding specifications While testing some addtional ?i (list of key assignments) changes, I wanted to give every key a binding. When I tried BIND=M-^A:exploremode the text to key conversion didn't like that. This adds support for M-^x and M-C-x plus variations where dashes are omitted. This adds support for ^? even though that isn't really a control character. I bound #terrain to it and surprising--to me at least--the key worked to invoke that command. Also changes 'char txt2key(...)' to be 'uchar txt2key(...)'. --- include/extern.h | 4 +-- src/cmd.c | 82 +++++++++++++++++++++++++++++++++--------------- src/options.c | 25 ++++++++------- 3 files changed, 72 insertions(+), 39 deletions(-) diff --git a/include/extern.h b/include/extern.h index 4fc957d30..bbb2fd88d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.886 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1607561572 2020/12/10 00:52:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.928 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -229,7 +229,7 @@ E void FDECL(pushch, (CHAR_P)); E void FDECL(savech, (CHAR_P)); E const char *FDECL(key2extcmddesc, (UCHAR_P)); E boolean FDECL(bind_specialkey, (UCHAR_P, const char *)); -E char FDECL(txt2key, (char *)); +E uchar FDECL(txt2key, (char *)); E void FDECL(parseautocomplete, (char *, BOOLEAN_P)); E void FDECL(reset_commands, (BOOLEAN_P)); E void FDECL(rhack, (char *)); diff --git a/src/cmd.c b/src/cmd.c index bd348ae8d..bc50986ec 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607471879 2020/12/08 23:57:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.429 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607561570 2020/12/10 00:52:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.430 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -379,7 +379,7 @@ const struct ext_func_tab *efp; /* if Null, add a footnote to the menu */ } } -/* here after #? - now list all full-word commands and provid +/* here after #? - now list all full-word commands and provide some navigation capability through the long list */ int doextlist(VOID_ARGS) @@ -2858,19 +2858,21 @@ const char *command; return FALSE; } -/* returns a one-byte character from the text (it may massacre the txt - * buffer) */ -char +/* returns a one-byte character from the text; may change txt[] */ +uchar txt2key(txt) char *txt; { + uchar uc; + boolean makemeta = FALSE; + txt = trimspaces(txt); if (!*txt) return '\0'; /* simple character */ if (!txt[1]) - return txt[0]; + return (uchar) txt[0]; /* a few special entries */ if (!strcmp(txt, "")) @@ -2881,25 +2883,55 @@ char *txt; return '\033'; /* control and meta keys */ - switch (*txt) { - case 'm': /* can be mx, Mx, m-x, M-x */ - case 'M': - txt++; + if (highc(*txt) == 'M') { + /* + * M return 'M' + * M - return M-'-' + * M return M- + * otherwise M is pending until after ^/C- processing. + * Since trailing spaces are discarded, the only way to + * specify M-' ' is via "160". + */ + if (!txt[1]) + return (uchar) *txt; + /* skip past 'M' or 'm' and maybe '-' */ + ++txt; if (*txt == '-' && txt[1]) - txt++; - if (txt[1]) - return '\0'; - return M(*txt); - case 'c': /* can be cx, Cx, ^x, c-x, C-x, ^-x */ - case 'C': - case '^': - txt++; - if (*txt == '-' && txt[1]) - txt++; - if (txt[1]) - return '\0'; - return C(*txt); + ++txt; + if (!txt[1]) + return M((uchar) *txt); + makemeta = TRUE; } + if (*txt == '^' || highc(*txt) == 'C') { + /* + * C return 'C' or M-'C' + * C - return '-' or M-'-' + * C [-] return C- or M-C- + * C [-] ? return + * otherwise return C- or M-C- + */ + uc = (uchar) *txt; + if (!txt[1]) + return makemeta ? M(uc) : uc; + ++txt; + /* unlike M-x, lots of values of x are invalid for C-x; + checking and rejecting them is not worthwhile; GIGO; + we do accept "^-x" as synonym for "^x" or "C-x" */ + if (*txt == '-' && txt[1]) + ++txt; + /* and accept ^?, which gets used despite not being a control char */ + if (*txt == '?') + return (uchar) (makemeta ? '\377' : '\177'); /* rubout/delete */ + uc = C((uchar) *txt); + return makemeta ? M(uc) : uc; + } + if (makemeta && *txt) + return M((uchar) *txt); + + /* FIXME: should accept single-quote single-character single-quote + and probably single-quote backslash octal-digits single-quote; + if we do that, the M- and C- results should be pending until + after, so that C-'X' becomes valid for ^X */ /* ascii codes: must be three-digit decimal */ if (*txt >= '0' && *txt <= '9') { @@ -2929,9 +2961,9 @@ char *txt; /* sufficiently long buffer */ if (c == ' ') Sprintf(txt, ""); else if (c == '\033') - Sprintf(txt, ""); + Sprintf(txt, ""); /* "" won't fit */ else if (c == '\n') - Sprintf(txt, ""); + Sprintf(txt, ""); /* "" won't fit */ else if (c == '\177') Sprintf(txt, ""); /* "" won't fit */ else diff --git a/src/options.c b/src/options.c index e82877b5a..f4a008c9b 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1606445249 2020/11/27 02:47:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.482 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1607561571 2020/12/10 00:52:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.484 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -281,7 +281,7 @@ static boolean FDECL(is_wc2_option, (const char *)); static boolean FDECL(wc2_supported, (const char *)); static void FDECL(wc_set_font_name, (int, char *)); static int FDECL(wc_set_window_colors, (char *)); -static boolean FDECL(illegal_menu_cmd_key, (CHAR_P)); +static boolean FDECL(illegal_menu_cmd_key, (UCHAR_P)); #ifndef CHANGE_COLOR int FDECL(optfn_palette, (int, int, BOOLEAN_P, char *, char *)); #endif @@ -4664,7 +4664,7 @@ char *op; escapes(op, op_buf); c = *op_buf; - if (illegal_menu_cmd_key(c)) + if (illegal_menu_cmd_key((uchar) c)) return optn_err; add_menu_cmd_alias(c, default_menu_cmd_info[midx].cmd); } @@ -6362,10 +6362,10 @@ const char *optn; /* parse key:command */ boolean parsebindings(bindings) -char* bindings; +char *bindings; { char *bind; - char key; + uchar key; int i; boolean ret = FALSE; @@ -6400,7 +6400,7 @@ char* bindings; config_error_add("Bad menu key %s:%s", visctrl(key), bind); return FALSE; } else - add_menu_cmd_alias(key, default_menu_cmd_info[i].cmd); + add_menu_cmd_alias((char) key, default_menu_cmd_info[i].cmd); return TRUE; } } @@ -7151,18 +7151,19 @@ char **opp; /* Check if character c is illegal as a menu command key */ boolean illegal_menu_cmd_key(c) -char c; +uchar c; { - if (c == 0 || c == '\r' || c == '\n' || c == '\033' - || c == ' ' || digit(c) || (letter(c) && c != '@')) { - config_error_add("Reserved menu command key '%s'", visctrl(c)); + if (c == 0 || c == '\r' || c == '\n' || c == '\033' || c == ' ' + || digit((char) c) || (letter((char) c) && c != '@')) { + config_error_add("Reserved menu command key '%s'", visctrl((char) c)); return TRUE; } else { /* reject default object class symbols */ int j; + for (j = 1; j < MAXOCLASSES; j++) - if (c == def_oc_syms[j].sym) { + if (c == (uchar) def_oc_syms[j].sym) { config_error_add("Menu command key '%s' is an object class", - visctrl(c)); + visctrl((char) c)); return TRUE; } } From 241cb2a8d37a3325094001e8661e069c90ed6294 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Dec 2020 01:01:04 -0800 Subject: [PATCH 556/708] Guidebook catchup The command rename "#seegold" to "#showgold" that also revised a few of the short command desctipions didn't include a Guidebook update. So here one is. --- doc/Guidebook.mn | 29 +++++++++++++++++++++-------- doc/Guidebook.tex | 30 +++++++++++++++++++++++------- 2 files changed, 44 insertions(+), 15 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 82880c6d1..074cbf2d8 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.402 $ $NHDT-Date: 1606781766 2020/12/01 00:16:06 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.403 $ $NHDT-Date: 1607590842 2020/12/10 09:00:42 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "November 30, 2020 +.ds f2 "December 9, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1036,7 +1036,7 @@ Tell what equipment you are using. Combines the preceding five type-specific commands into one. .lp $ -Count your gold pieces. +Report the gold you're carrying, possibly shop credit and/or debt too. .lp + List the spells you know. .lp "" @@ -1387,9 +1387,6 @@ Default key is \(oq\(dq\(cq. \" double quote .lp #seearmor Show the armor currently worn. Default key is \(oq[\(cq. -.lp "#seegold " -Count your gold. -Default key is \(oq$\(cq. .lp #seerings Show the ring(s) currently worn. Default key is \(oq=\(cq. @@ -1406,11 +1403,20 @@ When enabled, access for specific users can be controlled by the system configuration file. Use the shell command \(oq\f(CRexit\fP\(cq to return to the game. Default key is \(oq!\(cq. +.lp "#showgold" +Report the gold in your inventory and if you are inside a shop, +report any credit or debt you have in that shop. +Does not report on any gold inside containers you're carrying. +Default key is \(oq$\(cq. .lp #showspells List and reorder known spells. Default key is \(oq+\(cq. .lp "#showtrap" -Show the type of an adjacent trap. +Describe an adjacent trap, possibly covered by objects or a monster. +To be eligible, the trap must already be discovered. +(The \(lq#terrain\(rq command can display your map with all objects and +monsters temporarily removed, making it possible to see all discovered +traps.) Default key is \(oq\(ha\(cq. \" 'hat' (circumflex character) .lp "#sit " Sit down. @@ -1496,10 +1502,17 @@ Autocompletes. Debug mode only. .lp "#version " Print compile time options for this version of NetHack. +.lp "" +The second paragraph lists the user interface(s) that are included. +If there are more than one, you can use the +.op window_type +option in your run-time configuration file to select the one you want. +.lp "" Autocompletes. Default key is \(oqM-v\(cq. .lp #versionshort -Show version string. +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 \(oqv\(cq. .lp "#vision " Show vision array. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 045329d68..236322d1b 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{November 30, 2020} +\date{December 9, 2020} \maketitle @@ -1136,7 +1136,7 @@ Combines the preceding five type-specific commands into one. %.lp \item[\tb{\$}] -Count your gold pieces. +Report the gold you're carrying, possibly shop credit and/or debt too. %.lp \item[\tb{+}] List the spells you know.\\ @@ -1471,9 +1471,6 @@ Show the amulet currently worn. Default key is `{\tt "}'. \item[\tb{\#seearmor}] Show the armor currently worn. Default key is `{\tt [}'. %.lp -\item[\tb{\#seegold}] -Count your gold. Default key is `{\tt \$}'. -%.lp \item[\tb{\#seerings}] Show the ring(s) currently worn. Default key is `{\tt =}'. %.lp @@ -1491,12 +1488,22 @@ configuration file. Use the shell command `{\tt exit}' to return to the game. Default key is `{\tt !}'. %.lp +\item[\tb{\#showgold}] +Report the gold in your inventory and if you are inside a shop, +report any credit or debt you have in that shop. +Does not report on any gold inside containers you're carrying. +Default key is `{\tt \$}'. +%.lp \item[\tb{\#showspells}] List and reorder known spells. Default key is `{\tt +}'. %.lp \item[\tb{\#showtrap}] -Show the type of an adjacent trap. +Describe an adjacent trap, possibly covered by objects or a monster. +To be eligible, the trap must already be discovered. +(The ``{\tt \#terrain}'' command can display your map with all objects and +monsters temporarily removed, making it possible to see all discovered +traps.) Default key is `{\tt \^{}}'. %.lp \item[\tb{\#sit}] @@ -1586,10 +1593,19 @@ Debug mode only. %.lp \item[\tb{\#version}] Print compile time options for this version of {\it NetHack\/}. + +%.lp +The second paragraph lists the user interface(s) that are included. +If there are more than one, you can use the {\it window\verb+_+type\/} +option in your run-time configuration file to select the one you want. + +%.lp Autocompletes. Default key is `{\tt M-v}'. %.lp \item[\tb{\#versionshort}] -Show version string. Default key is `{\tt v}'. +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 `{\tt v}'. %.lp \item[\tb{\#vision}] Show vision array. From 3e183d0c6ad0f3aac42d821b15ada2cc1173bf2c Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Dec 2020 01:07:07 -0800 Subject: [PATCH 557/708] yet more key bindings - lack of same... When ?i shows key bindings, at the end of each group (movement, prefixes, general, game, debug) report any commands for that group which don't have any key assigned. Movement and prefixes all have keys; they'd be pretty useless without and key bindings won't override movement commands. For general, the "keyless" are |#exploremode |#herecmdmenu |#therecmdmenu after this adds the relevant flag to their command definitions; for game, "#terrain" is the only one; the debug section has 20. There is a known problem that I've going to pretend that I didn't notice: if I use BIND=D:takeoffall then 'A' becomes unassigned, 'D' invokes #takeoffall, "#droptype" becomes keyless, and ?i reports those correctly. But if I use BIND=M:takeoffall, 'A' becomes unassigned, 'M' continues to be its usual prefix, and the "#takeoffall" command is nowhere to be seen. The code that tracks assignments is letting that case fall through the cracks. 'M' ends up assigned to both and the ?i code deliberately only shows the first. --- doc/fixes37.0 | 5 ++- src/cmd.c | 120 ++++++++++++++++++++++++++++++++++---------------- src/options.c | 4 +- src/pager.c | 6 +-- 4 files changed, 92 insertions(+), 43 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index c36d0c43e..77dc16702 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.380 $ $NHDT-Date: 1607471879 2020/12/08 23:57:59 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.381 $ $NHDT-Date: 1607591199 2020/12/10 09:06:39 $ General Fixes and Modified Features ----------------------------------- @@ -645,6 +645,9 @@ reading blessed scroll of teleportation confers one-shot teleport control mild zombie apocalypse list lamps and lanterns in charging prompt let tourists read conical hats +when "?i" (show key bindings) displays commands and their keys, also show + commands without any key (so useable via '#', or possibly menu, only; + the majority are debugging commands) Platform- and/or Interface-Specific New Features diff --git a/src/cmd.c b/src/cmd.c index bc50986ec..f7c8121eb 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607561570 2020/12/10 00:52:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.430 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607591200 2020/12/10 09:06:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.431 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -181,7 +181,8 @@ static void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P)); static boolean FDECL(help_dir, (CHAR_P, int, const char *)); static void NDECL(commands_init); -static int FDECL(dokeylist_putcmds, (winid, BOOLEAN_P, int, int, boolean *)); +static boolean FDECL(keylist_func_has_key, (const struct ext_func_tab *)); +static int FDECL(keylist_putcmds, (winid, BOOLEAN_P, int, int, boolean *)); static int FDECL(ch2spkeys, (CHAR_P, int, int)); static boolean FDECL(prefix_cmd, (CHAR_P)); @@ -1791,9 +1792,10 @@ struct ext_func_tab extcmdlist[] = { doapply }, { C('x'), "attributes", "show your attributes", doattributes, IFBURIED }, - { '@', "autopickup", "toggle the pickup option on/off", + { '@', "autopickup", "toggle the 'autopickup' option on/off", dotogglepickup, IFBURIED }, - { 'C', "call", "call (name) something", docallcmd, IFBURIED }, + { 'C', "call", "name a monster, a specific object, or a type of object", + docallcmd, IFBURIED }, { 'Z', "cast", "zap (cast) a spell", docast, IFBURIED }, { M('c'), "chat", "talk to someone", dotalk, IFBURIED | AUTOCOMPLETE }, { 'c', "close", "close a door", doclose }, @@ -1808,14 +1810,14 @@ struct ext_func_tab extcmdlist[] = { { M('e'), "enhance", "advance or check weapon and spell skills", enhance_weapon_skill, IFBURIED | AUTOCOMPLETE }, { '\0', "exploremode", "enter explore (discovery) mode", - enter_explore_mode, IFBURIED }, + enter_explore_mode, IFBURIED | GENERALCMD }, { 'f', "fire", "fire ammunition from quiver", dofire }, { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE }, { ';', "glance", "show what type of thing a map symbol corresponds to", doquickwhatis, IFBURIED | GENERALCMD }, { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD }, { '\0', "herecmdmenu", "show menu of commands you can do here", - doherecmdmenu, IFBURIED }, + doherecmdmenu, IFBURIED | GENERALCMD }, { 'V', "history", "show long version and game history", dohistory, IFBURIED | GENERALCMD }, { 'i', "inventory", "show your inventory", ddoinv, IFBURIED }, @@ -1841,7 +1843,7 @@ struct ext_func_tab extcmdlist[] = { #endif { M('m'), "monster", "use monster's special ability", domonability, IFBURIED | AUTOCOMPLETE }, - { 'N', "name", "name a monster or an object", + { 'N', "name", "same as call; name a monster or object or object type", docallcmd, IFBURIED | AUTOCOMPLETE }, { M('o'), "offer", "offer a sacrifice to the gods", dosacrifice, AUTOCOMPLETE }, @@ -1915,7 +1917,7 @@ struct ext_func_tab extcmdlist[] = { doterrain, IFBURIED | AUTOCOMPLETE }, { '\0', "therecmdmenu", "menu of commands you can do from here to adjacent spot", - dotherecmdmenu }, + dotherecmdmenu, GENERALCMD }, { 't', "throw", "throw something", dothrow }, { '\0', "timeout", "look at timeout queue and hero's timed intrinsics", wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, @@ -1931,7 +1933,7 @@ struct ext_func_tab extcmdlist[] = { { M('v'), "version", "list compile time options for this version of NetHack", doextversion, IFBURIED | AUTOCOMPLETE | GENERALCMD }, - { 'v', "versionshort", "show version and date/time program was built", + { 'v', "versionshort", "show version and date+time program was built", doversion, IFBURIED | GENERALCMD }, { '\0', "vision", "show vision array", wiz_show_vision, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, @@ -2117,20 +2119,32 @@ commands_init() (void) bind_key(' ', "wait"); } -static int -dokeylist_putcmds(datawin, docount, cmdflags, exflags, keys_used) -winid datawin; -boolean docount; -int cmdflags, exflags; -boolean *keys_used; /* boolean keys_used[256] */ +static boolean +keylist_func_has_key(extcmd) +const struct ext_func_tab *extcmd; { int i; - char buf[BUFSZ]; - char buf2[QBUFSZ]; + + for (i = 0; i < 256; i++) { + if (g.Cmd.commands[i] == extcmd) + return TRUE; + } + return FALSE; +} + +static int +keylist_putcmds(datawin, docount, incl_flags, excl_flags, keys_used) +winid datawin; +boolean docount; +int incl_flags, excl_flags; +boolean *keys_used; /* boolean keys_used[256] */ +{ + const struct ext_func_tab *extcmd; + int i; + char buf[BUFSZ], buf2[QBUFSZ]; int count = 0; for (i = 0; i < 256; i++) { - const struct ext_func_tab *extcmd; uchar key = (uchar) i; if (keys_used[i]) @@ -2138,20 +2152,38 @@ boolean *keys_used; /* boolean keys_used[256] */ if (key == ' ' && !flags.rest_on_space) continue; if ((extcmd = g.Cmd.commands[i]) != (struct ext_func_tab *) 0) { - if ((cmdflags && !(extcmd->flags & cmdflags)) - || (exflags && (extcmd->flags & exflags))) + if ((incl_flags && !(extcmd->flags & incl_flags)) + || (excl_flags && (extcmd->flags & excl_flags))) continue; if (docount) { count++; continue; } - Sprintf(buf, "%-8s %-12s %s", key2txt(key, buf2), - extcmd->ef_txt, - extcmd->ef_desc); + Sprintf(buf, "%-7s %-13s %s", key2txt(key, buf2), + extcmd->ef_txt, extcmd->ef_desc); putstr(datawin, 0, buf); keys_used[i] = TRUE; } } + /* also list commands that lack key assignments; most are wizard mode */ + for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) { + if ((incl_flags && !(extcmd->flags & incl_flags)) + || (excl_flags && (extcmd->flags & excl_flags))) + continue; + /* can't just check for non-Null extcmd->key; it holds the + default assignment and a user-specified binding might hijack + the this command's default key for some other command */ + if (keylist_func_has_key(extcmd)) + continue; + /* found a command for current category without any key assignment */ + if (docount) { + count++; + continue; + } + /* '#'+20 for one column here == 7+' '+13 for two columns above */ + Sprintf(buf, "#%-20s %s", extcmd->ef_txt, extcmd->ef_desc); + putstr(datawin, 0, buf); + } return count; } @@ -2159,6 +2191,7 @@ boolean *keys_used; /* boolean keys_used[256] */ void dokeylist(VOID_ARGS) { + const struct ext_func_tab *extcmd; char buf[BUFSZ], buf2[BUFSZ]; uchar key; boolean keys_used[256]; @@ -2181,9 +2214,9 @@ dokeylist(VOID_ARGS) { NHKF_FIGHT, forcefight_desc, FALSE }, { NHKF_FIGHT2, forcefight_desc, TRUE } , { NHKF_NOPICKUP, - "Prefix: move without picking up objects/fighting", FALSE }, + "Prefix: move without picking up objects or fighting", FALSE }, { NHKF_RUN_NOPICKUP, - "Prefix: run without picking up objects/fighting", FALSE }, + "Prefix: run without picking up objects or fighting", FALSE }, { NHKF_DOINV, "view inventory", TRUE }, { NHKF_REQMENU, "Prefix: request a menu", FALSE }, { NHKF_COUNT, @@ -2196,7 +2229,18 @@ dokeylist(VOID_ARGS) datawin = create_nhwindow(NHW_TEXT); putstr(datawin, 0, ""); - putstr(datawin, 0, " Full Current Key Bindings List"); + Sprintf(buf, "%7s %s", "", " Full Current Key Bindings List"); + putstr(datawin, 0, buf); + for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) + /* this can only check for commands without any key assigned, not + ones whose key has been hijacked by something that's processed + before it (in use as a prefix, for instance) */ + if (!keylist_func_has_key(extcmd)) { + Sprintf(buf, "%7s %s", "", + "(also commands with no key assignment)"); + putstr(datawin, 0, buf); + break; + } /* directional keys */ putstr(datawin, 0, ""); @@ -2229,7 +2273,7 @@ dokeylist(VOID_ARGS) putstr(datawin, 0, ""); putstr(datawin, 0, "Ctrl+ will run in specified direction until something very"); - Sprintf(buf, "%8s %s", "", "interesting is seen."); + Sprintf(buf, "%7s %s", "", "interesting is seen."); putstr(datawin, 0, buf); Strcpy(buf, "Shift"); } else { @@ -2244,7 +2288,7 @@ dokeylist(VOID_ARGS) Strcat(buf, "+ will run in specified direction until you encounter"); putstr(datawin, 0, buf); - Sprintf(buf, "%8s %s", "", "an obstacle."); + Sprintf(buf, "%7s %s", "", "an obstacle."); putstr(datawin, 0, buf); putstr(datawin, 0, ""); @@ -2254,13 +2298,13 @@ dokeylist(VOID_ARGS) if (key && ((misc_keys[i].numpad && iflags.num_pad) || !misc_keys[i].numpad)) { keys_used[(uchar) key] = TRUE; - Sprintf(buf, "%-8s %s", key2txt(key, buf2), misc_keys[i].desc); + Sprintf(buf, "%-7s %s", key2txt(key, buf2), misc_keys[i].desc); putstr(datawin, 0, buf); } } #ifndef NO_SIGNAL keys_used[(uchar) C('c')] = TRUE; - Sprintf(buf, "%-8s %s", key2txt(C('c'), buf2), + Sprintf(buf, "%-7s %s", key2txt(C('c'), buf2), "break out of NetHack (SIGINT)"); putstr(datawin, 0, buf); #endif @@ -2268,24 +2312,26 @@ dokeylist(VOID_ARGS) putstr(datawin, 0, ""); show_menu_controls(datawin, TRUE); - if (dokeylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) { + if (keylist_putcmds(datawin, TRUE, GENERALCMD, WIZMODECMD, keys_used)) { putstr(datawin, 0, ""); putstr(datawin, 0, "General commands:"); - (void) dokeylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD, + (void) keylist_putcmds(datawin, FALSE, GENERALCMD, WIZMODECMD, keys_used); } - if (dokeylist_putcmds(datawin, TRUE, 0, WIZMODECMD, keys_used)) { + if (keylist_putcmds(datawin, TRUE, 0, + GENERALCMD | WIZMODECMD, keys_used)) { putstr(datawin, 0, ""); putstr(datawin, 0, "Game commands:"); - (void) dokeylist_putcmds(datawin, FALSE, 0, WIZMODECMD, keys_used); + (void) keylist_putcmds(datawin, FALSE, 0, + GENERALCMD | WIZMODECMD, keys_used); } if (wizard - && dokeylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) { + && keylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) { putstr(datawin, 0, ""); - putstr(datawin, 0, "Wizard-mode commands:"); - (void) dokeylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used); + putstr(datawin, 0, "Debug mode commands:"); + (void) keylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used); } display_nhwindow(datawin, FALSE); diff --git a/src/options.c b/src/options.c index f4a008c9b..01a3b29ae 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1607561571 2020/12/10 00:52:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.484 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1607591206 2020/12/10 09:06:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.485 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7721,7 +7721,7 @@ boolean dolist; int i; for (i = 0; i < SIZE(default_menu_cmd_info); i++) { - Sprintf(buf, "%-8s %s", + Sprintf(buf, "%-7s %s", visctrl(get_menu_cmd_key(default_menu_cmd_info[i].cmd)), default_menu_cmd_info[i].desc); putstr(win, 0, buf); diff --git a/src/pager.c b/src/pager.c index 7a6acebd3..991b633b9 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1596498194 2020/08/03 23:43:14 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.189 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1607591207 2020/12/10 09:06:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2093,9 +2093,9 @@ static const struct { { hmenu_dowhatdoes, "Info on what a given key does." }, { option_help, "List of game options." }, { dispfile_optionfile, "Longer explanation of game options." }, - { dokeylist, "Full list of keyboard commands" }, + { dokeylist, "Full list of keyboard commands." }, { hmenu_doextlist, "List of extended commands." }, - { domenucontrols, "List menu control keys" }, + { domenucontrols, "List menu control keys." }, { dispfile_license, "The NetHack license." }, { docontact, "Support information." }, #ifdef PORT_HELP From 68b69380fbe2eb33348fcccde1d59aa8170d826a Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 10 Dec 2020 04:24:07 -0500 Subject: [PATCH 558/708] This is cron-daily v1-Jan-20-2020. guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 2864 ++++++++++++++++++++++----------------------- 1 file changed, 1432 insertions(+), 1432 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 78e198ac6..9e6902777 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - November 30, 2020 + December 9, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1130,20 +1130,21 @@ Combines the preceding five type-specific commands into one. - $ Count your gold pieces. + $ Report the gold you're carrying, possibly shop credit and/or + debt too. + 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 an- - other to swap places with it. Swapping pairs of spells + 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 an- + other to swap places with it. Swapping pairs of spells changes their casting letters, so the change lasts after the - current `+' command finishes. Sorting the whole list is - temporary. To make the most recent sort order persist be- - yond 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 + current `+' command finishes. Sorting the whole list is + temporary. To make the most recent sort order persist be- + yond 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. @@ -1156,7 +1157,7 @@ - As you can see, the authors of NetHack used up all the let- + As you can see, the authors of NetHack used up all the let- ters, so this is a way to introduce the less frequently used com- mands. What extended commands are available depends on what fea- tures the game was compiled with. @@ -1165,24 +1166,23 @@ 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 + 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 particu- lar location when inventory listings are displayed. You can move to a currently empty slot, or if the destination is oc- cupied--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 + 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 letter. - Adjusting without a count used to collect all compatible - stacks when moving to the destination. That behavior has + 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 + into its own inventory slot. If it has a name assigned, - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1192,31 +1192,32 @@ - provided that all their other attributes match. If it does - not have a name, only other stacks with no name are eligi- - ble. In either case, otherwise compatible stacks with a - different name will not be merged. This contrasts with us- + 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 eligi- + ble. In either case, otherwise compatible stacks with a + different name will not be merged. This contrasts with us- ing "#adjust" to move from one slot to a different slot. In - that situation, moving (no count given) a compatible stack + that situation, moving (no count given) a compatible 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 + 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 current dungeon level. All levels with annotations are dis- - played by the "#overview" command. Autocompletes. Default + played by the "#overview" command. Autocompletes. Default key is `M-A', and also `^N' if number_pad is on. #apply - Apply (use) a tool such as a pick-axe, a key, or a lamp. + Apply (use) a tool such as a pick-axe, a key, or a lamp. Default key is `a'. - If the tool used acts on items on the floor, using the `m' + 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 + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. #attributes @@ -1226,9 +1227,9 @@ Toggle the autopickup option on/off. Default key is `@'. #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 level (same as "#annotate"). Default key is + 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 @@ -1241,14 +1242,13 @@ Close a door. Default key is `c'. #conduct - List voluntary challenges you have maintained. Autocom- + List voluntary challenges you have maintained. Autocom- pletes. Default key is `M-C'. - See the section below entitled "Conduct" for details. - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1258,8 +1258,10 @@ + See the section below entitled "Conduct" for details. + #dip - Dip an object into something. Autocompletes. Default key + Dip an object into something. Autocompletes. Default key is `M-d'. #down @@ -1272,22 +1274,22 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips + 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 Enter the explore mode. Requires confirmation; default response is n (no). To real- - ly switch to explore mode, respond with y. You can set the - paranoid_confirmation:quit option to require a response of + ly switch to explore mode, respond with y. You can set the + paranoid_confirmation:quit option to require a response of yes instead. #fire @@ -1297,11 +1299,11 @@ Force a lock. Autocompletes. Default key is `M-f'. #glance - Show what type of thing a map symbol corresponds to. De- + Show what type of thing a map symbol corresponds to. De- fault key is `;'. #help - Show the help menu. Default key is `?', and also `h' if + Show the help menu. Default key is `?', and also `h' if number_pad is on. #herecmdmenu @@ -1310,11 +1312,9 @@ #history Show long version and game history. Default key is `V'. - #inventory - Show your inventory. Default key is `i'. - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1324,19 +1324,22 @@ + #inventory + Show your inventory. Default key is `i'. + #inventtype Inventory specific item types. Default key is `I'. #invoke - Invoke an object's special powers. Autocompletes. Default + Invoke an object's special powers. Autocompletes. Default key is `M-i'. #jump - Jump to another location. Autocompletes. Default key is + 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 + Kick something. Default key is `^D', and `k' if number_pad is on. #known @@ -1348,7 +1351,7 @@ is ``'. #levelchange - Change your experience level. Autocompletes. Debug mode + Change your experience level. Autocompletes. Debug mode only. #lightsources @@ -1358,29 +1361,26 @@ Look at what is here, under you. Default key is `:'. #loot - 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 + 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 number_pad is on. #monster - Use a monster's special ability (when polymorphed into mon- + Use a monster's special ability (when polymorphed into mon- ster form). Autocompletes. Default key is `M-m'. #name - Name a monster, an individual object, or a type of object. - Same as "#call". Autocompletes. Default keys are `N', `M- + 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 `M-o'. + Offer a sacrifice to the gods. Autocompletes. Default key - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1390,8 +1390,10 @@ - You'll need to find an altar to have any chance at success. - Corpses of recently killed monsters are the fodder of + 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 al- @@ -1404,22 +1406,22 @@ Show and change option settings. Default key is `O'. #overview - Display information you've discovered about the dungeon. - Any visited level (unless forgotten due to amnesia) with an - annotation is included, and many things (altars, thrones, - fountains, and so on; extra stairs leading to another dun- - geon branch) trigger an automatic annotation. If dungeon + Display information you've discovered about the dungeon. + Any visited level (unless forgotten due to amnesia) with an + annotation is included, and many things (altars, thrones, + fountains, and so on; extra stairs leading to another dun- + geon branch) trigger an automatic annotation. If dungeon overview is chosen during end-of-game disclosure, every vis- - ited level will be included regardless of annotations. Au- + ited level will be included regardless of annotations. Au- tocompletes. Default keys are `^O', and `M-O'. #panic Test the panic routine. Terminates the current game. Auto- completes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. - To really panic, respond with y. You can set the para- - noid_confirmation:quit option to require a response of yes + Asks for confirmation; default is n (no); continue playing. + To really panic, respond with y. You can set the para- + noid_confirmation:quit option to require a response of yes instead. #pay @@ -1433,20 +1435,18 @@ Polymorph self. Autocompletes. Debug mode only. #pray - Pray to the gods for help. Autocompletes. Default key is + 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 re- + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having re- ceived 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. + 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 - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1456,63 +1456,63 @@ + you can reset the paranoid_confirmation option to disable + it. + #prevmsg - Show previously displayed game messages. Default key is + Show previously displayed game messages. Default key is `^P'. #puton - Put on an accessory (ring, amulet, etc). Default key is + Put on an accessory (ring, amulet, etc). Default key is `P'. #quaff Quaff (drink) something. Default key is `q'. #quit - Quit the program without saving your game. Autocompletes. + Quit the program without saving your game. Autocompletes. Default key is `M-q'. - Since using this command by accident would throw away the - current game, you are asked to confirm your intent before + 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_con- + really quit, respond with y. You can set the paranoid_con- firmation: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 + Read a scroll, a spellbook, or something else. Default key is `r'. #redraw - Redraw the screen. Default key is `^R', and also `^L' if + Redraw the screen. Default key is `^R', and also `^L' if number_pad is on. #remove - Remove an accessory (ring, amulet, etc). Default key is + Remove an accessory (ring, amulet, etc). Default key is `R'. #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- + Rub a lamp or a stone. Autocompletes. Default key is `M- r'. #save Save the game and exit the program. Default key is `S'. #search - Search for traps and secret doors around you. Default key + Search for traps and secret doors around you. Default key is `s'. - #seeall - Show all equipment in use. Default key is `*'. - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -1522,15 +1522,15 @@ + #seeall + Show all equipment in use. Default key is `*'. + #seeamulet Show the amulet currently worn. Default key is `"'. #seearmor Show the armor currently worn. Default key is `['. - #seegold - Count your gold. Default key is `$'. - #seerings Show the ring(s) currently worn. Default key is `='. @@ -1541,17 +1541,27 @@ Show the weapon currently wielded. Default key is `)'. #shell - Do a shell escape, switching from NetHack to a subprocess. - Can be disabled at the time the program is built. When en- - abled, access for specific users can be controlled by the - system configuration file. Use the shell command `exit' to + Do a shell escape, switching from NetHack to a subprocess. + Can be disabled at the time the program is built. When en- + abled, access for specific users can be controlled by the + system configuration file. Use the shell command `exit' to return to the game. Default key is `!'. + #showgold + Report the gold in your inventory and if you are inside a + shop, report any credit or debt you have in that shop. Does + not report on any gold inside containers you're carrying. + Default key is `$'. + #showspells List and reorder known spells. Default key is `+'. #showtrap - Show the type of an adjacent trap. Default key is `^'. + Describe an adjacent trap, possibly covered by objects or a + monster. To be eligible, the trap must already be discov- + ered. (The "#terrain" command can display your map with all + objects and monsters temporarily removed, making it possible + to see all discovered traps.) Default key is `^'. #sit Sit down. Autocompletes. Default key is `M-s'. @@ -1566,6 +1576,18 @@ 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 + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 25 + + + is `^Z'. #swap @@ -1577,17 +1599,6 @@ #takeoffall Remove all armor. Default key is `A'. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 25 - - - #teleport Teleport around the level. Default key is `^T'. @@ -1631,6 +1642,18 @@ Untrap something (trap, door, or chest). Default key is `M- u', and `u' if number_pad is on. + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 26 + + + In some circumstances it can also be used to rescue trapped monsters. @@ -1641,23 +1664,19 @@ List vanquished monsters. Autocompletes. Debug mode only. #version - Print compile time options for this version of NetHack. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 26 - + Print compile time options for this version of NetHack. + The second paragraph lists the user interface(s) that are + included. If there are more than one, you can use the win- + dow_type option in your run-time configuration file to se- + lect the one you want. Autocompletes. Default key is `M-v'. #versionshort - Show version string. Default key is `v'. + Show the program's version number, plus the date and time + that the running copy was built from sources (not the ver- + sion's release date). Default key is `v'. #vision Show vision array. Autocompletes. Debug mode only. @@ -1690,6 +1709,17 @@ Bury objects under and around you. Autocompletes. Debug mode only. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 27 + + + #wizdetect Search for hidden things (secret doors or traps or unseen monsters) within a modest radius. Autocompletes. Debug @@ -1708,18 +1738,6 @@ Set one or more intrinsic attributes. Autocompletes. Debug mode only. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 27 - - - #wizlevelport Teleport to another level. Autocompletes. Debug mode only. Default key is `^V'. @@ -1755,6 +1773,19 @@ #wmode Show wall modes. Autocompletes. Debug mode only. + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 28 + + + #zap Zap a wand. Default key is `z'. @@ -1775,17 +1806,6 @@ followed by the other key, you may set the altmeta option to have NetHack combine them into meta+key. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 28 - - - M-? #? (not supported by all platforms) M-2 #twoweapon (unless the number_pad option is enabled) @@ -1820,6 +1840,18 @@ M-p #pray + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 29 + + + M-q #quit M-r #rub @@ -1840,18 +1872,6 @@ - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 29 - - - If the number_pad option is on, some additional letter com- mands are available: @@ -1886,6 +1906,18 @@ 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 + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 30 + + + 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 @@ -1906,18 +1938,6 @@ carrying an unlocking tool, you'll be asked whether to use it on the door's lock. Alternatively, you can break a closed door (whether locked or not) down by kicking it via the `^D' (kick) - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 30 - - - command. Kicking down a door destroys it and makes a lot of noise which might wake sleeping monsters. @@ -1952,6 +1972,18 @@ usually won't 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) command (multiple attempts are often needed; if + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 31 + + + your luck is poor, many attempts might be needed). Wands of se- cret door detection and spell of detect unseen also reveal traps within a modest radius but only if the trap is also within line- @@ -1972,18 +2004,6 @@ porters send you elsewhere on the same dungeon level. Level teleporters send you to a random dungeon level, the destination chosen from a few levels lower all the way to the top. Trap - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 31 - - - 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. All of these traps choose a @@ -2018,6 +2038,18 @@ to 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 + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 32 + + + will lower your luck without any specific message given about that. See the Conduct section for information about getting feedback for your actions in Sokoban. @@ -2038,18 +2070,6 @@ sends you to another level, the level you're leaving will be de- activated 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 - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 32 - - - 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 @@ -2084,6 +2104,18 @@ of gold and asked whether you're willing to sell, or you'll be told that the shopkeeper isn't interested (generally, your item needs to be compatible with the type of merchandise carried by + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 33 + + + the shop). If you drop something in a shop by accident, the shopkeeper @@ -2104,18 +2136,6 @@ paid items (those which still belong to the shop) if you are car- rying any. The "Ix" command shows an inventory-like display of any unpaid items which have been used up, along with other shop - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 33 - - - fees, if any. 5.4.1. Shop idiosyncrasies @@ -2149,8 +2169,20 @@ 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 num- - ber refers to the count of separate stacks of objects present + list all objects no matter how big a pile is. Note that the + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 34 + + + + number refers to the count of separate stacks of objects present rather than the sum of the quantities of those stacks (so 7 ar- rows 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 loca- @@ -2169,44 +2201,31 @@ 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 + fountain or an altar or various other things doesn't elicit any- + thing 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 ob- + jects, in which case the back on land circumstance is implied. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 34 - - - - anything unless it is covered by one or more objects so is ob- - scured 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. Assum- - ing 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 re- - peat 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 im- - plied. - - 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 + 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 + 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 at- - tack (see the Fighting subsection of Monsters below). The - "fight" command prefix (default `F'; also `-' if number_pad is + tack (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 attacking a peaceful or tame + monster is or when deliberately attacking a peaceful or tame creature. The run_mode option controls how frequently the map gets re- @@ -2215,30 +2234,11 @@ 5.6. Rogue level - One dungeon level (occurring in mid to late teens of the - main dungeon) is a tribute to the ancestor game hack's inspira- - tion rogue. - - It is usually displayed differently from other levels: pos- - sibly 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 differences 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.... - - 6. Monsters - - Monsters you cannot see are not displayed on the screen. - Beware! You may suddenly come upon one in a dark place. Some + One dungeon level (occurring in mid to late teens of the + main dungeon) is a tribute to the ancestor game hack's - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2248,63 +2248,63 @@ - magic items can help you locate them before they locate you + inspiration rogue. + + It is usually displayed differently from other levels: pos- + sibly 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 differences 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.... + + 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 do very well). - The commands `/' and `;' may be used to obtain information - about those monsters who are displayed on the screen. The com- - mand "#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 + The commands `/' and `;' may be used to obtain information + about those monsters who are displayed on the screen. The com- + mand "#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 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 mon- - sters such as a shopkeeper or the Oracle of Delphi can produce + sters 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 + 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 - monster by moving into its location, you'll be asked to confirm - your intent. By default an answer of `y' acknowledges that in- - tent, which can be error prone if you're using `y' to move. You + In most circumstances, if you attempt to attack a peaceful + monster by moving into its location, you'll be asked to confirm + your intent. By default an answer of `y' acknowledges that in- + tent, which can be error prone if you're using `y' to move. You can set the paranoid_confirmation option to require a response of "yes" instead. - 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 mon- + 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 mon- ster 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 re- - member 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 mon- - sters with you. Like you, your pet needs food to survive. Dogs - and cats usually feed themselves on fresh carrion and other - meats; horses need vegetarian 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 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 - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2314,63 +2314,63 @@ + 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 re- + member 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 mon- + sters with you. Like you, your pet needs food to survive. Dogs + and cats usually feed themselves on fresh carrion and other + meats; horses need vegetarian 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 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 pets useful for low-level characters. - 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 + 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-adjacent pet will be left behind. Your - pet may trigger such traps itself; you will not be carried along + 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 rid- + Some types of creatures in the dungeon can actually be rid- den 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 or- + 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 or- der to forge the alliance. Once you do have the beast under your - control however, you can easily climb in and out of the saddle + 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 + Riding skill is managed by the "#enhance" command. See the section on Weapon proficiency for more information about that. Use the `a' (apply) command and pick a saddle in your inven- - tory to attempt to put that saddle on an adjacent creature. If + tory to attempt to put that saddle on an adjacent creature. If successful, it will be transferred to that creature's inventory. Use the "#loot" command while adjacent to a saddled creature - to try to remove the saddle from that creature. If successful, + 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 adventur- - ers (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 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 last victory. - - 6.5. Persistence of Monsters - - Monsters (a generic reference which also includes humans and - pets) are only shown while they can be seen or otherwise sensed. - Moving 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 who moved rather than you. - - However, if you encounter a monster which you can't see or - sense--perhaps it is invisible and has just tapped you on the - NetHack 3.7 November 30, 2020 + + NetHack 3.7 December 9, 2020 @@ -2380,63 +2380,63 @@ - noggin--a special "remembered, unseen monster" marker will be - displayed at the location where you think it is. That will per- - sist 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 + 6.4. Bones levels + + You may encounter the shades and corpses of other adventur- + ers (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 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 last victory. + + 6.5. Persistence of Monsters + + Monsters (a generic reference which also includes humans and + pets) are only shown while they can be seen or otherwise sensed. + Moving 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 who moved rather than you. + + 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 per- + sist 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 automatically by - walking over the object (unless you turn off the autopickup op- - tion (see below), or move with the `m' prefix (see above)), or + walking over the object (unless you turn off the autopickup op- + tion (see below), or move with the `m' prefix (see above)), or manually by using the `,' command. - 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 + 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 de- - pends on your strength and your constitution. The stronger and - sturdier you are, the less the additional load will affect you. + As you add items to your inventory, you also add the weight + of that object to your load. The amount that you can carry de- + pends 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 encum- + you are carrying around with you through the dungeon will encum- ber you. Your reactions will get slower and you'll burn calories - faster, requiring food more frequently to cope with it. Eventu- - ally, you'll be so overloaded that you'll either have to discard + faster, requiring food more frequently to cope with it. Eventu- + ally, 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, Overtaxed, or Overloaded will be shown on the bottom - line status display. - - When you pick up an object, it is assigned an inventory let- - ter. 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 pre- - sented with a list of inventory letters to choose from (see Com- - mands, above). - - Some objects, such as weapons, are easily differentiated. - Others, 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 "#name" command, for the same purpose at any time, to name + NetHack will tell you how badly you have loaded yourself. + If you are encumbered, one of the conditions Burdened, Stressed, + Strained, Overtaxed, or Overloaded will be shown on the bottom - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2446,63 +2446,63 @@ - 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 in- + line status display. + + When you pick up an object, it is assigned an inventory let- + ter. 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 pre- + sented with a list of inventory letters to choose from (see Com- + mands, above). + + Some objects, such as weapons, are easily differentiated. + Others, 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 "#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 in- stead of assigning a new one. 7.1. Curses and Blessings - Any object that you find may be cursed, even if the object + 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 en- + 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 en- chantments 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 + 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 + example, a blessed weapon will do slightly more damage against demons. 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" + 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 + 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. - An item with unknown status will be reported in your inven- - tory with no prefix. An item which you know the state of will be - distinguished 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 information is displayed. The implicit_uncursed op- - tion can be used to control 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 "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term - beatitude is occasionally used as well.) - - 7.2. Weapons (`)') - - Given a chance, most monsters in the Mazes of Menace will - gratuitously try to kill you. You need weapons for self-defense - (killing them first). Without a weapon, you do only 1-2 hit - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2512,63 +2512,63 @@ - points of damage (plus bonuses, if any). Monk characters are an - exception; they normally do more damage with bare (or gloved) + An item with unknown status will be reported in your inven- + tory with no prefix. An item which you know the state of will be + distinguished 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 information is displayed. The implicit_uncursed op- + tion can be used to control 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 "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term + beatitude is occasionally used as well.) + + 7.2. Weapons (`)') + + Given a chance, most monsters in the Mazes of Menace will + gratuitously 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 normally 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 cross- + 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 cross- bow 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 + 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 iden- - tified somehow. Most weapons are subject to some type of damage + tified somehow. Most 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 (en- + 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 (en- chantment and/or erosion), experience level, strength, dexterity, - encumbrance, and proficiency (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 + encumbrance, and proficiency (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 simul- + 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 simul- taneously as primary and secondary; use the `X' command to engage - or disengage that. Only some types of characters (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 all. To accomplish that, wield `-', or else use the `A' com- - mand which 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 each weapon which existed in AD&D does roughly the same dam- - age to monsters in NetHack. Some of the more obscure weapons - (such as the aklys, lucern hammer, and bec-de-corbin) are defined - in an appendix to Unearthed Arcana, an AD&D supplement. - - The commands to use weapons are `w' (wield), `t' (throw), - `f' (fire, an alternate way of throwing), `Q' (quiver), `x' (ex- - change), `X' (twoweapon), and "#enhance" (see below). - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2578,63 +2578,63 @@ + or disengage that. Only some types of characters (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 all. To accomplish that, wield `-', or else use the `A' com- + mand which 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 each weapon which existed in AD&D does roughly the same dam- + age to monsters in NetHack. Some of the more obscure weapons + (such as the aklys, lucern hammer, and bec-de-corbin) are defined + in an appendix to Unearthed Arcana, an AD&D supplement. + + The commands to use weapons are `w' (wield), `t' (throw), + `f' (fire, an alternate way of throwing), `Q' (quiver), `x' (ex- + change), `X' (twoweapon), and "#enhance" (see below). + 7.2.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 + 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 target. The distance something can be thrown de- + what to throw, you will be prompted for a direction rather than + for a specific target. The distance something can be thrown de- pends mainly on the type of object and your strength. Arrows can - be thrown by hand, but can be thrown much farther and will be + 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. - 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 + 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 + quiver sack, or have at the ready) when the inventory slot used for `Q' runs out. - Some characters have the ability to fire a volley of multi- - ple items in a single turn. Knowing how to load several rounds + Some characters have the ability to fire a volley of multi- + ple items in a single turn. 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 wield- - ing 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 + 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 wield- + ing 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 lim- - it the number of shots by using a numeric prefix before the `t' - or `f' command. For 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 shoot- - ing 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.2.2. Weapon proficiency - - You will have varying degrees of skill in the weapons avail- - able. Weapon proficiency, or weapon skills, affect how well you - can use particular types of weapons, and you'll be able to im- - prove your skills as 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 daggers or staves but not in swords or + it the number of shots by using a numeric prefix before the `t' + or `f' command. For example, "2f" (or "n2f" if using number_pad + mode) would ensure that at most 2 arrows are shot even if you - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2644,63 +2644,63 @@ + could have fired 3. If you specify a larger number than would + have been shot ("4f" in this example), you'll just end up shoot- + ing 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.2.2. Weapon proficiency + + You will have varying degrees of skill in the weapons avail- + able. Weapon proficiency, or weapon skills, affect how well you + can use particular types of weapons, and you'll be able to im- + prove your skills as 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 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 + 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" (some- + become eligible to do so. The skill rankings are "none" (some- times also referred to as "restricted", because you won't be able - to advance), "unskilled", "basic", "skilled", and "expert". Re- + to advance), "unskilled", "basic", "skilled", and "expert". Re- stricted skills simply will not appear in the list shown by "#en- hance". (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 + basic.) Some characters can enhance their 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 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 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 your to- - tal overall skills, so you need to actively choose which skills + 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 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 your to- + tal overall skills, so you need to actively choose which skills to enhance and which to ignore. 7.2.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" com- - mand. But first you need to have a weapon in each hand. (Note - that your two 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 sec- - ondary 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 the correct weapon, use `w', `x', `w' to - first wield the intended secondary, swap it to off hand, and then - wield the primary. + up to do so can seem cumbersome but becomes second nature with + use. To wield two weapons, you need to use the "#twoweapon" - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2710,16 +2710,35 @@ - The whole process can be simplified via use of the push- + command. But first you need to have a weapon in each hand. + (Note that your two 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 that's been designat- + ed 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 the correct weapon, use `w', `x', `w' to + first wield the intended secondary, swap it to off hand, and then + wield the primary. + + The whole process can be simplified via use of the push- weapon option. When it is enabled, then using `w' to wield some- - thing causes the currently wielded weapon to become your alter- + thing causes the currently wielded weapon to become your alter- nate 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 posi- + want as primary which will push the first into secondary posi- tion. - When in two-weapon combat mode, using the `X' command tog- - gles back to single-weapon mode. Throwing or dropping either of + When in two-weapon combat mode, using the `X' command tog- + gles back to single-weapon mode. Throwing or dropping either of the weapons or having one of them be stolen or destroyed will al- so make you revert to single-weapon combat. @@ -2727,13 +2746,13 @@ Lots of unfriendly things lurk about; you need armor to pro- tect yourself from their blows. Some types of armor offer better - protection than others. Your armor class is a measure of this + protection than others. Your armor class is a measure of this protection. Armor class (AC) is measured as in AD&D, with 10 be- - ing the equivalent of no armor, and lower numbers meaning better - armor. Each suit of armor which exists in AD&D gives the same + ing 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 + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -2744,29 +2763,10 @@ Ring mail, Studded leather armor, Dragon scales 7 Leather armor, Orcish ring mail 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 even further. Most of these provide a one or two - point improvement to 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 corrosion to suits worn un- - der them and against some monster touch attacks. - - 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 immediately find out the armor class and any - "plusses" it provides. Cursed pieces of armor usually have - NetHack 3.7 November 30, 2020 + + NetHack 3.7 December 9, 2020 @@ -2776,63 +2776,63 @@ - negative enchantments (minuses) in addition to being unremovable. + Leather jacket 9 + none 10 - Many types of armor are subject to some kind of damage like - rust. Such damage can be repaired. Some types of armor may in- + 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 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 corrosion to suits worn un- + der them and against some monster touch attacks. + + 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 immediately find out the armor class and any + "plusses" it provides. Cursed pieces of armor usually have nega- + tive enchantments (minuses) in addition 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 in- hibit spell casting. - The nudist option can be set (prior to game start) to at- - tempt to play the entire game without wearing any armor (a self- + The nudist option can be set (prior to game start) to at- + tempt to play the entire game without wearing any armor (a self- imposed challenge which is extremely difficult to accomplish). 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 nor- - mally for accessories can be used for armor, but pieces of armor + 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 nor- + mally for accessories 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.4. 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 + 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 usual- - ly stay fresh, but ice boxes are heavy, and tins take a while to + ly 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 + 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 what you eat." Some character roles and some monsters are vegetarian. Veg- - etarian monsters will typically never eat animal corpses, while - vegetarian players can, but with some rather unpleasant side-ef- - fects. - - You can name one food item after something you like to eat - with the fruit option. - - The command to eat food is `e'. - - 7.5. 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 (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 ob- - jects of subtle enchantment are difficult to identify without - these. + etarian monsters will typically never eat animal corpses, while + vegetarian players can, but with some rather unpleasant side- - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2842,16 +2842,36 @@ + effects. + + You can name one food item after something you like to eat + with the fruit option. + + The command to eat food is `e'. + + 7.5. 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 (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 ob- + jects of subtle enchantment are difficult to identify without + these. + 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 + 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" en- vironment variable to the file name of your mailbox. You may al- - so want to set the "MAILREADER" environment variable to the file + so 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 + 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. @@ -2859,46 +2879,26 @@ 7.6. Potions (`!') - Potions are distinguished by the color of the liquid inside + 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 + 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 + 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. The command to drink a potion is `q' (quaff). 7.7. Wands (`/') - Wands usually have multiple magical charges. Some types of + 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, however, 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, at- - tempts to use the wand will usually result in nothing happening. - Occasionally, 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 cer- - tainly cause a catastrophic release of magical energies. - - When you have fully identified a particular wand, inventory - display will include additional information in parentheses: the - number of times it has been recharged followed by a colon and + them at yourself (just give a `.' or `s' for the direction). Be + warned, however, for this is often unwise. Other types of wands - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2908,29 +2908,49 @@ + 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, at- + tempts to use the wand will usually result in nothing happening. + Occasionally, 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 cer- + tainly cause a catastrophic release of magical energies. + + When you have fully identified a particular wand, inventory + display will include additional information in parentheses: the + number of times it has been recharged followed by a colon and then by its current 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 command to use a wand is `z' (zap). To break one, use the `a' (apply) command. 7.8. Rings (`=') - Rings are very useful items, since they are relatively per- - manent magic, unlike the usually fleeting effects of potions, + Rings are very useful items, since they are relatively per- + manent magic, unlike the usually fleeting effects of potions, scrolls, and wands. 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, + 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 manually take them off before putting on or remov- - ing a ring and then re-wear them after. That's done implicitly + 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 manually take them off before putting on or remov- + ing 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). @@ -2939,32 +2959,12 @@ 7.9. Spellbooks (`+') 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 + `r' (read) command, they transfer to the reader the knowledge of + a spell (and therefore eventually become unreadable)--unless the attempt backfires. Reading a cursed spellbook or one with mystic - runes beyond your ken can be harmful to your health! - - 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 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 within you. Casting temporarily drains your magical - power, which will slowly be recovered, and causes you to need ad- - ditional food. Casting of spells also requires practice. With - practice, your skill in each category of spell casting will im- - prove. Over time, however, your memory of each spell will dim, - and you will need to relearn it. - - Some spells require a direction in which to cast them, simi- - lar to wands. To cast one at yourself, just give a `.' or `s' - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -2974,42 +2974,74 @@ + runes beyond your ken can be harmful to your health! + + 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 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 within you. Casting temporarily drains your magical + power, which will slowly be recovered, and causes you to need ad- + ditional food. Casting of spells also requires practice. With + practice, your skill in each category of spell casting will im- + prove. Over time, however, your memory of each spell will dim, + and you will need to relearn it. + + Some spells require a direction in which to cast them, simi- + lar to wands. To cast one at yourself, just give a `.' or `s' for the direction. A few spells require you to pick a target lo- - cation rather than just specify a particular direction. Other + cation 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 + 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 + 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 + 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".) Casting a spell also requires flexible movement, and wearing various types of armor may interfere with that. - The command to read a spellbook is the same as for scrolls, + 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) com- + estimate of how strongly it is remembered. The `Z' (cast) com- mand casts a spell. 7.10. Tools (`(') Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For - example, lamps burn out after a while. Other tools are contain- + tools have a limited number of uses, akin to wand charges. For + example, lamps burn out after a while. Other tools are contain- ers, 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 + 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 + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 47 + + + weapons in addition to being applied for their usual purpose, and - in some cases (again, pick-axe) become wielded as a weapon even + 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 @@ -3020,26 +3052,14 @@ 7.10.1. Containers - You may encounter bags, boxes, and chests in your travels. - A tool of this sort can be opened with the "#loot" extended com- - mand when you are standing on top of it (that is, on the same - floor spot), or with the `a' (apply) command when you are carry- - ing it. However, chests are often locked, and are in any case - unwieldy objects. You must set one down before unlocking it by + You may encounter bags, boxes, and chests in your travels. + A tool of this sort can be opened with the "#loot" extended com- + mand when you are standing on top of it (that is, on the same + floor spot), or with the `a' (apply) command when you are carry- + ing 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' command, or by using a weapon to force - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 47 - - - + kicking it with the `^D' command, or by using a weapon to force the lock with the "#force" extended command. Some chests are trapped, causing nasty things to happen when @@ -3048,55 +3068,35 @@ 7.11. Amulets (`"') - Amulets are very similar to rings, and often more powerful. + Amulets are very similar to rings, and often more powerful. Like rings, amulets have various magical properties, some benefi- cial, 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, + 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. - 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 normally 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 + 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 normally 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.12. 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. + 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 projec- - tile weapons (if you have a sling). In the most desperate of - cases, you can still throw them by hand. - - 7.13. Large rocks (``') - - Statues and boulders are not particularly useful, and are - generally heavy. It is rumored that some statues are not what - they seem. - - 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 pick-axe. 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 though. + much less valuable. All rocks, however, can be used as projec- + tile weapons (if you have a sling). In the most desperate of - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -3106,63 +3106,63 @@ - For some configurations of the program, statues are no - longer shown as ``' but by the letter representing the monster + cases, you can still throw them by hand. + + 7.13. Large rocks (``') + + Statues and boulders are not particularly useful, and are + generally heavy. It is rumored that some statues are not what + they seem. + + 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 pick-axe. 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 though. + + For some configurations of the program, statues are no + longer shown as ``' but by the letter representing the monster they depict instead. 7.14. 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 + 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 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 de- - scribed 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 bless/curse state unknown rather than as - known to be uncursed. Only matters when you're using an object + Gold pieces are the only type of object where bless/curse + state does not apply. They're always uncursed but never de- + scribed 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 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.15. Persistence of Objects Normally, if you have seen an object at a particular map lo- - cation 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 ex- - ception is that if the object gets covered by the "remembered, - unseen monster" marker. When that marker is later removed after + cation 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 ex- + ception is that if the object gets covered 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, + 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-discov- er 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 op- - tion 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 challenges, 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. - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -3172,63 +3172,63 @@ - Several of the challenges are related to eating behavior. - The most difficult of these is the foodless challenge. Although + The situation is the same for a pile of objects, except that + only the top item of the pile is displayed. The hilite_pile op- + tion 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 challenges, 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 most difficult of these is the foodless challenge. Although creatures can survive long periods of time without food, there is - a physiological need for water; thus there is no restriction on - drinking beverages, even if they provide some minor food bene- - fits. Calling upon your god for help with starvation does not + a physiological need for water; thus there is no restriction on + drinking beverages, even if they provide some minor food bene- + fits. 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 + A strict vegan diet is one which avoids any food derived from animals. The primary source of nutrition is fruits and veg- etables. 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 normally indigestible material eaten + 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 normally indigestible material eaten while polymorphed into a creature that can digest it is also con- - sidered vegan food. Note however that eating such items still + sidered vegan food. Note however that eating such items still counts against foodless conduct. - Vegetarians do not eat animals; however, they are less se- - lective about eating animal byproducts than vegans. In addition + Vegetarians do not eat animals; however, they are less se- + lective 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 + (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 - foodless 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 + Eating any kind of meat violates the vegetarian, vegan, and + foodless 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 polymorphed is treated as if you ate the creature's - corpse. Eating leather, dragon hide, or bone items while poly- - morphed into a creature that can digest it, or eating monster + corpse. Eating leather, dragon hide, or bone items while poly- + morphed 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 - indigestible, and others which are hazardous to eat. Using a - swallow-and-digest attack against a monster is equivalent to eat- - ing 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 contain milk, so they are - compatible with a vegan diet. Slime molds or player-defined - "fruits", although they could be anything from "cherries" to - "pork chops", are also assumed to be vegan. - - An atheist is one who rejects religion. This means that you - cannot #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 - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -3238,63 +3238,63 @@ - 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 other religious + an animal, although wax is only an animal byproduct. + + Regardless of conduct, there will be some items which are + indigestible, and others which are hazardous to eat. Using a + swallow-and-digest attack against a monster is equivalent to eat- + ing 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 contain milk, so they are + compatible with a vegan diet. Slime molds or player-defined + "fruits", although they could be anything from "cherries" to + "pork chops", are also assumed to be vegan. + + An atheist is one who rejects religion. This means that you + cannot #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 con- + duct; 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 be- + ing 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. - Most players fight with a wielded weapon (or tool intended + 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 + 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 particularly difficult challenge, although it is still + 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 particularly difficult challenge, although it is still possible to gain experience by other means. - An illiterate character does not read or write. This in- + An illiterate character does not read or write. This in- cludes reading a scroll, spellbook, fortune cookie message, or t- shirt; writing 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 + 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 men- + briefly described in the earlier section about Traps. As men- tioned 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 + 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 diago- - nally. 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, providing 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 ac- - tions 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 disclosed conduct even if you haven't done anything interest- - ing there. Ending the game with "never broke the Sokoban rules" - conduct is most meaningful if you also manage to perform the "ob- - tained 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 geno- - cide; playing without this feature is considered a challenge. + that are active when in that branch of the dungeon. Some rules + can't be bypassed, such as being unable to push a boulder - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -3304,6 +3304,26 @@ + diagonally. Other rules can, such as not smashing boulders with + magic or tools, but doing so causes you to receive a luck penal- + ty. No message about that is given at the time, but it is + tracked as a conduct. The #conduct command and end of game dis- + closure will report whether you have abided by the special rules + of Sokoban, and if not, how many times you violated them, provid- + ing you with a way to discover which actions incur bad luck so + that you can be better informed about whether or not to avoid re- + peating 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 disclosed conduct even if you haven't done any- + thing 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 geno- + cide; 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 @@ -3338,6 +3358,18 @@ Sokoban - Entered Sokoban. Big Room - Entered the Big Room. Soko-Prize - Explored to the top of Sokoban + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 52 + + + and found a special item there. Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. @@ -3358,18 +3390,6 @@ Achievements are recorded and subsequently reported in the order in which they happen during your current game rather than - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 52 - - - the order listed here. There are nine titles for each role, bestowed at ex- @@ -3404,6 +3424,18 @@ Due to variations in personal tastes and conceptions of how NetHack should do things, there are options you can set to change + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 53 + + + how NetHack behaves. 9.1. Setting the options @@ -3425,17 +3457,6 @@ er's home directory. The file may not exist, but it is a normal ASCII text file and can be created with any text editor. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 53 - - - On Windows, it is ".nethackrc" in the folder "\%USERPRO- FILE%\NetHack\3.6". The file may not exist, but it is a normal ASCII text file can can be created with any text editor. After @@ -3468,6 +3489,19 @@ Here is a list of allowed directives: + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 54 + + + OPTIONS There are two types of options, boolean and compound options. Boolean options toggle a setting on or off, while compound op- @@ -3490,18 +3524,6 @@ file so setting HACKDIR to override that is not usually neces- sary or recommended. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 54 - - - LEVELDIR The location that in-progress level files are stored. Defaults to HACKDIR, must be writable. @@ -3533,6 +3555,19 @@ AUTOCOMPLETE=zap,!annotate + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 55 + + + AUTOPICKUP_EXCEPTION Set exceptions to the pickup_types option. See the "Configur- ing Autopickup Exceptions" section. @@ -3553,21 +3588,6 @@ Example: - - - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 55 - - - OPTIONS=color CHOOSE=char A,char B [char A] @@ -3602,6 +3622,18 @@ Define the directory that contains the sound files. See the "Configuring User Sounds" section. + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 56 + + + SYMBOLS Override one or more symbols in the symbol set used for all dungeon levels except for the special rogue level. See the @@ -3624,18 +3656,6 @@ - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 56 - - - - - Here is an example of configuration file contents: # Set your character's role, race, gender, and alignment. @@ -3667,6 +3687,19 @@ equals sign, and then the value of the string. The value is ter- minated by the next comma or the end of string. + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 57 + + + 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 @@ -3687,19 +3720,6 @@ to left. Other types of configuration directives such as BIND or MSGTYPE are not allowed. - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 57 - - - 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 @@ -3735,6 +3755,17 @@ get a location on the map (default true). The whatis_coord op- tion controls whether the description includes map coordinates. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 58 + + + autodig Automatically dig if you are wielding a digging tool and moving into a place that can be dug (default false). Persistent. @@ -3753,28 +3784,15 @@ 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, enchant- - ment, damage, or quality of the weapon; you are free to - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 58 - - - - 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. Persis- - tent. + ment, damage, or quality of the weapon; you are free to manual- + ly 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 - Walking into a locked door or looting a locked container while - carrying an unlocking tool (such as a key) will ask whether to - use that tool to unlock the door or container (default true). + Walking into a locked door or looting a locked container while + carrying an unlocking tool (such as a key) will ask whether to + use that tool to unlock the door or container (default true). Persistent. blind @@ -3782,47 +3800,29 @@ tent. bones - Allow saving and loading bones files (default true). Persis- + Allow saving and loading bones files (default true). Persis- tent. boulder - Set the character used to display boulders (default is the + Set the character used to display boulders (default is the "large rock" class symbol, ``'). catname - Name your starting cat (for example "catname:Morris"). Cannot + 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 ex- + Synonym for "role" to pick the type of your character (for ex- ample "character:Monk"). See role for more details. checkpoint - Save game state after each level change, for possible recovery + Save game state after each level change, for possible recovery after program crash (default on). Persistent. - clicklook - Allows looking at things on the screen by navigating the mouse - over them and clicking the right mouse button (default off). - - cmdassist - 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 creatures (default on). Persistent. - - dark_room - Show out-of-sight areas of lit rooms (default on). Persistent. - - disclose - Controls what information the program reveals when the game - ends. Value is a space separated list of prompting/category - NetHack 3.7 November 30, 2020 + + NetHack 3.7 December 9, 2020 @@ -3832,7 +3832,26 @@ - pairs (default is "ni na nv ng nc no", prompt with default re- + clicklook + Allows looking at things on the screen by navigating the mouse + over them and clicking the right mouse button (default off). + + cmdassist + 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 creatures (default on). Persistent. + + dark_room + Show out-of-sight areas of lit rooms (default on). Persistent. + + disclose + 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 re- sponse of `n' for each candidate). Persistent. The possibili- ties are: @@ -3843,8 +3862,8 @@ c - display your conduct; also achievements, if any; o - display dungeon overview. - Each disclosure possibility can optionally be preceded by a - prefix which lets you refine how it behaves. Here are the + 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; @@ -3852,43 +3871,24 @@ + - disclose it without prompting; - - do not disclose it and do not prompt. - The listing of vanquished monsters can be sorted, so there are + The listing of vanquished monsters can be sorted, so there are two additional choices for `v': ? - 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 + `+' disclose without prompting choice, or being prompted and answering `y' rather than `a', will default to showing monsters in the traditional order, from high level to low level. Omitted categories are implicitly added with `n' prefix. Spec- ified categories with omitted prefix implicitly use `+' prefix. - Order of the disclosure categories does not matter, program + 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 inven- - tory to prompt and default to yes, attributes to prompt and de- - fault to no, vanquished to disclose without prompting, genocid- - ed 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 by traps and each other as well as by you. And the dun- - geon overview shows all levels you had visited but does not re- - veal things about them that you hadn't discovered. - - dogname - 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 - available commands. It is keystroke compatible with the - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -3898,9 +3898,26 @@ - traditional interface except that it does not require that you - hit Enter. It is implemented for the tty interface (default - off). + (for example "disclose:yi na +v -g o") The example sets inven- + tory to prompt and default to yes, attributes to prompt and de- + fault to no, vanquished to disclose without prompting, genocid- + ed 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 by traps and each other as well as by you. And the dun- + geon overview shows all levels you had visited but does not re- + veal things about them that you hadn't discovered. + + dogname + 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 + available commands. It is keystroke compatible with the tradi- + tional 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 avail- @@ -3935,6 +3952,18 @@ option will take precedence. The default is to randomly pick an appropriate gender. If you prefix the value with `!' or "no", you will exclude that gender from being picked randomly. + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 61 + + + Cannot be set with the `O' command. Persistent. goldX @@ -3953,17 +3982,6 @@ means that you might miss some interesting and/or important in- formation. Persistent. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 61 - - - herecmd_menu When using a windowport that supports mouse and clicking on yourself or next to you, show a menu of possible actions for @@ -4001,6 +4019,17 @@ Ignore interrupt signals, including breaks (default off). Per- sistent. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 62 + + + implicit_uncursed Omit "uncursed" from object descriptions when it can be deduced from other aspects of the description (default on). Persis- @@ -4018,18 +4047,6 @@ lootabc When using a menu to interact with a container, use the old - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 62 - - - `a', `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. @@ -4066,9 +4083,21 @@ class(es) of interest, but then displays a menu of matching ob- jects 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. Partial skips the ob- - ject class filtering and immediately displays a menu of all ob- - jects. Persistent. + menu of matching objects for selection. Partial skips the + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 63 + + + + object class filtering and immediately displays a menu of all + objects. Persistent. menu_deselect_all Menu character accelerator to deselect all items in a menu. @@ -4083,19 +4112,6 @@ Menu character accelerator to jump to the first page in a menu. Implemented by the Amiga, Gem and tty ports. Default `^'. - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 63 - - - menu_headings Controls how the headings in a menu are highlighted. Values are "none", "bold", "dim", "underline", "blink", or "inverse". @@ -4135,6 +4151,17 @@ Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default `:'. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 64 + + + menu_select_all Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `.'. @@ -4150,18 +4177,6 @@ mouse_support Allow use of the mouse for input and travel. Valid settings - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 64 - - - are: 0 - disabled @@ -4201,6 +4216,18 @@ 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 + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 65 + + + setting this with the `O' command. nudist @@ -4216,18 +4243,6 @@ 0 - move by letters; "yuhjklbn" 1 - move by numbers; digit `5' acts as `G' movement prefix 2 - like 1 but `5' works as `g' prefix instead of as `G' - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 65 - - - 3 - by numbers using phone key layout; 123 above, 789 below 4 - combines 3 with 2; phone layout plus MS-DOS compatibility -1 - by letters but use `z' to go northwest, `y' to zap wands @@ -4267,6 +4282,18 @@ bones data when dying in debug mode; attack - require "yes" rather than `y' to confirm attack- ing a peaceful monster; + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 66 + + + wand-break - require "yes" rather than `y' to confirm breaking a wand; eating - require "yes" rather than `y' to confirm whether @@ -4282,18 +4309,6 @@ all - turn on all of the above. By default, the pray choice is enabled, the others disabled. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 66 - - - To disable it without setting any of the other choices, use "paranoid_confirmation:none". To keep it enabled while setting any of the others, include it in the list, such as "para- @@ -4333,6 +4348,18 @@ pettype Specify the type of your initial pet, if you are playing a + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 67 + + + 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". If the choice is not allowed for the role @@ -4348,18 +4375,6 @@ pickup_thrown If this option is on and autopickup is also on, try to pick up - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 67 - - - things that you threw, even if they aren't in pickup_types or match an autopickup exception. Default is on. Persistent. @@ -4399,6 +4414,18 @@ message where play pauses to allow you to browse the map when- ever clairvoyance randomly activates. Some situations, such as being underwater or engulfed, ignore this option. It does not + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 68 + + + affect the clairvoyance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Per- sistent. @@ -4413,19 +4440,6 @@ Make the space bar a synonym for the `.' (#wait) command (de- fault off). Persistent. - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 68 - - - role Pick your type of character (for example "role:Samurai"); syn- onym for "character". See "name" for an alternate method of @@ -4466,6 +4480,18 @@ Prevent you from (knowingly) attacking your pets (default on). Persistent. + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 69 + + + safe_wait Prevents you from waiting or searching when next to a hostile monster (default on). Persistent. @@ -4480,18 +4506,6 @@ scores"). Only the first letter of each category (`t', `a', or `o') is necessary. Persistent. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 69 - - - showexp Show your accumulated experience points on bottom line (default off). Persistent. @@ -4531,6 +4545,19 @@ standout Boldface monsters and "--More--" (default off). Persistent. + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 70 + + + statushilites Controls how many turns status hilite behaviors highlight the field. If negated or set to zero, disables status hiliting. @@ -4545,19 +4572,6 @@ alert notification messages about feature changes for that and prior versions (for example "suppress_alert:3.3.1"). - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 70 - - - symset This option may be used to select one of the named symbol sets found within "symbols" to alter the symbols displayed on the @@ -4597,6 +4611,19 @@ Provide more commentary during the game (default on). Persis- tent. + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 71 + + + whatis_coord When using the `/' or `;' commands to look around on the map with autodescribe on, display coordinates after the descrip- @@ -4612,18 +4639,6 @@ n - none (no coordinates shown) [default]. The whatis_coord option is also used with the "/m", "/M", "/o", - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 71 - - - and "/O" sub-commands of `/', where the "none" setting is over- ridden with "map". @@ -4663,6 +4678,18 @@ might enable or disable the availability of various other op- tions. For multiple lines in a configuration file, that would be the first non-comment line. For a comma-separated list in + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 72 + + + NETHACKOPTIONS or an OPTIONS line in a configuration file, that would be the rightmost option in the list. @@ -4675,21 +4702,6 @@ the contents. Not all ports support zero-comp compression. It has no effect on reading an existing save file. - - - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 72 - - - 9.5. Window Port Customization options Here are explanations of the various options that are used @@ -4732,6 +4744,18 @@ font_map if NetHack can, it should use a font by the chosen name for the + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 73 + + + map window. font_menu @@ -4744,18 +4768,6 @@ font_status If NetHack can, it should use a font by the chosen name for the - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 73 - - - status window. font_text @@ -4798,6 +4810,18 @@ player_selection If NetHack can, it should pop up dialog boxes, or use prompts + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 74 + + + for character selection. popup_dialog @@ -4810,18 +4834,6 @@ so enhances performance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 74 - - - scroll_amount If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. @@ -4864,6 +4876,18 @@ be slightly condensed, moving some fields to different lines to eliminate one whole line, reducing the height needed. For Qt, statuslines can only be set in the configuration file or via + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 75 + + + NETHACKOPTIONS, not with the `O' command. term_cols and @@ -4876,18 +4900,6 @@ tile_file Specify the name of an alternative tile file to override the - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 75 - - - default. tile_height @@ -4931,6 +4943,17 @@ If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 76 + + + OPTION=windowcolors:wintype foreground/background where wintype is one of "menu", "message", "status", or @@ -4941,21 +4964,9 @@ silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one of Windows UI colors (activeborder, activecaption, appworkspace, background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 76 - - - - inactivecaption, menu, menutext, scrollbar, window, windowframe, - windowtext). + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- + text). wraptext If NetHack can, it should wrap long lines of text if they don't @@ -4997,6 +5008,18 @@ chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 77 + + + flush (default off, Amiga NetHack only). @@ -5007,23 +5030,11 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 77 - - - - bulletproof input (MS-DOS sometimes treats `^P' as a printer - toggle without it) (default off, OS/2, PC, and ST NetHack on- - ly). Note: DEC Rainbows hang if this is turned on. Cannot be - set with the `O' command. + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue (Win32 tty NetHack only). May be used to alter the value of @@ -5062,21 +5073,10 @@ command. videoshades - Set the intensity level of the three gray scales available (de- - fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the - `O' command. - - 9.7. Regular Expressions - - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if + Set the intensity level of the three gray scales available - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -5086,6 +5086,17 @@ + (default dark normal light, PC NetHack only). If the game dis- + play is difficult to read, try adjusting these scales; if this + does not correct the problem, try !color. Cannot be set with + the `O' command. + + 9.7. Regular Expressions + + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -5128,8 +5139,20 @@ 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 ex- - clusion of items known to be cursed from autopickup. + any corpse from autopickup. The last example results in the + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 79 + + + + exclusion of items known to be cursed from autopickup. 9.9. Changing Key Bindings @@ -5140,18 +5163,6 @@ key can be a single character ("x"), a control key ("^X", "C-x"), a meta key ("M-x"), or a three-digit decimal ASCII code. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 79 - - - For example: BIND=^X:getpos.autodescribe @@ -5194,6 +5205,19 @@ When asked for a direction, the key to show the help. Default is `?'. + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 80 + + + getdir.self When asked for a direction, the key to target yourself. De- fault is `.'. @@ -5206,18 +5230,6 @@ When asked for a location, the key to toggle autodescribe. De- fault is `#'. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 80 - - - getpos.all.next When asked for a location, the key to go to next closest inter- esting thing. Default is `a'. @@ -5259,6 +5271,19 @@ ous keys to cycle through targets, toggle showing a menu in- stead. Default is `!'. + + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 81 + + + 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 @@ -5272,18 +5297,6 @@ getpos.pick When asked for a location, the key to choose the location, and - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 81 - - - possibly ask for more info. Default is `.'. getpos.pick.once @@ -5326,6 +5339,17 @@ nopickup Prefix key to move without picking up items. Default is `m'. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 82 + + + redraw Key to redraw the screen. Default is `^R'. @@ -5339,17 +5363,6 @@ reqmenu Prefix key to request menu from some commands. Default is `m'. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 82 - - - run Prefix key to run towards a direction. Default is `G'. @@ -5391,6 +5404,18 @@ MSGTYPE=stop "You feel hungry." MSGTYPE=hide "You displaced *." + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 83 + + + specifies that whenever a message "You feel hungry" is shown, the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. @@ -5405,17 +5430,6 @@ when the line matches a user-defined pattern. At this time the tty, curses, win32tty and win32gui interfaces support this. - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 83 - - - In general, the configuration file entries to describe the menu color mappings look like this: @@ -5457,6 +5471,17 @@ uration file, and the last MENUCOLOR line that matches a menu line will be used for the line. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 84 + + + Note that if you intend to have one or more color specifica- tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed @@ -5469,19 +5494,6 @@ to the message window. At this time the Qt port and the win32tty and win32gui ports support the use of user sounds. - - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 84 - - - The following configuration file entries are relevant to mapping user sounds to messages: @@ -5524,6 +5536,18 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) + + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 85 + + + For another example, the following line in your configura- tion file will cause wisdom to be displayed red if it drops and green if it rises: @@ -5536,18 +5560,6 @@ ground color on the display, which is not necessarily the same as black or white or any of the other colors. - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 85 - - - Allowed attributes are none, bold, dim, underline, blink, and inverse. "Normal" is a synonym for "none"; they should not be used in combination with any of the other attributes. @@ -5591,6 +5603,17 @@ nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. + + NetHack 3.7 December 9, 2020 + + + + + + NetHack Guidebook 86 + + + Allowed behaviors are "always", "up", "down", "changed", a per- centage or absolute number threshold, or text to match against. @@ -5602,18 +5625,6 @@ * "changed" sets the field attribute for when the field val- ue changes. This attribute times out after statushilites - - - NetHack 3.7 November 30, 2020 - - - - - - NetHack Guidebook 86 - - - turns. (If a field has both a "changed" rule and an "up" or "down" rule which matches a change in the field's val- ue, the "up" or "down" one takes precedence.) @@ -5658,19 +5669,8 @@ The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- - tushilites to 0. - Example hilites: - - - - - - - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -5680,6 +5680,11 @@ + The whole feature can be disabled by setting option sta- + tushilites to 0. + + Example hilites: + OPTION=hilite_status: gold/up/yellow/down/brown OPTION=hilite_status: characteristics/up/green/down/red OPTION=hilite_status: hitpoints/100%/gray&normal @@ -5728,15 +5733,10 @@ ^ S_arrow_trap (arrow trap) 0 S_ball (iron ball) # S_bars (iron bars) - B S_bat (bat or bird) - ^ S_bear_trap (bear trap) - - S_blcorn (bottom left corner) - b S_blob (blob) - + S_book (spellbook) - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -5746,6 +5746,11 @@ + B S_bat (bat or bird) + ^ S_bear_trap (bear trap) + - S_blcorn (bottom left corner) + b S_blob (blob) + + S_book (spellbook) ) S_boomleft (boomerang open left) ( S_boomright (boomerang open right) ` S_boulder (boulder) @@ -5794,15 +5799,10 @@ - S_hbeam (horizontal beam [zap animation]) # S_hcdbridge (horizontal raised drawbridge) + S_hcdoor (closed door in horizontal wall) - . S_hodbridge (horizontal lowered drawbridge) - | S_hodoor (open door in horizontal wall) - ^ S_hole (hole) - @ S_human (human or elf) - h S_humanoid (humanoid) - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -5812,6 +5812,11 @@ + . S_hodbridge (horizontal lowered drawbridge) + | S_hodoor (open door in horizontal wall) + ^ S_hole (hole) + @ S_human (human or elf) + h S_humanoid (humanoid) - S_hwall (horizontal wall) . S_ice (ice) i S_imp (imp or minor demon) @@ -5860,15 +5865,10 @@ # S_sink (sink) ^ S_sleeping_gas_trap (sleeping gas trap) S S_snake (snake) - s S_spider (arachnid or centipede) - ^ S_spiked_pit (spiked pit) - ^ S_squeaky_board (squeaky board) - 0 S_ss1 (magic shield 1 of 4) - # S_ss2 (magic shield 2 of 4) - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -5878,6 +5878,11 @@ + s S_spider (arachnid or centipede) + ^ S_spiked_pit (spiked pit) + ^ S_squeaky_board (squeaky board) + 0 S_ss1 (magic shield 1 of 4) + # S_ss2 (magic shield 2 of 4) @ S_ss3 (magic shield 3 of 4) * S_ss4 (magic shield 4 of 4) ^ S_statue_trap (statue trap) @@ -5926,15 +5931,10 @@ w S_worm (worm) ~ S_worm_tail (long worm tail) W S_wraith (wraith) - x S_xan (xan or other extraordinary insect) - X S_xorn (xorn) - Y S_yeti (apelike creature) - Z S_zombie (zombie) - z S_zruty (zruty) - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -5944,6 +5944,11 @@ + x S_xan (xan or other extraordinary insect) + X S_xorn (xorn) + Y S_yeti (apelike creature) + Z S_zombie (zombie) + z S_zruty (zruty) S_pet_override (any pet if ACCESSIBILITY=1 is set) S_hero_override (hero if ACCESSIBILITY=1 is set) @@ -5992,15 +5997,10 @@ While it is not difficult for experienced users to edit the defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the "symbols" file of all of- - ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you - may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your + somewhat daunting. Included within the "symbols" file of all - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6010,6 +6010,11 @@ + official distributions of NetHack is a symset called NHAccess. + Selecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you + may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your configuration file to better suit your preferences. See the pre- vious section for the special symbols S_pet_override to force a consistent symbol for all pets and S_hero_override to force a @@ -6058,15 +6063,10 @@ When targeting with cursor and using fast-move, skip the same glyphs 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 in- - formation can be seen via the "#attributes" command. - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6076,6 +6076,11 @@ + nostatus_updates + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- + formation can be seen via the "#attributes" command. + 9.16. Global Configuration for System Administrators If NetHack is compiled with the SYSCF option, a system ad- @@ -6126,13 +6131,8 @@ 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, WIZ- - ARDS, and SHELLERS check for the player name instead of the us- - er's login name. - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6142,6 +6142,10 @@ + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- + ARDS, and SHELLERS check for the player name instead of the us- + er's login name. + 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 @@ -6192,13 +6196,9 @@ 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. - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6208,6 +6208,10 @@ + 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, how much loot you accumulated, how deep you explored, and how the game ended. If you quit the game, you escape with all of @@ -6260,11 +6264,7 @@ mode instead. - - - - - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6330,7 +6330,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6396,7 +6396,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6462,7 +6462,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6528,7 +6528,7 @@ dows CE port for 3.4.1. - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6594,7 +6594,7 @@ beloved community patches. Many bugs were fixed and some code was - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6660,7 +6660,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6726,7 +6726,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 @@ -6792,7 +6792,7 @@ - NetHack 3.7 November 30, 2020 + NetHack 3.7 December 9, 2020 From b5cfd8333f03b7ac1a93123de9a4f735be4fed2e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 18:02:31 +0200 Subject: [PATCH 559/708] Split trap effects out of dotrap --- src/trap.c | 1275 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 742 insertions(+), 533 deletions(-) diff --git a/src/trap.c b/src/trap.c index 558fb2f0f..40eae559a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -12,6 +12,26 @@ static boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *, static boolean FDECL(mu_maybe_destroy_web, (struct monst *, BOOLEAN_P, struct trap *)); static struct obj *FDECL(t_missile, (int, struct trap *)); +static void FDECL(trapeffect_arrow_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_dart_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_rocktrap, (struct trap *, unsigned)); +static void FDECL(trapeffect_sqky_board, (struct trap *, unsigned)); +static void FDECL(trapeffect_bear_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_slp_gas_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_rust_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_fire_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_pit, (struct trap *, unsigned)); +static void FDECL(trapeffect_hole, (struct trap *, unsigned)); +static void FDECL(trapeffect_telep_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_level_telep, (struct trap *, unsigned)); +static void FDECL(trapeffect_web, (struct trap *, unsigned)); +static void FDECL(trapeffect_statue_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_magic_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_anti_magic, (struct trap *, unsigned)); +static void FDECL(trapeffect_poly_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_landmine, (struct trap *, unsigned)); +static void FDECL(trapeffect_rolling_boulder_trap, (struct trap *, unsigned)); +static void FDECL(trapeffect_magic_portal, (struct trap *, unsigned)); static char *FDECL(trapnote, (struct trap *, BOOLEAN_P)); static int FDECL(steedintrap, (struct trap *, struct obj *)); static void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P)); @@ -902,6 +922,704 @@ boolean msg; } } +static void +trapeffect_arrow_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + struct obj *otmp; + + if (trap->once && trap->tseen && !rn2(15)) { + You_hear("a loud click!"); + deltrap(trap); + newsym(u.ux, u.uy); + return; + } + trap->once = 1; + seetrap(trap); + pline("An arrow shoots out at you!"); + otmp = t_missile(ARROW, trap); + if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { + ; /* nothing */ + } else if (thitu(8, dmgval(otmp, &g.youmonst), &otmp, "arrow")) { + if (otmp) + obfree(otmp, (struct obj *) 0); + } else { + place_object(otmp, u.ux, u.uy); + if (!Blind) + otmp->dknown = 1; + stackobj(otmp); + newsym(u.ux, u.uy); + } +} + +static void +trapeffect_dart_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + struct obj *otmp; + int oldumort = u.umortality; + + if (trap->once && trap->tseen && !rn2(15)) { + You_hear("a soft click."); + deltrap(trap); + newsym(u.ux, u.uy); + return; + } + trap->once = 1; + seetrap(trap); + pline("A little dart shoots out at you!"); + otmp = t_missile(DART, trap); + if (!rn2(6)) + otmp->opoisoned = 1; + if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { + ; /* nothing */ + } else if (thitu(7, dmgval(otmp, &g.youmonst), &otmp, "little dart")) { + if (otmp) { + if (otmp->opoisoned) + poisoned("dart", A_CON, "little dart", + /* if damage triggered life-saving, + poison is limited to attrib loss */ + (u.umortality > oldumort) ? 0 : 10, TRUE); + obfree(otmp, (struct obj *) 0); + } + } else { + place_object(otmp, u.ux, u.uy); + if (!Blind) + otmp->dknown = 1; + stackobj(otmp); + newsym(u.ux, u.uy); + } +} + +static void +trapeffect_rocktrap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + if (trap->once && trap->tseen && !rn2(15)) { + pline("A trap door in %s opens, but nothing falls out!", + the(ceiling(u.ux, u.uy))); + deltrap(trap); + newsym(u.ux, u.uy); + } else { + int dmg = d(2, 6); /* should be std ROCK dmg? */ + struct obj *otmp; + + trap->once = 1; + feeltrap(trap); + otmp = t_missile(ROCK, trap); + place_object(otmp, u.ux, u.uy); + + pline("A trap door in %s opens and %s falls on your %s!", + the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD)); + if (uarmh) { + if (is_metallic(uarmh)) { + pline("Fortunately, you are wearing a hard helmet."); + dmg = 2; + } else if (flags.verbose) { + pline("%s does not protect you.", Yname2(uarmh)); + } + } + if (!Blind) + otmp->dknown = 1; + stackobj(otmp); + newsym(u.ux, u.uy); /* map the rock */ + + losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN); + exercise(A_STR, FALSE); + } +} + +static void +trapeffect_sqky_board(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + boolean forcetrap = ((trflags & FORCETRAP) != 0 + || (trflags & FAILEDUNTRAP) != 0); + + if ((Levitation || Flying) && !forcetrap) { + if (!Blind) { + seetrap(trap); + if (Hallucination) + You("notice a crease in the linoleum."); + else + You("notice a loose board below you."); + } + } else { + seetrap(trap); + pline("A board beneath you %s%s%s.", + Deaf ? "vibrates" : "squeaks ", + Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly"); + wake_nearby(); + } +} + +static void +trapeffect_bear_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + boolean forcetrap = ((trflags & FORCETRAP) != 0 + || (trflags & FAILEDUNTRAP) != 0); + + int dmg = d(2, 4); + + if ((Levitation || Flying) && !forcetrap) + return; + feeltrap(trap); + if (amorphous(g.youmonst.data) || is_whirly(g.youmonst.data) + || unsolid(g.youmonst.data)) { + pline("%s bear trap closes harmlessly through you.", + A_Your[trap->madeby_u]); + return; + } + if (!u.usteed && g.youmonst.data->msize <= MZ_SMALL) { + pline("%s bear trap closes harmlessly over you.", + A_Your[trap->madeby_u]); + return; + } + set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP); + if (u.usteed) { + pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u], + s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT)); + if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE)) + reset_utrap(TRUE); /* steed died, hero not trapped */ + } else { + pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u], + body_part(FOOT)); + set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10)); + if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) + You("howl in anger!"); + losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN); + } + exercise(A_DEX, FALSE); +} + +static void +trapeffect_slp_gas_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + seetrap(trap); + if (Sleep_resistance || breathless(g.youmonst.data)) { + You("are enveloped in a cloud of gas!"); + } else { + pline("A cloud of gas puts you to sleep!"); + fall_asleep(-rnd(25), TRUE); + } + (void) steedintrap(trap, (struct obj *) 0); +} + +static void +trapeffect_rust_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + struct obj *otmp; + + seetrap(trap); + + /* Unlike monsters, traps cannot aim their rust attacks at + * you, so instead of looping through and taking either the + * first rustable one or the body, we take whatever we get, + * even if it is not rustable. + */ + switch (rn2(5)) { + case 0: + pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD)); + (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE); + break; + case 1: + pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM)); + if (water_damage(uarms, "shield", TRUE) != ER_NOTHING) + break; + if (u.twoweap || (uwep && bimanual(uwep))) + (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE); +glovecheck: + (void) water_damage(uarmg, gloves_simple_name(uarmg), TRUE); + break; + case 2: + pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM)); + (void) water_damage(uwep, 0, TRUE); + goto glovecheck; + default: + pline("%s you!", A_gush_of_water_hits); + /* note: exclude primary and seconary weapons from splashing + because cases 1 and 2 target them [via water_damage()] */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (otmp->lamplit && otmp != uwep + && (otmp != uswapwep || !u.twoweap)) + (void) splash_lit(otmp); + if (uarmc) + (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE); + else if (uarm) + (void) water_damage(uarm, suit_simple_name(uarm), TRUE); + else if (uarmu) + (void) water_damage(uarmu, "shirt", TRUE); + } + update_inventory(); + + if (u.umonnum == PM_IRON_GOLEM) { + int dam = u.mhmax; + + 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(&g.youmonst, (struct monst *) 0); + } +} + +static void +trapeffect_fire_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + seetrap(trap); + dofiretrap((struct obj *) 0); +} + +static void +trapeffect_pit(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + int ttype = trap->ttyp; + boolean plunged = (trflags & TOOKPLUNGE) != 0; + boolean conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE); + boolean adj_pit = adj_nonconjoined_pit(trap); + int steed_article = ARTICLE_THE; + int oldumort; + + /* KMH -- You can't escape the Sokoban level traps */ + if (!Sokoban && (Levitation || (Flying && !plunged))) + return; + feeltrap(trap); + if (!Sokoban && is_clinger(g.youmonst.data) && !plunged) { + if (trap->tseen) { + You_see("%s %spit below you.", a_your[trap->madeby_u], + ttype == SPIKED_PIT ? "spiked " : ""); + } else { + pline("%s pit %sopens up under you!", A_Your[trap->madeby_u], + ttype == SPIKED_PIT ? "full of spikes " : ""); + You("don't fall in!"); + } + return; + } + if (!Sokoban) { + char verbbuf[BUFSZ]; + + *verbbuf = '\0'; + if (u.usteed) { + if ((trflags & RECURSIVETRAP) != 0) + Sprintf(verbbuf, "and %s fall", + x_monnam(u.usteed, steed_article, (char *) 0, + SUPPRESS_SADDLE, FALSE)); + else + Sprintf(verbbuf, "lead %s", + x_monnam(u.usteed, steed_article, "poor", + SUPPRESS_SADDLE, FALSE)); + } else if (conj_pit) { + You("move into an adjacent pit."); + } else if (adj_pit) { + You("stumble over debris%s.", + !rn2(5) ? " between the pits" : ""); + } else { + Strcpy(verbbuf, + !plunged ? "fall" : (Flying ? "dive" : "plunge")); + } + if (*verbbuf) + You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]); + } + /* wumpus reference */ + if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once + && In_quest(&u.uz) && Is_qlocate(&u.uz)) { + pline("Fortunately it has a bottom after all..."); + trap->once = 1; + } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) { + pline("How pitiful. Isn't that the pits?"); + } + if (ttype == SPIKED_PIT) { + const char *predicament = "on a set of sharp iron spikes"; + + if (u.usteed) { + pline("%s %s %s!", + upstart(x_monnam(u.usteed, steed_article, "poor", + SUPPRESS_SADDLE, FALSE)), + conj_pit ? "steps" : "lands", predicament); + } else + You("%s %s!", conj_pit ? "step" : "land", predicament); + } + /* FIXME: + * if hero gets killed here, setting u.utrap in advance will + * show "you were trapped in a pit" during disclosure's display + * of enlightenment, but hero is dying *before* becoming trapped. + */ + set_utrap((unsigned) rn1(6, 2), TT_PIT); + if (!steedintrap(trap, (struct obj *) 0)) { + if (ttype == SPIKED_PIT) { + oldumort = u.umortality; + losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)), + /* note: these don't need locomotion() handling; + if fatal while poly'd and Unchanging, the + death reason will be overridden with + "killed while stuck in creature form" */ + plunged + ? "deliberately plunged into a pit of iron spikes" + : conj_pit + ? "stepped into a pit of iron spikes" + : adj_pit + ? "stumbled into a pit of iron spikes" + : "fell into a pit of iron spikes", + NO_KILLER_PREFIX); + if (!rn2(6)) + poisoned("spikes", A_STR, + (conj_pit || adj_pit) + ? "stepping on poison spikes" + : "fall onto poison spikes", + /* if damage triggered life-saving, + poison is limited to attrib loss */ + (u.umortality > oldumort) ? 0 : 8, FALSE); + } else { + /* plunging flyers take spike damage but not pit damage */ + if (!conj_pit + && !(plunged && (Flying || is_clinger(g.youmonst.data)))) + losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)), + plunged ? "deliberately plunged into a pit" + : "fell into a pit", + NO_KILLER_PREFIX); + } + if (Punished && !carried(uball)) { + unplacebc(); + ballfall(); + placebc(); + } + if (!conj_pit) + selftouch("Falling, you"); + g.vision_full_recalc = 1; /* vision limits change */ + exercise(A_STR, FALSE); + exercise(A_DEX, FALSE); + } +} + +static void +trapeffect_hole(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + if (!Can_fall_thru(&u.uz)) { + seetrap(trap); /* normally done in fall_through */ + impossible("dotrap: %ss cannot exist on this level.", + trapname(trap->ttyp, TRUE)); + return; /* don't activate it after all */ + } + fall_through(TRUE, (trflags & TOOKPLUNGE)); +} + +static void +trapeffect_telep_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + seetrap(trap); + tele_trap(trap); +} + +static void +trapeffect_level_telep(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + seetrap(trap); + level_tele_trap(trap, trflags); +} + +static void +trapeffect_web(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + boolean webmsgok = (trflags & NOWEBMSG) == 0; + boolean forcetrap = ((trflags & FORCETRAP) != 0 + || (trflags & FAILEDUNTRAP) != 0); + boolean viasitting = (trflags & VIASITTING) != 0; + int steed_article = ARTICLE_THE; + + feeltrap(trap); + if (mu_maybe_destroy_web(&g.youmonst, webmsgok, trap)) + return; + if (webmaker(g.youmonst.data)) { + if (webmsgok) + pline(trap->madeby_u ? "You take a walk on your web." + : "There is a spider web here."); + return; + } + if (webmsgok) { + char verbbuf[BUFSZ]; + + if (forcetrap || viasitting) { + Strcpy(verbbuf, "are caught by"); + } else if (u.usteed) { + Sprintf(verbbuf, "lead %s into", + x_monnam(u.usteed, steed_article, "poor", + SUPPRESS_SADDLE, FALSE)); + } else { + Sprintf(verbbuf, "%s into", + Levitation ? (const char *) "float" + : locomotion(g.youmonst.data, "stumble")); + } + You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]); + } + + /* time will be adjusted below */ + set_utrap(1, TT_WEB); + + /* Time stuck in the web depends on your/steed strength. */ + { + int tim, str = ACURR(A_STR); + + /* If mounted, the steed gets trapped. Use mintrap + * to do all the work. If mtrapped is set as a result, + * unset it and set utrap instead. In the case of a + * strongmonst and mintrap said it's trapped, use a + * short but non-zero trap time. Otherwise, monsters + * have no specific strength, so use player strength. + * This gets skipped for webmsgok, which implies that + * the steed isn't a factor. + */ + if (u.usteed && webmsgok) { + /* mtmp location might not be up to date */ + u.usteed->mx = u.ux; + u.usteed->my = u.uy; + + /* mintrap currently does not return 2(died) for webs */ + if (mintrap(u.usteed)) { + u.usteed->mtrapped = 0; + if (strongmonst(u.usteed->data)) + str = 17; + } else { + reset_utrap(FALSE); + return; + } + + webmsgok = FALSE; /* mintrap printed the messages */ + } + if (str <= 3) + tim = rn1(6, 6); + else if (str < 6) + tim = rn1(6, 4); + else if (str < 9) + tim = rn1(4, 4); + else if (str < 12) + tim = rn1(4, 2); + else if (str < 15) + tim = rn1(2, 2); + else if (str < 18) + tim = rnd(2); + else if (str < 69) + tim = 1; + else { + tim = 0; + if (webmsgok) + You("tear through %s web!", a_your[trap->madeby_u]); + deltrap(trap); + newsym(u.ux, u.uy); /* get rid of trap symbol */ + } + set_utrap((unsigned) tim, TT_WEB); + } +} + +static void +trapeffect_statue_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); +} + +static void +trapeffect_magic_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + seetrap(trap); + if (!rn2(30)) { + deltrap(trap); + newsym(u.ux, u.uy); /* update position */ + You("are caught in a magical explosion!"); + losehp(rnd(10), "magical explosion", KILLED_BY_AN); + Your("body absorbs some of the magical energy!"); + u.uen = (u.uenmax += 2); + return; + } else { + domagictrap(); + } + (void) steedintrap(trap, (struct obj *) 0); +} + +static void +trapeffect_anti_magic(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + seetrap(trap); + /* hero without magic resistance loses spell energy, + hero with magic resistance takes damage instead; + possibly non-intuitive but useful for play balance */ + if (!Antimagic) { + drain_en(rnd(u.ulevel) + 1); + } else { + struct obj *otmp; + int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp; + + /* Half_XXX_damage has opposite its usual effect (approx) + but isn't cumulative if hero has more than one */ + if (Half_physical_damage || Half_spell_damage) + dmgval2 += rnd(4); + /* give Magicbane wielder dose of own medicine */ + if (uwep && uwep->oartifact == ART_MAGICBANE) + dmgval2 += rnd(4); + /* having an artifact--other than own quest one--which + confers magic resistance simply by being carried + also increases the effect */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (otmp->oartifact && !is_quest_artifact(otmp) + && defends_when_carried(AD_MAGM, otmp)) + break; + if (otmp) + dmgval2 += rnd(4); + if (Passes_walls) + dmgval2 = (dmgval2 + 3) / 4; + + You_feel((dmgval2 >= hp) ? "unbearably torpid!" + : (dmgval2 >= hp / 4) ? "very lethargic." + : "sluggish."); + /* opposite of magical explosion */ + losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN); + } +} + +static void +trapeffect_poly_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + boolean viasitting = (trflags & VIASITTING) != 0; + int steed_article = ARTICLE_THE; + char verbbuf[BUFSZ]; + + seetrap(trap); + if (viasitting) + Strcpy(verbbuf, "trigger"); /* follows "You sit down." */ + else if (u.usteed) + Sprintf(verbbuf, "lead %s onto", + x_monnam(u.usteed, steed_article, (char *) 0, + SUPPRESS_SADDLE, FALSE)); + else + Sprintf(verbbuf, "%s onto", + Levitation ? (const char *) "float" + : locomotion(g.youmonst.data, "step")); + You("%s a polymorph trap!", verbbuf); + if (Antimagic || Unchanging) { + shieldeff(u.ux, u.uy); + You_feel("momentarily different."); + /* Trap did nothing; don't remove it --KAA */ + } else { + (void) steedintrap(trap, (struct obj *) 0); + deltrap(trap); /* delete trap before polymorph */ + newsym(u.ux, u.uy); /* get rid of trap symbol */ + You_feel("a change coming over you."); + polyself(0); + } +} + +static void +trapeffect_landmine(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + boolean already_seen = trap->tseen; + boolean forcetrap = ((trflags & FORCETRAP) != 0 + || (trflags & FAILEDUNTRAP) != 0); + boolean forcebungle = (trflags & FORCEBUNGLE) != 0; + unsigned steed_mid = 0; + struct obj *saddle = 0; + + if ((Levitation || Flying) && !forcetrap) { + if (!already_seen && rn2(3)) + return; + feeltrap(trap); + pline("%s %s in a pile of soil below you.", + already_seen ? "There is" : "You discover", + trap->madeby_u ? "the trigger of your mine" : "a trigger"); + if (already_seen && rn2(3)) + return; + pline("KAABLAMM!!! %s %s%s off!", + forcebungle ? "Your inept attempt sets" + : "The air currents set", + already_seen ? a_your[trap->madeby_u] : "", + already_seen ? " land mine" : "it"); + } else { + /* prevent landmine from killing steed, throwing you to + * the ground, and you being affected again by the same + * mine because it hasn't been deleted yet + */ + static boolean recursive_mine = FALSE; + + if (recursive_mine) + return; + feeltrap(trap); + pline("KAABLAMM!!! You triggered %s land mine!", + a_your[trap->madeby_u]); + if (u.usteed) + steed_mid = u.usteed->m_id; + recursive_mine = TRUE; + (void) steedintrap(trap, (struct obj *) 0); + recursive_mine = FALSE; + saddle = sobj_at(SADDLE, u.ux, u.uy); + set_wounded_legs(LEFT_SIDE, rn1(35, 41)); + set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); + exercise(A_DEX, FALSE); + } + blow_up_landmine(trap); + if (steed_mid && saddle && !u.usteed) + (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle); + newsym(u.ux, u.uy); /* update trap symbol */ + losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN); + /* fall recursively into the pit... */ + if ((trap = t_at(u.ux, u.uy)) != 0) + dotrap(trap, RECURSIVETRAP); + fill_pit(u.ux, u.uy); +} + +static void +trapeffect_rolling_boulder_trap(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); + + feeltrap(trap); + pline("Click! You trigger a rolling boulder trap!"); + if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y, + trap->launch2.x, trap->launch2.y, style)) { + deltrap(trap); + newsym(u.ux, u.uy); /* get rid of trap symbol */ + pline("Fortunately for you, no boulder was released."); + } +} + +static void +trapeffect_magic_portal(trap, trflags) +struct trap *trap; +unsigned trflags; +{ + feeltrap(trap); + domagicportal(trap); +} + void dotrap(trap, trflags) register struct trap *trap; @@ -973,594 +1691,85 @@ unsigned trflags; switch (ttype) { case ARROW_TRAP: - if (trap->once && trap->tseen && !rn2(15)) { - You_hear("a loud click!"); - deltrap(trap); - newsym(u.ux, u.uy); - break; - } - trap->once = 1; - seetrap(trap); - pline("An arrow shoots out at you!"); - otmp = t_missile(ARROW, trap); - if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { - ; /* nothing */ - } else if (thitu(8, dmgval(otmp, &g.youmonst), &otmp, "arrow")) { - if (otmp) - obfree(otmp, (struct obj *) 0); - } else { - place_object(otmp, u.ux, u.uy); - if (!Blind) - otmp->dknown = 1; - stackobj(otmp); - newsym(u.ux, u.uy); - } + trapeffect_arrow_trap(trap, trflags); break; case DART_TRAP: - if (trap->once && trap->tseen && !rn2(15)) { - You_hear("a soft click."); - deltrap(trap); - newsym(u.ux, u.uy); - break; - } - trap->once = 1; - seetrap(trap); - pline("A little dart shoots out at you!"); - otmp = t_missile(DART, trap); - if (!rn2(6)) - otmp->opoisoned = 1; - oldumort = u.umortality; - if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { - ; /* nothing */ - } else if (thitu(7, dmgval(otmp, &g.youmonst), &otmp, "little dart")) { - if (otmp) { - if (otmp->opoisoned) - poisoned("dart", A_CON, "little dart", - /* if damage triggered life-saving, - poison is limited to attrib loss */ - (u.umortality > oldumort) ? 0 : 10, TRUE); - obfree(otmp, (struct obj *) 0); - } - } else { - place_object(otmp, u.ux, u.uy); - if (!Blind) - otmp->dknown = 1; - stackobj(otmp); - newsym(u.ux, u.uy); - } + trapeffect_dart_trap(trap, trflags); break; case ROCKTRAP: - if (trap->once && trap->tseen && !rn2(15)) { - pline("A trap door in %s opens, but nothing falls out!", - the(ceiling(u.ux, u.uy))); - deltrap(trap); - newsym(u.ux, u.uy); - } else { - int dmg = d(2, 6); /* should be std ROCK dmg? */ - - trap->once = 1; - feeltrap(trap); - otmp = t_missile(ROCK, trap); - place_object(otmp, u.ux, u.uy); - - pline("A trap door in %s opens and %s falls on your %s!", - the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD)); - if (uarmh) { - if (is_metallic(uarmh)) { - pline("Fortunately, you are wearing a hard helmet."); - dmg = 2; - } else if (flags.verbose) { - pline("%s does not protect you.", Yname2(uarmh)); - } - } - if (!Blind) - otmp->dknown = 1; - stackobj(otmp); - newsym(u.ux, u.uy); /* map the rock */ - - losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN); - exercise(A_STR, FALSE); - } + trapeffect_rocktrap(trap, trflags); break; case SQKY_BOARD: /* stepped on a squeaky board */ - if ((Levitation || Flying) && !forcetrap) { - if (!Blind) { - seetrap(trap); - if (Hallucination) - You("notice a crease in the linoleum."); - else - You("notice a loose board below you."); - } - } else { - seetrap(trap); - pline("A board beneath you %s%s%s.", - Deaf ? "vibrates" : "squeaks ", - Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly"); - wake_nearby(); - } + trapeffect_sqky_board(trap, trflags); break; - case BEAR_TRAP: { - int dmg = d(2, 4); - - if ((Levitation || Flying) && !forcetrap) - break; - feeltrap(trap); - if (amorphous(g.youmonst.data) || is_whirly(g.youmonst.data) - || unsolid(g.youmonst.data)) { - pline("%s bear trap closes harmlessly through you.", - A_Your[trap->madeby_u]); - break; - } - if (!u.usteed && g.youmonst.data->msize <= MZ_SMALL) { - pline("%s bear trap closes harmlessly over you.", - A_Your[trap->madeby_u]); - break; - } - set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP); - if (u.usteed) { - pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u], - s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT)); - if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE)) - reset_utrap(TRUE); /* steed died, hero not trapped */ - } else { - pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u], - body_part(FOOT)); - set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10)); - if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) - You("howl in anger!"); - losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN); - } - exercise(A_DEX, FALSE); + case BEAR_TRAP: + trapeffect_bear_trap(trap, trflags); break; - } case SLP_GAS_TRAP: - seetrap(trap); - if (Sleep_resistance || breathless(g.youmonst.data)) { - You("are enveloped in a cloud of gas!"); - } else { - pline("A cloud of gas puts you to sleep!"); - fall_asleep(-rnd(25), TRUE); - } - (void) steedintrap(trap, (struct obj *) 0); + trapeffect_slp_gas_trap(trap, trflags); break; case RUST_TRAP: - seetrap(trap); - - /* Unlike monsters, traps cannot aim their rust attacks at - * you, so instead of looping through and taking either the - * first rustable one or the body, we take whatever we get, - * even if it is not rustable. - */ - switch (rn2(5)) { - case 0: - pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD)); - (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE); - break; - case 1: - pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM)); - if (water_damage(uarms, "shield", TRUE) != ER_NOTHING) - break; - if (u.twoweap || (uwep && bimanual(uwep))) - (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE); - glovecheck: - (void) water_damage(uarmg, gloves_simple_name(uarmg), TRUE); - break; - case 2: - pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM)); - (void) water_damage(uwep, 0, TRUE); - goto glovecheck; - default: - pline("%s you!", A_gush_of_water_hits); - /* note: exclude primary and seconary weapons from splashing - because cases 1 and 2 target them [via water_damage()] */ - for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (otmp->lamplit && otmp != uwep - && (otmp != uswapwep || !u.twoweap)) - (void) splash_lit(otmp); - if (uarmc) - (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE); - else if (uarm) - (void) water_damage(uarm, suit_simple_name(uarm), TRUE); - else if (uarmu) - (void) water_damage(uarmu, "shirt", TRUE); - } - update_inventory(); - - if (u.umonnum == PM_IRON_GOLEM) { - int dam = u.mhmax; - - 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(&g.youmonst, (struct monst *) 0); - } - + trapeffect_rust_trap(trap, trflags); break; case FIRE_TRAP: - seetrap(trap); - dofiretrap((struct obj *) 0); + trapeffect_fire_trap(trap, trflags); break; case PIT: case SPIKED_PIT: - /* KMH -- You can't escape the Sokoban level traps */ - if (!Sokoban && (Levitation || (Flying && !plunged))) - break; - feeltrap(trap); - if (!Sokoban && is_clinger(g.youmonst.data) && !plunged) { - if (trap->tseen) { - You_see("%s %spit below you.", a_your[trap->madeby_u], - ttype == SPIKED_PIT ? "spiked " : ""); - } else { - pline("%s pit %sopens up under you!", A_Your[trap->madeby_u], - ttype == SPIKED_PIT ? "full of spikes " : ""); - You("don't fall in!"); - } - break; - } - if (!Sokoban) { - char verbbuf[BUFSZ]; - - *verbbuf = '\0'; - if (u.usteed) { - if ((trflags & RECURSIVETRAP) != 0) - Sprintf(verbbuf, "and %s fall", - x_monnam(u.usteed, steed_article, (char *) 0, - SUPPRESS_SADDLE, FALSE)); - else - Sprintf(verbbuf, "lead %s", - x_monnam(u.usteed, steed_article, "poor", - SUPPRESS_SADDLE, FALSE)); - } else if (conj_pit) { - You("move into an adjacent pit."); - } else if (adj_pit) { - You("stumble over debris%s.", - !rn2(5) ? " between the pits" : ""); - } else { - Strcpy(verbbuf, - !plunged ? "fall" : (Flying ? "dive" : "plunge")); - } - if (*verbbuf) - You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]); - } - /* wumpus reference */ - if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once - && In_quest(&u.uz) && Is_qlocate(&u.uz)) { - pline("Fortunately it has a bottom after all..."); - trap->once = 1; - } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) { - pline("How pitiful. Isn't that the pits?"); - } - if (ttype == SPIKED_PIT) { - const char *predicament = "on a set of sharp iron spikes"; - - if (u.usteed) { - pline("%s %s %s!", - upstart(x_monnam(u.usteed, steed_article, "poor", - SUPPRESS_SADDLE, FALSE)), - conj_pit ? "steps" : "lands", predicament); - } else - You("%s %s!", conj_pit ? "step" : "land", predicament); - } - /* FIXME: - * if hero gets killed here, setting u.utrap in advance will - * show "you were trapped in a pit" during disclosure's display - * of enlightenment, but hero is dying *before* becoming trapped. - */ - set_utrap((unsigned) rn1(6, 2), TT_PIT); - if (!steedintrap(trap, (struct obj *) 0)) { - if (ttype == SPIKED_PIT) { - oldumort = u.umortality; - losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)), - /* note: these don't need locomotion() handling; - if fatal while poly'd and Unchanging, the - death reason will be overridden with - "killed while stuck in creature form" */ - plunged - ? "deliberately plunged into a pit of iron spikes" - : conj_pit - ? "stepped into a pit of iron spikes" - : adj_pit - ? "stumbled into a pit of iron spikes" - : "fell into a pit of iron spikes", - NO_KILLER_PREFIX); - if (!rn2(6)) - poisoned("spikes", A_STR, - (conj_pit || adj_pit) - ? "stepping on poison spikes" - : "fall onto poison spikes", - /* if damage triggered life-saving, - poison is limited to attrib loss */ - (u.umortality > oldumort) ? 0 : 8, FALSE); - } else { - /* plunging flyers take spike damage but not pit damage */ - if (!conj_pit - && !(plunged && (Flying || is_clinger(g.youmonst.data)))) - losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)), - plunged ? "deliberately plunged into a pit" - : "fell into a pit", - NO_KILLER_PREFIX); - } - if (Punished && !carried(uball)) { - unplacebc(); - ballfall(); - placebc(); - } - if (!conj_pit) - selftouch("Falling, you"); - g.vision_full_recalc = 1; /* vision limits change */ - exercise(A_STR, FALSE); - exercise(A_DEX, FALSE); - } + trapeffect_pit(trap, trflags); break; case HOLE: case TRAPDOOR: - if (!Can_fall_thru(&u.uz)) { - seetrap(trap); /* normally done in fall_through */ - impossible("dotrap: %ss cannot exist on this level.", - trapname(ttype, TRUE)); - break; /* don't activate it after all */ - } - fall_through(TRUE, (trflags & TOOKPLUNGE)); + trapeffect_hole(trap, trflags); break; case TELEP_TRAP: - seetrap(trap); - tele_trap(trap); + trapeffect_telep_trap(trap, trflags); break; case LEVEL_TELEP: - seetrap(trap); - level_tele_trap(trap, trflags); + trapeffect_level_telep(trap, trflags); break; case WEB: /* Our luckless player has stumbled into a web. */ - feeltrap(trap); - if (mu_maybe_destroy_web(&g.youmonst, webmsgok, trap)) - break; - if (webmaker(g.youmonst.data)) { - if (webmsgok) - pline(trap->madeby_u ? "You take a walk on your web." - : "There is a spider web here."); - break; - } - if (webmsgok) { - char verbbuf[BUFSZ]; - - if (forcetrap || viasitting) { - Strcpy(verbbuf, "are caught by"); - } else if (u.usteed) { - Sprintf(verbbuf, "lead %s into", - x_monnam(u.usteed, steed_article, "poor", - SUPPRESS_SADDLE, FALSE)); - } else { - Sprintf(verbbuf, "%s into", - Levitation ? (const char *) "float" - : locomotion(g.youmonst.data, "stumble")); - } - You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]); - } - - /* time will be adjusted below */ - set_utrap(1, TT_WEB); - - /* Time stuck in the web depends on your/steed strength. */ - { - int tim, str = ACURR(A_STR); - - /* If mounted, the steed gets trapped. Use mintrap - * to do all the work. If mtrapped is set as a result, - * unset it and set utrap instead. In the case of a - * strongmonst and mintrap said it's trapped, use a - * short but non-zero trap time. Otherwise, monsters - * have no specific strength, so use player strength. - * This gets skipped for webmsgok, which implies that - * the steed isn't a factor. - */ - if (u.usteed && webmsgok) { - /* mtmp location might not be up to date */ - u.usteed->mx = u.ux; - u.usteed->my = u.uy; - - /* mintrap currently does not return 2(died) for webs */ - if (mintrap(u.usteed)) { - u.usteed->mtrapped = 0; - if (strongmonst(u.usteed->data)) - str = 17; - } else { - reset_utrap(FALSE); - break; - } - - webmsgok = FALSE; /* mintrap printed the messages */ - } - if (str <= 3) - tim = rn1(6, 6); - else if (str < 6) - tim = rn1(6, 4); - else if (str < 9) - tim = rn1(4, 4); - else if (str < 12) - tim = rn1(4, 2); - else if (str < 15) - tim = rn1(2, 2); - else if (str < 18) - tim = rnd(2); - else if (str < 69) - tim = 1; - else { - tim = 0; - if (webmsgok) - You("tear through %s web!", a_your[trap->madeby_u]); - deltrap(trap); - newsym(u.ux, u.uy); /* get rid of trap symbol */ - } - set_utrap((unsigned) tim, TT_WEB); - } + trapeffect_web(trap, trflags); break; case STATUE_TRAP: - (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); + trapeffect_statue_trap(trap, trflags); break; case MAGIC_TRAP: /* A magic trap. */ - seetrap(trap); - if (!rn2(30)) { - deltrap(trap); - newsym(u.ux, u.uy); /* update position */ - You("are caught in a magical explosion!"); - losehp(rnd(10), "magical explosion", KILLED_BY_AN); - Your("body absorbs some of the magical energy!"); - u.uen = (u.uenmax += 2); - break; - } else { - domagictrap(); - } - (void) steedintrap(trap, (struct obj *) 0); + trapeffect_magic_trap(trap, trflags); break; case ANTI_MAGIC: - seetrap(trap); - /* hero without magic resistance loses spell energy, - hero with magic resistance takes damage instead; - possibly non-intuitive but useful for play balance */ - if (!Antimagic) { - drain_en(rnd(u.ulevel) + 1); - } else { - int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp; - - /* Half_XXX_damage has opposite its usual effect (approx) - but isn't cumulative if hero has more than one */ - if (Half_physical_damage || Half_spell_damage) - dmgval2 += rnd(4); - /* give Magicbane wielder dose of own medicine */ - if (uwep && uwep->oartifact == ART_MAGICBANE) - dmgval2 += rnd(4); - /* having an artifact--other than own quest one--which - confers magic resistance simply by being carried - also increases the effect */ - for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (otmp->oartifact && !is_quest_artifact(otmp) - && defends_when_carried(AD_MAGM, otmp)) - break; - if (otmp) - dmgval2 += rnd(4); - if (Passes_walls) - dmgval2 = (dmgval2 + 3) / 4; - - You_feel((dmgval2 >= hp) ? "unbearably torpid!" - : (dmgval2 >= hp / 4) ? "very lethargic." - : "sluggish."); - /* opposite of magical explosion */ - losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN); - } + trapeffect_anti_magic(trap, trflags); break; - case POLY_TRAP: { - char verbbuf[BUFSZ]; - - seetrap(trap); - if (viasitting) - Strcpy(verbbuf, "trigger"); /* follows "You sit down." */ - else if (u.usteed) - Sprintf(verbbuf, "lead %s onto", - x_monnam(u.usteed, steed_article, (char *) 0, - SUPPRESS_SADDLE, FALSE)); - else - Sprintf(verbbuf, "%s onto", - Levitation ? (const char *) "float" - : locomotion(g.youmonst.data, "step")); - You("%s a polymorph trap!", verbbuf); - if (Antimagic || Unchanging) { - shieldeff(u.ux, u.uy); - You_feel("momentarily different."); - /* Trap did nothing; don't remove it --KAA */ - } else { - (void) steedintrap(trap, (struct obj *) 0); - deltrap(trap); /* delete trap before polymorph */ - newsym(u.ux, u.uy); /* get rid of trap symbol */ - You_feel("a change coming over you."); - polyself(0); - } + case POLY_TRAP: + trapeffect_poly_trap(trap, trflags); break; - } - case LANDMINE: { - unsigned steed_mid = 0; - struct obj *saddle = 0; - if ((Levitation || Flying) && !forcetrap) { - if (!already_seen && rn2(3)) - break; - feeltrap(trap); - pline("%s %s in a pile of soil below you.", - already_seen ? "There is" : "You discover", - trap->madeby_u ? "the trigger of your mine" : "a trigger"); - if (already_seen && rn2(3)) - break; - pline("KAABLAMM!!! %s %s%s off!", - forcebungle ? "Your inept attempt sets" - : "The air currents set", - already_seen ? a_your[trap->madeby_u] : "", - already_seen ? " land mine" : "it"); - } else { - /* prevent landmine from killing steed, throwing you to - * the ground, and you being affected again by the same - * mine because it hasn't been deleted yet - */ - static boolean recursive_mine = FALSE; - - if (recursive_mine) - break; - feeltrap(trap); - pline("KAABLAMM!!! You triggered %s land mine!", - a_your[trap->madeby_u]); - if (u.usteed) - steed_mid = u.usteed->m_id; - recursive_mine = TRUE; - (void) steedintrap(trap, (struct obj *) 0); - recursive_mine = FALSE; - saddle = sobj_at(SADDLE, u.ux, u.uy); - set_wounded_legs(LEFT_SIDE, rn1(35, 41)); - set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); - exercise(A_DEX, FALSE); - } - blow_up_landmine(trap); - if (steed_mid && saddle && !u.usteed) - (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle); - newsym(u.ux, u.uy); /* update trap symbol */ - losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN); - /* fall recursively into the pit... */ - if ((trap = t_at(u.ux, u.uy)) != 0) - dotrap(trap, RECURSIVETRAP); - fill_pit(u.ux, u.uy); + case LANDMINE: + trapeffect_landmine(trap, trflags); break; - } - case ROLLING_BOULDER_TRAP: { - int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); - - feeltrap(trap); - pline("Click! You trigger a rolling boulder trap!"); - if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y, - trap->launch2.x, trap->launch2.y, style)) { - deltrap(trap); - newsym(u.ux, u.uy); /* get rid of trap symbol */ - pline("Fortunately for you, no boulder was released."); - } + case ROLLING_BOULDER_TRAP: + trapeffect_rolling_boulder_trap(trap, trflags); break; - } case MAGIC_PORTAL: - feeltrap(trap); - domagicportal(trap); + trapeffect_magic_portal(trap, trflags); break; case VIBRATING_SQUARE: From 640be5ff7edc07657d92b3ccfde7533b83657243 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 18:27:31 +0200 Subject: [PATCH 560/708] Unify arrow trap --- src/trap.c | 89 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/trap.c b/src/trap.c index 40eae559a..fb8b7dfb6 100644 --- a/src/trap.c +++ b/src/trap.c @@ -12,7 +12,7 @@ static boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *, static boolean FDECL(mu_maybe_destroy_web, (struct monst *, BOOLEAN_P, struct trap *)); static struct obj *FDECL(t_missile, (int, struct trap *)); -static void FDECL(trapeffect_arrow_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_arrow_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_dart_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_rocktrap, (struct trap *, unsigned)); static void FDECL(trapeffect_sqky_board, (struct trap *, unsigned)); @@ -922,35 +922,60 @@ boolean msg; } } -static void -trapeffect_arrow_trap(trap, trflags) +static int +trapeffect_arrow_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { struct obj *otmp; - if (trap->once && trap->tseen && !rn2(15)) { - You_hear("a loud click!"); - deltrap(trap); - newsym(u.ux, u.uy); - return; - } - trap->once = 1; - seetrap(trap); - pline("An arrow shoots out at you!"); - otmp = t_missile(ARROW, trap); - if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { - ; /* nothing */ - } else if (thitu(8, dmgval(otmp, &g.youmonst), &otmp, "arrow")) { - if (otmp) - obfree(otmp, (struct obj *) 0); + if (mtmp == &g.youmonst) { + if (trap->once && trap->tseen && !rn2(15)) { + You_hear("a loud click!"); + deltrap(trap); + newsym(u.ux, u.uy); + return 0; + } + trap->once = 1; + seetrap(trap); + pline("An arrow shoots out at you!"); + otmp = t_missile(ARROW, trap); + if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { + ; /* nothing */ + } else if (thitu(8, dmgval(otmp, &g.youmonst), &otmp, "arrow")) { + if (otmp) + obfree(otmp, (struct obj *) 0); + } else { + place_object(otmp, u.ux, u.uy); + if (!Blind) + otmp->dknown = 1; + stackobj(otmp); + newsym(u.ux, u.uy); + } } else { - place_object(otmp, u.ux, u.uy); - if (!Blind) - otmp->dknown = 1; - stackobj(otmp); - newsym(u.ux, u.uy); + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean see_it = cansee(mtmp->mx, mtmp->my); + boolean trapkilled = FALSE; + + if (trap->once && trap->tseen && !rn2(15)) { + if (in_sight && see_it) + pline("%s triggers a trap but nothing happens.", + Monnam(mtmp)); + deltrap(trap); + newsym(mtmp->mx, mtmp->my); + return 0; + } + trap->once = 1; + otmp = t_missile(ARROW, trap); + if (in_sight) + seetrap(trap); + if (thitm(8, mtmp, otmp, 0, FALSE)) + trapkilled = TRUE; + + return trapkilled ? 2 : mtmp->mtrapped; } + return 0; } static void @@ -1691,7 +1716,7 @@ unsigned trflags; switch (ttype) { case ARROW_TRAP: - trapeffect_arrow_trap(trap, trflags); + (void) trapeffect_arrow_trap(&g.youmonst, trap, trflags); break; case DART_TRAP: @@ -2421,21 +2446,7 @@ register struct monst *mtmp; in_sight = TRUE; switch (tt) { case ARROW_TRAP: - if (trap->once && trap->tseen && !rn2(15)) { - if (in_sight && see_it) - pline("%s triggers a trap but nothing happens.", - Monnam(mtmp)); - deltrap(trap); - newsym(mtmp->mx, mtmp->my); - break; - } - trap->once = 1; - otmp = t_missile(ARROW, trap); - if (in_sight) - seetrap(trap); - if (thitm(8, mtmp, otmp, 0, FALSE)) - trapkilled = TRUE; - break; + return trapeffect_arrow_trap(mtmp, trap, 0); case DART_TRAP: if (trap->once && trap->tseen && !rn2(15)) { if (in_sight && see_it) From 485985968e6d17c3470a2d26e000a1d476f83cfe Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 18:31:25 +0200 Subject: [PATCH 561/708] Unify dart trap --- src/trap.c | 109 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/src/trap.c b/src/trap.c index fb8b7dfb6..24c170409 100644 --- a/src/trap.c +++ b/src/trap.c @@ -13,7 +13,7 @@ static boolean FDECL(mu_maybe_destroy_web, (struct monst *, BOOLEAN_P, struct trap *)); static struct obj *FDECL(t_missile, (int, struct trap *)); static int FDECL(trapeffect_arrow_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_dart_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_dart_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_rocktrap, (struct trap *, unsigned)); static void FDECL(trapeffect_sqky_board, (struct trap *, unsigned)); static void FDECL(trapeffect_bear_trap, (struct trap *, unsigned)); @@ -978,44 +978,72 @@ unsigned trflags; return 0; } -static void -trapeffect_dart_trap(trap, trflags) +static int +trapeffect_dart_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { struct obj *otmp; - int oldumort = u.umortality; - if (trap->once && trap->tseen && !rn2(15)) { - You_hear("a soft click."); - deltrap(trap); - newsym(u.ux, u.uy); - return; - } - trap->once = 1; - seetrap(trap); - pline("A little dart shoots out at you!"); - otmp = t_missile(DART, trap); - if (!rn2(6)) - otmp->opoisoned = 1; - if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { - ; /* nothing */ - } else if (thitu(7, dmgval(otmp, &g.youmonst), &otmp, "little dart")) { - if (otmp) { - if (otmp->opoisoned) - poisoned("dart", A_CON, "little dart", - /* if damage triggered life-saving, - poison is limited to attrib loss */ - (u.umortality > oldumort) ? 0 : 10, TRUE); - obfree(otmp, (struct obj *) 0); + if (mtmp == &g.youmonst) { + int oldumort = u.umortality; + + if (trap->once && trap->tseen && !rn2(15)) { + You_hear("a soft click."); + deltrap(trap); + newsym(u.ux, u.uy); + return 0; + } + trap->once = 1; + seetrap(trap); + pline("A little dart shoots out at you!"); + otmp = t_missile(DART, trap); + if (!rn2(6)) + otmp->opoisoned = 1; + if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { + ; /* nothing */ + } else if (thitu(7, dmgval(otmp, &g.youmonst), &otmp, "little dart")) { + if (otmp) { + if (otmp->opoisoned) + poisoned("dart", A_CON, "little dart", + /* if damage triggered life-saving, + poison is limited to attrib loss */ + (u.umortality > oldumort) ? 0 : 10, TRUE); + obfree(otmp, (struct obj *) 0); + } + } else { + place_object(otmp, u.ux, u.uy); + if (!Blind) + otmp->dknown = 1; + stackobj(otmp); + newsym(u.ux, u.uy); } } else { - place_object(otmp, u.ux, u.uy); - if (!Blind) - otmp->dknown = 1; - stackobj(otmp); - newsym(u.ux, u.uy); + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean see_it = cansee(mtmp->mx, mtmp->my); + boolean trapkilled = FALSE; + + if (trap->once && trap->tseen && !rn2(15)) { + if (in_sight && see_it) + pline("%s triggers a trap but nothing happens.", + Monnam(mtmp)); + deltrap(trap); + newsym(mtmp->mx, mtmp->my); + return 0; + } + trap->once = 1; + otmp = t_missile(DART, trap); + if (!rn2(6)) + otmp->opoisoned = 1; + if (in_sight) + seetrap(trap); + if (thitm(7, mtmp, otmp, 0, FALSE)) + trapkilled = TRUE; + + return trapkilled ? 2 : mtmp->mtrapped; } + return 0; } static void @@ -1720,7 +1748,7 @@ unsigned trflags; break; case DART_TRAP: - trapeffect_dart_trap(trap, trflags); + (void) trapeffect_dart_trap(&g.youmonst, trap, trflags); break; case ROCKTRAP: @@ -2448,22 +2476,7 @@ register struct monst *mtmp; case ARROW_TRAP: return trapeffect_arrow_trap(mtmp, trap, 0); case DART_TRAP: - if (trap->once && trap->tseen && !rn2(15)) { - if (in_sight && see_it) - pline("%s triggers a trap but nothing happens.", - Monnam(mtmp)); - deltrap(trap); - newsym(mtmp->mx, mtmp->my); - break; - } - trap->once = 1; - otmp = t_missile(DART, trap); - if (!rn2(6)) - otmp->opoisoned = 1; - if (in_sight) - seetrap(trap); - if (thitm(7, mtmp, otmp, 0, FALSE)) - trapkilled = TRUE; + return trapeffect_dart_trap(mtmp, trap, 0); break; case ROCKTRAP: if (trap->once && trap->tseen && !rn2(15)) { From a1227cefb3eb3965caf3b94a71b54acc7dc4e781 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 18:47:54 +0200 Subject: [PATCH 562/708] Unify rocktrap --- src/trap.c | 105 +++++++++++++++++++++++++++++------------------------ 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/src/trap.c b/src/trap.c index 24c170409..0f1d2b98b 100644 --- a/src/trap.c +++ b/src/trap.c @@ -14,7 +14,7 @@ static boolean FDECL(mu_maybe_destroy_web, (struct monst *, BOOLEAN_P, static struct obj *FDECL(t_missile, (int, struct trap *)); static int FDECL(trapeffect_arrow_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_dart_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_rocktrap, (struct trap *, unsigned)); +static int FDECL(trapeffect_rocktrap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_sqky_board, (struct trap *, unsigned)); static void FDECL(trapeffect_bear_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_slp_gas_trap, (struct trap *, unsigned)); @@ -1046,43 +1046,69 @@ unsigned trflags; return 0; } -static void -trapeffect_rocktrap(trap, trflags) +static int +trapeffect_rocktrap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - if (trap->once && trap->tseen && !rn2(15)) { - pline("A trap door in %s opens, but nothing falls out!", - the(ceiling(u.ux, u.uy))); - deltrap(trap); - newsym(u.ux, u.uy); - } else { - int dmg = d(2, 6); /* should be std ROCK dmg? */ - struct obj *otmp; + struct obj *otmp; - trap->once = 1; - feeltrap(trap); - otmp = t_missile(ROCK, trap); - place_object(otmp, u.ux, u.uy); + if (mtmp == &g.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))); + deltrap(trap); + newsym(u.ux, u.uy); + } else { + int dmg = d(2, 6); /* should be std ROCK dmg? */ - pline("A trap door in %s opens and %s falls on your %s!", - the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD)); - if (uarmh) { - if (is_metallic(uarmh)) { - pline("Fortunately, you are wearing a hard helmet."); - dmg = 2; - } else if (flags.verbose) { - pline("%s does not protect you.", Yname2(uarmh)); + trap->once = 1; + feeltrap(trap); + otmp = t_missile(ROCK, trap); + place_object(otmp, u.ux, u.uy); + + pline("A trap door in %s opens and %s falls on your %s!", + the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD)); + if (uarmh) { + if (is_metallic(uarmh)) { + pline("Fortunately, you are wearing a hard helmet."); + dmg = 2; + } else if (flags.verbose) { + pline("%s does not protect you.", Yname2(uarmh)); + } } - } - if (!Blind) - otmp->dknown = 1; - stackobj(otmp); - newsym(u.ux, u.uy); /* map the rock */ + if (!Blind) + otmp->dknown = 1; + stackobj(otmp); + newsym(u.ux, u.uy); /* map the rock */ - losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN); - exercise(A_STR, FALSE); + losehp(Maybe_Half_Phys(dmg), "falling rock", KILLED_BY_AN); + exercise(A_STR, FALSE); + } + } else { + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean see_it = cansee(mtmp->mx, mtmp->my); + boolean trapkilled = FALSE; + + if (trap->once && trap->tseen && !rn2(15)) { + if (in_sight && see_it) + pline("A trap door above %s opens, but nothing falls out!", + mon_nam(mtmp)); + deltrap(trap); + newsym(mtmp->mx, mtmp->my); + return 0; + } + trap->once = 1; + otmp = t_missile(ROCK, trap); + if (in_sight) + seetrap(trap); + if (thitm(0, mtmp, otmp, d(2, 6), FALSE)) + trapkilled = TRUE; + + return trapkilled ? 2 : mtmp->mtrapped; } + return 0; } static void @@ -1752,7 +1778,7 @@ unsigned trflags; break; case ROCKTRAP: - trapeffect_rocktrap(trap, trflags); + (void) trapeffect_rocktrap(&g.youmonst, trap, trflags); break; case SQKY_BOARD: /* stepped on a squeaky board */ @@ -2477,23 +2503,8 @@ register struct monst *mtmp; return trapeffect_arrow_trap(mtmp, trap, 0); case DART_TRAP: return trapeffect_dart_trap(mtmp, trap, 0); - break; case ROCKTRAP: - if (trap->once && trap->tseen && !rn2(15)) { - if (in_sight && see_it) - pline("A trap door above %s opens, but nothing falls out!", - mon_nam(mtmp)); - deltrap(trap); - newsym(mtmp->mx, mtmp->my); - break; - } - trap->once = 1; - otmp = t_missile(ROCK, trap); - if (in_sight) - seetrap(trap); - if (thitm(0, mtmp, otmp, d(2, 6), FALSE)) - trapkilled = TRUE; - break; + return trapeffect_rocktrap(mtmp, trap, 0); case SQKY_BOARD: if (is_flyer(mptr)) break; From e07968e8e5ebcbd73f35f2d3d24315906647ee68 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 18:50:55 +0200 Subject: [PATCH 563/708] Unify squeaky board --- src/trap.c | 84 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/src/trap.c b/src/trap.c index 0f1d2b98b..3c4464f4e 100644 --- a/src/trap.c +++ b/src/trap.c @@ -15,7 +15,7 @@ static struct obj *FDECL(t_missile, (int, struct trap *)); static int FDECL(trapeffect_arrow_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_dart_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_rocktrap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_sqky_board, (struct trap *, unsigned)); +static int FDECL(trapeffect_sqky_board, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_bear_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_slp_gas_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_rust_trap, (struct trap *, unsigned)); @@ -1111,29 +1111,59 @@ unsigned trflags; return 0; } -static void -trapeffect_sqky_board(trap, trflags) +static int +trapeffect_sqky_board(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { boolean forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0); - if ((Levitation || Flying) && !forcetrap) { - if (!Blind) { + if (mtmp == &g.youmonst) { + if ((Levitation || Flying) && !forcetrap) { + if (!Blind) { + seetrap(trap); + if (Hallucination) + You("notice a crease in the linoleum."); + else + You("notice a loose board below you."); + } + } else { seetrap(trap); - if (Hallucination) - You("notice a crease in the linoleum."); - else - You("notice a loose board below you."); + pline("A board beneath you %s%s%s.", + Deaf ? "vibrates" : "squeaks ", + Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly"); + wake_nearby(); } } else { - seetrap(trap); - pline("A board beneath you %s%s%s.", - Deaf ? "vibrates" : "squeaks ", - Deaf ? "" : trapnote(trap, 0), Deaf ? "" : " loudly"); - wake_nearby(); + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + + if (is_flyer(mtmp->data)) + return 0; + /* stepped on a squeaky board */ + if (in_sight) { + if (!Deaf) { + pline("A board beneath %s squeaks %s loudly.", + mon_nam(mtmp), trapnote(trap, 0)); + seetrap(trap); + } else { + pline("%s stops momentarily and appears to cringe.", + Monnam(mtmp)); + } + } else { + /* same near/far threshold as mzapmsg() */ + int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */ + ? (BOLT_LIM + 1) : (BOLT_LIM - 3); + + You_hear("a %s squeak %s.", trapnote(trap, 1), + (distu(mtmp->mx, mtmp->my) <= range * range) + ? "nearby" : "in the distance"); + } + /* wake up nearby monsters */ + wake_nearto(mtmp->mx, mtmp->my, 40); } + return 0; } static void @@ -1782,7 +1812,7 @@ unsigned trflags; break; case SQKY_BOARD: /* stepped on a squeaky board */ - trapeffect_sqky_board(trap, trflags); + (void) trapeffect_sqky_board(&g.youmonst, trap, trflags); break; case BEAR_TRAP: @@ -2506,29 +2536,7 @@ register struct monst *mtmp; case ROCKTRAP: return trapeffect_rocktrap(mtmp, trap, 0); case SQKY_BOARD: - if (is_flyer(mptr)) - break; - /* stepped on a squeaky board */ - if (in_sight) { - if (!Deaf) { - pline("A board beneath %s squeaks %s loudly.", - mon_nam(mtmp), trapnote(trap, 0)); - seetrap(trap); - } else { - pline("%s stops momentarily and appears to cringe.", - Monnam(mtmp)); - } - } else { - /* same near/far threshold as mzapmsg() */ - int range = couldsee(mtmp->mx, mtmp->my) /* 9 or 5 */ - ? (BOLT_LIM + 1) : (BOLT_LIM - 3); - - You_hear("a %s squeak %s.", trapnote(trap, 1), - (distu(mtmp->mx, mtmp->my) <= range * range) - ? "nearby" : "in the distance"); - } - /* wake up nearby monsters */ - wake_nearto(mtmp->mx, mtmp->my, 40); + return trapeffect_sqky_board(mtmp, trap, 0); break; case BEAR_TRAP: if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr) From 0a47c3d4f2460b57f4fb37bbcf39d30c18f742cb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 18:57:51 +0200 Subject: [PATCH 564/708] Unify bear trap --- src/trap.c | 118 +++++++++++++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 53 deletions(-) diff --git a/src/trap.c b/src/trap.c index 3c4464f4e..33117cc40 100644 --- a/src/trap.c +++ b/src/trap.c @@ -16,7 +16,7 @@ static int FDECL(trapeffect_arrow_trap, (struct monst *, struct trap *, unsigned static int FDECL(trapeffect_dart_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_rocktrap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_sqky_board, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_bear_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_bear_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_slp_gas_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_rust_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_fire_trap, (struct trap *, unsigned)); @@ -1166,45 +1166,77 @@ unsigned trflags; return 0; } -static void -trapeffect_bear_trap(trap, trflags) +static int +trapeffect_bear_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { boolean forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0); - int dmg = d(2, 4); + if (mtmp == &g.youmonst) { + int dmg = d(2, 4); - if ((Levitation || Flying) && !forcetrap) - return; - feeltrap(trap); - if (amorphous(g.youmonst.data) || is_whirly(g.youmonst.data) - || unsolid(g.youmonst.data)) { - pline("%s bear trap closes harmlessly through you.", - A_Your[trap->madeby_u]); - return; - } - if (!u.usteed && g.youmonst.data->msize <= MZ_SMALL) { - pline("%s bear trap closes harmlessly over you.", - A_Your[trap->madeby_u]); - return; - } - set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP); - if (u.usteed) { - pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u], - s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT)); - if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE)) - reset_utrap(TRUE); /* steed died, hero not trapped */ + if ((Levitation || Flying) && !forcetrap) + return 0; + feeltrap(trap); + if (amorphous(g.youmonst.data) || is_whirly(g.youmonst.data) + || unsolid(g.youmonst.data)) { + pline("%s bear trap closes harmlessly through you.", + A_Your[trap->madeby_u]); + return 0; + } + if (!u.usteed && g.youmonst.data->msize <= MZ_SMALL) { + pline("%s bear trap closes harmlessly over you.", + A_Your[trap->madeby_u]); + return 0; + } + set_utrap((unsigned) rn1(4, 4), TT_BEARTRAP); + if (u.usteed) { + pline("%s bear trap closes on %s %s!", A_Your[trap->madeby_u], + s_suffix(mon_nam(u.usteed)), mbodypart(u.usteed, FOOT)); + if (thitm(0, u.usteed, (struct obj *) 0, dmg, FALSE)) + reset_utrap(TRUE); /* steed died, hero not trapped */ + } else { + pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u], + body_part(FOOT)); + set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10)); + if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) + You("howl in anger!"); + losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN); + } + exercise(A_DEX, FALSE); } else { - pline("%s bear trap closes on your %s!", A_Your[trap->madeby_u], - body_part(FOOT)); - set_wounded_legs(rn2(2) ? RIGHT_SIDE : LEFT_SIDE, rn1(10, 10)); - if (u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR) - You("howl in anger!"); - losehp(Maybe_Half_Phys(dmg), "bear trap", KILLED_BY_AN); + struct permonst *mptr = mtmp->data; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean trapkilled = FALSE; + + if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr) + && !is_whirly(mptr) && !unsolid(mptr)) { + mtmp->mtrapped = 1; + if (in_sight) { + pline("%s is caught in %s bear trap!", Monnam(mtmp), + a_your[trap->madeby_u]); + seetrap(trap); + } else { + if (mptr == &mons[PM_OWLBEAR] + || mptr == &mons[PM_BUGBEAR]) + You_hear("the roaring of an angry bear!"); + } + } else if (g.force_mintrap) { + if (in_sight) { + pline("%s evades %s bear trap!", Monnam(mtmp), + a_your[trap->madeby_u]); + seetrap(trap); + } + } + if (mtmp->mtrapped) + trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE); + + return trapkilled ? 2 : mtmp->mtrapped; } - exercise(A_DEX, FALSE); + return 0; } static void @@ -1816,7 +1848,7 @@ unsigned trflags; break; case BEAR_TRAP: - trapeffect_bear_trap(trap, trflags); + (void) trapeffect_bear_trap(&g.youmonst, trap, trflags); break; case SLP_GAS_TRAP: @@ -2539,27 +2571,7 @@ register struct monst *mtmp; return trapeffect_sqky_board(mtmp, trap, 0); break; case BEAR_TRAP: - if (mptr->msize > MZ_SMALL && !amorphous(mptr) && !is_flyer(mptr) - && !is_whirly(mptr) && !unsolid(mptr)) { - mtmp->mtrapped = 1; - if (in_sight) { - pline("%s is caught in %s bear trap!", Monnam(mtmp), - a_your[trap->madeby_u]); - seetrap(trap); - } else { - if (mptr == &mons[PM_OWLBEAR] - || mptr == &mons[PM_BUGBEAR]) - You_hear("the roaring of an angry bear!"); - } - } else if (g.force_mintrap) { - if (in_sight) { - pline("%s evades %s bear trap!", Monnam(mtmp), - a_your[trap->madeby_u]); - seetrap(trap); - } - } - if (mtmp->mtrapped) - trapkilled = thitm(0, mtmp, (struct obj *) 0, d(2, 4), FALSE); + return trapeffect_bear_trap(mtmp, trap, 0); break; case SLP_GAS_TRAP: if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping From 4974a57832cea29f1534fc60fe33e78dca9b206f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 19:01:15 +0200 Subject: [PATCH 565/708] Unify sleeping gas trap --- src/trap.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/src/trap.c b/src/trap.c index 33117cc40..374bbd631 100644 --- a/src/trap.c +++ b/src/trap.c @@ -17,7 +17,7 @@ static int FDECL(trapeffect_dart_trap, (struct monst *, struct trap *, unsigned) static int FDECL(trapeffect_rocktrap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_sqky_board, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_bear_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_slp_gas_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_slp_gas_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_rust_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_fire_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_pit, (struct trap *, unsigned)); @@ -1239,19 +1239,33 @@ unsigned trflags; return 0; } -static void -trapeffect_slp_gas_trap(trap, trflags) +static int +trapeffect_slp_gas_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - seetrap(trap); - if (Sleep_resistance || breathless(g.youmonst.data)) { - You("are enveloped in a cloud of gas!"); + if (mtmp == &g.youmonst) { + seetrap(trap); + if (Sleep_resistance || breathless(g.youmonst.data)) { + You("are enveloped in a cloud of gas!"); + } else { + pline("A cloud of gas puts you to sleep!"); + fall_asleep(-rnd(25), TRUE); + } + (void) steedintrap(trap, (struct obj *) 0); } else { - pline("A cloud of gas puts you to sleep!"); - fall_asleep(-rnd(25), TRUE); + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + + if (!resists_sleep(mtmp) && !breathless(mtmp->data) && !mtmp->msleeping + && mtmp->mcanmove) { + if (sleep_monst(mtmp, rnd(25), -1) && in_sight) { + pline("%s suddenly falls asleep!", Monnam(mtmp)); + seetrap(trap); + } + } } - (void) steedintrap(trap, (struct obj *) 0); + return 0; } static void @@ -1852,7 +1866,7 @@ unsigned trflags; break; case SLP_GAS_TRAP: - trapeffect_slp_gas_trap(trap, trflags); + (void) trapeffect_slp_gas_trap(&g.youmonst, trap, trflags); break; case RUST_TRAP: @@ -2574,13 +2588,7 @@ register struct monst *mtmp; return trapeffect_bear_trap(mtmp, trap, 0); break; case SLP_GAS_TRAP: - if (!resists_sleep(mtmp) && !breathless(mptr) && !mtmp->msleeping - && mtmp->mcanmove) { - if (sleep_monst(mtmp, rnd(25), -1) && in_sight) { - pline("%s suddenly falls asleep!", Monnam(mtmp)); - seetrap(trap); - } - } + return trapeffect_slp_gas_trap(mtmp, trap, 0); break; case RUST_TRAP: { struct obj *target; From c78e873c7c4febd75d24adcc9ff4558cb593d906 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 19:06:10 +0200 Subject: [PATCH 566/708] Unify rust trap --- src/trap.c | 232 ++++++++++++++++++++++++++++------------------------- 1 file changed, 121 insertions(+), 111 deletions(-) diff --git a/src/trap.c b/src/trap.c index 374bbd631..8910cc699 100644 --- a/src/trap.c +++ b/src/trap.c @@ -18,7 +18,7 @@ static int FDECL(trapeffect_rocktrap, (struct monst *, struct trap *, unsigned)) static int FDECL(trapeffect_sqky_board, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_bear_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_slp_gas_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_rust_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_rust_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_fire_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_pit, (struct trap *, unsigned)); static void FDECL(trapeffect_hole, (struct trap *, unsigned)); @@ -1268,63 +1268,133 @@ unsigned trflags; return 0; } -static void -trapeffect_rust_trap(trap, trflags) +static int +trapeffect_rust_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { struct obj *otmp; - seetrap(trap); + if (mtmp == &g.youmonst) { + seetrap(trap); - /* Unlike monsters, traps cannot aim their rust attacks at - * you, so instead of looping through and taking either the - * first rustable one or the body, we take whatever we get, - * even if it is not rustable. - */ - switch (rn2(5)) { - case 0: - pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD)); - (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE); - break; - case 1: - pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM)); - if (water_damage(uarms, "shield", TRUE) != ER_NOTHING) + /* Unlike monsters, traps cannot aim their rust attacks at + * you, so instead of looping through and taking either the + * first rustable one or the body, we take whatever we get, + * even if it is not rustable. + */ + switch (rn2(5)) { + case 0: + pline("%s you on the %s!", A_gush_of_water_hits, body_part(HEAD)); + (void) water_damage(uarmh, helm_simple_name(uarmh), TRUE); break; - if (u.twoweap || (uwep && bimanual(uwep))) - (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE); -glovecheck: - (void) water_damage(uarmg, gloves_simple_name(uarmg), TRUE); - break; - case 2: - pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM)); - (void) water_damage(uwep, 0, TRUE); - goto glovecheck; - default: - pline("%s you!", A_gush_of_water_hits); - /* note: exclude primary and seconary weapons from splashing - because cases 1 and 2 target them [via water_damage()] */ - for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (otmp->lamplit && otmp != uwep - && (otmp != uswapwep || !u.twoweap)) - (void) splash_lit(otmp); - if (uarmc) - (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE); - else if (uarm) - (void) water_damage(uarm, suit_simple_name(uarm), TRUE); - else if (uarmu) - (void) water_damage(uarmu, "shirt", TRUE); - } - update_inventory(); + case 1: + pline("%s your left %s!", A_gush_of_water_hits, body_part(ARM)); + if (water_damage(uarms, "shield", TRUE) != ER_NOTHING) + break; + if (u.twoweap || (uwep && bimanual(uwep))) + (void) water_damage(u.twoweap ? uswapwep : uwep, 0, TRUE); + uglovecheck: + (void) water_damage(uarmg, gloves_simple_name(uarmg), TRUE); + break; + case 2: + pline("%s your right %s!", A_gush_of_water_hits, body_part(ARM)); + (void) water_damage(uwep, 0, TRUE); + goto uglovecheck; + default: + pline("%s you!", A_gush_of_water_hits); + /* note: exclude primary and seconary weapons from splashing + because cases 1 and 2 target them [via water_damage()] */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (otmp->lamplit && otmp != uwep + && (otmp != uswapwep || !u.twoweap)) + (void) splash_lit(otmp); + if (uarmc) + (void) water_damage(uarmc, cloak_simple_name(uarmc), TRUE); + else if (uarm) + (void) water_damage(uarm, suit_simple_name(uarm), TRUE); + else if (uarmu) + (void) water_damage(uarmu, "shirt", TRUE); + } + update_inventory(); - if (u.umonnum == PM_IRON_GOLEM) { - int dam = u.mhmax; + if (u.umonnum == PM_IRON_GOLEM) { + int dam = u.mhmax; - 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(&g.youmonst, (struct monst *) 0); + 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(&g.youmonst, (struct monst *) 0); + } + } else { + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean trapkilled = FALSE; + struct permonst *mptr = mtmp->data; + struct obj *target; + + if (in_sight) + seetrap(trap); + switch (rn2(5)) { + case 0: + if (in_sight) + pline("%s %s on the %s!", A_gush_of_water_hits, + mon_nam(mtmp), mbodypart(mtmp, HEAD)); + target = which_armor(mtmp, W_ARMH); + (void) water_damage(target, helm_simple_name(target), TRUE); + break; + case 1: + if (in_sight) + pline("%s %s's left %s!", A_gush_of_water_hits, + mon_nam(mtmp), mbodypart(mtmp, ARM)); + target = which_armor(mtmp, W_ARMS); + if (water_damage(target, "shield", TRUE) != ER_NOTHING) + break; + target = MON_WEP(mtmp); + if (target && bimanual(target)) + (void) water_damage(target, 0, TRUE); + mglovecheck: + target = which_armor(mtmp, W_ARMG); + (void) water_damage(target, gloves_simple_name(target), TRUE); + break; + case 2: + if (in_sight) + pline("%s %s's right %s!", A_gush_of_water_hits, + mon_nam(mtmp), mbodypart(mtmp, ARM)); + (void) water_damage(MON_WEP(mtmp), 0, TRUE); + goto mglovecheck; + default: + if (in_sight) + pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp)); + for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) + if (otmp->lamplit + /* exclude weapon(s) because cases 1 and 2 do them */ + && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0) + (void) splash_lit(otmp); + if ((target = which_armor(mtmp, W_ARMC)) != 0) + (void) water_damage(target, cloak_simple_name(target), + TRUE); + else if ((target = which_armor(mtmp, W_ARM)) != 0) + (void) water_damage(target, suit_simple_name(target), + TRUE); + else if ((target = which_armor(mtmp, W_ARMU)) != 0) + (void) water_damage(target, "shirt", TRUE); + } + + if (completelyrusts(mptr)) { + if (in_sight) + pline("%s %s to pieces!", Monnam(mtmp), + !mlifesaver(mtmp) ? "falls" : "starts to fall"); + monkilled(mtmp, (const char *) 0, AD_RUST); + if (DEADMONSTER(mtmp)) + trapkilled = TRUE; + } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { + (void) split_mon(mtmp, (struct monst *) 0); + } + + return trapkilled ? 2 : mtmp->mtrapped; } + return 0; } static void @@ -1870,7 +1940,7 @@ unsigned trflags; break; case RUST_TRAP: - trapeffect_rust_trap(trap, trflags); + (void) trapeffect_rust_trap(&g.youmonst, trap, trflags); break; case FIRE_TRAP: @@ -2590,69 +2660,9 @@ register struct monst *mtmp; case SLP_GAS_TRAP: return trapeffect_slp_gas_trap(mtmp, trap, 0); break; - case RUST_TRAP: { - struct obj *target; - - if (in_sight) - seetrap(trap); - switch (rn2(5)) { - case 0: - if (in_sight) - pline("%s %s on the %s!", A_gush_of_water_hits, - mon_nam(mtmp), mbodypart(mtmp, HEAD)); - target = which_armor(mtmp, W_ARMH); - (void) water_damage(target, helm_simple_name(target), TRUE); - break; - case 1: - if (in_sight) - pline("%s %s's left %s!", A_gush_of_water_hits, - mon_nam(mtmp), mbodypart(mtmp, ARM)); - target = which_armor(mtmp, W_ARMS); - if (water_damage(target, "shield", TRUE) != ER_NOTHING) - break; - target = MON_WEP(mtmp); - if (target && bimanual(target)) - (void) water_damage(target, 0, TRUE); - glovecheck: - target = which_armor(mtmp, W_ARMG); - (void) water_damage(target, gloves_simple_name(target), TRUE); - break; - case 2: - if (in_sight) - pline("%s %s's right %s!", A_gush_of_water_hits, - mon_nam(mtmp), mbodypart(mtmp, ARM)); - (void) water_damage(MON_WEP(mtmp), 0, TRUE); - goto glovecheck; - default: - if (in_sight) - pline("%s %s!", A_gush_of_water_hits, mon_nam(mtmp)); - for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) - if (otmp->lamplit - /* exclude weapon(s) because cases 1 and 2 do them */ - && (otmp->owornmask & (W_WEP | W_SWAPWEP)) == 0) - (void) splash_lit(otmp); - if ((target = which_armor(mtmp, W_ARMC)) != 0) - (void) water_damage(target, cloak_simple_name(target), - TRUE); - else if ((target = which_armor(mtmp, W_ARM)) != 0) - (void) water_damage(target, suit_simple_name(target), - TRUE); - else if ((target = which_armor(mtmp, W_ARMU)) != 0) - (void) water_damage(target, "shirt", TRUE); - } - - if (completelyrusts(mptr)) { - if (in_sight) - pline("%s %s to pieces!", Monnam(mtmp), - !mlifesaver(mtmp) ? "falls" : "starts to fall"); - monkilled(mtmp, (const char *) 0, AD_RUST); - if (DEADMONSTER(mtmp)) - trapkilled = TRUE; - } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) { - (void) split_mon(mtmp, (struct monst *) 0); - } + case RUST_TRAP: + return trapeffect_rust_trap(mtmp, trap, 0); break; - } /* RUST_TRAP */ case FIRE_TRAP: mfiretrap: if (in_sight) From 5773f49dfe11904435114c04e3e69de645ad5b23 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 19:10:46 +0200 Subject: [PATCH 567/708] Unify fire trap --- src/trap.c | 147 +++++++++++++++++++++++++++++------------------------ 1 file changed, 80 insertions(+), 67 deletions(-) diff --git a/src/trap.c b/src/trap.c index 8910cc699..47fd69d74 100644 --- a/src/trap.c +++ b/src/trap.c @@ -19,7 +19,7 @@ static int FDECL(trapeffect_sqky_board, (struct monst *, struct trap *, unsigned static int FDECL(trapeffect_bear_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_slp_gas_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_rust_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_fire_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_fire_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_pit, (struct trap *, unsigned)); static void FDECL(trapeffect_hole, (struct trap *, unsigned)); static void FDECL(trapeffect_telep_trap, (struct trap *, unsigned)); @@ -1397,13 +1397,86 @@ unsigned trflags; return 0; } -static void -trapeffect_fire_trap(trap, trflags) +static int +trapeffect_fire_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - seetrap(trap); - dofiretrap((struct obj *) 0); + if (mtmp == &g.youmonst) { + seetrap(trap); + dofiretrap((struct obj *) 0); + } else { + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean see_it = cansee(mtmp->mx, mtmp->my); + boolean trapkilled = FALSE; + struct permonst *mptr = mtmp->data; + + if (in_sight) + pline("A %s erupts from the %s under %s!", tower_of_flame, + surface(mtmp->mx, mtmp->my), mon_nam(mtmp)); + else if (see_it) /* evidently `mtmp' is invisible */ + You_see("a %s erupt from the %s!", tower_of_flame, + surface(mtmp->mx, mtmp->my)); + + if (resists_fire(mtmp)) { + if (in_sight) { + shieldeff(mtmp->mx, mtmp->my); + pline("%s is uninjured.", Monnam(mtmp)); + } + } else { + int num = d(2, 4), alt; + boolean immolate = FALSE; + + /* paper burns very fast, assume straw is tightly packed + and burns a bit slower + (note: this is inconsistent with mattackm()'s AD_FIRE + damage where completelyburns() includes straw golem) */ + switch (monsndx(mptr)) { + case PM_PAPER_GOLEM: + immolate = TRUE; + alt = mtmp->mhpmax; + break; + case PM_STRAW_GOLEM: + alt = mtmp->mhpmax / 2; + break; + case PM_WOOD_GOLEM: + alt = mtmp->mhpmax / 4; + break; + case PM_LEATHER_GOLEM: + alt = mtmp->mhpmax / 8; + break; + default: + alt = 0; + break; + } + if (alt > num) + num = alt; + + if (thitm(0, mtmp, (struct obj *) 0, num, immolate)) + trapkilled = TRUE; + else + /* we know mhp is at least `num' below mhpmax, + so no (mhp > mhpmax) check is needed here */ + mtmp->mhpmax -= rn2(num + 1); + } + if (burnarmor(mtmp) || rn2(3)) { + (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); + (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); + (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); + ignite_items(mtmp->minvent); + } + if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE) + && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3) + You("smell smoke."); + if (is_ice(mtmp->mx, mtmp->my)) + melt_ice(mtmp->mx, mtmp->my, (char *) 0); + if (see_it && t_at(mtmp->mx, mtmp->my)) + seetrap(trap); + + return trapkilled ? 2 : mtmp->mtrapped; + } + return 0; } static void @@ -1944,7 +2017,7 @@ unsigned trflags; break; case FIRE_TRAP: - trapeffect_fire_trap(trap, trflags); + (void) trapeffect_fire_trap(&g.youmonst, trap, trflags); break; case PIT: @@ -2665,67 +2738,7 @@ register struct monst *mtmp; break; case FIRE_TRAP: mfiretrap: - if (in_sight) - pline("A %s erupts from the %s under %s!", tower_of_flame, - surface(mtmp->mx, mtmp->my), mon_nam(mtmp)); - else if (see_it) /* evidently `mtmp' is invisible */ - You_see("a %s erupt from the %s!", tower_of_flame, - surface(mtmp->mx, mtmp->my)); - - if (resists_fire(mtmp)) { - if (in_sight) { - shieldeff(mtmp->mx, mtmp->my); - pline("%s is uninjured.", Monnam(mtmp)); - } - } else { - int num = d(2, 4), alt; - boolean immolate = FALSE; - - /* paper burns very fast, assume straw is tightly packed - and burns a bit slower - (note: this is inconsistent with mattackm()'s AD_FIRE - damage where completelyburns() includes straw golem) */ - switch (monsndx(mptr)) { - case PM_PAPER_GOLEM: - immolate = TRUE; - alt = mtmp->mhpmax; - break; - case PM_STRAW_GOLEM: - alt = mtmp->mhpmax / 2; - break; - case PM_WOOD_GOLEM: - alt = mtmp->mhpmax / 4; - break; - case PM_LEATHER_GOLEM: - alt = mtmp->mhpmax / 8; - break; - default: - alt = 0; - break; - } - if (alt > num) - num = alt; - - if (thitm(0, mtmp, (struct obj *) 0, num, immolate)) - trapkilled = TRUE; - else - /* we know mhp is at least `num' below mhpmax, - so no (mhp > mhpmax) check is needed here */ - mtmp->mhpmax -= rn2(num + 1); - } - if (burnarmor(mtmp) || rn2(3)) { - (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE); - (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE); - (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE); - ignite_items(mtmp->minvent); - } - if (burn_floor_objects(mtmp->mx, mtmp->my, see_it, FALSE) - && !see_it && distu(mtmp->mx, mtmp->my) <= 3 * 3) - You("smell smoke."); - if (is_ice(mtmp->mx, mtmp->my)) - melt_ice(mtmp->mx, mtmp->my, (char *) 0); - if (see_it && t_at(mtmp->mx, mtmp->my)) - seetrap(trap); + return trapeffect_fire_trap(mtmp, trap, 0); break; case PIT: case SPIKED_PIT: From afa1fef1fffd40ab40d9ce6a9b9340c6691cdd65 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 9 Dec 2020 19:36:52 +0200 Subject: [PATCH 568/708] Unify pits --- src/trap.c | 298 ++++++++++++++++++++++++++++------------------------- 1 file changed, 158 insertions(+), 140 deletions(-) diff --git a/src/trap.c b/src/trap.c index 47fd69d74..dcfa4e4ed 100644 --- a/src/trap.c +++ b/src/trap.c @@ -20,7 +20,7 @@ static int FDECL(trapeffect_bear_trap, (struct monst *, struct trap *, unsigned) static int FDECL(trapeffect_slp_gas_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_rust_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_fire_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_pit, (struct trap *, unsigned)); +static int FDECL(trapeffect_pit, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_hole, (struct trap *, unsigned)); static void FDECL(trapeffect_telep_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_level_telep, (struct trap *, unsigned)); @@ -1479,127 +1479,174 @@ unsigned trflags; return 0; } -static void -trapeffect_pit(trap, trflags) +static int +trapeffect_pit(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { int ttype = trap->ttyp; - boolean plunged = (trflags & TOOKPLUNGE) != 0; - boolean conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE); - boolean adj_pit = adj_nonconjoined_pit(trap); - int steed_article = ARTICLE_THE; - int oldumort; - /* KMH -- You can't escape the Sokoban level traps */ - if (!Sokoban && (Levitation || (Flying && !plunged))) - return; - feeltrap(trap); - if (!Sokoban && is_clinger(g.youmonst.data) && !plunged) { - if (trap->tseen) { - You_see("%s %spit below you.", a_your[trap->madeby_u], - ttype == SPIKED_PIT ? "spiked " : ""); - } else { - pline("%s pit %sopens up under you!", A_Your[trap->madeby_u], - ttype == SPIKED_PIT ? "full of spikes " : ""); - You("don't fall in!"); + if (mtmp == &g.youmonst) { + boolean plunged = (trflags & TOOKPLUNGE) != 0; + boolean conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE); + boolean adj_pit = adj_nonconjoined_pit(trap); + int steed_article = ARTICLE_THE; + int oldumort; + + /* KMH -- You can't escape the Sokoban level traps */ + if (!Sokoban && (Levitation || (Flying && !plunged))) + return 0; + feeltrap(trap); + if (!Sokoban && is_clinger(g.youmonst.data) && !plunged) { + if (trap->tseen) { + You_see("%s %spit below you.", a_your[trap->madeby_u], + ttype == SPIKED_PIT ? "spiked " : ""); + } else { + pline("%s pit %sopens up under you!", A_Your[trap->madeby_u], + ttype == SPIKED_PIT ? "full of spikes " : ""); + You("don't fall in!"); + } + return 0; } - return; - } - if (!Sokoban) { - char verbbuf[BUFSZ]; + if (!Sokoban) { + char verbbuf[BUFSZ]; - *verbbuf = '\0'; - if (u.usteed) { - if ((trflags & RECURSIVETRAP) != 0) - Sprintf(verbbuf, "and %s fall", - x_monnam(u.usteed, steed_article, (char *) 0, - SUPPRESS_SADDLE, FALSE)); - else - Sprintf(verbbuf, "lead %s", - x_monnam(u.usteed, steed_article, "poor", - SUPPRESS_SADDLE, FALSE)); - } else if (conj_pit) { - You("move into an adjacent pit."); - } else if (adj_pit) { - You("stumble over debris%s.", - !rn2(5) ? " between the pits" : ""); - } else { - Strcpy(verbbuf, - !plunged ? "fall" : (Flying ? "dive" : "plunge")); + *verbbuf = '\0'; + if (u.usteed) { + if ((trflags & RECURSIVETRAP) != 0) + Sprintf(verbbuf, "and %s fall", + x_monnam(u.usteed, steed_article, (char *) 0, + SUPPRESS_SADDLE, FALSE)); + else + Sprintf(verbbuf, "lead %s", + x_monnam(u.usteed, steed_article, "poor", + SUPPRESS_SADDLE, FALSE)); + } else if (conj_pit) { + You("move into an adjacent pit."); + } else if (adj_pit) { + You("stumble over debris%s.", + !rn2(5) ? " between the pits" : ""); + } else { + Strcpy(verbbuf, + !plunged ? "fall" : (Flying ? "dive" : "plunge")); + } + if (*verbbuf) + You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]); + } + /* wumpus reference */ + if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once + && In_quest(&u.uz) && Is_qlocate(&u.uz)) { + pline("Fortunately it has a bottom after all..."); + trap->once = 1; + } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) { + pline("How pitiful. Isn't that the pits?"); } - if (*verbbuf) - You("%s into %s pit!", verbbuf, a_your[trap->madeby_u]); - } - /* wumpus reference */ - if (Role_if(PM_RANGER) && !trap->madeby_u && !trap->once - && In_quest(&u.uz) && Is_qlocate(&u.uz)) { - pline("Fortunately it has a bottom after all..."); - trap->once = 1; - } else if (u.umonnum == PM_PIT_VIPER || u.umonnum == PM_PIT_FIEND) { - pline("How pitiful. Isn't that the pits?"); - } - if (ttype == SPIKED_PIT) { - const char *predicament = "on a set of sharp iron spikes"; - - if (u.usteed) { - pline("%s %s %s!", - upstart(x_monnam(u.usteed, steed_article, "poor", - SUPPRESS_SADDLE, FALSE)), - conj_pit ? "steps" : "lands", predicament); - } else - You("%s %s!", conj_pit ? "step" : "land", predicament); - } - /* FIXME: - * if hero gets killed here, setting u.utrap in advance will - * show "you were trapped in a pit" during disclosure's display - * of enlightenment, but hero is dying *before* becoming trapped. - */ - set_utrap((unsigned) rn1(6, 2), TT_PIT); - if (!steedintrap(trap, (struct obj *) 0)) { if (ttype == SPIKED_PIT) { - oldumort = u.umortality; - losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)), - /* note: these don't need locomotion() handling; - if fatal while poly'd and Unchanging, the - death reason will be overridden with - "killed while stuck in creature form" */ - plunged - ? "deliberately plunged into a pit of iron spikes" - : conj_pit - ? "stepped into a pit of iron spikes" - : adj_pit - ? "stumbled into a pit of iron spikes" - : "fell into a pit of iron spikes", - NO_KILLER_PREFIX); - if (!rn2(6)) - poisoned("spikes", A_STR, - (conj_pit || adj_pit) - ? "stepping on poison spikes" - : "fall onto poison spikes", - /* if damage triggered life-saving, - poison is limited to attrib loss */ - (u.umortality > oldumort) ? 0 : 8, FALSE); - } else { - /* plunging flyers take spike damage but not pit damage */ - if (!conj_pit - && !(plunged && (Flying || is_clinger(g.youmonst.data)))) - losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)), - plunged ? "deliberately plunged into a pit" - : "fell into a pit", + const char *predicament = "on a set of sharp iron spikes"; + + if (u.usteed) { + pline("%s %s %s!", + upstart(x_monnam(u.usteed, steed_article, "poor", + SUPPRESS_SADDLE, FALSE)), + conj_pit ? "steps" : "lands", predicament); + } else + You("%s %s!", conj_pit ? "step" : "land", predicament); + } + /* FIXME: + * if hero gets killed here, setting u.utrap in advance will + * show "you were trapped in a pit" during disclosure's display + * of enlightenment, but hero is dying *before* becoming trapped. + */ + set_utrap((unsigned) rn1(6, 2), TT_PIT); + if (!steedintrap(trap, (struct obj *) 0)) { + if (ttype == SPIKED_PIT) { + oldumort = u.umortality; + losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)), + /* note: these don't need locomotion() handling; + if fatal while poly'd and Unchanging, the + death reason will be overridden with + "killed while stuck in creature form" */ + plunged + ? "deliberately plunged into a pit of iron spikes" + : conj_pit + ? "stepped into a pit of iron spikes" + : adj_pit + ? "stumbled into a pit of iron spikes" + : "fell into a pit of iron spikes", NO_KILLER_PREFIX); + if (!rn2(6)) + poisoned("spikes", A_STR, + (conj_pit || adj_pit) + ? "stepping on poison spikes" + : "fall onto poison spikes", + /* if damage triggered life-saving, + poison is limited to attrib loss */ + (u.umortality > oldumort) ? 0 : 8, FALSE); + } else { + /* plunging flyers take spike damage but not pit damage */ + if (!conj_pit + && !(plunged && (Flying || is_clinger(g.youmonst.data)))) + losehp(Maybe_Half_Phys(rnd(adj_pit ? 3 : 6)), + plunged ? "deliberately plunged into a pit" + : "fell into a pit", + NO_KILLER_PREFIX); + } + if (Punished && !carried(uball)) { + unplacebc(); + ballfall(); + placebc(); + } + if (!conj_pit) + selftouch("Falling, you"); + g.vision_full_recalc = 1; /* vision limits change */ + exercise(A_STR, FALSE); + exercise(A_DEX, FALSE); } - if (Punished && !carried(uball)) { - unplacebc(); - ballfall(); - placebc(); + } else { + int tt = trap->ttyp; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean trapkilled = FALSE; + boolean inescapable = (g.force_mintrap + || ((tt == HOLE || tt == PIT) + && Sokoban && !trap->madeby_u)); + struct permonst *mptr = mtmp->data; + const char *fallverb; + + fallverb = "falls"; + if (is_flyer(mptr) || is_floater(mptr) + || (mtmp->wormno && count_wsegs(mtmp) > 5) + || is_clinger(mptr)) { + if (g.force_mintrap && !Sokoban) { + /* openfallingtrap; not inescapable here */ + if (in_sight) { + seetrap(trap); + pline("%s doesn't fall into the pit.", Monnam(mtmp)); + } + return 0; + } + if (!inescapable) + return 0; /* avoids trap */ + fallverb = "is dragged"; /* sokoban pit */ } - if (!conj_pit) - selftouch("Falling, you"); - g.vision_full_recalc = 1; /* vision limits change */ - exercise(A_STR, FALSE); - exercise(A_DEX, FALSE); + if (!passes_walls(mptr)) + mtmp->mtrapped = 1; + if (in_sight) { + pline("%s %s into %s pit!", Monnam(mtmp), fallverb, + a_your[trap->madeby_u]); + if (mptr == &mons[PM_PIT_VIPER] + || mptr == &mons[PM_PIT_FIEND]) + pline("How pitiful. Isn't that the pits?"); + seetrap(trap); + } + mselftouch(mtmp, "Falling, ", FALSE); + if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0, + rnd((tt == PIT) ? 6 : 10), FALSE)) + trapkilled = TRUE; + + return trapkilled ? 2 : mtmp->mtrapped; } + return 0; } static void @@ -2022,7 +2069,7 @@ unsigned trflags; case PIT: case SPIKED_PIT: - trapeffect_pit(trap, trflags); + (void) trapeffect_pit(&g.youmonst, trap, trflags); break; case HOLE: @@ -2742,36 +2789,7 @@ register struct monst *mtmp; break; case PIT: case SPIKED_PIT: - fallverb = "falls"; - if (is_flyer(mptr) || is_floater(mptr) - || (mtmp->wormno && count_wsegs(mtmp) > 5) - || is_clinger(mptr)) { - if (g.force_mintrap && !Sokoban) { - /* openfallingtrap; not inescapable here */ - if (in_sight) { - seetrap(trap); - pline("%s doesn't fall into the pit.", Monnam(mtmp)); - } - break; /* inescapable = FALSE; */ - } - if (!inescapable) - break; /* avoids trap */ - fallverb = "is dragged"; /* sokoban pit */ - } - if (!passes_walls(mptr)) - mtmp->mtrapped = 1; - if (in_sight) { - pline("%s %s into %s pit!", Monnam(mtmp), fallverb, - a_your[trap->madeby_u]); - if (mptr == &mons[PM_PIT_VIPER] - || mptr == &mons[PM_PIT_FIEND]) - pline("How pitiful. Isn't that the pits?"); - seetrap(trap); - } - mselftouch(mtmp, "Falling, ", FALSE); - if (DEADMONSTER(mtmp) || thitm(0, mtmp, (struct obj *) 0, - rnd((tt == PIT) ? 6 : 10), FALSE)) - trapkilled = TRUE; + return trapeffect_pit(mtmp, trap, 0); break; case HOLE: case TRAPDOOR: From 3bd60d6d54c0a014e45b2b3fd72ad6a6b040130d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 17:09:15 +0200 Subject: [PATCH 569/708] Unify holes, level teleport and teleport traps --- src/trap.c | 165 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 94 insertions(+), 71 deletions(-) diff --git a/src/trap.c b/src/trap.c index dcfa4e4ed..3bd8d16bd 100644 --- a/src/trap.c +++ b/src/trap.c @@ -21,9 +21,9 @@ static int FDECL(trapeffect_slp_gas_trap, (struct monst *, struct trap *, unsign static int FDECL(trapeffect_rust_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_fire_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_pit, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_hole, (struct trap *, unsigned)); -static void FDECL(trapeffect_telep_trap, (struct trap *, unsigned)); -static void FDECL(trapeffect_level_telep, (struct trap *, unsigned)); +static int FDECL(trapeffect_hole, (struct monst *, struct trap *, unsigned)); +static int FDECL(trapeffect_telep_trap, (struct monst *, struct trap *, unsigned)); +static int FDECL(trapeffect_level_telep, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_web, (struct trap *, unsigned)); static void FDECL(trapeffect_statue_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_magic_trap, (struct trap *, unsigned)); @@ -1649,36 +1649,104 @@ unsigned trflags; return 0; } -static void -trapeffect_hole(trap, trflags) +static int +trapeffect_hole(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - if (!Can_fall_thru(&u.uz)) { - seetrap(trap); /* normally done in fall_through */ - impossible("dotrap: %ss cannot exist on this level.", - trapname(trap->ttyp, TRUE)); - return; /* don't activate it after all */ + if (mtmp == &g.youmonst) { + if (!Can_fall_thru(&u.uz)) { + seetrap(trap); /* normally done in fall_through */ + impossible("dotrap: %ss cannot exist on this level.", + trapname(trap->ttyp, TRUE)); + return 0; /* don't activate it after all */ + } + fall_through(TRUE, (trflags & TOOKPLUNGE)); + } else { + int tt = trap->ttyp; + struct permonst *mptr = mtmp->data; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean inescapable = (g.force_mintrap + || ((tt == HOLE || tt == PIT) + && Sokoban && !trap->madeby_u)); + + if (!Can_fall_thru(&u.uz)) { + impossible("mintrap: %ss cannot exist on this level.", + trapname(tt, TRUE)); + return 0; /* don't activate it after all */ + } + if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS] + || (mtmp->wormno && count_wsegs(mtmp) > 5) + || mptr->msize >= MZ_HUGE) { + if (g.force_mintrap && !Sokoban) { + /* openfallingtrap; not inescapable here */ + if (in_sight) { + seetrap(trap); + if (tt == TRAPDOOR) + pline( + "A trap door opens, but %s doesn't fall through.", + mon_nam(mtmp)); + else /* (tt == HOLE) */ + pline("%s doesn't fall through the hole.", + Monnam(mtmp)); + } + return 0; /* inescapable = FALSE; */ + } + if (inescapable) { /* sokoban hole */ + if (in_sight) { + pline("%s seems to be yanked down!", Monnam(mtmp)); + /* suppress message in mlevel_tele_trap() */ + in_sight = FALSE; + seetrap(trap); + } + } else + return 0; + } + return trapeffect_level_telep(mtmp, trap, trflags); } - fall_through(TRUE, (trflags & TOOKPLUNGE)); + return 0; } -static void -trapeffect_telep_trap(trap, trflags) +static int +trapeffect_telep_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - seetrap(trap); - tele_trap(trap); + if (mtmp == &g.youmonst) { + seetrap(trap); + tele_trap(trap); + } else { + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + + mtele_trap(mtmp, trap, in_sight); + } + return 0; } -static void -trapeffect_level_telep(trap, trflags) +static int +trapeffect_level_telep(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - seetrap(trap); - level_tele_trap(trap, trflags); + if (mtmp == &g.youmonst) { + seetrap(trap); + level_tele_trap(trap, trflags); + } else { + int mlev_res; + int tt = trap->ttyp; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean inescapable = (g.force_mintrap + || ((tt == HOLE || tt == PIT) + && Sokoban && !trap->madeby_u)); + + mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight); + if (mlev_res) + return mlev_res; + } + return 0; } static void @@ -2074,15 +2142,15 @@ unsigned trflags; case HOLE: case TRAPDOOR: - trapeffect_hole(trap, trflags); + (void) trapeffect_hole(&g.youmonst, trap, trflags); break; case TELEP_TRAP: - trapeffect_telep_trap(trap, trflags); + (void) trapeffect_telep_trap(&g.youmonst, trap, trflags); break; case LEVEL_TELEP: - trapeffect_level_telep(trap, trflags); + (void) trapeffect_level_telep(&g.youmonst, trap, trflags); break; case WEB: /* Our luckless player has stumbled into a web. */ @@ -2773,71 +2841,26 @@ register struct monst *mtmp; return trapeffect_rocktrap(mtmp, trap, 0); case SQKY_BOARD: return trapeffect_sqky_board(mtmp, trap, 0); - break; case BEAR_TRAP: return trapeffect_bear_trap(mtmp, trap, 0); - break; case SLP_GAS_TRAP: return trapeffect_slp_gas_trap(mtmp, trap, 0); - break; case RUST_TRAP: return trapeffect_rust_trap(mtmp, trap, 0); - break; case FIRE_TRAP: mfiretrap: return trapeffect_fire_trap(mtmp, trap, 0); - break; case PIT: case SPIKED_PIT: return trapeffect_pit(mtmp, trap, 0); - break; case HOLE: case TRAPDOOR: - if (!Can_fall_thru(&u.uz)) { - impossible("mintrap: %ss cannot exist on this level.", - trapname(tt, TRUE)); - break; /* don't activate it after all */ - } - if (is_flyer(mptr) || is_floater(mptr) || mptr == &mons[PM_WUMPUS] - || (mtmp->wormno && count_wsegs(mtmp) > 5) - || mptr->msize >= MZ_HUGE) { - if (g.force_mintrap && !Sokoban) { - /* openfallingtrap; not inescapable here */ - if (in_sight) { - seetrap(trap); - if (tt == TRAPDOOR) - pline( - "A trap door opens, but %s doesn't fall through.", - mon_nam(mtmp)); - else /* (tt == HOLE) */ - pline("%s doesn't fall through the hole.", - Monnam(mtmp)); - } - break; /* inescapable = FALSE; */ - } - if (inescapable) { /* sokoban hole */ - if (in_sight) { - pline("%s seems to be yanked down!", Monnam(mtmp)); - /* suppress message in mlevel_tele_trap() */ - in_sight = FALSE; - seetrap(trap); - } - } else - break; - } - /*FALLTHRU*/ + return trapeffect_hole(mtmp, trap, 0); case LEVEL_TELEP: - case MAGIC_PORTAL: { - int mlev_res; - - mlev_res = mlevel_tele_trap(mtmp, trap, inescapable, in_sight); - if (mlev_res) - return mlev_res; - break; - } + case MAGIC_PORTAL: + return trapeffect_level_telep(mtmp, trap, 0); case TELEP_TRAP: - mtele_trap(mtmp, trap, in_sight); - break; + return trapeffect_telep_trap(mtmp, trap, 0); case WEB: /* Monster in a web. */ if (webmaker(mptr)) From eb58352860bb0f41948a778165aebce0adb9f1dd Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 17:17:22 +0200 Subject: [PATCH 570/708] Unify webs --- src/trap.c | 304 +++++++++++++++++++++++++++-------------------------- 1 file changed, 157 insertions(+), 147 deletions(-) diff --git a/src/trap.c b/src/trap.c index 3bd8d16bd..334e616a8 100644 --- a/src/trap.c +++ b/src/trap.c @@ -24,7 +24,7 @@ static int FDECL(trapeffect_pit, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_hole, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_telep_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_level_telep, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_web, (struct trap *, unsigned)); +static int FDECL(trapeffect_web, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_statue_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_magic_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_anti_magic, (struct trap *, unsigned)); @@ -1749,99 +1749,167 @@ unsigned trflags; return 0; } -static void -trapeffect_web(trap, trflags) +static int +trapeffect_web(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - boolean webmsgok = (trflags & NOWEBMSG) == 0; - boolean forcetrap = ((trflags & FORCETRAP) != 0 - || (trflags & FAILEDUNTRAP) != 0); - boolean viasitting = (trflags & VIASITTING) != 0; - int steed_article = ARTICLE_THE; + if (mtmp == &g.youmonst) { + boolean webmsgok = (trflags & NOWEBMSG) == 0; + boolean forcetrap = ((trflags & FORCETRAP) != 0 + || (trflags & FAILEDUNTRAP) != 0); + boolean viasitting = (trflags & VIASITTING) != 0; + int steed_article = ARTICLE_THE; - feeltrap(trap); - if (mu_maybe_destroy_web(&g.youmonst, webmsgok, trap)) - return; - if (webmaker(g.youmonst.data)) { - if (webmsgok) - pline(trap->madeby_u ? "You take a walk on your web." - : "There is a spider web here."); - return; - } - if (webmsgok) { - char verbbuf[BUFSZ]; - - if (forcetrap || viasitting) { - Strcpy(verbbuf, "are caught by"); - } else if (u.usteed) { - Sprintf(verbbuf, "lead %s into", - x_monnam(u.usteed, steed_article, "poor", - SUPPRESS_SADDLE, FALSE)); - } else { - Sprintf(verbbuf, "%s into", - Levitation ? (const char *) "float" - : locomotion(g.youmonst.data, "stumble")); - } - You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]); - } - - /* time will be adjusted below */ - set_utrap(1, TT_WEB); - - /* Time stuck in the web depends on your/steed strength. */ - { - int tim, str = ACURR(A_STR); - - /* If mounted, the steed gets trapped. Use mintrap - * to do all the work. If mtrapped is set as a result, - * unset it and set utrap instead. In the case of a - * strongmonst and mintrap said it's trapped, use a - * short but non-zero trap time. Otherwise, monsters - * have no specific strength, so use player strength. - * This gets skipped for webmsgok, which implies that - * the steed isn't a factor. - */ - if (u.usteed && webmsgok) { - /* mtmp location might not be up to date */ - u.usteed->mx = u.ux; - u.usteed->my = u.uy; - - /* mintrap currently does not return 2(died) for webs */ - if (mintrap(u.usteed)) { - u.usteed->mtrapped = 0; - if (strongmonst(u.usteed->data)) - str = 17; - } else { - reset_utrap(FALSE); - return; - } - - webmsgok = FALSE; /* mintrap printed the messages */ - } - if (str <= 3) - tim = rn1(6, 6); - else if (str < 6) - tim = rn1(6, 4); - else if (str < 9) - tim = rn1(4, 4); - else if (str < 12) - tim = rn1(4, 2); - else if (str < 15) - tim = rn1(2, 2); - else if (str < 18) - tim = rnd(2); - else if (str < 69) - tim = 1; - else { - tim = 0; + feeltrap(trap); + if (mu_maybe_destroy_web(&g.youmonst, webmsgok, trap)) + return 0; + if (webmaker(g.youmonst.data)) { if (webmsgok) - You("tear through %s web!", a_your[trap->madeby_u]); - deltrap(trap); - newsym(u.ux, u.uy); /* get rid of trap symbol */ + pline(trap->madeby_u ? "You take a walk on your web." + : "There is a spider web here."); + return 0; } - set_utrap((unsigned) tim, TT_WEB); + if (webmsgok) { + char verbbuf[BUFSZ]; + + if (forcetrap || viasitting) { + Strcpy(verbbuf, "are caught by"); + } else if (u.usteed) { + Sprintf(verbbuf, "lead %s into", + x_monnam(u.usteed, steed_article, "poor", + SUPPRESS_SADDLE, FALSE)); + } else { + Sprintf(verbbuf, "%s into", + Levitation ? (const char *) "float" + : locomotion(g.youmonst.data, "stumble")); + } + You("%s %s spider web!", verbbuf, a_your[trap->madeby_u]); + } + + /* time will be adjusted below */ + set_utrap(1, TT_WEB); + + /* Time stuck in the web depends on your/steed strength. */ + { + int tim, str = ACURR(A_STR); + + /* If mounted, the steed gets trapped. Use mintrap + * to do all the work. If mtrapped is set as a result, + * unset it and set utrap instead. In the case of a + * strongmonst and mintrap said it's trapped, use a + * short but non-zero trap time. Otherwise, monsters + * have no specific strength, so use player strength. + * This gets skipped for webmsgok, which implies that + * the steed isn't a factor. + */ + if (u.usteed && webmsgok) { + /* mtmp location might not be up to date */ + u.usteed->mx = u.ux; + u.usteed->my = u.uy; + + /* mintrap currently does not return 2(died) for webs */ + if (mintrap(u.usteed)) { + u.usteed->mtrapped = 0; + if (strongmonst(u.usteed->data)) + str = 17; + } else { + reset_utrap(FALSE); + return 0; + } + + webmsgok = FALSE; /* mintrap printed the messages */ + } + if (str <= 3) + tim = rn1(6, 6); + else if (str < 6) + tim = rn1(6, 4); + else if (str < 9) + tim = rn1(4, 4); + else if (str < 12) + tim = rn1(4, 2); + else if (str < 15) + tim = rn1(2, 2); + else if (str < 18) + tim = rnd(2); + else if (str < 69) + tim = 1; + else { + tim = 0; + if (webmsgok) + You("tear through %s web!", a_your[trap->madeby_u]); + deltrap(trap); + newsym(u.ux, u.uy); /* get rid of trap symbol */ + } + set_utrap((unsigned) tim, TT_WEB); + } + } else { + /* Monster in a web. */ + boolean tear_web; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + struct permonst *mptr = mtmp->data; + + if (webmaker(mptr)) + return 0; + if (mu_maybe_destroy_web(mtmp, in_sight, trap)) + return 0; + tear_web = FALSE; + switch (monsndx(mptr)) { + case PM_OWLBEAR: /* Eric Backus */ + case PM_BUGBEAR: + if (!in_sight) { + You_hear("the roaring of a confused bear!"); + mtmp->mtrapped = 1; + break; + } + /*FALLTHRU*/ + default: + if (mptr->mlet == S_GIANT + /* exclude baby dragons and relatively short worms */ + || (mptr->mlet == S_DRAGON && extra_nasty(mptr)) + || (mtmp->wormno && count_wsegs(mtmp) > 5)) { + tear_web = TRUE; + } else if (in_sight) { + pline("%s is caught in %s spider web.", Monnam(mtmp), + a_your[trap->madeby_u]); + seetrap(trap); + } + mtmp->mtrapped = tear_web ? 0 : 1; + break; + /* this list is fairly arbitrary; it deliberately + excludes wumpus & giant/ettin zombies/mummies */ + case PM_TITANOTHERE: + case PM_BALUCHITHERIUM: + case PM_PURPLE_WORM: + case PM_JABBERWOCK: + case PM_IRON_GOLEM: + case PM_BALROG: + case PM_KRAKEN: + case PM_MASTODON: + case PM_ORION: + case PM_NORN: + case PM_CYCLOPS: + case PM_LORD_SURTUR: + tear_web = TRUE; + break; + } + if (tear_web) { + if (in_sight) + pline("%s tears through %s spider web!", Monnam(mtmp), + a_your[trap->madeby_u]); + deltrap(trap); + newsym(mtmp->mx, mtmp->my); + } else if (g.force_mintrap && !mtmp->mtrapped) { + if (in_sight) { + pline("%s avoids %s spider web!", Monnam(mtmp), + a_your[trap->madeby_u]); + seetrap(trap); + } + } + return mtmp->mtrapped; } + return 0; } static void @@ -2154,7 +2222,7 @@ unsigned trflags; break; case WEB: /* Our luckless player has stumbled into a web. */ - trapeffect_web(trap, trflags); + (void) trapeffect_web(&g.youmonst, trap, trflags); break; case STATUE_TRAP: @@ -2862,65 +2930,7 @@ register struct monst *mtmp; case TELEP_TRAP: return trapeffect_telep_trap(mtmp, trap, 0); case WEB: - /* Monster in a web. */ - if (webmaker(mptr)) - break; - if (mu_maybe_destroy_web(mtmp, in_sight, trap)) - break; - tear_web = FALSE; - switch (monsndx(mptr)) { - case PM_OWLBEAR: /* Eric Backus */ - case PM_BUGBEAR: - if (!in_sight) { - You_hear("the roaring of a confused bear!"); - mtmp->mtrapped = 1; - break; - } - /*FALLTHRU*/ - default: - if (mptr->mlet == S_GIANT - /* exclude baby dragons and relatively short worms */ - || (mptr->mlet == S_DRAGON && extra_nasty(mptr)) - || (mtmp->wormno && count_wsegs(mtmp) > 5)) { - tear_web = TRUE; - } else if (in_sight) { - pline("%s is caught in %s spider web.", Monnam(mtmp), - a_your[trap->madeby_u]); - seetrap(trap); - } - mtmp->mtrapped = tear_web ? 0 : 1; - break; - /* this list is fairly arbitrary; it deliberately - excludes wumpus & giant/ettin zombies/mummies */ - case PM_TITANOTHERE: - case PM_BALUCHITHERIUM: - case PM_PURPLE_WORM: - case PM_JABBERWOCK: - case PM_IRON_GOLEM: - case PM_BALROG: - case PM_KRAKEN: - case PM_MASTODON: - case PM_ORION: - case PM_NORN: - case PM_CYCLOPS: - case PM_LORD_SURTUR: - tear_web = TRUE; - break; - } - if (tear_web) { - if (in_sight) - pline("%s tears through %s spider web!", Monnam(mtmp), - a_your[trap->madeby_u]); - deltrap(trap); - newsym(mtmp->mx, mtmp->my); - } else if (g.force_mintrap && !mtmp->mtrapped) { - if (in_sight) { - pline("%s avoids %s spider web!", Monnam(mtmp), - a_your[trap->madeby_u]); - seetrap(trap); - } - } - break; + return trapeffect_web(mtmp, trap, 0); case STATUE_TRAP: break; case MAGIC_TRAP: From c15d0625021fd7f582384c846c971fb0fcbb0161 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 17:35:14 +0200 Subject: [PATCH 571/708] Unify statue traps --- src/trap.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/trap.c b/src/trap.c index 334e616a8..9985fa3b4 100644 --- a/src/trap.c +++ b/src/trap.c @@ -25,7 +25,7 @@ static int FDECL(trapeffect_hole, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_telep_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_level_telep, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_web, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_statue_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_statue_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_magic_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_anti_magic, (struct trap *, unsigned)); static void FDECL(trapeffect_poly_trap, (struct trap *, unsigned)); @@ -1912,12 +1912,18 @@ unsigned trflags; return 0; } -static void -trapeffect_statue_trap(trap, trflags) +static int +trapeffect_statue_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); + if (mtmp == &g.youmonst) { + (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); + } else { + /* monsters don't trigger statue traps */ + } + return 0; } static void @@ -2226,7 +2232,7 @@ unsigned trflags; break; case STATUE_TRAP: - trapeffect_statue_trap(trap, trflags); + (void) trapeffect_statue_trap(&g.youmonst, trap, trflags); break; case MAGIC_TRAP: /* A magic trap. */ @@ -2932,7 +2938,7 @@ register struct monst *mtmp; case WEB: return trapeffect_web(mtmp, trap, 0); case STATUE_TRAP: - break; + return trapeffect_statue_trap(mtmp, trap, 0); case MAGIC_TRAP: /* A magic trap. Monsters usually immune. */ if (!rn2(21)) From ed3a736bd8b71278d18b8c403e3f593c6a0ec499 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 17:38:25 +0200 Subject: [PATCH 572/708] Unify fire traps --- src/trap.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/trap.c b/src/trap.c index 9985fa3b4..94496148a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -26,7 +26,7 @@ static int FDECL(trapeffect_telep_trap, (struct monst *, struct trap *, unsigned static int FDECL(trapeffect_level_telep, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_web, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_statue_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_magic_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_magic_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_anti_magic, (struct trap *, unsigned)); static void FDECL(trapeffect_poly_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_landmine, (struct trap *, unsigned)); @@ -1926,24 +1926,32 @@ unsigned trflags; return 0; } -static void -trapeffect_magic_trap(trap, trflags) +static int +trapeffect_magic_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - seetrap(trap); - if (!rn2(30)) { - deltrap(trap); - newsym(u.ux, u.uy); /* update position */ - You("are caught in a magical explosion!"); - losehp(rnd(10), "magical explosion", KILLED_BY_AN); - Your("body absorbs some of the magical energy!"); - u.uen = (u.uenmax += 2); - return; + if (mtmp == &g.youmonst) { + seetrap(trap); + if (!rn2(30)) { + deltrap(trap); + newsym(u.ux, u.uy); /* update position */ + You("are caught in a magical explosion!"); + losehp(rnd(10), "magical explosion", KILLED_BY_AN); + Your("body absorbs some of the magical energy!"); + u.uen = (u.uenmax += 2); + return 0; + } else { + domagictrap(); + } + (void) steedintrap(trap, (struct obj *) 0); } else { - domagictrap(); + /* A magic trap. Monsters usually immune. */ + if (!rn2(21)) + return trapeffect_fire_trap(mtmp, trap, trflags); } - (void) steedintrap(trap, (struct obj *) 0); + return 0; } static void @@ -2236,7 +2244,7 @@ unsigned trflags; break; case MAGIC_TRAP: /* A magic trap. */ - trapeffect_magic_trap(trap, trflags); + (void) trapeffect_magic_trap(&g.youmonst, trap, trflags); break; case ANTI_MAGIC: @@ -2940,9 +2948,7 @@ register struct monst *mtmp; case STATUE_TRAP: return trapeffect_statue_trap(mtmp, trap, 0); case MAGIC_TRAP: - /* A magic trap. Monsters usually immune. */ - if (!rn2(21)) - goto mfiretrap; + return trapeffect_statue_trap(mtmp, trap, 0); break; case ANTI_MAGIC: /* similar to hero's case, more or less */ From 6eb89c6b44c2aaef02197d872ff1cba03eedf59e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 17:55:06 +0200 Subject: [PATCH 573/708] Unify anti magic traps --- src/trap.c | 161 +++++++++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 74 deletions(-) diff --git a/src/trap.c b/src/trap.c index 94496148a..a7edb3ee9 100644 --- a/src/trap.c +++ b/src/trap.c @@ -27,7 +27,7 @@ static int FDECL(trapeffect_level_telep, (struct monst *, struct trap *, unsigne static int FDECL(trapeffect_web, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_statue_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_magic_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_anti_magic, (struct trap *, unsigned)); +static int FDECL(trapeffect_anti_magic, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_poly_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_landmine, (struct trap *, unsigned)); static void FDECL(trapeffect_rolling_boulder_trap, (struct trap *, unsigned)); @@ -1954,46 +1954,97 @@ unsigned trflags; return 0; } -static void -trapeffect_anti_magic(trap, trflags) +static int +trapeffect_anti_magic(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - seetrap(trap); - /* hero without magic resistance loses spell energy, - hero with magic resistance takes damage instead; - possibly non-intuitive but useful for play balance */ - if (!Antimagic) { - drain_en(rnd(u.ulevel) + 1); + if (mtmp == &g.youmonst) { + seetrap(trap); + /* hero without magic resistance loses spell energy, + hero with magic resistance takes damage instead; + possibly non-intuitive but useful for play balance */ + if (!Antimagic) { + drain_en(rnd(u.ulevel) + 1); + } else { + struct obj *otmp; + int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp; + + /* Half_XXX_damage has opposite its usual effect (approx) + but isn't cumulative if hero has more than one */ + if (Half_physical_damage || Half_spell_damage) + dmgval2 += rnd(4); + /* give Magicbane wielder dose of own medicine */ + if (uwep && uwep->oartifact == ART_MAGICBANE) + dmgval2 += rnd(4); + /* having an artifact--other than own quest one--which + confers magic resistance simply by being carried + also increases the effect */ + for (otmp = g.invent; otmp; otmp = otmp->nobj) + if (otmp->oartifact && !is_quest_artifact(otmp) + && defends_when_carried(AD_MAGM, otmp)) + break; + if (otmp) + dmgval2 += rnd(4); + if (Passes_walls) + dmgval2 = (dmgval2 + 3) / 4; + + You_feel((dmgval2 >= hp) ? "unbearably torpid!" + : (dmgval2 >= hp / 4) ? "very lethargic." + : "sluggish."); + /* opposite of magical explosion */ + losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN); + } } else { - struct obj *otmp; - int dmgval2 = rnd(4), hp = Upolyd ? u.mh : u.uhp; + boolean trapkilled = FALSE; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean see_it = cansee(mtmp->mx, mtmp->my); + struct permonst *mptr = mtmp->data; - /* Half_XXX_damage has opposite its usual effect (approx) - but isn't cumulative if hero has more than one */ - if (Half_physical_damage || Half_spell_damage) - dmgval2 += rnd(4); - /* give Magicbane wielder dose of own medicine */ - if (uwep && uwep->oartifact == ART_MAGICBANE) - dmgval2 += rnd(4); - /* having an artifact--other than own quest one--which - confers magic resistance simply by being carried - also increases the effect */ - for (otmp = g.invent; otmp; otmp = otmp->nobj) - if (otmp->oartifact && !is_quest_artifact(otmp) - && defends_when_carried(AD_MAGM, otmp)) - break; - if (otmp) - dmgval2 += rnd(4); - if (Passes_walls) - dmgval2 = (dmgval2 + 3) / 4; + /* similar to hero's case, more or less */ + if (!resists_magm(mtmp)) { /* lose spell energy */ + if (!mtmp->mcan && (attacktype(mptr, AT_MAGC) + || attacktype(mptr, AT_BREA))) { + mtmp->mspec_used += d(2, 2); + if (in_sight) { + seetrap(trap); + pline("%s seems lethargic.", Monnam(mtmp)); + } + } + } else { /* take some damage */ + struct obj *otmp; + int dmgval2 = rnd(4); - You_feel((dmgval2 >= hp) ? "unbearably torpid!" - : (dmgval2 >= hp / 4) ? "very lethargic." - : "sluggish."); - /* opposite of magical explosion */ - losehp(dmgval2, "anti-magic implosion", KILLED_BY_AN); + if ((otmp = MON_WEP(mtmp)) != 0 + && otmp->oartifact == ART_MAGICBANE) + dmgval2 += rnd(4); + for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) + if (otmp->oartifact + && defends_when_carried(AD_MAGM, otmp)) + break; + if (otmp) + dmgval2 += rnd(4); + if (passes_walls(mptr)) + dmgval2 = (dmgval2 + 3) / 4; + + if (in_sight) + seetrap(trap); + mtmp->mhp -= dmgval2; + if (DEADMONSTER(mtmp)) + monkilled(mtmp, + in_sight + ? "compression from an anti-magic field" + : (const char *) 0, + -AD_MAGM); + if (DEADMONSTER(mtmp)) + trapkilled = TRUE; + if (see_it) + newsym(trap->tx, trap->ty); + } + return trapkilled ? 2 : mtmp->mtrapped; } + return 0; } static void @@ -2248,7 +2299,7 @@ unsigned trflags; break; case ANTI_MAGIC: - trapeffect_anti_magic(trap, trflags); + (void) trapeffect_anti_magic(&g.youmonst, trap, trflags); break; case POLY_TRAP: @@ -2951,45 +3002,7 @@ register struct monst *mtmp; return trapeffect_statue_trap(mtmp, trap, 0); break; case ANTI_MAGIC: - /* similar to hero's case, more or less */ - if (!resists_magm(mtmp)) { /* lose spell energy */ - if (!mtmp->mcan && (attacktype(mptr, AT_MAGC) - || attacktype(mptr, AT_BREA))) { - mtmp->mspec_used += d(2, 2); - if (in_sight) { - seetrap(trap); - pline("%s seems lethargic.", Monnam(mtmp)); - } - } - } else { /* take some damage */ - int dmgval2 = rnd(4); - - if ((otmp = MON_WEP(mtmp)) != 0 - && otmp->oartifact == ART_MAGICBANE) - dmgval2 += rnd(4); - for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj) - if (otmp->oartifact - && defends_when_carried(AD_MAGM, otmp)) - break; - if (otmp) - dmgval2 += rnd(4); - if (passes_walls(mptr)) - dmgval2 = (dmgval2 + 3) / 4; - - if (in_sight) - seetrap(trap); - mtmp->mhp -= dmgval2; - if (DEADMONSTER(mtmp)) - monkilled(mtmp, - in_sight - ? "compression from an anti-magic field" - : (const char *) 0, - -AD_MAGM); - if (DEADMONSTER(mtmp)) - trapkilled = TRUE; - if (see_it) - newsym(trap->tx, trap->ty); - } + return trapeffect_anti_magic(mtmp, trap, 0); break; case LANDMINE: if (rn2(3)) From 5dcd6b2e17ebb49effeb6898fa9205efe76a488f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 17:58:48 +0200 Subject: [PATCH 574/708] Unify polymorph traps --- src/trap.c | 80 +++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/trap.c b/src/trap.c index a7edb3ee9..f711accd0 100644 --- a/src/trap.c +++ b/src/trap.c @@ -28,7 +28,7 @@ static int FDECL(trapeffect_web, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_statue_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_magic_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_anti_magic, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_poly_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_poly_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_landmine, (struct trap *, unsigned)); static void FDECL(trapeffect_rolling_boulder_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_magic_portal, (struct trap *, unsigned)); @@ -2047,38 +2047,52 @@ unsigned trflags; return 0; } -static void -trapeffect_poly_trap(trap, trflags) +static int +trapeffect_poly_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - boolean viasitting = (trflags & VIASITTING) != 0; - int steed_article = ARTICLE_THE; - char verbbuf[BUFSZ]; + if (mtmp == &g.youmonst) { + boolean viasitting = (trflags & VIASITTING) != 0; + int steed_article = ARTICLE_THE; + char verbbuf[BUFSZ]; - seetrap(trap); - if (viasitting) - Strcpy(verbbuf, "trigger"); /* follows "You sit down." */ - else if (u.usteed) - Sprintf(verbbuf, "lead %s onto", - x_monnam(u.usteed, steed_article, (char *) 0, - SUPPRESS_SADDLE, FALSE)); - else - Sprintf(verbbuf, "%s onto", - Levitation ? (const char *) "float" - : locomotion(g.youmonst.data, "step")); - You("%s a polymorph trap!", verbbuf); - if (Antimagic || Unchanging) { - shieldeff(u.ux, u.uy); - You_feel("momentarily different."); - /* Trap did nothing; don't remove it --KAA */ + seetrap(trap); + if (viasitting) + Strcpy(verbbuf, "trigger"); /* follows "You sit down." */ + else if (u.usteed) + Sprintf(verbbuf, "lead %s onto", + x_monnam(u.usteed, steed_article, (char *) 0, + SUPPRESS_SADDLE, FALSE)); + else + Sprintf(verbbuf, "%s onto", + Levitation ? (const char *) "float" + : locomotion(g.youmonst.data, "step")); + You("%s a polymorph trap!", verbbuf); + if (Antimagic || Unchanging) { + shieldeff(u.ux, u.uy); + You_feel("momentarily different."); + /* Trap did nothing; don't remove it --KAA */ + } else { + (void) steedintrap(trap, (struct obj *) 0); + deltrap(trap); /* delete trap before polymorph */ + newsym(u.ux, u.uy); /* get rid of trap symbol */ + You_feel("a change coming over you."); + polyself(0); + } } else { - (void) steedintrap(trap, (struct obj *) 0); - deltrap(trap); /* delete trap before polymorph */ - newsym(u.ux, u.uy); /* get rid of trap symbol */ - You_feel("a change coming over you."); - polyself(0); + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + + if (resists_magm(mtmp)) { + shieldeff(mtmp->mx, mtmp->my); + } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { + (void) newcham(mtmp, (struct permonst *) 0, FALSE, FALSE); + if (in_sight) + seetrap(trap); + } } + return 0; } static void @@ -2303,7 +2317,7 @@ unsigned trflags; break; case POLY_TRAP: - trapeffect_poly_trap(trap, trflags); + (void) trapeffect_poly_trap(&g.youmonst, trap, trflags); break; case LANDMINE: @@ -3052,15 +3066,7 @@ register struct monst *mtmp; } break; case POLY_TRAP: - if (resists_magm(mtmp)) { - shieldeff(mtmp->mx, mtmp->my); - } else if (!resist(mtmp, WAND_CLASS, 0, NOTELL)) { - if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE)) - /* we're done with mptr but keep it up to date */ - mptr = mtmp->data; - if (in_sight) - seetrap(trap); - } + return trapeffect_poly_trap(mtmp, trap, 0); break; case ROLLING_BOULDER_TRAP: if (!is_flyer(mptr)) { From 97a9bcf9c531ae939919aa0368e72dfc94f0a8a5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:03:06 +0200 Subject: [PATCH 575/708] Unify landmines --- src/trap.c | 206 ++++++++++++++++++++++++++++------------------------- 1 file changed, 109 insertions(+), 97 deletions(-) diff --git a/src/trap.c b/src/trap.c index f711accd0..e3842b228 100644 --- a/src/trap.c +++ b/src/trap.c @@ -29,7 +29,7 @@ static int FDECL(trapeffect_statue_trap, (struct monst *, struct trap *, unsigne static int FDECL(trapeffect_magic_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_anti_magic, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_poly_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_landmine, (struct trap *, unsigned)); +static int FDECL(trapeffect_landmine, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_rolling_boulder_trap, (struct trap *, unsigned)); static void FDECL(trapeffect_magic_portal, (struct trap *, unsigned)); static char *FDECL(trapnote, (struct trap *, BOOLEAN_P)); @@ -2095,63 +2095,119 @@ unsigned trflags; return 0; } -static void -trapeffect_landmine(trap, trflags) +static int +trapeffect_landmine(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - boolean already_seen = trap->tseen; - boolean forcetrap = ((trflags & FORCETRAP) != 0 - || (trflags & FAILEDUNTRAP) != 0); - boolean forcebungle = (trflags & FORCEBUNGLE) != 0; - unsigned steed_mid = 0; - struct obj *saddle = 0; + if (mtmp == &g.youmonst) { + boolean already_seen = trap->tseen; + boolean forcetrap = ((trflags & FORCETRAP) != 0 + || (trflags & FAILEDUNTRAP) != 0); + boolean forcebungle = (trflags & FORCEBUNGLE) != 0; + unsigned steed_mid = 0; + struct obj *saddle = 0; - if ((Levitation || Flying) && !forcetrap) { - if (!already_seen && rn2(3)) - return; - feeltrap(trap); - pline("%s %s in a pile of soil below you.", - already_seen ? "There is" : "You discover", - trap->madeby_u ? "the trigger of your mine" : "a trigger"); - if (already_seen && rn2(3)) - return; - pline("KAABLAMM!!! %s %s%s off!", - forcebungle ? "Your inept attempt sets" - : "The air currents set", - already_seen ? a_your[trap->madeby_u] : "", - already_seen ? " land mine" : "it"); + if ((Levitation || Flying) && !forcetrap) { + if (!already_seen && rn2(3)) + return 0; + feeltrap(trap); + pline("%s %s in a pile of soil below you.", + already_seen ? "There is" : "You discover", + trap->madeby_u ? "the trigger of your mine" : "a trigger"); + if (already_seen && rn2(3)) + return 0; + pline("KAABLAMM!!! %s %s%s off!", + forcebungle ? "Your inept attempt sets" + : "The air currents set", + already_seen ? a_your[trap->madeby_u] : "", + already_seen ? " land mine" : "it"); + } else { + /* prevent landmine from killing steed, throwing you to + * the ground, and you being affected again by the same + * mine because it hasn't been deleted yet + */ + static boolean recursive_mine = FALSE; + + if (recursive_mine) + return 0; + feeltrap(trap); + pline("KAABLAMM!!! You triggered %s land mine!", + a_your[trap->madeby_u]); + if (u.usteed) + steed_mid = u.usteed->m_id; + recursive_mine = TRUE; + (void) steedintrap(trap, (struct obj *) 0); + recursive_mine = FALSE; + saddle = sobj_at(SADDLE, u.ux, u.uy); + set_wounded_legs(LEFT_SIDE, rn1(35, 41)); + set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); + exercise(A_DEX, FALSE); + } + blow_up_landmine(trap); + if (steed_mid && saddle && !u.usteed) + (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle); + newsym(u.ux, u.uy); /* update trap symbol */ + losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN); + /* fall recursively into the pit... */ + if ((trap = t_at(u.ux, u.uy)) != 0) + dotrap(trap, RECURSIVETRAP); + fill_pit(u.ux, u.uy); } else { - /* prevent landmine from killing steed, throwing you to - * the ground, and you being affected again by the same - * mine because it hasn't been deleted yet - */ - static boolean recursive_mine = FALSE; + boolean trapkilled = FALSE; + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + struct permonst *mptr = mtmp->data; + xchar tx = trap->tx, ty = trap->ty; - if (recursive_mine) - return; - feeltrap(trap); - pline("KAABLAMM!!! You triggered %s land mine!", - a_your[trap->madeby_u]); - if (u.usteed) - steed_mid = u.usteed->m_id; - recursive_mine = TRUE; - (void) steedintrap(trap, (struct obj *) 0); - recursive_mine = FALSE; - saddle = sobj_at(SADDLE, u.ux, u.uy); - set_wounded_legs(LEFT_SIDE, rn1(35, 41)); - set_wounded_legs(RIGHT_SIDE, rn1(35, 41)); - exercise(A_DEX, FALSE); + if (rn2(3)) + return 0; /* monsters usually don't set it off */ + if (is_flyer(mptr)) { + boolean already_seen = trap->tseen; + + if (in_sight && !already_seen) { + pline("A trigger appears in a pile of soil below %s.", + mon_nam(mtmp)); + seetrap(trap); + } + if (rn2(3)) + return 0; + if (in_sight) { + newsym(mtmp->mx, mtmp->my); + pline_The("air currents set %s off!", + already_seen ? "a land mine" : "it"); + } + } else if (in_sight) { + newsym(mtmp->mx, mtmp->my); + pline("%s%s triggers %s land mine!", + !Deaf ? "KAABLAMM!!! " : "", Monnam(mtmp), + a_your[trap->madeby_u]); + } + if (!in_sight && !Deaf) + pline("Kaablamm! %s an explosion in the distance!", + "You hear"); /* Deaf-aware */ + blow_up_landmine(trap); + /* explosion might have destroyed a drawbridge; don't + dish out more damage if monster is already dead */ + if (DEADMONSTER(mtmp) + || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) { + trapkilled = TRUE; + } else { + /* monsters recursively fall into new pit */ + if (mintrap(mtmp) == 2) + trapkilled = TRUE; + } + /* a boulder may fill the new pit, crushing monster */ + fill_pit(tx, ty); /* thitm may have already destroyed the trap */ + if (DEADMONSTER(mtmp)) + trapkilled = TRUE; + if (unconscious()) { + g.multi = -1; + g.nomovemsg = "The explosion awakens you!"; + } + return trapkilled ? 2 : mtmp->mtrapped; } - blow_up_landmine(trap); - if (steed_mid && saddle && !u.usteed) - (void) keep_saddle_with_steedcorpse(steed_mid, fobj, saddle); - newsym(u.ux, u.uy); /* update trap symbol */ - losehp(Maybe_Half_Phys(rnd(16)), "land mine", KILLED_BY_AN); - /* fall recursively into the pit... */ - if ((trap = t_at(u.ux, u.uy)) != 0) - dotrap(trap, RECURSIVETRAP); - fill_pit(u.ux, u.uy); + return 0; } static void @@ -2321,7 +2377,7 @@ unsigned trflags; break; case LANDMINE: - trapeffect_landmine(trap, trflags); + (void) trapeffect_landmine(&g.youmonst, trap, trflags); break; case ROLLING_BOULDER_TRAP: @@ -3019,51 +3075,7 @@ register struct monst *mtmp; return trapeffect_anti_magic(mtmp, trap, 0); break; case LANDMINE: - if (rn2(3)) - break; /* monsters usually don't set it off */ - if (is_flyer(mptr)) { - boolean already_seen = trap->tseen; - - if (in_sight && !already_seen) { - pline("A trigger appears in a pile of soil below %s.", - mon_nam(mtmp)); - seetrap(trap); - } - if (rn2(3)) - break; - if (in_sight) { - newsym(mtmp->mx, mtmp->my); - pline_The("air currents set %s off!", - already_seen ? "a land mine" : "it"); - } - } else if (in_sight) { - newsym(mtmp->mx, mtmp->my); - pline("%s%s triggers %s land mine!", - !Deaf ? "KAABLAMM!!! " : "", Monnam(mtmp), - a_your[trap->madeby_u]); - } - if (!in_sight && !Deaf) - pline("Kaablamm! %s an explosion in the distance!", - "You hear"); /* Deaf-aware */ - blow_up_landmine(trap); - /* explosion might have destroyed a drawbridge; don't - dish out more damage if monster is already dead */ - if (DEADMONSTER(mtmp) - || thitm(0, mtmp, (struct obj *) 0, rnd(16), FALSE)) { - trapkilled = TRUE; - } else { - /* monsters recursively fall into new pit */ - if (mintrap(mtmp) == 2) - trapkilled = TRUE; - } - /* a boulder may fill the new pit, crushing monster */ - fill_pit(tx, ty); /* thitm may have already destroyed the trap */ - if (DEADMONSTER(mtmp)) - trapkilled = TRUE; - if (unconscious()) { - g.multi = -1; - g.nomovemsg = "The explosion awakens you!"; - } + return trapeffect_landmine(mtmp, trap, 0); break; case POLY_TRAP: return trapeffect_poly_trap(mtmp, trap, 0); From 5dbcc125f52e4e439ec8bce83e0bdd48d187b26a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:06:49 +0200 Subject: [PATCH 576/708] Unify rolling boulder traps --- src/trap.c | 71 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/trap.c b/src/trap.c index e3842b228..e9bdc57ab 100644 --- a/src/trap.c +++ b/src/trap.c @@ -30,7 +30,7 @@ static int FDECL(trapeffect_magic_trap, (struct monst *, struct trap *, unsigned static int FDECL(trapeffect_anti_magic, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_poly_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_landmine, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_rolling_boulder_trap, (struct trap *, unsigned)); +static int FDECL(trapeffect_rolling_boulder_trap, (struct monst *, struct trap *, unsigned)); static void FDECL(trapeffect_magic_portal, (struct trap *, unsigned)); static char *FDECL(trapnote, (struct trap *, BOOLEAN_P)); static int FDECL(steedintrap, (struct trap *, struct obj *)); @@ -2210,21 +2210,49 @@ unsigned trflags; return 0; } -static void -trapeffect_rolling_boulder_trap(trap, trflags) +static int +trapeffect_rolling_boulder_trap(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); + if (mtmp == &g.youmonst) { + int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); - feeltrap(trap); - pline("Click! You trigger a rolling boulder trap!"); - if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y, - trap->launch2.x, trap->launch2.y, style)) { - deltrap(trap); - newsym(u.ux, u.uy); /* get rid of trap symbol */ - pline("Fortunately for you, no boulder was released."); + feeltrap(trap); + pline("Click! You trigger a rolling boulder trap!"); + if (!launch_obj(BOULDER, trap->launch.x, trap->launch.y, + trap->launch2.x, trap->launch2.y, style)) { + deltrap(trap); + newsym(u.ux, u.uy); /* get rid of trap symbol */ + pline("Fortunately for you, no boulder was released."); + } + } else { + struct permonst *mptr = mtmp->data; + + if (!is_flyer(mptr)) { + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN); + boolean trapkilled = FALSE; + + newsym(mtmp->mx, mtmp->my); + if (in_sight) + pline("Click! %s triggers %s.", Monnam(mtmp), + trap->tseen ? "a rolling boulder trap" : something); + if (launch_obj(BOULDER, trap->launch.x, trap->launch.y, + trap->launch2.x, trap->launch2.y, style)) { + if (in_sight) + trap->tseen = TRUE; + if (DEADMONSTER(mtmp)) + trapkilled = TRUE; + } else { + deltrap(trap); + newsym(mtmp->mx, mtmp->my); + } + return trapkilled ? 2 : mtmp->mtrapped; + } } + return 0; } static void @@ -2381,7 +2409,7 @@ unsigned trflags; break; case ROLLING_BOULDER_TRAP: - trapeffect_rolling_boulder_trap(trap, trflags); + (void) trapeffect_rolling_boulder_trap(&g.youmonst, trap, trflags); break; case MAGIC_PORTAL: @@ -3081,24 +3109,7 @@ register struct monst *mtmp; return trapeffect_poly_trap(mtmp, trap, 0); break; case ROLLING_BOULDER_TRAP: - if (!is_flyer(mptr)) { - int style = ROLL | (in_sight ? 0 : LAUNCH_UNSEEN); - - newsym(mtmp->mx, mtmp->my); - if (in_sight) - pline("Click! %s triggers %s.", Monnam(mtmp), - trap->tseen ? "a rolling boulder trap" : something); - if (launch_obj(BOULDER, trap->launch.x, trap->launch.y, - trap->launch2.x, trap->launch2.y, style)) { - if (in_sight) - trap->tseen = TRUE; - if (DEADMONSTER(mtmp)) - trapkilled = TRUE; - } else { - deltrap(trap); - newsym(mtmp->mx, mtmp->my); - } - } + return trapeffect_rolling_boulder_trap(mtmp, trap, 0); break; case VIBRATING_SQUARE: if (see_it && !Blind) { From 31a7f2b4d8d8e01d57de81d7c8d9c44d4d1beeb4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:07:30 +0200 Subject: [PATCH 577/708] Remove unused label --- src/trap.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/trap.c b/src/trap.c index e9bdc57ab..739fd3909 100644 --- a/src/trap.c +++ b/src/trap.c @@ -3079,7 +3079,6 @@ register struct monst *mtmp; case RUST_TRAP: return trapeffect_rust_trap(mtmp, trap, 0); case FIRE_TRAP: - mfiretrap: return trapeffect_fire_trap(mtmp, trap, 0); case PIT: case SPIKED_PIT: From d537ceb2c4d3e9fcc4e84a0b7bc1b4157b6afa0e Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:10:05 +0200 Subject: [PATCH 578/708] Unify magic portals --- src/trap.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/trap.c b/src/trap.c index 739fd3909..9a8d88668 100644 --- a/src/trap.c +++ b/src/trap.c @@ -31,7 +31,7 @@ static int FDECL(trapeffect_anti_magic, (struct monst *, struct trap *, unsigned static int FDECL(trapeffect_poly_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_landmine, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_rolling_boulder_trap, (struct monst *, struct trap *, unsigned)); -static void FDECL(trapeffect_magic_portal, (struct trap *, unsigned)); +static int FDECL(trapeffect_magic_portal, (struct monst *, struct trap *, unsigned)); static char *FDECL(trapnote, (struct trap *, BOOLEAN_P)); static int FDECL(steedintrap, (struct trap *, struct obj *)); static void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P)); @@ -2255,13 +2255,19 @@ unsigned trflags; return 0; } -static void -trapeffect_magic_portal(trap, trflags) +static int +trapeffect_magic_portal(mtmp, trap, trflags) +struct monst *mtmp; struct trap *trap; unsigned trflags; { - feeltrap(trap); - domagicportal(trap); + if (mtmp == &g.youmonst) { + feeltrap(trap); + domagicportal(trap); + } else { + return trapeffect_level_telep(mtmp, trap, trflags); + } + return 0; } void @@ -2413,7 +2419,7 @@ unsigned trflags; break; case MAGIC_PORTAL: - trapeffect_magic_portal(trap, trflags); + (void) trapeffect_magic_portal(&g.youmonst, trap, trflags); break; case VIBRATING_SQUARE: @@ -3087,8 +3093,9 @@ register struct monst *mtmp; case TRAPDOOR: return trapeffect_hole(mtmp, trap, 0); case LEVEL_TELEP: - case MAGIC_PORTAL: return trapeffect_level_telep(mtmp, trap, 0); + case MAGIC_PORTAL: + return trapeffect_magic_portal(mtmp, trap, 0); case TELEP_TRAP: return trapeffect_telep_trap(mtmp, trap, 0); case WEB: From e6142f1149780537825c43e70ff94eb4399cb15a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:28:00 +0200 Subject: [PATCH 579/708] Unify vibrating square --- src/trap.c | 74 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/src/trap.c b/src/trap.c index 9a8d88668..97fcfdefd 100644 --- a/src/trap.c +++ b/src/trap.c @@ -32,6 +32,7 @@ static int FDECL(trapeffect_poly_trap, (struct monst *, struct trap *, unsigned) static int FDECL(trapeffect_landmine, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_rolling_boulder_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_magic_portal, (struct monst *, struct trap *, unsigned)); +static int FDECL(trapeffect_vibrating_square, (struct monst *, struct trap *, unsigned)); static char *FDECL(trapnote, (struct trap *, BOOLEAN_P)); static int FDECL(steedintrap, (struct trap *, struct obj *)); static void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P)); @@ -2270,6 +2271,49 @@ unsigned trflags; return 0; } +static int +trapeffect_vibrating_square(mtmp, trap, trflags) +struct monst *mtmp; +struct trap *trap; +unsigned trflags; +{ + if (mtmp == &g.youmonst) { + feeltrap(trap); + /* messages handled elsewhere; the trap symbol is merely to mark the + * square for future reference */ + } else { + boolean in_sight = canseemon(mtmp) || (mtmp == u.usteed); + boolean see_it = cansee(mtmp->mx, mtmp->my); + + if (see_it && !Blind) { + seetrap(trap); /* before messages */ + if (in_sight) { + char buf[BUFSZ], *p, *monnm = mon_nam(mtmp); + + if (nolimbs(mtmp->data) + || is_floater(mtmp->data) || is_flyer(mtmp->data)) { + /* just "beneath " */ + Strcpy(buf, monnm); + } else { + Strcpy(buf, s_suffix(monnm)); + p = eos(strcat(buf, " ")); + Strcpy(p, makeplural(mbodypart(mtmp, FOOT))); + /* avoid "beneath 'rear paws'" or 'rear hooves' */ + (void) strsubst(p, "rear ", ""); + } + You_see("a strange vibration beneath %s.", buf); + } else { + /* notice something (hearing uses a larger threshold + for 'nearby') */ + You_see("the ground vibrate %s.", + (distu(mtmp->mx, mtmp->my) <= 2 * 2) + ? "nearby" : "in the distance"); + } + } + } + return 0; +} + void dotrap(trap, trflags) register struct trap *trap; @@ -2423,9 +2467,7 @@ unsigned trflags; break; case VIBRATING_SQUARE: - feeltrap(trap); - /* messages handled elsewhere; the trap symbol is merely to mark the - * square for future reference */ + (void) trapeffect_vibrating_square(&g.youmonst, trap, trflags); break; default: @@ -3118,31 +3160,7 @@ register struct monst *mtmp; return trapeffect_rolling_boulder_trap(mtmp, trap, 0); break; case VIBRATING_SQUARE: - if (see_it && !Blind) { - seetrap(trap); /* before messages */ - if (in_sight) { - char buf[BUFSZ], *p, *monnm = mon_nam(mtmp); - - if (nolimbs(mtmp->data) - || is_floater(mtmp->data) || is_flyer(mtmp->data)) { - /* just "beneath " */ - Strcpy(buf, monnm); - } else { - Strcpy(buf, s_suffix(monnm)); - p = eos(strcat(buf, " ")); - Strcpy(p, makeplural(mbodypart(mtmp, FOOT))); - /* avoid "beneath 'rear paws'" or 'rear hooves' */ - (void) strsubst(p, "rear ", ""); - } - You_see("a strange vibration beneath %s.", buf); - } else { - /* notice something (hearing uses a larger threshold - for 'nearby') */ - You_see("the ground vibrate %s.", - (distu(mtmp->mx, mtmp->my) <= 2 * 2) - ? "nearby" : "in the distance"); - } - } + return trapeffect_vibrating_square(mtmp, trap, 0); break; default: impossible("Some monster encountered a strange trap of type %d.", From fd665a180aa1489b0a0e1b47dfb6486a5b107169 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:39:09 +0200 Subject: [PATCH 580/708] Unify trap selector --- src/trap.c | 209 ++++++++++++++++------------------------------------- 1 file changed, 63 insertions(+), 146 deletions(-) diff --git a/src/trap.c b/src/trap.c index 97fcfdefd..efec44835 100644 --- a/src/trap.c +++ b/src/trap.c @@ -33,6 +33,7 @@ static int FDECL(trapeffect_landmine, (struct monst *, struct trap *, unsigned)) static int FDECL(trapeffect_rolling_boulder_trap, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_magic_portal, (struct monst *, struct trap *, unsigned)); static int FDECL(trapeffect_vibrating_square, (struct monst *, struct trap *, unsigned)); +static int FDECL(trapeffect_selector, (struct monst *, struct trap *, unsigned)); static char *FDECL(trapnote, (struct trap *, BOOLEAN_P)); static int FDECL(steedintrap, (struct trap *, struct obj *)); static void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P)); @@ -2314,6 +2315,65 @@ unsigned trflags; return 0; } +static int +trapeffect_selector(mtmp, trap, trflags) +struct monst *mtmp; +struct trap *trap; +unsigned trflags; +{ + switch (trap->ttyp) { + case ARROW_TRAP: + return trapeffect_arrow_trap(mtmp, trap, trflags); + case DART_TRAP: + return trapeffect_dart_trap(mtmp, trap, trflags); + case ROCKTRAP: + return trapeffect_rocktrap(mtmp, trap, trflags); + case SQKY_BOARD: + return trapeffect_sqky_board(mtmp, trap, trflags); + case BEAR_TRAP: + return trapeffect_bear_trap(mtmp, trap, trflags); + case SLP_GAS_TRAP: + return trapeffect_slp_gas_trap(mtmp, trap, trflags); + case RUST_TRAP: + return trapeffect_rust_trap(mtmp, trap, trflags); + case FIRE_TRAP: + return trapeffect_fire_trap(mtmp, trap, trflags); + case PIT: + case SPIKED_PIT: + return trapeffect_pit(mtmp, trap, trflags); + case HOLE: + case TRAPDOOR: + return trapeffect_hole(mtmp, trap, trflags); + case LEVEL_TELEP: + return trapeffect_level_telep(mtmp, trap, trflags); + case MAGIC_PORTAL: + return trapeffect_magic_portal(mtmp, trap, trflags); + case TELEP_TRAP: + return trapeffect_telep_trap(mtmp, trap, trflags); + case WEB: + return trapeffect_web(mtmp, trap, trflags); + case STATUE_TRAP: + return trapeffect_statue_trap(mtmp, trap, trflags); + case MAGIC_TRAP: + return trapeffect_magic_trap(mtmp, trap, trflags); + case ANTI_MAGIC: + return trapeffect_anti_magic(mtmp, trap, trflags); + case LANDMINE: + return trapeffect_landmine(mtmp, trap, trflags); + case POLY_TRAP: + return trapeffect_poly_trap(mtmp, trap, trflags); + case ROLLING_BOULDER_TRAP: + return trapeffect_rolling_boulder_trap(mtmp, trap, trflags); + case VIBRATING_SQUARE: + return trapeffect_vibrating_square(mtmp, trap, trflags); + default: + impossible("%s encountered a strange trap of type %d.", + (mtmp == &g.youmonst) ? "You" : "Some monster", + trap->ttyp); + } + return 0; +} + void dotrap(trap, trflags) register struct trap *trap; @@ -2383,97 +2443,7 @@ unsigned trflags; * would be somewhat harsh for what's usually a minor impairment. */ - switch (ttype) { - case ARROW_TRAP: - (void) trapeffect_arrow_trap(&g.youmonst, trap, trflags); - break; - - case DART_TRAP: - (void) trapeffect_dart_trap(&g.youmonst, trap, trflags); - break; - - case ROCKTRAP: - (void) trapeffect_rocktrap(&g.youmonst, trap, trflags); - break; - - case SQKY_BOARD: /* stepped on a squeaky board */ - (void) trapeffect_sqky_board(&g.youmonst, trap, trflags); - break; - - case BEAR_TRAP: - (void) trapeffect_bear_trap(&g.youmonst, trap, trflags); - break; - - case SLP_GAS_TRAP: - (void) trapeffect_slp_gas_trap(&g.youmonst, trap, trflags); - break; - - case RUST_TRAP: - (void) trapeffect_rust_trap(&g.youmonst, trap, trflags); - break; - - case FIRE_TRAP: - (void) trapeffect_fire_trap(&g.youmonst, trap, trflags); - break; - - case PIT: - case SPIKED_PIT: - (void) trapeffect_pit(&g.youmonst, trap, trflags); - break; - - case HOLE: - case TRAPDOOR: - (void) trapeffect_hole(&g.youmonst, trap, trflags); - break; - - case TELEP_TRAP: - (void) trapeffect_telep_trap(&g.youmonst, trap, trflags); - break; - - case LEVEL_TELEP: - (void) trapeffect_level_telep(&g.youmonst, trap, trflags); - break; - - case WEB: /* Our luckless player has stumbled into a web. */ - (void) trapeffect_web(&g.youmonst, trap, trflags); - break; - - case STATUE_TRAP: - (void) trapeffect_statue_trap(&g.youmonst, trap, trflags); - break; - - case MAGIC_TRAP: /* A magic trap. */ - (void) trapeffect_magic_trap(&g.youmonst, trap, trflags); - break; - - case ANTI_MAGIC: - (void) trapeffect_anti_magic(&g.youmonst, trap, trflags); - break; - - case POLY_TRAP: - (void) trapeffect_poly_trap(&g.youmonst, trap, trflags); - break; - - case LANDMINE: - (void) trapeffect_landmine(&g.youmonst, trap, trflags); - break; - - case ROLLING_BOULDER_TRAP: - (void) trapeffect_rolling_boulder_trap(&g.youmonst, trap, trflags); - break; - - case MAGIC_PORTAL: - (void) trapeffect_magic_portal(&g.youmonst, trap, trflags); - break; - - case VIBRATING_SQUARE: - (void) trapeffect_vibrating_square(&g.youmonst, trap, trflags); - break; - - default: - feeltrap(trap); - impossible("You hit a trap of type %u", trap->ttyp); - } + (void) trapeffect_selector(&g.youmonst, trap, trflags); } static char * @@ -3111,61 +3081,8 @@ register struct monst *mtmp; /* assume hero can tell what's going on for the steed */ if (mtmp == u.usteed) in_sight = TRUE; - switch (tt) { - case ARROW_TRAP: - return trapeffect_arrow_trap(mtmp, trap, 0); - case DART_TRAP: - return trapeffect_dart_trap(mtmp, trap, 0); - case ROCKTRAP: - return trapeffect_rocktrap(mtmp, trap, 0); - case SQKY_BOARD: - return trapeffect_sqky_board(mtmp, trap, 0); - case BEAR_TRAP: - return trapeffect_bear_trap(mtmp, trap, 0); - case SLP_GAS_TRAP: - return trapeffect_slp_gas_trap(mtmp, trap, 0); - case RUST_TRAP: - return trapeffect_rust_trap(mtmp, trap, 0); - case FIRE_TRAP: - return trapeffect_fire_trap(mtmp, trap, 0); - case PIT: - case SPIKED_PIT: - return trapeffect_pit(mtmp, trap, 0); - case HOLE: - case TRAPDOOR: - return trapeffect_hole(mtmp, trap, 0); - case LEVEL_TELEP: - return trapeffect_level_telep(mtmp, trap, 0); - case MAGIC_PORTAL: - return trapeffect_magic_portal(mtmp, trap, 0); - case TELEP_TRAP: - return trapeffect_telep_trap(mtmp, trap, 0); - case WEB: - return trapeffect_web(mtmp, trap, 0); - case STATUE_TRAP: - return trapeffect_statue_trap(mtmp, trap, 0); - case MAGIC_TRAP: - return trapeffect_statue_trap(mtmp, trap, 0); - break; - case ANTI_MAGIC: - return trapeffect_anti_magic(mtmp, trap, 0); - break; - case LANDMINE: - return trapeffect_landmine(mtmp, trap, 0); - break; - case POLY_TRAP: - return trapeffect_poly_trap(mtmp, trap, 0); - break; - case ROLLING_BOULDER_TRAP: - return trapeffect_rolling_boulder_trap(mtmp, trap, 0); - break; - case VIBRATING_SQUARE: - return trapeffect_vibrating_square(mtmp, trap, 0); - break; - default: - impossible("Some monster encountered a strange trap of type %d.", - tt); - } + + return trapeffect_selector(mtmp, trap, 0); } if (trapkilled) return 2; From f936cd9887867d39f6843ed5a8c41505064dce36 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 18:51:40 +0200 Subject: [PATCH 581/708] Remove unused variables --- src/trap.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/trap.c b/src/trap.c index efec44835..9ac995c4b 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2380,17 +2380,13 @@ register struct trap *trap; unsigned trflags; { register int ttype = trap->ttyp; - struct obj *otmp; boolean already_seen = trap->tseen, forcetrap = ((trflags & FORCETRAP) != 0 || (trflags & FAILEDUNTRAP) != 0), - webmsgok = (trflags & NOWEBMSG) == 0, forcebungle = (trflags & FORCEBUNGLE) != 0, plunged = (trflags & TOOKPLUNGE) != 0, - viasitting = (trflags & VIASITTING) != 0, conj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE), adj_pit = adj_nonconjoined_pit(trap); - int oldumort; int steed_article = ARTICLE_THE; nomul(0); @@ -3009,7 +3005,6 @@ register struct monst *mtmp; register struct trap *trap = t_at(mtmp->mx, mtmp->my); boolean trapkilled = FALSE; struct permonst *mptr = mtmp->data; - struct obj *otmp; if (!trap) { mtmp->mtrapped = 0; /* perhaps teleported? */ @@ -3052,12 +3047,10 @@ register struct monst *mtmp; } } else { register int tt = trap->ttyp; - boolean in_sight, tear_web, see_it, + boolean in_sight, see_it, inescapable = (g.force_mintrap || ((tt == HOLE || tt == PIT) && Sokoban && !trap->madeby_u)); - const char *fallverb; - xchar tx = trap->tx, ty = trap->ty; /* true when called from dotrap, inescapable is not an option */ if (mtmp == u.usteed) From 0dc6792b80e9e8dcc2db0b2fbd5e2acedb966bd8 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 19:04:04 +0200 Subject: [PATCH 582/708] Fixes bit for unifying the traps --- doc/fixes37.0 | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 77dc16702..33e66bd34 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -768,5 +768,6 @@ move 'restoring' to the program_state struct; add corresponding 'saving'; inventory when the relevant activity is in progress unify special attack damages from separate you-hit-monster, monster-hits-you, and monster-hits-monster into functions by damage type +unify trap effects for hero and monster stepping on the trap by trap type From eb1fb93d0608cafc96b39efaf24b46e0faa35778 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 22:08:32 +0200 Subject: [PATCH 583/708] Mark unused parameters --- src/trap.c | 22 +++++++++++----------- sys/unix/hints/linux | 2 ++ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/trap.c b/src/trap.c index 9ac995c4b..746699d65 100644 --- a/src/trap.c +++ b/src/trap.c @@ -928,7 +928,7 @@ static int trapeffect_arrow_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { struct obj *otmp; @@ -984,7 +984,7 @@ static int trapeffect_dart_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { struct obj *otmp; @@ -1052,7 +1052,7 @@ static int trapeffect_rocktrap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { struct obj *otmp; @@ -1245,7 +1245,7 @@ static int trapeffect_slp_gas_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { seetrap(trap); @@ -1274,7 +1274,7 @@ static int trapeffect_rust_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { struct obj *otmp; @@ -1403,7 +1403,7 @@ static int trapeffect_fire_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { seetrap(trap); @@ -1714,7 +1714,7 @@ static int trapeffect_telep_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { seetrap(trap); @@ -1918,7 +1918,7 @@ static int trapeffect_statue_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { (void) activate_statue_trap(trap, u.ux, u.uy, FALSE); @@ -1960,7 +1960,7 @@ static int trapeffect_anti_magic(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { seetrap(trap); @@ -2216,7 +2216,7 @@ static int trapeffect_rolling_boulder_trap(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { int style = ROLL | (trap->tseen ? LAUNCH_KNOWN : 0); @@ -2276,7 +2276,7 @@ static int trapeffect_vibrating_square(mtmp, trap, trflags) struct monst *mtmp; struct trap *trap; -unsigned trflags; +unsigned trflags UNUSED; { if (mtmp == &g.youmonst) { feeltrap(trap); diff --git a/sys/unix/hints/linux b/sys/unix/hints/linux index 48ab631c1..7b1ae9136 100644 --- a/sys/unix/hints/linux +++ b/sys/unix/hints/linux @@ -34,6 +34,8 @@ CFLAGS+=-DCURSES_GRAPHICS #CFLAGS+=-DSCORE_ON_BOTL #CFLAGS+=-DMSGHANDLER #CFLAGS+=-DTTY_TILES_ESCCODES +CFLAGS+=-Wunused +CFLAGS+=-Wunused-parameter # when building liblua.a, avoid warning that use of tmpnam() should be # replaced by mkstemp(); the lua code doesn't use nethack's config.h so From 971ea03b9effb06d23b489977d1b4611ff6da30a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 10 Dec 2020 22:14:07 +0200 Subject: [PATCH 584/708] Remove accidental compile warning flags --- sys/unix/hints/linux | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/unix/hints/linux b/sys/unix/hints/linux index 7b1ae9136..48ab631c1 100644 --- a/sys/unix/hints/linux +++ b/sys/unix/hints/linux @@ -34,8 +34,6 @@ CFLAGS+=-DCURSES_GRAPHICS #CFLAGS+=-DSCORE_ON_BOTL #CFLAGS+=-DMSGHANDLER #CFLAGS+=-DTTY_TILES_ESCCODES -CFLAGS+=-Wunused -CFLAGS+=-Wunused-parameter # when building liblua.a, avoid warning that use of tmpnam() should be # replaced by mkstemp(); the lua code doesn't use nethack's config.h so From fd5ef1ecaad6ce935acb07fdff44bd82ac314fbd Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Dec 2020 15:06:26 -0800 Subject: [PATCH 585/708] more key bindings number_pad==1 adds '5' => 'G' M-5 => 'g' '0' => 'i' number_pad==2 swaps 5 and M-5 and adds M-0 '5' => 'g' M-5 => 'G' '0' => 'i' M-0 => 'I' M-5 and M-0 were missing from the bound key handling; they still used hardcoded digits even though the actions for plain 5 and plain 0 can be bound to other keys these days. This implements the M-5 variation as NHKF_RUSH2. Changing numpad from 1 to 2 or vice versa will swap the NHKF_RUN2 and NHKF_RUSH2 actions regardless of what keys they're assigned to. I haven't done anything for unimplemented NHKF_DOINV2 though (and am not planning to in case someone else wants to jump in...). This also fixes the description of the 'I' command. The extended command name for that still misleadingly refers to "type" rather than "class" though. --- doc/fixes37.0 | 4 +++- include/decl.h | 21 ++++++++++--------- src/cmd.c | 55 ++++++++++++++++++++++++++++++++++---------------- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 33e66bd34..104142e2d 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.381 $ $NHDT-Date: 1607591199 2020/12/10 09:06:39 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.383 $ $NHDT-Date: 1607641577 2020/12/10 23:06:17 $ General Fixes and Modified Features ----------------------------------- @@ -322,6 +322,8 @@ brown pudding monster hitting another monster with decay attack corroded armor instead of rotting it -> omitted 'n' prefix and M-digit for number_pad mode, and ^A/re-do was suppressed due lack of obsolete '#define REDO' +add missing key binding support for rush.numpad; default is M-5 for numpad==1 + or plain 5 for numpad==2 where behavior of 5 and M-5 are swapped Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/decl.h b/include/decl.h index 6cc5f75bb..71147ce18 100644 --- a/include/decl.h +++ b/include/decl.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 decl.h $NHDT-Date: 1606919254 2020/12/02 14:27:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.247 $ */ +/* NetHack 3.7 decl.h $NHDT-Date: 1607641577 2020/12/10 23:06:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.248 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2007. */ /* NetHack may be freely redistributed. See license for details. */ @@ -416,15 +416,16 @@ enum nh_keyfunc { NHKF_REQMENU, /* run ... clicklook need to be in a continuous block */ - NHKF_RUN, - NHKF_RUN2, - NHKF_RUSH, - NHKF_FIGHT, - NHKF_FIGHT2, - NHKF_NOPICKUP, - NHKF_RUN_NOPICKUP, - NHKF_DOINV, - NHKF_TRAVEL, + NHKF_RUN, /* 'G' */ + NHKF_RUN2, /* '5' or M-5 */ + NHKF_RUSH, /* 'g' */ + NHKF_RUSH2, /* M-5 or '5' */ + NHKF_FIGHT, /* 'F' */ + NHKF_FIGHT2, /* '-' */ + NHKF_NOPICKUP, /* 'm' */ + NHKF_RUN_NOPICKUP, /* 'M' */ + NHKF_DOINV, /* '0' */ + NHKF_TRAVEL, /* via mouse */ NHKF_CLICKLOOK, NHKF_REDRAW, diff --git a/src/cmd.c b/src/cmd.c index f7c8121eb..bdc9d0c9f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607591200 2020/12/10 09:06:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.431 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607641581 2020/12/10 23:06:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.432 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1821,7 +1821,7 @@ struct ext_func_tab extcmdlist[] = { { 'V', "history", "show long version and game history", dohistory, IFBURIED | GENERALCMD }, { 'i', "inventory", "show your inventory", ddoinv, IFBURIED }, - { 'I', "inventtype", "inventory specific item types", + { 'I', "inventtype", "show inventory of one specific item class", dotypeinv, IFBURIED }, { M('i'), "invoke", "invoke an object's special powers", doinvoke, IFBURIED | AUTOCOMPLETE }, @@ -2199,6 +2199,7 @@ dokeylist(VOID_ARGS) int i; static const char run_desc[] = "Prefix: run until something very interesting is seen", + rush_desc[] = "Prefix: rush until something interesting is seen", forcefight_desc[] = "Prefix: force fight even if you don't see a monster"; static const struct { @@ -2206,9 +2207,9 @@ dokeylist(VOID_ARGS) const char *desc; boolean numpad; } misc_keys[] = { - { NHKF_ESC, "escape from the current query/action", FALSE }, - { NHKF_RUSH, - "Prefix: rush until something interesting is seen", FALSE }, + { NHKF_ESC, "cancel current prompt or pending prefix", FALSE }, + { NHKF_RUSH, rush_desc, FALSE }, + { NHKF_RUSH2, rush_desc, TRUE }, { NHKF_RUN, run_desc, FALSE }, { NHKF_RUN2, run_desc, TRUE }, { NHKF_FIGHT, forcefight_desc, FALSE }, @@ -2217,7 +2218,9 @@ dokeylist(VOID_ARGS) "Prefix: move without picking up objects or fighting", FALSE }, { NHKF_RUN_NOPICKUP, "Prefix: run without picking up objects or fighting", FALSE }, - { NHKF_DOINV, "view inventory", TRUE }, + { NHKF_DOINV, "view full inventory", TRUE }, + /* NHKF_DOINV2 for num_pad+pcHack_compat isn't implemented */ + /* { NHKF_DOINV2, "view inventory of one class of objects", TRUE }, */ { NHKF_REQMENU, "Prefix: request a menu", FALSE }, { NHKF_COUNT, "Prefix: for digits when prefixing a command with a count", TRUE }, @@ -2303,8 +2306,9 @@ dokeylist(VOID_ARGS) } } #ifndef NO_SIGNAL - keys_used[(uchar) C('c')] = TRUE; - Sprintf(buf, "%-7s %s", key2txt(C('c'), buf2), + key = (uchar) C('c'); + keys_used[key] = TRUE; + Sprintf(buf, "%-7s %s", key2txt(key, buf2), "break out of NetHack (SIGINT)"); putstr(datawin, 0, buf); #endif @@ -2320,15 +2324,14 @@ dokeylist(VOID_ARGS) } if (keylist_putcmds(datawin, TRUE, 0, - GENERALCMD | WIZMODECMD, keys_used)) { + GENERALCMD | WIZMODECMD, keys_used)) { putstr(datawin, 0, ""); putstr(datawin, 0, "Game commands:"); (void) keylist_putcmds(datawin, FALSE, 0, - GENERALCMD | WIZMODECMD, keys_used); + GENERALCMD | WIZMODECMD, keys_used); } - if (wizard - && keylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) { + if (wizard && keylist_putcmds(datawin, TRUE, WIZMODECMD, 0, keys_used)) { putstr(datawin, 0, ""); putstr(datawin, 0, "Debug mode commands:"); (void) keylist_putcmds(datawin, FALSE, WIZMODECMD, 0, keys_used); @@ -2842,7 +2845,7 @@ wiz_migrate_mons() static struct { int nhkf; - char key; + uchar key; const char *name; } const spkeys_binds[] = { { NHKF_ESC, '\033', (char *) 0 }, /* no binding */ @@ -2851,6 +2854,7 @@ static struct { { NHKF_RUN, 'G', "run" }, { NHKF_RUN2, '5', "run.numpad" }, { NHKF_RUSH, 'g', "rush" }, + { NHKF_RUSH2, M('5'), "rush.numpad" }, { NHKF_FIGHT, 'F', "fight" }, { NHKF_FIGHT2, '-', "fight.numpad" }, { NHKF_NOPICKUP, 'm', "nopickup" }, @@ -3109,13 +3113,14 @@ boolean initial; if (flagtemp != g.Cmd.swap_yz) { g.Cmd.swap_yz = flagtemp; ++updated; - /* g.Cmd.swap_yz has been toggled; + /* FIXME? should Cmd.spkeys[] be scanned for y and/or z to swap? + Cmd.swap_yz has been toggled; perform the swap (or reverse previous one) */ for (i = 0; i < SIZE(ylist); i++) { c = ylist[i] & 0xff; - cmdtmp = g.Cmd.commands[c]; /* tmp = [y] */ + cmdtmp = g.Cmd.commands[c]; /* tmp = [y] */ g.Cmd.commands[c] = g.Cmd.commands[c + 1]; /* [y] = [z] */ - g.Cmd.commands[c + 1] = cmdtmp; /* [z] = tmp */ + g.Cmd.commands[c + 1] = cmdtmp; /* [z] = tmp */ } } /* MSDOS compatibility mode (only applicable for num_pad) */ @@ -3124,10 +3129,17 @@ boolean initial; g.Cmd.pcHack_compat = flagtemp; ++updated; /* pcHack_compat has been toggled */ +#if 0 c = M('5') & 0xff; cmdtmp = g.Cmd.commands['5']; g.Cmd.commands['5'] = g.Cmd.commands[c]; g.Cmd.commands[c] = cmdtmp; +#else + c = g.Cmd.spkeys[NHKF_RUN2]; + g.Cmd.spkeys[NHKF_RUN2] = g.Cmd.spkeys[NHKF_RUSH2]; + g.Cmd.spkeys[NHKF_RUSH2] = c; +#endif + /* FIXME: NHKF_DOINV2 ought to be implemented instead of this */ c = M('0') & 0xff; g.Cmd.commands[c] = g.Cmd.pcHack_compat ? g.Cmd.commands['I'] : 0; } @@ -3338,6 +3350,10 @@ register char *cmd; spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK); switch (spkey) { + case NHKF_RUSH2: + if (!g.Cmd.num_pad) + break; + /*FALLTHRU*/ case NHKF_RUSH: if (movecmd(cmd[1])) { g.context.run = 2; @@ -3597,7 +3613,8 @@ char c; || c == g.Cmd.spkeys[NHKF_RUN_NOPICKUP] || c == g.Cmd.spkeys[NHKF_FIGHT] || (g.Cmd.num_pad && (c == g.Cmd.spkeys[NHKF_RUN2] - || c == g.Cmd.spkeys[NHKF_FIGHT2]))); + || c == g.Cmd.spkeys[NHKF_RUSH2] + || c == g.Cmd.spkeys[NHKF_FIGHT2]))); } /* @@ -3751,6 +3768,10 @@ const char *msg; case NHKF_NOPICKUP: dothat = "move"; break; + case NHKF_RUSH2: + if (!g.Cmd.num_pad) + break; + /*FALLTHRU*/ case NHKF_RUSH: dothat = "rush"; break; From 80a3c0c4d2743ac3519a1757b4b4364c1e0b19f1 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 10 Dec 2020 15:32:23 -0800 Subject: [PATCH 586/708] key rush.numpad/M-5 doc --- doc/Guidebook.mn | 14 ++++++++++++-- doc/Guidebook.tex | 16 ++++++++++++++-- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 074cbf2d8..27c9d1df8 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.403 $ $NHDT-Date: 1607590842 2020/12/10 09:00:42 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.404 $ $NHDT-Date: 1607643123 2020/12/10 23:32:03 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -4713,10 +4713,20 @@ Prefix key to run towards a direction. With .op number_pad only. -Default is \(oq5\(cq. +.lp "" +Default is \(oq5\(cq when number_pad is set to 1 or 3, +otherwise \(oqM-5\(cq when it is set to 2 or 4. .lp rush Prefix key to rush towards a direction. Default is \(oqg\(cq. +.lp rush.numpad +Prefix key to rush towards a direction. +With +.op number_pad +only. +.lp "" +Default is \(oqM-5\(cq when number_pad is set to 1 or 3, +otherwise \(oq5\(cq when it is set to 2 or 4. .hn 2 Configuring Message Types .pg diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 236322d1b..7c2f688ca 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -5155,11 +5155,23 @@ Prefix key to run towards a direction without picking up items on the way. Default is~`{\tt M}'. %.lp \item[{\bb{run.numpad}}] -Prefix key to run towards a direction. With {\it number\verb+_+pad\/} only. -Default is~`{\tt 5}'. +Prefix key to run towards a direction. +With {\it number\verb+_+pad\/} only. + +%.lp "" +Default is `{\tt 5}' when number_pad is set to 1~or~3, +otherwise `{\tt M-5}' when it is set to 2~or~4. %.lp \item[{\bb{rush}}] Prefix key to rush towards a direction. Default is~`{\tt g}'. +%.lp +\item[{\bb{rush.numpad}}] +Prefix key to rush towards a direction. +With {\it number\verb+_+pad\/} only. + +.lp "" +Default is `{\tt M-5}' when number_pad is set to 1~or~3, +otherwise `{\tt 5}' when it is set to 2~or~4. \elist From 6e960a4667d192371c816644cdfddd7b2990ca03 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Thu, 10 Dec 2020 19:24:07 -0500 Subject: [PATCH 587/708] This is cron-daily v1-Jan-20-2020. guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 1064 ++++++++++++++++++++++----------------------- 1 file changed, 532 insertions(+), 532 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 9e6902777..c051c4597 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -5371,18 +5371,26 @@ on the way. Default is `M'. run.numpad - Prefix key to run towards a direction. With number_pad only. - Default is `5'. + Prefix key to run towards a direction. With number_pad only. + + Default is `5' when number_pad is set to 1 or 3, otherwise + `M-5' when it is set to 2 or 4. rush Prefix key to rush towards a direction. Default is `g'. + rush.numpad + Prefix key to rush towards a direction. With number_pad only. + + Default is `M-5' when number_pad is set to 1 or 3, otherwise + `5' when it is set to 2 or 4. + 9.10. Configuring Message Types 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 + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5395,15 +5403,7 @@ 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 mes- - sage is shown in between. - - Here's an example of message types using NetHack's internal - pattern matching facility: - - MSGTYPE=stop "You feel hungry." - MSGTYPE=hide "You displaced *." - + norep - show the message once, but not again if no other NetHack 3.7 December 9, 2020 @@ -5416,61 +5416,61 @@ - specifies that whenever a message "You feel hungry" is shown, - the user is prompted with more-prompt, and a message matching + message is shown in between. + + 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 displaced ." is not shown at all. - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when 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 + 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 pat- + color - the color to use for lines matching the pat- tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- - genta, light-cyan, and white. And no-color, the default fore- - ground color, which isn't necessarily the same as any of the + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- - lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu - line will be used for the line. - NetHack 3.7 December 9, 2020 @@ -5482,36 +5482,44 @@ + 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 line will be shown in red + color and underlined. You can have multiple MENUCOLOR en- + tries in your configuration file, and the last MENUCOLOR + line that matches a menu line will be used for the line. + Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message 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 + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + 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 3.6); pattern - the pattern to match; sound file - the sound file to play; - volume - the volume to be set while playing the sound + volume - the volume to be set while playing the sound file; - sound index - optional; the index corresponding to a sound + sound index - optional; the index corresponding to a sound file. The pattern should be a POSIX extended regular expression. @@ -5519,7 +5527,7 @@ 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5527,14 +5535,6 @@ 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 hitpoints 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- - color&normal for >30%.) @@ -5548,38 +5548,47 @@ - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if + your hitpoints 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- + color&normal for >30%.) + + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground 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, blink, - and inverse. "Normal" is a synonym for "none"; they should not + Allowed attributes are none, bold, dim, underline, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5590,18 +5599,9 @@ 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 condition- - ally displayed depending upon your other option settings. - - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- - nor_troubles" for blind through hallu, "movement" for lev, fly, - and ride, and "all" for every condition. + 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 NetHack 3.7 December 9, 2020 @@ -5614,60 +5614,60 @@ + polymorphed. "experience", "time", and "score" are condition- + ally displayed depending upon your other option settings. + + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- + nor_troubles" for blind through hallu, "movement" for lev, fly, + and ride, and "all" for every condition. + Allowed behaviors are "always", "up", "down", "changed", a per- centage or absolute number threshold, or text to match against. * "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 + * "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 val- - ue 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 val- + ue 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 val- ue, 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 be- - tween 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 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 corresponding maxi- - mum field. Percentage highlight rules are also allowed + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- perience level to the start of the next level. So if lev- - el 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 + el 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 + a rule for =100% is allowed and matches the special case of being exactly 1 experience point short of the next lev- el. - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only - match when strictly above or below. - - * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". 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 - syntax for a configuration file. + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only NetHack 3.7 December 9, 2020 @@ -5680,7 +5680,18 @@ - The whole feature can be disabled by setting option sta- + match when strictly above or below. + + * text match sets the attribute when the field value matches + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + syntax for a configuration file. + + The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: @@ -5700,39 +5711,28 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols Symbol Name Description ----------------------------------------------------------------- - S_air (air) - _ S_altar (altar) - " S_amulet (amulet) - A S_angel (angelic being) - a S_ant (ant or other insect) - ^ S_anti_magic_trap (anti-magic field) - [ S_armor (suit or piece of armor) - [ S_armour (suit or piece of armor) - ^ S_arrow_trap (arrow trap) - 0 S_ball (iron ball) - # S_bars (iron bars) @@ -5746,6 +5746,17 @@ + S_air (air) + _ S_altar (altar) + " S_amulet (amulet) + A S_angel (angelic being) + a S_ant (ant or other insect) + ^ S_anti_magic_trap (anti-magic field) + [ S_armor (suit or piece of armor) + [ S_armour (suit or piece of armor) + ^ S_arrow_trap (arrow trap) + 0 S_ball (iron ball) + # S_bars (iron bars) B S_bat (bat or bird) ^ S_bear_trap (bear trap) - S_blcorn (bottom left corner) @@ -5788,17 +5799,6 @@ ! S_flashbeam (flash beam) % S_food (piece of food) { S_fountain (fountain) - F S_fungus (fungus or mold) - * S_gem (gem or rock) - S_ghost (ghost) - H S_giant (giant humanoid) - G S_gnome (gnome) - ' S_golem (golem) - | S_grave (grave) - g S_gremlin (gremlin) - - S_hbeam (horizontal beam [zap animation]) - # S_hcdbridge (horizontal raised drawbridge) - + S_hcdoor (closed door in horizontal wall) @@ -5812,6 +5812,17 @@ + F S_fungus (fungus or mold) + * S_gem (gem or rock) + S_ghost (ghost) + H S_giant (giant humanoid) + G S_gnome (gnome) + ' S_golem (golem) + | S_grave (grave) + g S_gremlin (gremlin) + - S_hbeam (horizontal beam [zap animation]) + # S_hcdbridge (horizontal raised drawbridge) + + S_hcdoor (closed door in horizontal wall) . S_hodbridge (horizontal lowered drawbridge) | S_hodoor (open door in horizontal wall) ^ S_hole (hole) @@ -5854,17 +5865,6 @@ q S_quadruped (quadruped) Q S_quantmech (quantum mechanic) = S_ring (ring) - ` S_rock (boulder or statue) - r S_rodent (rodent) - ^ S_rolling_boulder_trap (rolling boulder trap) - . S_room (floor of a room) - / S_rslant (diagonal beam [zap animation]) - ^ S_rust_trap (rust trap) - R S_rustmonst (rust monster or disenchanter) - ? S_scroll (scroll) - # S_sink (sink) - ^ S_sleeping_gas_trap (sleeping gas trap) - S S_snake (snake) @@ -5878,6 +5878,17 @@ + ` S_rock (boulder or statue) + r S_rodent (rodent) + ^ S_rolling_boulder_trap (rolling boulder trap) + . S_room (floor of a room) + / S_rslant (diagonal beam [zap animation]) + ^ S_rust_trap (rust trap) + R S_rustmonst (rust monster or disenchanter) + ? S_scroll (scroll) + # S_sink (sink) + ^ S_sleeping_gas_trap (sleeping gas trap) + S S_snake (snake) s S_spider (arachnid or centipede) ^ S_spiked_pit (spiked pit) ^ S_squeaky_board (squeaky board) @@ -5920,17 +5931,6 @@ + S_vcdoor (closed door in vertical wall) . S_venom (splash of venom) ^ S_vibrating_square (vibrating square) - . S_vodbridge (vertical lowered drawbridge) - - S_vodoor (open door in vertical wall) - v S_vortex (vortex) - | S_vwall (vertical wall) - / S_wand (wand) - } S_water (water) - ) S_weapon (weapon) - " S_web (web) - w S_worm (worm) - ~ S_worm_tail (long worm tail) - W S_wraith (wraith) @@ -5944,6 +5944,17 @@ + . S_vodbridge (vertical lowered drawbridge) + - S_vodoor (open door in vertical wall) + v S_vortex (vortex) + | S_vwall (vertical wall) + / S_wand (wand) + } S_water (water) + ) S_weapon (weapon) + " S_web (web) + w S_worm (worm) + ~ S_worm_tail (long worm tail) + W S_wraith (wraith) x S_xan (xan or other extraordinary insect) X S_xorn (xorn) Y S_yeti (apelike creature) @@ -5955,49 +5966,38 @@ Notes: * 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 en- + space character, except for S_pet_override and S_hero_override + which don't have any default value and can only be used if en- abled 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 de- - pict. So S_rock is only used for boulders and not used at all + * 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 de- + pict. So S_rock is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. 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 charac- + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- ter 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 + 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 location of items on the screen. - 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 message 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 environment variable NETHACK_MSGHANDLER - to an executable, which will be executed with the game message as - the program's only parameter. - - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the "symbols" file of all + NetHack can also be compiled with support for sending the + game messages to an external program, such as a text-to-speech NetHack 3.7 December 9, 2020 @@ -6010,25 +6010,36 @@ - official distributions of NetHack is a symset called NHAccess. - Selecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you + synthesizer. If the "#version" extended command shows "external + program as a message 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 environment variable NETHACK_MSGHANDLER + to an executable, which will be executed with the game message as + the program's only parameter. + + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task + somewhat daunting. Included within the "symbols" file of all of- + ficial distributions of NetHack is a symset called NHAccess. Se- + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- abled in the sysconf file. - The most crucial settings to make the game more accessible + The most crucial settings to make the game more accessible are: symset:NHAccess Load a symbol set appropriate for use by blind players. roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional @@ -6038,33 +6049,22 @@ 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 + 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. autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. - whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are - considered. - - whatis_moveskip - When targeting with cursor and using fast-move, skip the same - glyphs instead of moving 8 units at a time. - - - NetHack 3.7 December 9, 2020 @@ -6076,23 +6076,32 @@ + whatis_filter:area + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are + considered. + + whatis_moveskip + When targeting with cursor and using fast-move, skip the same + glyphs 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 in- + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. 9.16. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed + 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. @@ -6100,37 +6109,28 @@ SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS = A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- - fault value). - - 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 - option. When disabled, incubi and succubi behave like nymphs. - NetHack 3.7 December 9, 2020 @@ -6142,13 +6142,22 @@ - CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- + SUPPORT = A string explaining how to get local support (no de- + fault value). + + 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 + option. When disabled, incubi and succubi behave like nymphs. + + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6157,26 +6166,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6187,15 +6196,6 @@ %T - current time, UNIX timestamp format %d - game start time, YYYYMMDDhhmmss format %D - current time, YYYYMMDDhhmmss format - %n - player name - %N - first character of player name - - 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 NetHack 3.7 December 9, 2020 @@ -6208,60 +6208,60 @@ - list, or better your previous score, you will be inserted in the - proper place under your current name. How many scores are kept + %n - player name + %N - first character of player name + + 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 is compiled. - Your score is chiefly based upon how much experience you + 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 + 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 all your gold, but if + 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 + 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 + 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 paltry cost of not getting on the high score + "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 game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - other benefits of explore mode are left for the trepid reader to + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 par- - ticular 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. + vide god-like powers 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 NetHack 3.7 December 9, 2020 @@ -6274,59 +6274,59 @@ + switch or with the playmode:debug option. + + For some systems, the player must be logged in under a par- + ticular 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. + 12. Credits - 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 + 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 Dungeons of Doom, by Ken Arromdee. NetHack is the product of literally scores of people's work. - Main events in the course of the game development are described + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting + Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming Hack into a very different game. He published the Hack - source code for use on UNIX systems by posting that to Usenet + forming 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 ver- sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 1.0.3 in July of 1985. Usenet newsgroup net.games.hack - (later renamed rec.games.hack, eventually replaced by + nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, 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. @@ -6340,61 +6340,61 @@ - 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 + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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. + + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- - mor and so forth, not separate images for beetles and ants or for - cloaks and boots). - - NetHack 3.7 December 9, 2020 @@ -6406,59 +6406,59 @@ - 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 ob- + Dean Luick, with help from David Cohrs, developed NetHack + 3.1 for X11. It drew the map as text rather than graphically but + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- + mor 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- - corporated 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 systems that usually had such. @@ -6472,60 +6472,60 @@ - (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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- + corporated 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 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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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 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 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 plat- - form. Paul Winner and Yitzhak Sapir provided encouragement. - - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- - hanced 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- - dows CE port for 3.4.1. NetHack 3.7 December 9, 2020 @@ -6538,13 +6538,25 @@ + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- + form. Paul Winner and Yitzhak Sapir provided encouragement. + + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + hanced 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 inter- + face for the Windows port. Alex Kompel also contributed a Win- + dows 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 + 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 + 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 af- @@ -6553,45 +6565,33 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 + velopment 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 Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the - release of 3.6.0, new members 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 signif- - icant 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 + 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 NetHack 3.7 December 9, 2020 @@ -6604,59 +6604,59 @@ + Stephenson, Janet Walz, and Paul Winner. In early 2015, ahead of + the release of 3.6.0, new members 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 signif- + icant 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 restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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 en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 - security fix and a few bug fixes. - - 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 se- - curity fix and some bug fixes. - - The official NetHack web site is maintained by Ken Lorber at - https://www.nethack.org/. - @@ -6670,22 +6670,34 @@ + 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 security fixes and a small number of bug fixes. + + NetHack 3.6.6 was released on March 8, 2020 containing a se- + curity fix and some bug fixes. + + 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6711,18 +6723,6 @@ 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 @@ -6736,6 +6736,18 @@ + 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 @@ -6743,7 +6755,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6767,18 +6779,6 @@ - - - - - - - - - - - - From e2680bfc4a4014dc10b4f024f7bfe6279efdcbd6 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Dec 2020 05:10:43 -0800 Subject: [PATCH 588/708] add the hardcoded menu control keys to key help '? k' shows menu controls in a fancy layout and '? i' lists the same things in basic layout but both only showed the keys that can be changed via option settings. Add , , and so that all relevant keys are listed together whether re-bindable or not. The description of is accurate for tty and curses but possibly not for other interfaces. This also reorders how the controls are listed, moving next page and previous page before first page and last page, and placing invert between select and deselect rather than after both. --- src/options.c | 127 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 41 deletions(-) diff --git a/src/options.c b/src/options.c index 01a3b29ae..90d2c5b97 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1607591206 2020/12/10 09:06:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.485 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1607692223 2020/12/11 13:10:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.486 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -204,18 +204,19 @@ static NEARDATA const char *runmodes[] = { "teleport", "run", "walk", static NEARDATA const char *sortltype[] = { "none", "loot", "full" }; static const menu_cmd_t default_menu_cmd_info[] = { - { "menu_first_page", MENU_FIRST_PAGE, "Go to first page" }, - { "menu_last_page", MENU_LAST_PAGE, "Go to last page" }, { "menu_next_page", MENU_NEXT_PAGE, "Go to next page" }, { "menu_previous_page", MENU_PREVIOUS_PAGE, "Go to previous page" }, - { "menu_select_all", MENU_SELECT_ALL, "Select all items" }, - { "menu_deselect_all", MENU_UNSELECT_ALL, "Unselect all items" }, - { "menu_invert_all", MENU_INVERT_ALL, "Invert selection" }, - { "menu_select_page", MENU_SELECT_PAGE, "Select items in current page" }, + { "menu_first_page", MENU_FIRST_PAGE, "Go to first page" }, + { "menu_last_page", MENU_LAST_PAGE, "Go to last page" }, + { "menu_select_all", MENU_SELECT_ALL, "Select all items in entire menu" }, + { "menu_invert_all", MENU_INVERT_ALL, "Invert selection for all items" }, + { "menu_deselect_all", MENU_UNSELECT_ALL, + "Unselect all items in entire menu" }, + { "menu_select_page", MENU_SELECT_PAGE, "Select all items on current page" }, + { "menu_invert_page", MENU_INVERT_PAGE, "Invert current page's selections" }, { "menu_deselect_page", MENU_UNSELECT_PAGE, - "Unselect items in current page" }, - { "menu_invert_page", MENU_INVERT_PAGE, "Invert current page selection" }, - { "menu_search", MENU_SEARCH, "Search and toggle matching items" }, + "Unselect all items on current page" }, + { "menu_search", MENU_SEARCH, "Search and invert matching items" }, }; static void FDECL(nmcpy, (char *, const char *, int)); @@ -4808,11 +4809,13 @@ handler_disclose(VOID_ARGS) any.a_char = DISCLOSE_NO_WITHOUT_PROMPT; add_menu(tmpwin, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, "Never disclose, without prompting", - (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE); + (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); any.a_char = DISCLOSE_YES_WITHOUT_PROMPT; add_menu(tmpwin, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, "Always disclose, without prompting", - (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE); + (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); if (*disclosure_names[i] == 'v') { any.a_char = DISCLOSE_SPECIAL_WITHOUT_PROMPT; /* '#' */ add_menu(tmpwin, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, @@ -4823,11 +4826,13 @@ handler_disclose(VOID_ARGS) any.a_char = DISCLOSE_PROMPT_DEFAULT_NO; add_menu(tmpwin, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, "Prompt, with default answer of \"No\"", - (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE); + (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); any.a_char = DISCLOSE_PROMPT_DEFAULT_YES; add_menu(tmpwin, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, "Prompt, with default answer of \"Yes\"", - (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE); + (c == any.a_char) ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); if (*disclosure_names[i] == 'v') { any.a_char = DISCLOSE_PROMPT_DEFAULT_SPECIAL; /* '?' */ add_menu(tmpwin, NO_GLYPH, &any, 0, any.a_char, ATR_NONE, @@ -5080,7 +5085,8 @@ handler_sortloot(VOID_ARGS) any.a_char = *sortl_name; add_menu(tmpwin, NO_GLYPH, &any, *sortl_name, 0, ATR_NONE, sortl_name, (flags.sortloot == *sortl_name) - ? MENU_ITEMFLAGS_SELECTED : MENU_ITEMFLAGS_NONE); + ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); } end_menu(tmpwin, "Select loot sorting type:"); n = select_menu(tmpwin, PICK_ONE, &sortl_pick); @@ -7706,58 +7712,97 @@ int nset; add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, MENU_ITEMFLAGS_NONE); } -/* - * used by cmd.c and pager.c - */ +/* display keys for menu actions; used by cmd.c '?i' and pager.c '?k' */ void show_menu_controls(win, dolist) winid win; boolean dolist; { + struct xtra_cntrls { + const char *key, *desc; + }; + static const struct xtra_cntrls hardcoded[] = { + { "Return", "Accept current choice(s) and dismiss menu" }, + { "Enter", "Same as Return" }, + { "Space", "If not on last page, advance one page;" }, + { " ", "when on last page, treat like Return" }, + { "Escape", "Cancel menu without making any choice(s)" }, + { (char *) 0, (char *) 0} + }; + static const char mc_fmt[] = "%8s %-6s %s", + mc_altfmt[] = "%9s %-6s %s"; char buf[BUFSZ]; + const char *fmt, *arg; + const struct xtra_cntrls *xcp; + + /* + * Relies on spaces to line things up in columns, so must be rendered + * with a fixed-width font or will look dreadful. + */ putstr(win, 0, "Menu control keys:"); - if (dolist) { + if (dolist) { /* key bindings help: '?i' */ int i; + fmt = "%-7s %s"; for (i = 0; i < SIZE(default_menu_cmd_info); i++) { - Sprintf(buf, "%-7s %s", + Sprintf(buf, fmt, visctrl(get_menu_cmd_key(default_menu_cmd_info[i].cmd)), default_menu_cmd_info[i].desc); putstr(win, 0, buf); } - } else { + /* no separator before hardcoded */ + fmt = "%s%-7s %s"; /* extra specifier to absorb 'arg' */ + arg = ""; /* no extra prefix for 'dolist' */ + } else { /* menu controls help: '?k' */ putstr(win, 0, ""); - putstr(win, 0, " Page All items"); - Sprintf(buf, " Select %s %s", - visctrl(get_menu_cmd_key(MENU_SELECT_PAGE)), - visctrl(get_menu_cmd_key(MENU_SELECT_ALL))); + Sprintf(buf, mc_altfmt, "", "Whole", "Current"); putstr(win, 0, buf); - Sprintf(buf, "Deselect %s %s", - visctrl(get_menu_cmd_key(MENU_UNSELECT_PAGE)), - visctrl(get_menu_cmd_key(MENU_UNSELECT_ALL))); + Sprintf(buf, mc_altfmt, "", " Menu", " Page"); putstr(win, 0, buf); - Sprintf(buf, " Invert %s %s", - visctrl(get_menu_cmd_key(MENU_INVERT_PAGE)), - visctrl(get_menu_cmd_key(MENU_INVERT_ALL))); + Sprintf(buf, mc_fmt, "Select", + visctrl(get_menu_cmd_key(MENU_SELECT_ALL)), + visctrl(get_menu_cmd_key(MENU_SELECT_PAGE))); + putstr(win, 0, buf); + Sprintf(buf, mc_fmt, "Invert", + visctrl(get_menu_cmd_key(MENU_INVERT_ALL)), + visctrl(get_menu_cmd_key(MENU_INVERT_PAGE))); + putstr(win, 0, buf); + Sprintf(buf, mc_fmt, "Deselect", + visctrl(get_menu_cmd_key(MENU_UNSELECT_ALL)), + visctrl(get_menu_cmd_key(MENU_UNSELECT_PAGE))); putstr(win, 0, buf); putstr(win, 0, ""); - Sprintf(buf, " Go to %s Next page", - visctrl(get_menu_cmd_key(MENU_NEXT_PAGE))); + Sprintf(buf, mc_fmt, "Go to", + visctrl(get_menu_cmd_key(MENU_NEXT_PAGE)), + "Next page"); putstr(win, 0, buf); - Sprintf(buf, " %s Previous page", - visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE))); + Sprintf(buf, mc_fmt, "", + visctrl(get_menu_cmd_key(MENU_PREVIOUS_PAGE)), + "Previous page"); putstr(win, 0, buf); - Sprintf(buf, " %s First page", - visctrl(get_menu_cmd_key(MENU_FIRST_PAGE))); + Sprintf(buf, mc_fmt, "", + visctrl(get_menu_cmd_key(MENU_FIRST_PAGE)), + "First page"); putstr(win, 0, buf); - Sprintf(buf, " %s Last page", - visctrl(get_menu_cmd_key(MENU_LAST_PAGE))); + Sprintf(buf, mc_fmt, "", + visctrl(get_menu_cmd_key(MENU_LAST_PAGE)), + "Last page"); putstr(win, 0, buf); putstr(win, 0, ""); - Sprintf(buf, " %s Search and toggle matching entries", - visctrl(get_menu_cmd_key(MENU_SEARCH))); + Sprintf(buf, mc_fmt, "Search", + visctrl(get_menu_cmd_key(MENU_SEARCH)), + "Exter a target string and invert all matching entries"); putstr(win, 0, buf); + /* separator before hardcoded */ + putstr(win, 0, ""); + fmt = "%9s %-8s %s"; + arg = "Other "; /* prefix for first hardcoded[] entry, then reset */ + } + for (xcp = hardcoded; xcp->key; ++xcp) { + Sprintf(buf, fmt, arg, xcp->key, xcp->desc); + putstr(win, 0, buf); + arg = ""; } } static int From 6f5a1ccc63615c762d5eac73cc7fb92d36287afd Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Dec 2020 05:26:00 -0800 Subject: [PATCH 589/708] fix Guidebook thinko Fix the recently revised description of "#version". 'windowtype' doesn't have an underscore in it. --- doc/Guidebook.mn | 4 ++-- doc/Guidebook.tex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 27c9d1df8..e109c97fc 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.404 $ $NHDT-Date: 1607643123 2020/12/10 23:32:03 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.405 $ $NHDT-Date: 1607693152 2020/12/11 13:25:52 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -1505,7 +1505,7 @@ Print compile time options for this version of NetHack. .lp "" The second paragraph lists the user interface(s) that are included. If there are more than one, you can use the -.op window_type +.op windowtype option in your run-time configuration file to select the one you want. .lp "" Autocompletes. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 7c2f688ca..6b4a3ab5f 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -1596,7 +1596,7 @@ Print compile time options for this version of {\it NetHack\/}. %.lp The second paragraph lists the user interface(s) that are included. -If there are more than one, you can use the {\it window\verb+_+type\/} +If there are more than one, you can use the {\it windowtype\/} option in your run-time configuration file to select the one you want. %.lp From 69455f404eb8e127f1df5bdca28ba25b570bcec7 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 08:46:39 -0500 Subject: [PATCH 590/708] Guidebook date bump --- 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 e109c97fc..524cd88c9 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "December 9, 2020 +.ds f2 "December 11, 2020 . .\" A note on some special characters: .\" \(lq = left double quote diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 6b4a3ab5f..bbef61f06 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{December 9, 2020} +\date{December 11, 2020} \maketitle From 0d1a8946614bb59fe438af12208a059c00fed478 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 09:11:09 -0500 Subject: [PATCH 591/708] move .travis.yml to outdated for now --- .travis.yml => outdated/.travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .travis.yml => outdated/.travis.yml (100%) diff --git a/.travis.yml b/outdated/.travis.yml similarity index 100% rename from .travis.yml rename to outdated/.travis.yml From affb60dd97dc53c286132670d90326313f7f97f4 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 09:20:26 -0500 Subject: [PATCH 592/708] support for build with current Lua version 5.4.2 This may require make spotless make fetch-lua for some platforms. --- Porting | 2 +- sys/msdos/Makefile.GCC | 6 +++--- sys/msdos/fetch-cross-compiler.sh | 2 +- sys/unix/Makefile.top | 2 +- sys/unix/NetHack.xcodeproj/project.pbxproj | 4 ++-- sys/unix/hints/include/cross-pre.2020 | 6 +++--- sys/winnt/Install.nt | 12 ++++++------ sys/winnt/Makefile.gcc | 8 ++++---- sys/winnt/Makefile.msc | 11 +++++++---- sys/winnt/travis-gcc.sh | 4 ++-- win/win32/vs/NetHack.vcxproj | 3 ++- win/win32/vs/travisci.sh | 2 +- 12 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Porting b/Porting index 6a57e1aae..120292d2e 100644 --- a/Porting +++ b/Porting @@ -207,7 +207,7 @@ need to be included in the packaging of the game. 4.3. Lua Compile and link into a library, or obtain a prebuilt Lua library for -your platform. Place the Lua source into lib/lua-5.4.1 (or other folder +your platform. Place the Lua source into lib/lua-5.4.2 (or other folder representing an appropriate Lua version); place the compiled Lua library into lib. diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index abe561180..6ffb918d0 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -42,13 +42,13 @@ PDCURSES_TOP=../../pdcurses ifeq "$(LUA_VERSION)" "5.3.5" LUAVER=5.3.5 else -LUAVER=5.4.1 +LUAVER=5.4.2 endif #--------------------------------------------------------------- # Location of LUA # # Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.1.tar.gz +# http://www.lua.org/ftp/lua-5.4.2.tar.gz # # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere @@ -305,7 +305,7 @@ ALLOBJ = $(VOBJ) $(SOBJ) $(TILOBJ) $(TILOBJ2) $(VVOBJ) #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.2.tar.gz #================================================================= LUASRC = $(LUATOP)/src diff --git a/sys/msdos/fetch-cross-compiler.sh b/sys/msdos/fetch-cross-compiler.sh index b5267b590..fc78feae7 100644 --- a/sys/msdos/fetch-cross-compiler.sh +++ b/sys/msdos/fetch-cross-compiler.sh @@ -12,7 +12,7 @@ if [ -z "$GCCVER" ]; then fi if [ -z "$LUA_VERSION" ]; then - export LUA_VERSION=5.4.1 + export LUA_VERSION=5.4.2 fi if [ ! -d "$(pwd)/lib" ]; then diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 6c1363aeb..a0824a155 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -75,7 +75,7 @@ VARDAT = $(VARDATD) $(VARDATND) #CHGRP = chgrp # Lua version -LUA_VERSION = 5.4.1 +LUA_VERSION = 5.4.2 # # end of configuration diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index a22cb1e31..807c7231e 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -1381,7 +1381,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_INC_DIR}\necho '/* nhlua.h - generated by Xcode script */' > nhlua.h\necho '#include \"../lib/lua-5.4.1/src/lua.h\"' >> nhlua.h\nsed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' < ${NH_LIB_DIR}/lua-5.4.1/src/lua.h >> nhlua.h\necho '#include \"../lib/lua-5.4.1/src/lualib.h\"' >> nhlua.h\necho '#include \"../lib/lua-5.4.1/src/lauxlib.h\"' >> nhlua.h\necho '/*nhlua.h*/' >> nhlua.h\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_INC_DIR}\necho '/* nhlua.h - generated by Xcode script */' > nhlua.h\necho '#include \"../lib/lua-5.4.2/src/lua.h\"' >> nhlua.h\nsed -e '/(lua_error)/!d' -e '/(lua_error)/s/;/ NORETURN;/1' < ${NH_LIB_DIR}/lua-5.4.2/src/lua.h >> nhlua.h\necho '#include \"../lib/lua-5.4.2/src/lualib.h\"' >> nhlua.h\necho '#include \"../lib/lua-5.4.2/src/lauxlib.h\"' >> nhlua.h\necho '/*nhlua.h*/' >> nhlua.h\n"; }; 544768B8239954B9004B9739 /* Build Lua library */ = { isa = PBXShellScriptBuildPhase; @@ -1400,7 +1400,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_LIB_DIR}\nmkdir -p lua\ncd ${NH_LIB_DIR}/lua-5.4.1/src\nmake a\ncp liblua.a ../../lua\ncd ../../..\n\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncd ${NH_LIB_DIR}\nmkdir -p lua\ncd ${NH_LIB_DIR}/lua-5.4.2/src\nmake a\ncp liblua.a ../../lua\ncd ../../..\n\n"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/sys/unix/hints/include/cross-pre.2020 b/sys/unix/hints/include/cross-pre.2020 index d3cb72a50..99de7f559 100644 --- a/sys/unix/hints/include/cross-pre.2020 +++ b/sys/unix/hints/include/cross-pre.2020 @@ -47,9 +47,9 @@ endif ifdef BUILD_TARGET_LUA #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.2.tar.gz #================================================================= -LUA_VERSION ?=5.4.1 +LUA_VERSION ?=5.4.2 LUATOP ?= ../lib/lua-$(LUA_VERSION) LUASRCDIR ?= $(LUATOP)/src LUAOBJFILES1 = $(TARGETPFX)lapi.o $(TARGETPFX)lauxlib.o \ @@ -148,7 +148,7 @@ ifdef CROSS_TO_MSDOS # 2. Then # make CROSS_TO_MSDOS=1 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 all # -# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.2.tar.gz #================================================================= CFLAGS += -DCROSSCOMPILE diff --git a/sys/winnt/Install.nt b/sys/winnt/Install.nt index 101fb965a..a5ebaca2b 100644 --- a/sys/winnt/Install.nt +++ b/sys/winnt/Install.nt @@ -47,7 +47,7 @@ version. You can use one of the following build environments: | | | +----+ +------+ +-----------+ | | | | | | - share winnt tty win32 Lua-5.4.1 pdcurses + share winnt tty win32 Lua-5.4.2 pdcurses | vs @@ -55,11 +55,11 @@ version. You can use one of the following build environments: | Building And Running Using Visual Studio 2017 or 2019 | \--------------------------------------------------------/ -Before proceeding, please obtain the lua-5.4.1 sources and copy them to -the new directory lib\lua-5.4.1\src. This source can be obtain either from -http://www.lua.org/ftp/lua-5.4.1.tar.gz or from the git hub mirror -https://github.com/lua/lua.git using the tag 'v5.4.1'. The build expects -to find lua files such as 'lua.h' at 'lib\lua-5.4.1\src\lua.h'. +Before proceeding, please obtain the lua-5.4.2 sources and copy them to +the new directory lib\lua-5.4.2\src. This source can be obtain either from +http://www.lua.org/ftp/lua-5.4.2.tar.gz or from the git hub mirror +https://github.com/lua/lua.git using the tag 'v5.4.2'. The build expects +to find lua files such as 'lua.h' at 'lib\lua-5.4.2\src\lua.h'. If you are NOT using Visual Studio 2017 or 2019 IDE, or you prefer to build using a Make utility and a Makefile proceed to "Building Using Make". diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 2df3b9eb6..c2b2d1c16 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -127,7 +127,7 @@ TARGET_CPU=x86 # #--------------------------------------------------------------- ifndef LUA_VERSION -LUAVER=5.4.1 +LUAVER=5.4.2 else LUAVER=$(LUA_VERSION) endif @@ -135,7 +135,7 @@ endif # Location of LUA # # Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.1.tar.gz +# http://www.lua.org/ftp/lua-5.4.2.tar.gz # # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere @@ -416,11 +416,11 @@ OPTIONS_FILE = $(DAT)\options #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.2.tar.gz #================================================================= ifndef LUAVER -LUAVER = 5.4.1 +LUAVER = 5.4.2 endif LUASRC = $(LUATOP)/src LUALIB = $(O)lua-$(LUAVER).static.a diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 3a2d0749a..c793dd878 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -131,7 +131,7 @@ DEBUGINFO = Y # This marks the end of the BUILD DECISIONS section. #============================================================================== !IFNDEF LUA_VERSION -LUAVER=5.4.1 +LUAVER=5.4.2 !ELSE LUAVER=$(LUA_VERSION) !ENDIF @@ -140,7 +140,7 @@ LUAVER=$(LUA_VERSION) # Location of LUA # # Original source needs to be obtained from: -# http://www.lua.org/ftp/lua-5.4.1.tar.gz +# http://www.lua.org/ftp/lua-5.4.2.tar.gz # # This build assumes that the LUA sources are located # at the specified location. If they are actually elsewhere @@ -384,7 +384,7 @@ OPTIONS_FILE = $(DAT)\options #===============-================================================= # LUA library -# Source from http://www.lua.org/ftp/lua-5.4.1.tar.gz +# Source from http://www.lua.org/ftp/lua-5.4.2.tar.gz #================================================================= !IFNDEF LUAVER @@ -397,6 +397,9 @@ LUAVER = 5.4.0 !IF "$(LUATMP)" == "5.4.1" LUAVER = 5.4.1 !ENDIF +!IF "$(LUATMP)" == "5.4.2" +LUAVER = 5.4.2 +!ENDIF !ELSE !ERROR NetHack 3.7 requires LUA so LUATOP must be defined !ENDIF @@ -407,7 +410,7 @@ LUATMP = $(LUATMP:-BETA=) #strip suffix if exists "-BETA" !IF "$(LUATMP)" == "5.3.5" LUAVER = 5.3.5 !ELSE -LUAVER = 5.4.1 +LUAVER = 5.4.2 !ENDIF !ENDIF !ENDIF diff --git a/sys/winnt/travis-gcc.sh b/sys/winnt/travis-gcc.sh index ecdb79a9e..e1d5bf6b7 100644 --- a/sys/winnt/travis-gcc.sh +++ b/sys/winnt/travis-gcc.sh @@ -3,6 +3,6 @@ mkdir -p lib cd lib git clone --depth 1 https://github.com/wmcbrine/PDCurses.git pdcurses #git clone --depth 1 https://github.com/universal-ctags/ctags.git ctags -curl -R -O http://www.lua.org/ftp/lua-5.4.1.tar.gz -tar zxf lua-5.4.1.tar.gz +curl -R -O http://www.lua.org/ftp/lua-5.4.2.tar.gz +tar zxf lua-5.4.2.tar.gz cd ../ diff --git a/win/win32/vs/NetHack.vcxproj b/win/win32/vs/NetHack.vcxproj index 992ae9534..a3c2e0c26 100644 --- a/win/win32/vs/NetHack.vcxproj +++ b/win/win32/vs/NetHack.vcxproj @@ -57,8 +57,9 @@ - true + true true + true false diff --git a/win/win32/vs/travisci.sh b/win/win32/vs/travisci.sh index 0a8f9a01c..d7d48e3f0 100644 --- a/win/win32/vs/travisci.sh +++ b/win/win32/vs/travisci.sh @@ -24,7 +24,7 @@ export LIB=/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/$VSVER/$TOOLSVER export LIB=/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio/$VSVER/$TOOLSVER/VC/Tools/MSVC/$MSVER/lib/x86:$LIB export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/10/lib/$WKITVER/ucrt/x86:$LIB export LIB=/c/Program\ Files\ \(x86\)/Windows\ Kits/10/lib/$WKITVER/um/x86:$LIB -export LUA_VERSION=5.4.1 +export LUA_VERSION=5.4.2 mkdir -p lib cd lib git clone --depth 1 https://github.com/wmcbrine/PDCurses.git pdcurses From cb84c555d77168d11f33f38adc113d7f624a5b77 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 09:25:01 -0500 Subject: [PATCH 593/708] more Lua 5.4.2 bits --- outdated/.travis.yml | 16 ++++++++-------- win/win32/vs/NetHackProperties.props | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/outdated/.travis.yml b/outdated/.travis.yml index 81bb145b9..454ca418e 100644 --- a/outdated/.travis.yml +++ b/outdated/.travis.yml @@ -3,7 +3,7 @@ matrix: include: - name: linux-xenial-gcc-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.1 + env: HINTS=linux.2020 LUA_VERSION=5.4.2 compiler: gcc addons: apt: @@ -21,7 +21,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-bionic-gcc-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.1 + env: HINTS=linux.2020 LUA_VERSION=5.4.2 dist: bionic compiler: gcc addons: @@ -40,7 +40,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-focal-clang-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.1 + env: HINTS=linux.2020 LUA_VERSION=5.4.2 dist: focal compiler: clang addons: @@ -59,7 +59,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-xenial-gcc-nocommon os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.1 + env: HINTS=linux.2020 LUA_VERSION=5.4.2 dist: xenial compiler: gcc script: @@ -70,7 +70,7 @@ matrix: - make install - name: linux-focal-gcc9-win-all os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.1 + env: HINTS=linux.2020 LUA_VERSION=5.4.2 dist: focal compiler: gcc addons: @@ -91,7 +91,7 @@ matrix: - make LUA_VERSION=$LUA_VERSION WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc install - name: linux-xenial-gcc-minimal os: linux - env: HINTS=linux-minimal LUA_VERSION=5.4.1 + env: HINTS=linux-minimal LUA_VERSION=5.4.2 compiler: gcc script: | cd sys/unix/ && sh setup.sh hints/$HINTS && cd ../../ @@ -129,7 +129,7 @@ matrix: script: - export ADD_CURSES=Y - export PDCURSES_TOP=../lib/pdcurses - - export LUA_VERSION=5.4.1 + - export LUA_VERSION=5.4.2 - sh sys/winnt/travis-gcc.sh - test -d "lib/lua-$LUA_VERSION/src" || exit 0 - test -d "lib/pdcurses" || exit 0 @@ -138,7 +138,7 @@ matrix: - mingw32-make LUA_VERSION=$LUA_VERSION install - name: msdos-linux-focal-djgpp-crosscompile os: linux - env: HINTS=linux.2020 LUA_VERSION=5.4.1 + env: HINTS=linux.2020 LUA_VERSION=5.4.2 dist: focal compiler: gcc script: diff --git a/win/win32/vs/NetHackProperties.props b/win/win32/vs/NetHackProperties.props index c9a904613..25f634a7b 100644 --- a/win/win32/vs/NetHackProperties.props +++ b/win/win32/vs/NetHackProperties.props @@ -5,7 +5,7 @@ 3 7 0 - 5.4.1 + 5.4.2 true From ee6645cdaf592b038f4a6b23c28d944417d4dd52 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 11 Dec 2020 09:24:04 -0500 Subject: [PATCH 594/708] This is cron-daily v1-Jan-20-2020. guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 210 +++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index c051c4597..7b2cb3b1f 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - December 9, 2020 + December 11, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1182,7 +1182,7 @@ into its own inventory slot. If it has a name assigned, - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1248,7 +1248,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1314,7 +1314,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1380,7 +1380,7 @@ Offer a sacrifice to the gods. Autocompletes. Default key - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1446,7 +1446,7 @@ your intent before praying. It is enabled by default, and - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1512,7 +1512,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1578,7 +1578,7 @@ the shell command `fg' to return to the game. Default key - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1644,7 +1644,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1668,8 +1668,8 @@ The second paragraph lists the user interface(s) that are included. If there are more than one, you can use the win- - dow_type option in your run-time configuration file to se- - lect the one you want. + dowtype option in your run-time configuration file to select + the one you want. Autocompletes. Default key is `M-v'. @@ -1710,7 +1710,7 @@ mode only. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1776,7 +1776,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1842,7 +1842,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1908,7 +1908,7 @@ which may be open, closed, or locked. To open a closed door, use - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -1974,7 +1974,7 @@ the `s' (search) command (multiple attempts are often needed; if - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2040,7 +2040,7 @@ new boulders with a scroll of earth. However, doing such things - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2106,7 +2106,7 @@ needs to be compatible with the type of merchandise carried by - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2172,7 +2172,7 @@ list all objects no matter how big a pile is. Note that the - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2238,7 +2238,7 @@ main dungeon) is a tribute to the ancestor game hack's - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2304,7 +2304,7 @@ ster has moved, you will attack empty air. If you guess that the - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2370,7 +2370,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2436,7 +2436,7 @@ Strained, Overtaxed, or Overloaded will be shown on the bottom - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2502,7 +2502,7 @@ curse state provided that you can see them land. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2568,7 +2568,7 @@ taneously as primary and secondary; use the `X' command to engage - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2634,7 +2634,7 @@ mode) would ensure that at most 2 arrows are shot even if you - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2700,7 +2700,7 @@ use. To wield two weapons, you need to use the "#twoweapon" - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2766,7 +2766,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2832,7 +2832,7 @@ vegetarian players can, but with some rather unpleasant side- - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2898,7 +2898,7 @@ warned, however, for this is often unwise. Other types of wands - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -2964,7 +2964,7 @@ attempt backfires. Reading a cursed spellbook or one with mystic - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3030,7 +3030,7 @@ Amulets. Other tools (such as pick-axe) can be wielded as - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3096,7 +3096,7 @@ tile weapons (if you have a sling). In the most desperate of - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3162,7 +3162,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3228,7 +3228,7 @@ brains while polymorphed into a mind flayer, is considered eating - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3294,7 +3294,7 @@ can't be bypassed, such as being unable to push a boulder - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3360,7 +3360,7 @@ Soko-Prize - Explored to the top of Sokoban - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3426,7 +3426,7 @@ NetHack should do things, there are options you can set to change - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3492,7 +3492,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3558,7 +3558,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3624,7 +3624,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3690,7 +3690,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3756,7 +3756,7 @@ tion controls whether the description includes map coordinates. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3822,7 +3822,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3888,7 +3888,7 @@ display for end-of-game disclosure follows a set sequence. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -3954,7 +3954,7 @@ "no", you will exclude that gender from being picked randomly. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4020,7 +4020,7 @@ sistent. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4086,7 +4086,7 @@ menu of matching objects for selection. Partial skips the - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4152,7 +4152,7 @@ mented by the Amiga, Gem, X11 and tty ports. Default `:'. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4218,7 +4218,7 @@ news is shown at the beginning of the game, there's no point in - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4284,7 +4284,7 @@ ing a peaceful monster; - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4350,7 +4350,7 @@ Specify the type of your initial pet, if you are playing a - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4416,7 +4416,7 @@ being underwater or engulfed, ignore this option. It does not - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4482,7 +4482,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4548,7 +4548,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4614,7 +4614,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4680,7 +4680,7 @@ be the first non-comment line. For a comma-separated list in - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4746,7 +4746,7 @@ if NetHack can, it should use a font by the chosen name for the - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4812,7 +4812,7 @@ If NetHack can, it should pop up dialog boxes, or use prompts - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4878,7 +4878,7 @@ statuslines can only be set in the configuration file or via - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -4944,7 +4944,7 @@ foreground/background colors. Windows GUI only. The format is - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5010,7 +5010,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5076,7 +5076,7 @@ Set the intensity level of the three gray scales available - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5142,7 +5142,7 @@ any corpse from autopickup. The last example results in the - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5208,7 +5208,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5274,7 +5274,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5340,7 +5340,7 @@ Prefix key to move without picking up items. Default is `m'. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5406,7 +5406,7 @@ norep - show the message once, but not again if no other - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5472,7 +5472,7 @@ MENUCOLOR="* cursed *(being worn)"=red&underline - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5538,7 +5538,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5604,7 +5604,7 @@ dice", an approximation of experience level displayed when - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5670,7 +5670,7 @@ is below or above. If the prefix is `<' or `>', only - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5736,7 +5736,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5802,7 +5802,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5868,7 +5868,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -5934,7 +5934,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6000,7 +6000,7 @@ game messages to an external program, such as a text-to-speech - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6066,7 +6066,7 @@ coordinates relative to your character. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6132,7 +6132,7 @@ bones file content in ascii text. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6198,7 +6198,7 @@ %D - current time, YYYYMMDDhhmmss format - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6264,7 +6264,7 @@ It is initiated by starting the game with the -D command-line - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6330,7 +6330,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6396,7 +6396,7 @@ Michael Allison ported NetHack 3.1 to Windows NT. - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6462,7 +6462,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6528,7 +6528,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6594,7 +6594,7 @@ Jessie Collet, Ken Lorber, Dean Luick, Pat Rankin, Mike - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6660,7 +6660,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6726,7 +6726,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 @@ -6792,7 +6792,7 @@ - NetHack 3.7 December 9, 2020 + NetHack 3.7 December 11, 2020 From d5a8f783e0e286a674485cafd2aeb5cfa21e3c8e Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 11 Dec 2020 09:24:07 -0500 Subject: [PATCH 595/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Files b/Files index a7cfe86b1..c2102a2cf 100644 --- a/Files +++ b/Files @@ -7,9 +7,8 @@ from or not transferred to your system if you wish. .: (files in top directory) -.clang-format .travis.yml Cross-compiling -Files Porting README -azure-pipelines.yml +.clang-format Cross-compiling Files +Porting README azure-pipelines.yml DEVEL: (files for people developing changes to NetHack) @@ -110,6 +109,10 @@ you.h youprop.h (file for tty versions) wintty.h +outdated: +(files that are no longer maintained for current game code) +.travis.yml + outdated/include: (files that are no longer maintained for current game code) amiconf.h beconf.h def_os2.h mac-carbon.h mac-qt.h From ea93c17fa70c7d1f0ceecfeed2107dcac96fc0eb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 11 Dec 2020 19:49:21 +0200 Subject: [PATCH 596/708] Monsters can revive corpses on floor with undead turning ... but only if the corpse is in direct line from the monster to hero --- doc/fixes37.0 | 2 ++ include/extern.h | 1 + src/mthrowu.c | 37 ++++++++++++++++++++ src/muse.c | 89 +++++++++++++++++++++++++++++++----------------- 4 files changed, 98 insertions(+), 31 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 104142e2d..cc5b3f954 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -324,6 +324,8 @@ brown pudding monster hitting another monster with decay attack corroded armor and ^A/re-do was suppressed due lack of obsolete '#define REDO' add missing key binding support for rush.numpad; default is M-5 for numpad==1 or plain 5 for numpad==2 where behavior of 5 and M-5 are swapped +allow monsters to use wand of undead turning to revive corpses on floor + in some situations Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index bbb2fd88d..cef35a4d8 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1683,6 +1683,7 @@ E int FDECL(ohitmon, (struct monst *, struct obj *, int, BOOLEAN_P)); E void FDECL(thrwmu, (struct monst *)); E int FDECL(spitmu, (struct monst *, struct attack *)); E int FDECL(breamu, (struct monst *, struct attack *)); +E boolean FDECL(linedup_callback, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, boolean FDECL((*), (int,int)))); E boolean FDECL(linedup, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, int)); E boolean FDECL(lined_up, (struct monst *)); E struct obj *FDECL(m_carrying, (struct monst *, int)); diff --git a/src/mthrowu.c b/src/mthrowu.c index 2f21e543e..c5064e37d 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -969,6 +969,43 @@ struct attack *mattk; return breamm(mtmp, mattk, &g.youmonst); } +/* Move from (ax,ay) to (bx,by), but only if distance is up to BOLT_LIM + and only in straight line or diagonal, calling fnc for each step. + Stops if fnc return TRUE, or if step was blocked by wall or closed door. + Returns TRUE if fnc returned TRUE. */ +boolean +linedup_callback(ax, ay, bx, by, fnc) +xchar ax, ay, bx, by; +boolean FDECL((*fnc), (int, int)); +{ + int dx, dy; + + /* These two values are set for use after successful return. */ + g.tbx = ax - bx; + g.tby = ay - by; + + /* sometimes displacement makes a monster think that you're at its + own location; prevent it from throwing and zapping in that case */ + if (!g.tbx && !g.tby) + return FALSE; + + if ((!g.tbx || !g.tby || abs(g.tbx) == abs(g.tby)) /* straight line or diagonal */ + && distmin(g.tbx, g.tby, 0, 0) < BOLT_LIM) { + dx = sgn(ax - bx), dy = sgn(ay - by); + do { + /* is guaranteed to eventually converge with */ + bx += dx, by += dy; + if (!isok(bx, by)) + return FALSE; + if (IS_ROCK(levl[bx][by].typ) || closed_door(bx, by)) + return FALSE; + if ((*fnc)(bx, by)) + return TRUE; + } while (bx != ax || by != ay); + } + return FALSE; +} + boolean linedup(ax, ay, bx, by, boulderhandling) register xchar ax, ay, bx, by; diff --git a/src/muse.c b/src/muse.c index d82792d4a..94401d056 100644 --- a/src/muse.c +++ b/src/muse.c @@ -20,6 +20,8 @@ static void FDECL(mplayhorn, (struct monst *, struct obj *, BOOLEAN_P)); static void FDECL(mreadmsg, (struct monst *, struct obj *)); static void FDECL(mquaffmsg, (struct monst *, struct obj *)); static boolean FDECL(m_use_healing, (struct monst *)); +static boolean FDECL(linedup_chk_corpse, (int, int)); +static void FDECL(m_use_undead_turning, (struct monst *, struct obj *)); static int FDECL(mbhitm, (struct monst *, struct obj *)); static void FDECL(mbhit, (struct monst *, int, int FDECL((*), (MONST_P, OBJ_P)), @@ -1134,6 +1136,60 @@ struct monst *mtmp; /*#define MUSE_WAN_UNDEAD_TURNING 20*/ /* also a defensive item so don't * redefine; nonconsecutive value is ok */ +static boolean +linedup_chk_corpse(x, y) +int x, y; +{ + return (sobj_at(CORPSE, x, y) != 0); +} + +static void +m_use_undead_turning(mtmp, obj) +struct monst *mtmp; +struct obj *obj; +{ + int ax = u.ux + sgn(mtmp->mux - mtmp->mx) * 3, + ay = u.uy + sgn(mtmp->muy - mtmp->my) * 3; + int bx = mtmp->mx, by = mtmp->my; + + if (!(obj->otyp == WAN_UNDEAD_TURNING && obj->spe > 0)) + return; + + /* not necrophiliac(); unlike deciding whether to pick this + type of wand up, we aren't interested in corpses within + carried containers until they're moved into open inventory; + we don't check whether hero is poly'd into an undead--the + wand's turning effect is too weak to be a useful direct + attack--only whether hero is carrying at least one corpse */ + if (carrying(CORPSE)) { + /* + * Hero is carrying one or more corpses but isn't wielding + * a cockatrice corpse (unless being hit by one won't do + * the monster much harm); otherwise we'd be using this wand + * as a defensive item with higher priority. + * + * Might be cockatrice intended as a weapon (or being denied + * to glove-wearing monsters for use as a weapon) or lizard + * intended as a cure or lichen intended as veggy food or + * sacrifice fodder being lugged to an altar. Zapping with + * this will deprive hero of one from each stack although + * they might subsequently be recovered after killing again. + * In the sacrifice fodder case, it could even be to the + * player's advantage (fresher corpse if a new one gets + * dropped; player might not choose to spend a wand charge + * on that when/if hero acquires this wand). + */ + g.m.offensive = obj; + g.m.has_offense = MUSE_WAN_UNDEAD_TURNING; + } else if (linedup_callback(ax, ay, bx, by, linedup_chk_corpse)) { + /* There's a corpse on the ground in a direct line from the + * monster to the hero, and up to 3 steps beyond. + */ + g.m.offensive = obj; + g.m.has_offense = MUSE_WAN_UNDEAD_TURNING; + } +} + /* Select an offensive item/action for a monster. Returns TRUE iff one is * found. */ @@ -1208,34 +1264,7 @@ struct monst *mtmp; } } nomore(MUSE_WAN_UNDEAD_TURNING); - if (obj->otyp == WAN_UNDEAD_TURNING && obj->spe > 0 - /* not necrophiliac(); unlike deciding whether to pick this - type of wand up, we aren't interested in corpses within - carried containers until they're moved into open inventory; - we don't check whether hero is poly'd into an undead--the - wand's turning effect is too weak to be a useful direct - attack--only whether hero is carrying at least one corpse */ - && carrying(CORPSE)) { - /* - * Hero is carrying one or more corpses but isn't wielding - * a cockatrice corpse (unless being hit by one won't do - * the monster much harm); otherwise we'd be using this wand - * as a defensive item with higher priority. - * - * Might be cockatrice intended as a weapon (or being denied - * to glove-wearing monsters for use as a weapon) or lizard - * intended as a cure or lichen intended as veggy food or - * sacrifice fodder being lugged to an altar. Zapping with - * this will deprive hero of one from each stack although - * they might subsequently be recovered after killing again. - * In the sacrifice fodder case, it could even be to the - * player's advantage (fresher corpse if a new one gets - * dropped; player might not choose to spend a wand charge - * on that when/if hero acquires this wand). - */ - g.m.offensive = obj; - g.m.has_offense = MUSE_WAN_UNDEAD_TURNING; - } + m_use_undead_turning(mtmp, obj); nomore(MUSE_WAN_STRIKING); if (obj->otyp == WAN_STRIKING && obj->spe > 0) { g.m.offensive = obj; @@ -2342,11 +2371,9 @@ struct obj *obj; if (typ == WAN_POLYMORPH) return (boolean) (mons[monsndx(mon->data)].difficulty < 6); if (objects[typ].oc_dir == RAY || typ == WAN_STRIKING + || typ == WAN_UNDEAD_TURNING || typ == WAN_TELEPORTATION || typ == WAN_CREATE_MONSTER) return TRUE; - if (typ == WAN_UNDEAD_TURNING) - return (necrophiliac(g.invent, TRUE) - || (Upolyd && is_undead(g.youmonst.data))); break; case POTION_CLASS: if (typ == POT_HEALING || typ == POT_EXTRA_HEALING From abca3d26db71e48b73c450c0af372f7a537734d0 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 15:34:43 -0500 Subject: [PATCH 597/708] another Lua version bit, this one a recent addition --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 02d614c8f..30324cf9b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,7 +15,7 @@ resources: - repository: luarepo type: github name: lua/lua - ref: refs/tags/v5.4.1 + ref: refs/tags/v5.4.2 endpoint: github.com_barthouse steps: @@ -39,7 +39,7 @@ steps: - task: CopyFiles@2 inputs: SourceFolder: $(Agent.BuildDirectory)\s\lua - TargetFolder: $(Agent.BuildDirectory)\s\NetHack\lib\lua-5.4.1\src + TargetFolder: $(Agent.BuildDirectory)\s\NetHack\lib\lua-5.4.2\src condition: eq( variables['Agent.OS'], 'Windows_NT' ) - task: MSBuild@1 From 6dc033e5d8f482bbd8fe813bbaf60df7022a8456 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 16:28:59 -0500 Subject: [PATCH 598/708] don't miss the special furniture checks during liquid flow Closes #405 --- doc/fixes37.0 | 2 ++ src/dig.c | 55 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index cc5b3f954..5f7211531 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -419,6 +419,8 @@ options help ('? g') listed all boolean options, then repeated them among change name of #wizlevelflip to #wizfliplevel dwarves could sometimes pass through walls without digging their way fix genetic engineers dropping Schroedinger's cat box +the checks and handling for fountains, sinks, and drawbridges were being + missed during liquid_flow curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/dig.c b/src/dig.c index 7c3e603c2..15553d11b 100644 --- a/src/dig.c +++ b/src/dig.c @@ -13,6 +13,7 @@ static int NDECL(dig); static void FDECL(dig_up_grave, (coord *)); static int FDECL(adj_pit_checks, (coord *, char *)); static void FDECL(pit_flow, (struct trap *, SCHAR_P)); +static boolean FDECL(furniture_handled, (int, int, BOOLEAN_P)); /* Indices returned by dig_typ() */ enum dig_types { @@ -489,6 +490,33 @@ dig(VOID_ARGS) return 1; } +static boolean +furniture_handled(x, y, madeby_u) +int x, y; +boolean madeby_u; +{ + struct rm *lev = &levl[x][y]; + + if (IS_FOUNTAIN(lev->typ)) { + dogushforth(FALSE); + SET_FOUNTAIN_WARNED(x, y); /* force dryup */ + dryup(x, y, madeby_u); + } else if (IS_SINK(lev->typ)) { + breaksink(x, y); + } else if (lev->typ == DRAWBRIDGE_DOWN + || (is_drawbridge_wall(x, y) >= 0)) { + int bx = x, by = y; + + /* if under the portcullis, the bridge is adjacent */ + (void) find_drawbridge(&bx, &by); + destroy_drawbridge(bx, by); + } else { + return FALSE; + } + return TRUE; +} + + /* When will hole be finished? Very rough indication used by shopkeeper. */ int holetime() @@ -558,25 +586,8 @@ int ttyp; reset_utrap(FALSE); } - /* these furniture checks were in dighole(), but wand - breaking bypasses that routine and calls us directly */ - if (IS_FOUNTAIN(lev->typ)) { - dogushforth(FALSE); - SET_FOUNTAIN_WARNED(x, y); /* force dryup */ - dryup(x, y, madeby_u); + if (furniture_handled(x, y, madeby_u)) return; - } else if (IS_SINK(lev->typ)) { - breaksink(x, y); - return; - } else if (lev->typ == DRAWBRIDGE_DOWN - || (is_drawbridge_wall(x, y) >= 0)) { - int bx = x, by = y; - - /* if under the portcullis, the bridge is adjacent */ - (void) find_drawbridge(&bx, &by); - destroy_drawbridge(bx, by); - return; - } if (ttyp != PIT && (!Can_dig_down(&u.uz) && !lev->candig)) { impossible("digactualhole: can't dig %s on this level.", @@ -876,9 +887,11 @@ coord *cc; lev->flags = 0; if (typ != ROOM) { - lev->typ = typ; - liquid_flow(dig_x, dig_y, typ, ttmp, - "As you dig, the hole fills with %s!"); + if (!furniture_handled((int) dig_x, (int) dig_y, TRUE)) { + lev->typ = typ; + liquid_flow(dig_x, dig_y, typ, ttmp, + "As you dig, the hole fills with %s!"); + } return TRUE; } From 51e967ee4245ed1d49665492c8f0db714e888380 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Dec 2020 17:01:43 -0800 Subject: [PATCH 599/708] warning suppression - unused static routine --- src/muse.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/muse.c b/src/muse.c index 94401d056..e30bee61e 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 muse.c $NHDT-Date: 1605726852 2020/11/18 19:14:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.134 $ */ +/* NetHack 3.7 muse.c $NHDT-Date: 1607734843 2020/12/12 01:00:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.136 $ */ /* Copyright (C) 1990 by Ken Arromdee */ /* NetHack may be freely redistributed. See license for details. */ @@ -30,7 +30,9 @@ static struct permonst *FDECL(muse_newcham_mon, (struct monst *)); static int FDECL(mloot_container, (struct monst *mon, struct obj *, BOOLEAN_P)); static void FDECL(you_aggravate, (struct monst *)); +#if 0 static boolean FDECL(necrophiliac, (struct obj *, BOOLEAN_P)); +#endif static void FDECL(mon_consume_unstone, (struct monst *, struct obj *, BOOLEAN_P, BOOLEAN_P)); static boolean FDECL(cures_stoning, (struct monst *, struct obj *, @@ -2321,6 +2323,7 @@ struct monst *mtmp; return 0; } +#if 0 /* check whether hero is carrying a corpse or contained petrifier corpse */ static boolean necrophiliac(objlist, any_corpse) @@ -2337,6 +2340,7 @@ boolean any_corpse; } return FALSE; } +#endif boolean searches_for_item(mon, obj) From 0d0900b3a41180fa45ae8eb2739e0d4d5ae82919 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Dec 2020 17:15:21 -0800 Subject: [PATCH 600/708] dowhatis formatting for Qt The '/' command's variants /o, /O, /m, and /M use spaces to align output in columns and that looks quite bad if rendered in a proportional font. Qt normally uses proportional font for text windows but it watches the supplied lines for any with four consecutive spaces and forces fixed-width font if it sees any. So changing the existing separator line from "" to " " makes Qt format the dowhatis data as intended. --- src/pager.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pager.c b/src/pager.c index 991b633b9..5d5fdcce4 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1607591207 2020/12/10 09:06:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1607735717 2020/12/12 01:15:17 $ $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. */ @@ -1252,7 +1252,8 @@ coord *click_cc; any.a_char = '?'; add_menu(win, NO_GLYPH, &any, flags.lootabc ? 0 : any.a_char, 'n', ATR_NONE, - "something else (by symbol or name)", MENU_ITEMFLAGS_NONE); + "something else (by symbol or name)", + MENU_ITEMFLAGS_NONE); if (!u.uswallow && !Hallucination) { any = cg.zeroany; add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, @@ -1489,7 +1490,10 @@ boolean do_mons; /* True => monsters, False => objects */ Sprintf(outbuf, "All %s currently shown on the map:", which); putstr(win, 0, outbuf); - putstr(win, 0, ""); + /* hack alert! Qt watches a text window for any line + with 4 consecutive spaces and renders the window + in a fixed-width font it if finds at least one */ + putstr(win, 0, " "); /* separator */ } /* prefix: "coords C " where 'C' is mon or obj symbol */ Sprintf(outbuf, (cmode == GPCOORDS_SCREEN) ? "%s " From 5b709fcb550dd6d8dcf6a3eaeae866d564539914 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Dec 2020 18:11:27 -0800 Subject: [PATCH 601/708] Qt text search crash fix About 5 weeks ago, commit e4106bb1613da808ae87780dfeedb4c80e6afc2a changed Qt's searching in text windows to be able to find a match on the very first line. It assumed that the first line would be the current line except when repeating the same search after a match. But after a failed search the current line index is -1 and starting a new search would crash trying to look that line up. --- win/Qt/qt_menu.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index ab8b59ea7..1a549a8e0 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -1192,6 +1192,8 @@ void NetHackQtTextWindow::Search() if (get_a_line) { int linecount = lines->count(); int current = lines->currentRow(); + if (current == -1) + current = 0; // when no row is highlighted (selected), start the search // on the current row, otherwise start on the row after it // [normally means that the very first row is a candidate From fe874db0b3ee850510c0946f0c1b3c7c3ec842ef Mon Sep 17 00:00:00 2001 From: Bart House Date: Fri, 11 Dec 2020 18:45:44 -0800 Subject: [PATCH 602/708] Fix Windows build break caused by bump to lua 5.4.2. Modified Windows build to use submodules/lua for lua source. --- .gitmodules | 3 +++ azure-pipelines.yml | 2 +- submodules/lua | 1 + win/win32/vs/NetHackW.vcxproj | 1 + win/win32/vs/dirs.props | 2 +- win/win32/vs/makedefs.vcxproj | 6 +++--- 6 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .gitmodules create mode 160000 submodules/lua diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..c08764d7e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "submodules/lua"] + path = submodules/lua + url = https://github.com/lua/lua.git diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 30324cf9b..2c6eda1c5 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -20,7 +20,7 @@ resources: steps: - checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack -- checkout: luarepo # $(Agent.BuildDirectory)\s\lua + submodules: true - task: DownloadSecureFile@1 name: storeKey diff --git a/submodules/lua b/submodules/lua new file mode 160000 index 000000000..e2ea3b31c --- /dev/null +++ b/submodules/lua @@ -0,0 +1 @@ +Subproject commit e2ea3b31c94bb3e1da27c233661cb2a16699c685 diff --git a/win/win32/vs/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj index 61026d3a0..e9b5d7dd5 100644 --- a/win/win32/vs/NetHackW.vcxproj +++ b/win/win32/vs/NetHackW.vcxproj @@ -53,6 +53,7 @@ true true + true false diff --git a/win/win32/vs/dirs.props b/win/win32/vs/dirs.props index 05b6543ac..ed8a7554f 100644 --- a/win/win32/vs/dirs.props +++ b/win/win32/vs/dirs.props @@ -10,7 +10,7 @@ $(RootDir)dat\ $(RootDir)doc\ $(RootDir)include\ - $(RootDir)lib\lua-$(LUA_VERSION)\src\ + $(RootDir)submodules\lua\ $(RootDir)src\ $(RootDir)sys\ $(RootDir)util\ diff --git a/win/win32/vs/makedefs.vcxproj b/win/win32/vs/makedefs.vcxproj index 190952a6a..f82bb2c9a 100644 --- a/win/win32/vs/makedefs.vcxproj +++ b/win/win32/vs/makedefs.vcxproj @@ -55,10 +55,10 @@ Outputs="$(IncDir)\nhlua.h"> - + - - + + From d008d6c995cec54aa2433049f117ebc2ceed56a5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 11 Dec 2020 22:35:37 -0500 Subject: [PATCH 603/708] use .Substring to limit maintenance to major Lua version releases only --- win/win32/vs/NetHack.vcxproj | 6 ++---- win/win32/vs/NetHackW.vcxproj | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/win/win32/vs/NetHack.vcxproj b/win/win32/vs/NetHack.vcxproj index a3c2e0c26..6103c7d87 100644 --- a/win/win32/vs/NetHack.vcxproj +++ b/win/win32/vs/NetHack.vcxproj @@ -57,10 +57,8 @@ - true - true - true - false + true + false diff --git a/win/win32/vs/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj index e9b5d7dd5..d49463e30 100644 --- a/win/win32/vs/NetHackW.vcxproj +++ b/win/win32/vs/NetHackW.vcxproj @@ -51,10 +51,8 @@ - true - true - true - false + true + false From f48932883638267802607b1a256c60a303374fbe Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Fri, 11 Dec 2020 22:24:07 -0500 Subject: [PATCH 604/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Files b/Files index c2102a2cf..61f5315e8 100644 --- a/Files +++ b/Files @@ -226,6 +226,10 @@ uhitm.c vault.c version.c vision.c weapon.c were.c wield.c windows.c wizard.c worm.c worn.c write.c zap.c +submodules: +(file in top directory) +lua + sys/libnh: (files in top directory) README.md libnhmain.c sysconf From 8d65d6dbf013525355486141aaa51519d1069549 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 11 Dec 2020 22:32:38 -0800 Subject: [PATCH 605/708] fix #H3134 - selling container for credit If a container holds anything that a shop wouldn't ordinarily buy and sell and you sell it for gold, the 'foreign' contents are marked no_charge and hero still owns them. But selling the same container+contents for credit instead of gold would take shop possession of all the contents without increasing the credit amount. The fixes entry is longer than the fix. It solves cited case but I won't be surprised much if it messes up some other case(s). --- doc/fixes37.0 | 9 ++++++++- src/shk.c | 15 ++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 5f7211531..3ad0e9471 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.383 $ $NHDT-Date: 1607641577 2020/12/10 23:06:17 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.386 $ $NHDT-Date: 1607754748 2020/12/12 06:32:28 $ General Fixes and Modified Features ----------------------------------- @@ -326,6 +326,11 @@ add missing key binding support for rush.numpad; default is M-5 for numpad==1 or plain 5 for numpad==2 where behavior of 5 and M-5 are swapped allow monsters to use wand of undead turning to revive corpses on floor in some situations +selling a container to a shop for gold leaves any contents that the shop + doesn't ordinarily buy and sell owned by the hero, but selling the + container for credit resulted in the shop taking poesession of such + contents without giving any additional credit; mark out of place + contents 'no_charge' so that hero can reclaim them without buying Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -426,6 +431,8 @@ curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support Qt: at Xp levels above 20 with 'showexp' On, the combined status field "Level:NN/nnnnnnnn" was too big and truncated by a char at each end +Qt: searching a text window for something that wasn't found and then searching + for some other target could crash tty: redraw unexplored locations as S_unexplored rather than after map has been partially overwritten by popup menu or text display tty: previous change resulted in remnants of previous level being shown on diff --git a/src/shk.c b/src/shk.c index 64afd3207..2d1eb5b36 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1606343581 2020/11/25 22:33:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ +/* NetHack 3.7 shk.c $NHDT-Date: 1607754748 2020/12/12 06:32:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.193 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3192,13 +3192,14 @@ xchar x, y; c = 'n'; if (c == 'y') { - shk_names_obj( - shkp, obj, - (g.sell_how != SELL_NORMAL) - ? "traded %s for %ld zorkmid%s in %scredit." - : "relinquish %s and acquire %ld zorkmid%s in %scredit.", - tmpcr, (eshkp->credit > 0L) ? "additional " : ""); + shk_names_obj(shkp, obj, + ((g.sell_how != SELL_NORMAL) + ? "traded %s for %ld zorkmid%s in %scredit." + : "relinquish %s and acquire %ld zorkmid%s in %scredit."), + tmpcr, (eshkp->credit > 0L) ? "additional " : ""); eshkp->credit += tmpcr; + if (container) + dropped_container(obj, shkp, TRUE); subfrombill(obj, shkp); } else { if (c == 'q') From 704b11fb056ecc29d8868ca8e7529b6eaada3bbb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 12 Dec 2020 20:53:48 +0200 Subject: [PATCH 606/708] Add some new demonic and angelic maledictions From SpliceHack --- dat/quest.lua | 11 +++++++++++ doc/fixes37.0 | 1 + 2 files changed, 12 insertions(+) diff --git a/dat/quest.lua b/dat/quest.lua index d23208b36..4a9f275bf 100644 --- a/dat/quest.lua +++ b/dat/quest.lua @@ -82,6 +82,10 @@ questtext = { "\"Thou art but a godless void.\"", "\"Thou art not worthy to seek the Amulet.\"", "\"No one expects the Spanish Inquisition!\"", + "\"Judgment hath been passed upon thee, %p.\"", + "\"Thy reckoning is at hand, %p.\"", + "\"Thou shalt be brought before %D for thy crimes!\"", + "\"With %D as my witness, I shall strike thee down.\"", }, banished = { synopsis = "[You are banished from %H for betraying your allegiance to %d.]", @@ -118,6 +122,13 @@ Go now! You are banished from this place.]], "\"Verily, thy corpse could not smell worse!\"", "\"Wait! I shall polymorph into a grid bug to give thee a fighting chance!\"", "\"Why search for the Amulet? Thou wouldst but lose it, cretin.\"", + "\"Thou ought to be a comedian, thy skills are so laughable!\"", + "\"Thy gaze is so vacant, I thought thee a floating eye!\"", + "\"Thy head is unfit for a mind flayer to munch upon!\"", + "\"Only thy reflection could love thee!\"", + "\"Hast thou considered masking thy odor?\"", + "\"Hold! Thy face is a most exquisite torture!\"", + "\"I wouldst fart in thy direction, but it might improve thy smell!\"", }, legacy = { synopsis = "[%dC has chosen you to recover the Amulet of Yendor for %dI.]", diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 3ad0e9471..bc44a85e5 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -331,6 +331,7 @@ selling a container to a shop for gold leaves any contents that the shop container for credit resulted in the shop taking poesession of such contents without giving any additional credit; mark out of place contents 'no_charge' so that hero can reclaim them without buying +add some new demonic and angelic maledictions Fixes to 3.7.0-x Problems that Were Exposed Via git Repository From bbc5cee97f06ff9938fda196d3360ceac914516d Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 12 Dec 2020 11:47:44 -0800 Subject: [PATCH 607/708] Fix Azure pipeline introduced by only checking out a single repository. If checking out a single repository, the repository is checked out to the path $(Agent.BuildDirectory)\s instead of $(Agent.BuildDirectory)\s\. Modified checkout to hard code path to avoid this change in behavior. --- azure-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 2c6eda1c5..0b21c2c74 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,6 +21,7 @@ resources: steps: - checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack submodules: true + path: NetHack - task: DownloadSecureFile@1 name: storeKey From 25bcbe3846eb426eb1c2c6f4d466bcabe1ea872c Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 12 Dec 2020 12:04:20 -0800 Subject: [PATCH 608/708] fix github pull request #418 - towel wetness Fire damage would dry out a wet towel but never all the way to 0. Water damage would wet a towel but if it was already wet, its wetness might decrease. This uses the pull request's change for increasing the wetness but changes dry_a_towel so that the original code for decreasing that will work as is. Using wet_a_towel() to set wetness to 0 doesn't make much sense, so still won't do so; dry_a_towel() does and now will. This also adds missing perm_invent update for towels in inventory changing wetness. Fixes #418 --- doc/fixes37.0 | 4 ++++ src/trap.c | 7 +++++-- src/weapon.c | 10 +++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index bc44a85e5..747429504 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -332,6 +332,10 @@ selling a container to a shop for gold leaves any contents that the shop contents without giving any additional credit; mark out of place contents 'no_charge' so that hero can reclaim them without buying add some new demonic and angelic maledictions +when fire damage dried a wet towel, it would never reduce the wetness to 0 +when water damage wet a towel, the new wetness might randomly become less +when the wetness of a towel in inventory changed, persistent inventory wasn't + updated to show that Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/trap.c b/src/trap.c index 746699d65..60bd409f8 100644 --- a/src/trap.c +++ b/src/trap.c @@ -89,7 +89,7 @@ struct monst *victim; /* burning damage may dry wet towel */ item = hitting_u ? carrying(TOWEL) : m_carrying(victim, TOWEL); while (item) { - if (is_wet_towel(item)) { + if (is_wet_towel(item)) { /* True => (item->spe > 0) */ oldspe = item->spe; dry_a_towel(item, rn2(oldspe + 1), TRUE); if (item->spe != oldspe) @@ -3882,7 +3882,10 @@ boolean force; if (obj->otyp == CAN_OF_GREASE && obj->spe > 0) { return ER_NOTHING; } else if (obj->otyp == TOWEL && obj->spe < 7) { - wet_a_towel(obj, rnd(7), TRUE); + /* a negative change induces a reverse increment, adding abs(change); + spe starts 0..6, arg passed to rnd() is 1..7, change is -7..-1, + final spe is 1..7 and always greater than its starting value */ + wet_a_towel(obj, -rnd(7 - obj->spe), TRUE); return ER_NOTHING; } else if (obj->greased) { if (!rn2(2)) diff --git a/src/weapon.c b/src/weapon.c index a785f4fbf..7e29213cc 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -984,16 +984,18 @@ boolean verbose; with your wet towel" message on next attack with it */ if (obj == uwep) g.unweapon = !is_wet_towel(obj); + if (carried(obj)) + update_inventory(); } -/* decrease a towel's wetness */ +/* decrease a towel's wetness; unlike when wetting, 0 is not a no-op */ void dry_a_towel(obj, amt, verbose) struct obj *obj; -int amt; /* positive: new value; negative: decrement by -amt; zero: no-op */ +int amt; /* positive or zero: new value; negative: decrement by abs(amt) */ boolean verbose; { - int newspe = (amt <= 0) ? obj->spe + amt : amt; + int newspe = (amt < 0) ? obj->spe + amt : amt; /* new state is only reported if it's a decrease */ if (newspe < obj->spe) { @@ -1013,6 +1015,8 @@ boolean verbose; bashing with your towel" message on next attack with it */ if (obj == uwep) g.unweapon = !is_wet_towel(obj); + if (carried(obj)) + update_inventory(); } /* copy the skill level name into the given buffer */ From bc7fb05dcfd019c00a5b5b5ee9a0e5c1e730e9bf Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 12 Dec 2020 14:10:18 -0800 Subject: [PATCH 609/708] Makefile vs lua fix I've been ignoring submodules so far. For the old method of dealing with lua, the instructions You might need to do make spotless make fetch-lua aren't adequate. They should be When lua version has changed in Makefile.top, before running setup.sh to put that new Makefile in place, do make spotless then sys/unix/setup.sh [hints/...] make fetch-lua otherwise it will try to clean up the not yet fetched new lua version instead of the old one. --- sys/unix/Makefile.top | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index a0824a155..53fc5dbaf 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: 1597031649 2020/08/10 03:54:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.52 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1607810996 2020/12/12 22:09:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -320,7 +320,7 @@ clean: ( cd util ; $(MAKE) clean ) ( cd dat ; $(MAKE) clean ) ( cd doc ; $(MAKE) clean ) - ( cd lib/lua-$(LUA_VERSION)/src && $(MAKE) clean ) + -( cd lib/lua-$(LUA_VERSION)/src && $(MAKE) clean ) # 'make spotless' returns the source tree to near-distribution condition. # it removes .o files, executables, and compiled data files From b7a140d0063affb0a1b4259f3b75d3eeb01b8254 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 12 Dec 2020 14:22:21 -0800 Subject: [PATCH 610/708] towel adjustments Consolidate a small amount of duplicate code from wet_a_towel() and dry_a_towel(). --- src/weapon.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/weapon.c b/src/weapon.c index 7e29213cc..7abfcdbad 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 weapon.c $NHDT-Date: 1596498226 2020/08/03 23:43:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.87 $ */ +/* NetHack 3.7 weapon.c $NHDT-Date: 1607811730 2020/12/12 22:22:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.89 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -11,6 +11,7 @@ #include "hack.h" static void FDECL(give_may_advance_msg, (int)); +static void FDECL(finish_towel_change, (struct obj *obj, int)); static boolean FDECL(could_advance, (int)); static boolean FDECL(peaked_skill, (int)); static int FDECL(slots_required, (int)); @@ -954,6 +955,26 @@ dbon() return 6; } +/* called when wet_a_towel() or dry_a_towel() is changing a towel's wetness */ +static void +finish_towel_change(obj, newspe) +struct obj *obj; +int newspe; +{ + /* towel wetness is always between 0 (dry) and 7, inclusive */ + newspe = min(newspe, 7); + obj->spe = max(newspe, 0); + + /* if hero is wielding this towel, don't give "you begin bashing with + your [wet] towel" message if it's wet, do give one if it's dry */ + if (obj == uwep) + g.unweapon = !is_wet_towel(obj); + + /* description might change: "towel" vs "moist towel" vs "wet towel" */ + if (carried(obj)) + update_inventory(); +} + /* increase a towel's wetness */ void wet_a_towel(obj, amt, verbose) @@ -978,14 +999,9 @@ boolean verbose; xname(obj), wetness); } } - obj->spe = min(newspe, 7); - /* if hero is wielding this towel, don't give "you begin bashing - with your wet towel" message on next attack with it */ - if (obj == uwep) - g.unweapon = !is_wet_towel(obj); - if (carried(obj)) - update_inventory(); + if (newspe != obj->spe) + finish_towel_change(obj, newspe); } /* decrease a towel's wetness; unlike when wetting, 0 is not a no-op */ @@ -1008,15 +1024,9 @@ boolean verbose; xname(obj), !newspe ? " out" : ""); } } - newspe = min(newspe, 7); - obj->spe = max(newspe, 0); - /* if hero is wielding this towel and it is now dry, give "you begin - bashing with your towel" message on next attack with it */ - if (obj == uwep) - g.unweapon = !is_wet_towel(obj); - if (carried(obj)) - update_inventory(); + if (newspe != obj->spe) + finish_towel_change(obj, newspe); } /* copy the skill level name into the given buffer */ From 939b1c00ddb0b2f21b8263e4f0905705535d7c83 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sat, 12 Dec 2020 21:41:24 -0800 Subject: [PATCH 611/708] Fix azure pipeline build for linux/mac. --- azure-pipelines.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0b21c2c74..dc9103bf0 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -18,10 +18,16 @@ resources: ref: refs/tags/v5.4.2 endpoint: github.com_barthouse +variables: + ${{ if eq( variables['Agent.OS'], 'Windows_NT') }}: + NetHackPath: s\NetHack + ${{ if ne( variables['Agent.OS'], 'Windows_NT') }}: + NetHackPath: s/NetHack + steps: - checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack submodules: true - path: NetHack + path: $(NetHackPath) - task: DownloadSecureFile@1 name: storeKey @@ -37,12 +43,6 @@ steps: TargetFolder: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs condition: eq( variables['Agent.OS'], 'Windows_NT' ) -- task: CopyFiles@2 - inputs: - SourceFolder: $(Agent.BuildDirectory)\s\lua - TargetFolder: $(Agent.BuildDirectory)\s\NetHack\lib\lua-5.4.2\src - condition: eq( variables['Agent.OS'], 'Windows_NT' ) - - task: MSBuild@1 inputs: solution: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs\NetHack.sln @@ -54,7 +54,7 @@ steps: sudo apt-get -qq -y update sudo apt-get -qq -y install libncurses5-dev sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools - cd NetHack/sys/unix + cd sys/unix sh setup.sh hints/linux.2020 cd ../.. make fetch-lua @@ -63,7 +63,7 @@ steps: displayName: 'Linux Build' - bash: | - cd NetHack/sys/unix + cd sys/unix sh setup.sh hints/macos.2020 cd ../.. make fetch-lua From 02ba5e481174d2d256e8ea4d9e53091a9db39e15 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 11 Dec 2020 18:13:56 -0500 Subject: [PATCH 612/708] Improve consistency of polearm targeting rules Multiple functions are involved in the process of targeting and attacking an enemy with a polearm or lance, and these functions previously used inconsistent tests to determine which targets were legal. For instance, find_poleable_mon would give up immediately if the hero was blind, while neither get_valid_polearm_position nor use_pole cared as long as the hero could detect a target on the square (e.g. by ESP). find_poleable_mon considered warning symbols as potential targets, but use_pole discarded them. get_valid_polearm_position considered moats and pools to be illegal targets, but use_pole would let the hero successfully hit a monster on those squares; on the other hand, get_valid_polearm_position would mark squares that were not visible and did not contain a known monster as legal targets, while find_poleable_mon and use_pole would exclude them. Obviously this was inconsistent and could introduce confusion for polearm users, who would potentially need to explicitly target squares marked "(illegal)" at some point over the course of their game, among other problems. This commit makes polearm targeting tests more consistent; the following rules are applied to positions within the appropriate range: * Monsters which are detected by any means that reveals an actual monster glyph are legal to target, even if the hero is blind * Monsters the hero cannot detect, but is aware of -- i.e. those represented by an 'I' -- are similarly legal to target * Monsters detected via warning are not legal targets, since the hero does not have as strong a sense of where exactly they are, their shape and size, etc * Statues are legal targets, but will not be suggested by find_poleable_mon unless the hero is impaired (confused, stunned, or hallucinating); the same is true of tame/peaceful monsters * Apparently empty squares, including those containing an undetected monster, are legal to target unless they cannot be seen (whether due to blindness or a very dark room/level) * Positions which are otherwise legal but are blocked by an obstruction like a tree or pillar are not legal targets --- src/apply.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/apply.c b/src/apply.c index a7cc2d82c..daa2b9c4b 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2945,6 +2945,9 @@ static const char cant_see_spot[] = "won't hit anything if you can't see that spot.", cant_reach[] = "can't reach that spot from here."; +#define glyph_is_poleable(G) \ + (glyph_is_monster(G) || glyph_is_invisible(G) || glyph_is_statue(G)) + /* find pos of monster in range, if only one monster */ static boolean find_poleable_mon(pos, min_range, max_range) @@ -2956,8 +2959,6 @@ int min_range, max_range; boolean impaired; int x, y, lo_x, hi_x, lo_y, hi_y, rt, glyph; - if (Blind) - return FALSE; /* must be able to see target location */ impaired = (Confusion || Stunned || Hallucination); mpos.x = mpos.y = 0; /* no candidate location yet */ rt = isqrt(max_range); @@ -2974,10 +2975,8 @@ int min_range, max_range; && (mtmp = m_at(x, y)) != 0 && (mtmp->mtame || (mtmp->mpeaceful && flags.confirm))) continue; - if (glyph_is_monster(glyph) - || glyph_is_warning(glyph) - || glyph_is_invisible(glyph) - || (glyph_is_statue(glyph) && impaired)) { + if (glyph_is_poleable(glyph) + && (!glyph_is_statue(glyph) || impaired)) { if (mpos.x) return FALSE; /* more than one candidate location */ mpos.x = x, mpos.y = y; @@ -2994,9 +2993,14 @@ static boolean get_valid_polearm_position(x, y) int x, y; { - return (isok(x, y) && ACCESSIBLE(levl[x][y].typ) - && distu(x, y) >= g.polearm_range_min - && distu(x, y) <= g.polearm_range_max); + int glyph; + + glyph = glyph_at(x, y); + + return (isok(x, y) && distu(x, y) >= g.polearm_range_min + && distu(x, y) <= g.polearm_range_max + && (cansee(x, y) || (couldsee(x, y) + && glyph_is_poleable(glyph)))); } static void @@ -3076,7 +3080,7 @@ struct obj *obj; cc.x = u.ux; cc.y = u.uy; if (!find_poleable_mon(&cc, min_range, max_range) && hitm - && !DEADMONSTER(hitm) && cansee(hitm->mx, hitm->my) + && !DEADMONSTER(hitm) && sensemon(hitm) && distu(hitm->mx, hitm->my) <= max_range && distu(hitm->mx, hitm->my) >= min_range) { cc.x = hitm->mx; @@ -3093,8 +3097,7 @@ struct obj *obj; } else if (distu(cc.x, cc.y) < min_range) { pline("Too close!"); return res; - } else if (!cansee(cc.x, cc.y) && !glyph_is_monster(glyph) - && !glyph_is_invisible(glyph) && !glyph_is_statue(glyph)) { + } else if (!cansee(cc.x, cc.y) && !glyph_is_poleable(glyph)) { You(cant_see_spot); return res; } else if (!couldsee(cc.x, cc.y)) { /* Eyes of the Overworld */ From 472906284699b9affccdce264e383b3474d62300 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 13 Dec 2020 12:28:42 +0200 Subject: [PATCH 613/708] Make Death revive faster Death will revive faster than the other riders. Make all the riders revive after 67 turns, instead of 500. There was practically a zero chance a rider would revive at 500, so keep it somewhat sensible. --- doc/fixes37.0 | 1 + include/extern.h | 1 + src/do.c | 4 +--- src/mkobj.c | 26 ++++++++++++++++++-------- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 747429504..01ae61a10 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -336,6 +336,7 @@ when fire damage dried a wet towel, it would never reduce the wetness to 0 when water damage wet a towel, the new wetness might randomly become less when the wetness of a towel in inventory changed, persistent inventory wasn't updated to show that +make Death revive earlier, and all the Riders after 67 turns at latest Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index cef35a4d8..ee4d78f68 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1415,6 +1415,7 @@ E struct obj *FDECL(mk_named_object, (int, struct permonst *, int, int, const char *)); E struct obj *FDECL(rnd_treefruit_at, (int, int)); E void FDECL(set_corpsenm, (struct obj *, int)); +E long FDECL(rider_revival_time, (struct obj *, BOOLEAN_P)); E void FDECL(start_corpse_timeout, (struct obj *)); E void FDECL(bless, (struct obj *)); E void FDECL(unbless, (struct obj *)); diff --git a/src/do.c b/src/do.c index f1330eeb0..7090db33e 100644 --- a/src/do.c +++ b/src/do.c @@ -1960,9 +1960,7 @@ long timeout UNUSED; if (is_rider(mptr) && rn2(99)) { /* Rider usually tries again */ action = REVIVE_MON; - for (when = 3L; when < 67L; when++) - if (!rn2(3)) - break; + when = rider_revival_time(body, TRUE); } else { /* rot this corpse away */ You_feel("%sless hassled.", is_rider(mptr) ? "much " : ""); action = ROT_CORPSE; diff --git a/src/mkobj.c b/src/mkobj.c index 07ec33b67..85052e3fd 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1146,6 +1146,23 @@ int id; } } +/* Return the number of turns after which a Rider corpse revives */ +long +rider_revival_time(body, retry) +struct obj *body; +boolean retry; +{ + long when; + long minturn = retry ? 3L : (body->corpsenm == PM_DEATH) ? 6L : 12L; + + /* Riders have a 1/3 chance per turn of reviving after 12, 6, or 3 turns. + Always revive by 67. */ + for (when = minturn; when < 67L; when++) + if (!rn2(3)) + break; + return when; +} + /* * Start a corpse decay or revive timer. * This takes the age of the corpse into consideration as of 3.4.0. @@ -1178,15 +1195,8 @@ struct obj *body; when += (long) (rnz(rot_adjust) - rot_adjust); if (is_rider(&mons[body->corpsenm])) { - /* - * Riders always revive. They have a 1/3 chance per turn - * of reviving after 12 turns. Always revive by 500. - */ action = REVIVE_MON; - for (when = 12L; when < 500L; when++) - if (!rn2(3)) - break; - + when = rider_revival_time(body, FALSE); } else if (mons[body->corpsenm].mlet == S_TROLL && !no_revival) { long age; From 8c42d306f718e1dbefcf68115bfe94c10c4c4571 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 13 Dec 2020 10:27:49 -0500 Subject: [PATCH 614/708] purge trampoli.h --- include/extern.h | 78 ---------------------- include/hack.h | 13 ---- include/pcconf.h | 16 ----- include/tradstdc.h | 7 +- {include => outdated/include}/trampoli.h | 0 outdated/sys/amiga/Makefile.agc | 4 +- outdated/sys/amiga/Makefile.ami | 4 +- outdated/sys/wince/bootstrp.mak | 2 +- sys/msdos/Makefile.GCC | 2 +- sys/unix/Makefile.src | 4 +- sys/unix/NetHack.xcodeproj/project.pbxproj | 2 - sys/vms/Makefile.src | 4 +- sys/winnt/Makefile.gcc | 2 +- sys/winnt/Makefile.msc | 3 +- util/mdgrep.pl | 1 - win/win32/vs/NetHackW.vcxproj | 1 - win/win32/vs/tilemap.vcxproj | 3 +- 17 files changed, 16 insertions(+), 130 deletions(-) rename {include => outdated/include}/trampoli.h (100%) diff --git a/include/extern.h b/include/extern.h index ee4d78f68..b8f6faaa0 100644 --- a/include/extern.h +++ b/include/extern.h @@ -208,20 +208,6 @@ E char FDECL(cmd_from_func, (int NDECL((*)))); E const char *FDECL(cmdname_from_func, (int NDECL((*)), char *, BOOLEAN_P)); E boolean FDECL(redraw_cmd, (CHAR_P)); E const char *FDECL(levltyp_to_name, (int)); -#ifdef USE_TRAMPOLI -E int NDECL(doextcmd); -E int NDECL(domonability); -E int NDECL(doprev_message); -E int NDECL(timed_occupation); -E int NDECL(doattributes); -E int NDECL(wiz_detect); -E int NDECL(wiz_genesis); -E int NDECL(wiz_identify); -E int NDECL(wiz_level_tele); -E int NDECL(wiz_map); -E int NDECL(wiz_where); -E int NDECL(wiz_wish); -#endif /* USE_TRAMPOLI */ E void NDECL(reset_occupations); E void FDECL(set_occupation, (int (*)(void), const char *, int)); E char NDECL(pgetchar); @@ -297,10 +283,6 @@ E void FDECL(use_crystal_ball, (struct obj **)); E void NDECL(do_mapping); E void FDECL(do_vicinity_map, (struct obj *)); E void FDECL(cvt_sdoor_to_door, (struct rm *)); -#ifdef USE_TRAMPOLI -E void FDECL(findone, (int, int, genericptr_t)); -E void FDECL(openone, (int, int, genericptr_t)); -#endif E int NDECL(findit); E int NDECL(openit); E boolean FDECL(detecting, (void (*)(int, int, genericptr))); @@ -318,9 +300,6 @@ E void FDECL(reveal_terrain, (int, int)); E int FDECL(dig_typ, (struct obj *, XCHAR_P, XCHAR_P)); E boolean NDECL(is_digging); -#ifdef USE_TRAMPOLI -E int NDECL(dig); -#endif E int NDECL(holetime); E boolean FDECL(dig_check, (struct monst *, BOOLEAN_P, int, int)); E void FDECL(digactualhole, (int, int, struct monst *, int)); @@ -398,10 +377,6 @@ E int FDECL(warning_of, (struct monst *)); /* ### do.c ### */ -#ifdef USE_TRAMPOLI -E int FDECL(drop, (struct obj *)); -E int NDECL(wipeoff); -#endif E int NDECL(dodrop); E boolean FDECL(boulder_hits_pool, (struct obj *, int, int, BOOLEAN_P)); E boolean FDECL(flooreffects, (struct obj *, int, int, const char *)); @@ -485,14 +460,6 @@ E const char *FDECL(lookup_novel, (const char *, int *)); /* ### do_wear.c ### */ -#ifdef USE_TRAMPOLI -E int NDECL(Armor_on); -E int NDECL(Boots_on); -E int NDECL(Gloves_on); -E int NDECL(Helmet_on); -E int FDECL(select_off, (struct obj *)); -E int NDECL(take_off); -#endif E const char *FDECL(fingers_or_gloves, (BOOLEAN_P)); E void FDECL(off_msg, (struct obj *)); E void FDECL(toggle_displacement, (struct obj *, long, BOOLEAN_P)); @@ -562,9 +529,6 @@ E struct obj *FDECL(droppables, (struct monst *)); E int FDECL(dog_nutrition, (struct monst *, struct obj *)); E int FDECL(dog_eat, (struct monst *, struct obj *, int, int, BOOLEAN_P)); E int FDECL(dog_move, (struct monst *, int)); -#ifdef USE_TRAMPOLI -E void FDECL(wantdoor, (int, int, genericptr_t)); -#endif E void FDECL(finish_meating, (struct monst *)); /* ### dokick.c ### */ @@ -685,12 +649,6 @@ E const char *FDECL(endgamelevelname, (char *, int)); /* ### eat.c ### */ -#ifdef USE_TRAMPOLI -E int NDECL(eatmdone); -E int NDECL(eatfood); -E int NDECL(opentin); -E int NDECL(unfaint); -#endif E void NDECL(eatmupdate); E boolean FDECL(is_edible, (struct obj *)); E void NDECL(init_uhunger); @@ -724,9 +682,6 @@ E boolean FDECL(Popeye, (int)); E void FDECL(done1, (int)); E int NDECL(done2); -#ifdef USE_TRAMPOLI -E void FDECL(done_intr, (int)); -#endif E void FDECL(done_in_by, (struct monst *, int)); #endif /* !MAKEDEFS_C && MDLIB_C */ E void VDECL(panic, (const char *, ...)) PRINTF_F(1, 2) NORETURN; @@ -866,9 +821,6 @@ E boolean FDECL(Death_quote, (char *, int)); E void FDECL(floating_above, (const char *)); E void FDECL(dogushforth, (int)); -#ifdef USE_TRAMPOLI -E void FDECL(gush, (int, int, genericptr_t)); -#endif E void FDECL(dryup, (XCHAR_P, XCHAR_P, BOOLEAN_P)); E void NDECL(drinkfountain); E void FDECL(dipfountain, (struct obj *)); @@ -1026,9 +978,6 @@ E void FDECL(unsortloot, (Loot **)); E void FDECL(assigninvlet, (struct obj *)); E struct obj *FDECL(merge_choice, (struct obj *, struct obj *)); E int FDECL(merged, (struct obj **, struct obj **)); -#ifdef USE_TRAMPOLI -E int FDECL(ckunpaid, (struct obj *)); -#endif E void FDECL(addinv_core1, (struct obj *)); E void FDECL(addinv_core2, (struct obj *)); E struct obj *FDECL(addinv, (struct obj *)); @@ -1144,10 +1093,6 @@ E int NDECL(wiz_light_sources); /* ### lock.c ### */ -#ifdef USE_TRAMPOLI -E int NDECL(forcelock); -E int NDECL(picklock); -#endif E boolean FDECL(picking_lock, (int *, int *)); E boolean FDECL(picking_at, (int, int)); E void FDECL(breakchestlock, (struct obj *, BOOLEAN_P)); @@ -1318,9 +1263,6 @@ E void NDECL(gain_guardian_angel); /* ### mklev.c ### */ -#ifdef USE_TRAMPOLI -E int FDECL(do_comp, (genericptr_t, genericptr_t)); -#endif E void NDECL(sort_rooms); E void FDECL(add_room, (int, int, int, int, BOOLEAN_P, SCHAR_P, BOOLEAN_P)); E void FDECL(add_subroom, (struct mkroom *, int, int, int, int, BOOLEAN_P, @@ -1704,9 +1646,6 @@ E boolean FDECL(find_defensive, (struct monst *)); E int FDECL(use_defensive, (struct monst *)); E int FDECL(rnd_defensive_item, (struct monst *)); E boolean FDECL(find_offensive, (struct monst *)); -#ifdef USE_TRAMPOLI -E int FDECL(mbhitm, (struct monst *, struct obj *)); -#endif E int FDECL(use_offensive, (struct monst *)); E int FDECL(rnd_offensive_item, (struct monst *)); E boolean FDECL(find_misc, (struct monst *)); @@ -1998,10 +1937,6 @@ E boolean FDECL(allow_category, (struct obj *)); E boolean FDECL(is_worn_by_type, (struct obj *)); E int FDECL(ck_bag, (struct obj *)); E void FDECL(removed_from_icebox, (struct obj *)); -#ifdef USE_TRAMPOLI -E int FDECL(in_container, (struct obj *)); -E int FDECL(out_container, (struct obj *)); -#endif E int FDECL(pickup, (int)); E int FDECL(pickup_object, (struct obj *, long, BOOLEAN_P)); E int FDECL(query_category, (const char *, struct obj *, int, @@ -2104,9 +2039,6 @@ E const char *NDECL(bottlename); E boolean FDECL(critically_low_hp, (BOOLEAN_P)); E boolean NDECL(stuck_in_wall); -#ifdef USE_TRAMPOLI -E int NDECL(prayer_done); -#endif E int NDECL(dosacrifice); E boolean FDECL(can_pray, (BOOLEAN_P)); E int NDECL(dopray); @@ -2197,9 +2129,6 @@ E void FDECL(drop_boulder_on_player, (BOOLEAN_P, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); E boolean FDECL(drop_boulder_on_monster, (int, int, BOOLEAN_P, BOOLEAN_P)); E void FDECL(wand_explode, (struct obj *, int)); -#ifdef USE_TRAMPOLI -E void FDECL(set_lit, (int, int, genericptr_t)); -#endif E void FDECL(litroom, (BOOLEAN_P, struct obj *)); E void FDECL(do_genocide, (int)); E void FDECL(punish, (struct obj *)); @@ -2534,9 +2463,6 @@ E void FDECL(l_register_des, (lua_State *)); /* ### spell.c ### */ E void FDECL(book_cursed, (struct obj *)); -#ifdef USE_TRAMPOLI -E int NDECL(learn); -#endif E int FDECL(study_book, (struct obj *)); E void FDECL(book_disappears, (struct obj *)); E void FDECL(book_substitution, (struct obj *, struct obj *)); @@ -2551,10 +2477,6 @@ E void FDECL(initialspell, (struct obj *)); /* ### steal.c ### */ -#ifdef USE_TRAMPOLI -E int NDECL(stealarm); -E void NDECL(unstolenarm); -#endif E long FDECL(somegold, (long)); E void FDECL(stealgold, (struct monst *)); E void NDECL(thiefdead); diff --git a/include/hack.h b/include/hack.h index 9900d5426..0917b93c4 100644 --- a/include/hack.h +++ b/include/hack.h @@ -272,23 +272,10 @@ typedef struct sortloot_item Loot; #include "display.h" #include "engrave.h" -#ifdef USE_TRAMPOLI /* this doesn't belong here, but we have little choice */ -#undef NDECL -#define NDECL(f) f() -#endif - #include "extern.h" #include "winprocs.h" #include "sys.h" -#ifdef USE_TRAMPOLI -#include "wintty.h" -#undef WINTTY_H -#include "trampoli.h" -#undef EXTERN_H -#include "extern.h" -#endif /* USE_TRAMPOLI */ - /* flags to control makemon(); goodpos() uses some plus has some of its own*/ #define NO_MM_FLAGS 0x000000L /* use this rather than plain 0 */ #define NO_MINVENT 0x000001L /* suppress minvent when creating mon */ diff --git a/include/pcconf.h b/include/pcconf.h index 5e0445eba..e2e6eca8a 100644 --- a/include/pcconf.h +++ b/include/pcconf.h @@ -259,22 +259,6 @@ /* Sanity check, do not modify these blocks. */ -/* OVERLAY must be defined with MOVERLAY or VROOMM */ -#if (defined(MOVERLAY) || defined(VROOMM)) -#ifndef OVERLAY -#define OVERLAY -#endif -#endif - -#if defined(FUNCTION_LEVEL_LINKING) -#define OVERLAY -#endif - -#if defined(OVERLAY) && !defined(MOVERLAY) && !defined(VROOMM) \ - && !defined(FUNCTION_LEVEL_LINKING) -#define USE_TRAMPOLI -#endif - #if defined(MSDOS) && defined(NO_TERMS) #ifdef TERMLIB #if defined(_MSC_VER) || defined(__SC__) diff --git a/include/tradstdc.h b/include/tradstdc.h index 65fea90b0..3827195f5 100644 --- a/include/tradstdc.h +++ b/include/tradstdc.h @@ -184,11 +184,10 @@ typedef const char *vA; * FDECL() is used for functions with a fixed number of arguments; * VDECL() is used for functions with a variable number of arguments. * Separate macros are needed because ANSI will mix old-style declarations - * with prototypes, except in the case of varargs, and the OVERLAY-specific - * trampoli.* mechanism conflicts with the ANSI <> syntax. - */ + * with prototypes, except in the case of varargs + */ -#define NDECL(f) f(void) /* overridden later if USE_TRAMPOLI set */ +#define NDECL(f) f(void) #define FDECL(f, p) f p diff --git a/include/trampoli.h b/outdated/include/trampoli.h similarity index 100% rename from include/trampoli.h rename to outdated/include/trampoli.h diff --git a/outdated/sys/amiga/Makefile.agc b/outdated/sys/amiga/Makefile.agc index 22b1473f6..5f36d0049 100644 --- a/outdated/sys/amiga/Makefile.agc +++ b/outdated/sys/amiga/Makefile.agc @@ -1185,7 +1185,7 @@ $(I)global.h: $(I)coord.h $(I)pcconf.h $(I)amiconf.h $(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)trampoli.h $(I)sys.h + $(I)rect.h $(I)region.h $(I)sys.h -setdate $(I)hack.h -c:wait 2 @@ -1211,7 +1211,7 @@ $(I)dungeon.h: $(I)align.h -setdate $(I)dungeon.h -c:wait 2 -$(I)engrave.h: $(I)trampoli.h $(I)rect.h +$(I)engrave.h: $(I)rect.h -setdate $(I)engrave.h -c:wait 2 diff --git a/outdated/sys/amiga/Makefile.ami b/outdated/sys/amiga/Makefile.ami index b3b29e775..d07a6633b 100644 --- a/outdated/sys/amiga/Makefile.ami +++ b/outdated/sys/amiga/Makefile.ami @@ -1521,7 +1521,7 @@ $(I)global.h: $(I)coord.h $(I)pcconf.h $(I)amiconf.h $(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)trampoli.h $(I)sys.h + $(I)rect.h $(I)region.h $(I)sys.h -setdate $(I)hack.h -wait 2 @@ -1547,7 +1547,7 @@ $(I)dungeon.h: $(I)align.h -setdate $(I)dungeon.h -wait 2 -$(I)engrave.h: $(I)trampoli.h $(I)rect.h +$(I)engrave.h: $(I)rect.h -setdate $(I)engrave.h -wait 2 diff --git a/outdated/sys/wince/bootstrp.mak b/outdated/sys/wince/bootstrp.mak index 35cb62595..3d2414cb1 100644 --- a/outdated/sys/wince/bootstrp.mak +++ b/outdated/sys/wince/bootstrp.mak @@ -200,7 +200,7 @@ HACK_H = $(INCL)\hack.h $(CONFIG_H) $(INCL)\align.h \ $(INCL)\trap.h $(INCL)\flag.h $(INCL)\rm.h \ $(INCL)\vision.h $(INCL)\display.h $(INCL)\engrave.h \ $(INCL)\rect.h $(INCL)\region.h $(INCL)\winprocs.h \ - $(INCL)\wintty.h $(INCL)\trampoli.h + $(INCL)\wintty.h DGN_FILE_H = $(INCL)\dgn_file.h LEV_COMP_H = $(INCL)\lev_comp.h diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 6ffb918d0..0837d991b 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -400,7 +400,7 @@ HACK_H = $(CONFIG_H) $(INCL)/context.h $(DUNGEON_H) \ $(INCL)/mkroom.h $(INCL)/objclass.h $(INCL)/trap.h \ $(INCL)/flag.h $(RM_H) $(INCL)/vision.h \ $(INCL)/wintype.h $(INCL)/engrave.h $(INCL)/rect.h \ - $(INCL)/trampoli.h $(INCL)/hack.h $(REGION_H) \ + $(INCL)/hack.h $(REGION_H) \ $(INCL)/sys.h DLB_H = $(INCL)/dlb.h diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 335d71853..76631e60f 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -566,7 +566,7 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.h \ monattk.h mondata.h monflag.h monst.h monsym.h obj.h objclass.h \ optlist.h patchlevel.h pcconf.h permonst.h prop.h rect.h \ region.h rm.h sp_lev.h spell.h sys.h system.h tcap.h timeout.h \ - tradstdc.h trampoli.h trap.h unixconf.h vision.h vmsconf.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 HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h dgn_file.h @@ -852,7 +852,7 @@ $(HACK_H): ../include/hack.h $(CONFIG_H) ../include/lint.h ../include/align.h \ ../include/mextra.h ../include/skills.h ../include/onames.h \ ../include/timeout.h ../include/trap.h ../include/flag.h \ ../include/vision.h ../include/display.h ../include/winprocs.h \ - ../include/sys.h ../include/wintty.h ../include/trampoli.h + ../include/sys.h ../include/wintty.h touch $(HACK_H) # $(TARGETPFX)pcmain.o: ../sys/share/pcmain.c $(HACK_H) ../include/dlb.h diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index 807c7231e..db847d7fc 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -261,7 +261,6 @@ 3186A38921A4B0FB0052BF02 /* mttypriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mttypriv.h; path = ../../include/mttypriv.h; sourceTree = ""; }; 3186A38A21A4B0FB0052BF02 /* system.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = system.h; path = ../../include/system.h; sourceTree = ""; }; 3186A38B21A4B0FC0052BF02 /* onames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = onames.h; path = ../../include/onames.h; sourceTree = ""; }; - 3186A38C21A4B0FC0052BF02 /* trampoli.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = trampoli.h; path = ../../include/trampoli.h; sourceTree = ""; }; 3186A38D21A4B0FC0052BF02 /* vis_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vis_tab.h; path = ../../include/vis_tab.h; sourceTree = ""; }; 3186A38E21A4B0FC0052BF02 /* dlb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dlb.h; path = ../../include/dlb.h; sourceTree = ""; }; 3186A38F21A4B0FC0052BF02 /* monflag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = monflag.h; path = ../../include/monflag.h; sourceTree = ""; }; @@ -747,7 +746,6 @@ 3186A39421A4B0FC0052BF02 /* tileset.h */, 3186A3CA21A4B0FE0052BF02 /* timeout.h */, 3186A3C721A4B0FE0052BF02 /* tradstdc.h */, - 3186A38C21A4B0FC0052BF02 /* trampoli.h */, 3186A3CD21A4B0FE0052BF02 /* trap.h */, 3186A3AD21A4B0FD0052BF02 /* unixconf.h */, 3186A38D21A4B0FC0052BF02 /* vis_tab.h */, diff --git a/sys/vms/Makefile.src b/sys/vms/Makefile.src index 8e5ac62cf..fa561d17e 100644 --- a/sys/vms/Makefile.src +++ b/sys/vms/Makefile.src @@ -180,7 +180,7 @@ HACKINCL = align.h artifact.h artilist.h attrib.h color.h \ monattk.h mondata.h monflag.h monst.h monsym.h obj.h objclass.h \ patchlevel.h pcconf.h permonst.h prop.h rect.h \ region.h rm.h sp_lev.h spell.h sys.h system.h tcap.h timeout.h \ - tradstdc.h trampoli.h trap.h unixconf.h vision.h \ + tradstdc.h trap.h unixconf.h vision.h \ vmsconf.h wintty.h winX.h winprocs.h wintype.h you.h youprop.h #HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h\ @@ -403,7 +403,7 @@ $(HACK_H) : $(INC)hack.h $(CONFIG_H) $(INC)align.h \ $(INC)onames.h $(INC)timeout.h $(INC)trap.h \ $(INC)flag.h $(INC)rm.h $(INC)vision.h \ $(INC)display.h $(INC)engrave.h $(INC)rect.h $(INC)region.h \ - $(INC)winprocs.h $(INC)wintty.h $(INC)trampoli.h $(INC)sys.h + $(INC)winprocs.h $(INC)wintty.h $(INC)sys.h $(TOUCH) $(HACK_H) # VMS-specific code vmsmain.obj : $(VMS)vmsmain.c $(HACK_H) $(INC)dlb.h diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index c2b2d1c16..21ae0aa53 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -501,7 +501,7 @@ HACK_H = $(INCL)/hack.h $(CONFIG_H) $(INCL)/align.h $(INCL)/context.h \ $(INCL)/timeout.h $(INCL)/trap.h $(INCL)/flag.h $(INCL)/rm.h \ $(INCL)/vision.h $(INCL)/display.h $(INCL)/engrave.h \ $(INCL)/rect.h $(INCL)/region.h $(INCL)/winprocs.h \ - $(INCL)/wintty.h $(INCL)/sys.h $(INCL)/trampoli.h + $(INCL)/wintty.h $(INCL)/sys.h DGN_FILE_H = $(INCL)/dgn_file.h SP_LEV_H = $(INCL)/sp_lev.h diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index c793dd878..6aa6d484b 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -501,8 +501,7 @@ HACK_H = $(INCL)\hack.h $(CONFIG_H) $(INCL)\lint.h $(INCL)\align.h \ $(INCL)\mextra.h $(INCL)\skills.h $(INCL)\onames.h \ $(INCL)\timeout.h $(INCL)\trap.h $(INCL)\flag.h \ $(INCL)\vision.h $(INCL)\display.h $(INCL)\engrave.h \ - $(INCL)\winprocs.h $(INCL)\sys.h $(INCL)\wintty.h \ - $(INCL)\trampoli.h + $(INCL)\winprocs.h $(INCL)\sys.h $(INCL)\wintty.h TILE_H = ..\win\share\tile.h diff --git a/util/mdgrep.pl b/util/mdgrep.pl index 72eb7b567..72c06efb7 100644 --- a/util/mdgrep.pl +++ b/util/mdgrep.pl @@ -44,7 +44,6 @@ # NeXT __osf__ SVR4 _AIX32 _BULL_SOURCE AUX __sgi GNUDOS # TIMED_DELAY DEF_MAILREADER DEF_PAGER NO_SIGNAL PC_LOCKING LATTICE __GO32__ # msleep NO_FILE_LINKS bsdi HPUX AMIFLUSH -# OVERLAY USE_TRAMPOLI USE_OVLx SPEC_LEV DGN_COMP # SCREEN_BIOS SCREEN_DJGPPFAST SCREEN_VGA SCREEN_8514 # EXEPATH NOTSTDC SELECTSAVED NOTPARMDECL diff --git a/win/win32/vs/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj index d49463e30..994b7213e 100644 --- a/win/win32/vs/NetHackW.vcxproj +++ b/win/win32/vs/NetHackW.vcxproj @@ -310,7 +310,6 @@ - diff --git a/win/win32/vs/tilemap.vcxproj b/win/win32/vs/tilemap.vcxproj index 139dd17a2..8ab1ab1db 100644 --- a/win/win32/vs/tilemap.vcxproj +++ b/win/win32/vs/tilemap.vcxproj @@ -67,7 +67,6 @@ - @@ -86,4 +85,4 @@ - \ No newline at end of file + From 1a369f1af00271c809789a60a4fe46707aba0465 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 13 Dec 2020 10:40:02 -0500 Subject: [PATCH 615/708] ensure a rebuild of include/nhlua.h after fetching Lua source --- sys/unix/Makefile.top | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/unix/Makefile.top b/sys/unix/Makefile.top index 53fc5dbaf..969f3e4d5 100644 --- a/sys/unix/Makefile.top +++ b/sys/unix/Makefile.top @@ -270,6 +270,8 @@ fetch-Lua: ( mkdir -p lib && cd lib && \ curl -R -O http://www.lua.org/ftp/lua-$(LUA_VERSION).tar.gz && \ tar zxf lua-$(LUA_VERSION).tar.gz && rm -f lua-$(LUA_VERSION).tar.gz ) +#if we just fetched lua, force include/nhlua.h to be built based on it + -rm include/nhlua.h update: $(GAME) recover $(VARDAT) spec_levs # (don't yank the old version out from under people who're playing it) From abb21797e7ab466c7f826fde73ae86b3159465a9 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 13 Dec 2020 11:24:07 -0500 Subject: [PATCH 616/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Files b/Files index 61f5315e8..e413ea33c 100644 --- a/Files +++ b/Files @@ -102,9 +102,9 @@ ntconf.h obj.h objclass.h optlist.h patchlevel.h pcconf.h permonst.h prop.h quest.h rect.h region.h rm.h skills.h sp_lev.h spell.h sys.h system.h tcap.h tileset.h timeout.h -tradstdc.h trampoli.h trap.h unixconf.h vision.h -vmsconf.h winami.h wincurs.h winprocs.h wintype.h -you.h youprop.h +tradstdc.h trap.h unixconf.h vision.h vmsconf.h +winami.h wincurs.h winprocs.h wintype.h you.h +youprop.h (file for tty versions) wintty.h @@ -117,7 +117,7 @@ outdated/include: (files that are no longer maintained for current game code) amiconf.h beconf.h def_os2.h mac-carbon.h mac-qt.h mac-term.h macconf.h macpopup.h mactty.h macwin.h -mttypriv.h os2conf.h tosconf.h wceconf.h +mttypriv.h os2conf.h tosconf.h trampoli.h wceconf.h outdated/sys/amiga: (files for Amiga versions - untested for 3.7) From c1b0f4e47af3270ca2a93873f4de075acc2a780c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 13 Dec 2020 12:24:35 -0500 Subject: [PATCH 617/708] Xcode updates --- src/uhitm.c | 2 +- sys/unix/NetHack.xcodeproj/project.pbxproj | 28 ++----------------- .../xcshareddata/xcschemes/NetHack.xcscheme | 2 +- .../xcshareddata/xcschemes/makedefs.xcscheme | 2 +- .../xcshareddata/xcschemes/recover.xcscheme | 2 +- 5 files changed, 7 insertions(+), 29 deletions(-) diff --git a/src/uhitm.c b/src/uhitm.c index 5f2018078..5855962da 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -2581,7 +2581,7 @@ struct mhitm_data *mhm; /* mhitu */ int armpro = magic_negation(mdef); boolean uncancelled = !magr->mcan && (rn2(10) >= 3 * armpro); - int ptmp; + int ptmp = A_STR; /* A_STR == 0 */ char buf[BUFSZ]; switch (mattk->adtyp) { diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj index db847d7fc..0632530ea 100644 --- a/sys/unix/NetHack.xcodeproj/project.pbxproj +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj @@ -237,13 +237,11 @@ 3186A36F21A4B0FA0052BF02 /* winprocs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = winprocs.h; path = ../../include/winprocs.h; sourceTree = ""; }; 3186A37021A4B0FA0052BF02 /* extern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = extern.h; path = ../../include/extern.h; sourceTree = ""; }; 3186A37121A4B0FA0052BF02 /* context.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = context.h; path = ../../include/context.h; sourceTree = ""; }; - 3186A37221A4B0FA0052BF02 /* mac-term.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mac-term.h"; path = "../../include/mac-term.h"; sourceTree = ""; }; 3186A37321A4B0FA0052BF02 /* func_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = func_tab.h; path = ../../include/func_tab.h; sourceTree = ""; }; 3186A37421A4B0FA0052BF02 /* attrib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = attrib.h; path = ../../include/attrib.h; sourceTree = ""; }; 3186A37521A4B0FA0052BF02 /* patchlevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = patchlevel.h; path = ../../include/patchlevel.h; sourceTree = ""; }; 3186A37621A4B0FA0052BF02 /* wincurs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wincurs.h; path = ../../include/wincurs.h; sourceTree = ""; }; 3186A37721A4B0FA0052BF02 /* pm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pm.h; path = ../../include/pm.h; sourceTree = ""; }; - 3186A37821A4B0FA0052BF02 /* qt_kde0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qt_kde0.h; path = ../../include/qt_kde0.h; sourceTree = ""; }; 3186A37921A4B0FA0052BF02 /* monattk.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = monattk.h; path = ../../include/monattk.h; sourceTree = ""; }; 3186A37A21A4B0FA0052BF02 /* integer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = integer.h; path = ../../include/integer.h; sourceTree = ""; }; 3186A37B21A4B0FA0052BF02 /* region.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = region.h; path = ../../include/region.h; sourceTree = ""; }; @@ -258,7 +256,6 @@ 3186A38521A4B0FB0052BF02 /* mextra.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mextra.h; path = ../../include/mextra.h; sourceTree = ""; }; 3186A38721A4B0FB0052BF02 /* color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = color.h; path = ../../include/color.h; sourceTree = ""; }; 3186A38821A4B0FB0052BF02 /* artifact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = artifact.h; path = ../../include/artifact.h; sourceTree = ""; }; - 3186A38921A4B0FB0052BF02 /* mttypriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mttypriv.h; path = ../../include/mttypriv.h; sourceTree = ""; }; 3186A38A21A4B0FB0052BF02 /* system.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = system.h; path = ../../include/system.h; sourceTree = ""; }; 3186A38B21A4B0FC0052BF02 /* onames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = onames.h; path = ../../include/onames.h; sourceTree = ""; }; 3186A38D21A4B0FC0052BF02 /* vis_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vis_tab.h; path = ../../include/vis_tab.h; sourceTree = ""; }; @@ -269,19 +266,15 @@ 3186A39421A4B0FC0052BF02 /* tileset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tileset.h; path = ../../include/tileset.h; sourceTree = ""; }; 3186A39521A4B0FC0052BF02 /* obj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = obj.h; path = ../../include/obj.h; sourceTree = ""; }; 3186A39721A4B0FC0052BF02 /* rm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rm.h; path = ../../include/rm.h; sourceTree = ""; }; - 3186A39821A4B0FC0052BF02 /* qt_clust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qt_clust.h; path = ../../include/qt_clust.h; sourceTree = ""; }; 3186A39921A4B0FD0052BF02 /* load_img.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = load_img.h; path = ../../include/load_img.h; sourceTree = ""; }; 3186A39A21A4B0FD0052BF02 /* wintty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wintty.h; path = ../../include/wintty.h; sourceTree = ""; }; 3186A39B21A4B0FD0052BF02 /* ntconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ntconf.h; path = ../../include/ntconf.h; sourceTree = ""; }; 3186A39C21A4B0FD0052BF02 /* mkroom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mkroom.h; path = ../../include/mkroom.h; sourceTree = ""; }; - 3186A39D21A4B0FD0052BF02 /* macpopup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macpopup.h; path = ../../include/macpopup.h; sourceTree = ""; }; 3186A39E21A4B0FD0052BF02 /* quest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = quest.h; path = ../../include/quest.h; sourceTree = ""; }; - 3186A39F21A4B0FD0052BF02 /* mac-qt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mac-qt.h"; path = "../../include/mac-qt.h"; sourceTree = ""; }; 3186A3A021A4B0FD0052BF02 /* dgn_file.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dgn_file.h; path = ../../include/dgn_file.h; sourceTree = ""; }; 3186A3A121A4B0FD0052BF02 /* tile2x11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tile2x11.h; path = ../../include/tile2x11.h; sourceTree = ""; }; 3186A3A221A4B0FD0052BF02 /* engrave.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = engrave.h; path = ../../include/engrave.h; sourceTree = ""; }; 3186A3A321A4B0FD0052BF02 /* spell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spell.h; path = ../../include/spell.h; sourceTree = ""; }; - 3186A3A421A4B0FD0052BF02 /* mac-carbon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mac-carbon.h"; path = "../../include/mac-carbon.h"; sourceTree = ""; }; 3186A3A521A4B0FD0052BF02 /* hack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hack.h; path = ../../include/hack.h; sourceTree = ""; }; 3186A3A721A4B0FD0052BF02 /* youprop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = youprop.h; path = ../../include/youprop.h; sourceTree = ""; }; 3186A3A821A4B0FD0052BF02 /* objclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = objclass.h; path = ../../include/objclass.h; sourceTree = ""; }; @@ -290,30 +283,25 @@ 3186A3AB21A4B0FD0052BF02 /* artilist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = artilist.h; path = ../../include/artilist.h; sourceTree = ""; }; 3186A3AC21A4B0FD0052BF02 /* dungeon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dungeon.h; path = ../../include/dungeon.h; sourceTree = ""; }; 3186A3AD21A4B0FD0052BF02 /* unixconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unixconf.h; path = ../../include/unixconf.h; sourceTree = ""; }; - 3186A3AE21A4B0FD0052BF02 /* mactty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mactty.h; path = ../../include/mactty.h; sourceTree = ""; }; 3186A3B021A4B0FD0052BF02 /* date.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = date.h; path = ../../include/date.h; sourceTree = ""; }; 3186A3B121A4B0FD0052BF02 /* bitmfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bitmfile.h; path = ../../include/bitmfile.h; sourceTree = ""; }; 3186A3B321A4B0FD0052BF02 /* mfndpos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mfndpos.h; path = ../../include/mfndpos.h; sourceTree = ""; }; - 3186A3B421A4B0FD0052BF02 /* qt_win.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qt_win.h; path = ../../include/qt_win.h; sourceTree = ""; }; 3186A3B521A4B0FD0052BF02 /* flag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = flag.h; path = ../../include/flag.h; sourceTree = ""; }; 3186A3B621A4B0FD0052BF02 /* sp_lev.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sp_lev.h; path = ../../include/sp_lev.h; sourceTree = ""; }; 3186A3B721A4B0FD0052BF02 /* align.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = align.h; path = ../../include/align.h; sourceTree = ""; }; 3186A3B821A4B0FD0052BF02 /* mail.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mail.h; path = ../../include/mail.h; sourceTree = ""; }; 3186A3BB21A4B0FD0052BF02 /* monst.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = monst.h; path = ../../include/monst.h; sourceTree = ""; }; 3186A3BC21A4B0FD0052BF02 /* lint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lint.h; path = ../../include/lint.h; sourceTree = ""; }; - 3186A3BD21A4B0FD0052BF02 /* qt_xpms.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qt_xpms.h; path = ../../include/qt_xpms.h; sourceTree = ""; }; 3186A3BE21A4B0FD0052BF02 /* vmsconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vmsconf.h; path = ../../include/vmsconf.h; sourceTree = ""; }; 3186A3BF21A4B0FD0052BF02 /* you.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = you.h; path = ../../include/you.h; sourceTree = ""; }; 3186A3C021A4B0FD0052BF02 /* wintype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = wintype.h; path = ../../include/wintype.h; sourceTree = ""; }; 3186A3C121A4B0FD0052BF02 /* global.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = global.h; path = ../../include/global.h; sourceTree = ""; }; 3186A3C221A4B0FE0052BF02 /* winX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = winX.h; path = ../../include/winX.h; sourceTree = ""; }; 3186A3C321A4B0FE0052BF02 /* tcap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tcap.h; path = ../../include/tcap.h; sourceTree = ""; }; - 3186A3C421A4B0FE0052BF02 /* qttableview.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qttableview.h; path = ../../include/qttableview.h; sourceTree = ""; }; 3186A3C521A4B0FE0052BF02 /* coord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = coord.h; path = ../../include/coord.h; sourceTree = ""; }; 3186A3C621A4B0FE0052BF02 /* config1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config1.h; path = ../../include/config1.h; sourceTree = ""; }; 3186A3C721A4B0FE0052BF02 /* tradstdc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tradstdc.h; path = ../../include/tradstdc.h; sourceTree = ""; }; 3186A3C821A4B0FE0052BF02 /* mondata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mondata.h; path = ../../include/mondata.h; sourceTree = ""; }; - 3186A3C921A4B0FE0052BF02 /* macwin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macwin.h; path = ../../include/macwin.h; sourceTree = ""; }; 3186A3CA21A4B0FE0052BF02 /* timeout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = timeout.h; path = ../../include/timeout.h; sourceTree = ""; }; 3186A3CB21A4B0FE0052BF02 /* sys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sys.h; path = ../../include/sys.h; sourceTree = ""; }; 3186A3CC21A4B0FE0052BF02 /* gem_rsc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gem_rsc.h; path = ../../include/gem_rsc.h; sourceTree = ""; }; @@ -701,12 +689,6 @@ 3186A37A21A4B0FA0052BF02 /* integer.h */, 3186A3BC21A4B0FD0052BF02 /* lint.h */, 3186A39921A4B0FD0052BF02 /* load_img.h */, - 3186A3A421A4B0FD0052BF02 /* mac-carbon.h */, - 3186A39F21A4B0FD0052BF02 /* mac-qt.h */, - 3186A37221A4B0FA0052BF02 /* mac-term.h */, - 3186A39D21A4B0FD0052BF02 /* macpopup.h */, - 3186A3AE21A4B0FD0052BF02 /* mactty.h */, - 3186A3C921A4B0FE0052BF02 /* macwin.h */, 3186A3B821A4B0FD0052BF02 /* mail.h */, 3186A38521A4B0FB0052BF02 /* mextra.h */, 3186A3B321A4B0FD0052BF02 /* mfndpos.h */, @@ -717,7 +699,6 @@ 3186A38F21A4B0FC0052BF02 /* monflag.h */, 3186A3BB21A4B0FD0052BF02 /* monst.h */, 3186A38421A4B0FB0052BF02 /* monsym.h */, - 3186A38921A4B0FB0052BF02 /* mttypriv.h */, 3186A39B21A4B0FD0052BF02 /* ntconf.h */, 3186A39521A4B0FC0052BF02 /* obj.h */, 3186A3A821A4B0FD0052BF02 /* objclass.h */, @@ -727,11 +708,6 @@ 3186A38321A4B0FB0052BF02 /* permonst.h */, 3186A37721A4B0FA0052BF02 /* pm.h */, 3186A37F21A4B0FA0052BF02 /* prop.h */, - 3186A39821A4B0FC0052BF02 /* qt_clust.h */, - 3186A37821A4B0FA0052BF02 /* qt_kde0.h */, - 3186A3B421A4B0FD0052BF02 /* qt_win.h */, - 3186A3BD21A4B0FD0052BF02 /* qt_xpms.h */, - 3186A3C421A4B0FE0052BF02 /* qttableview.h */, 3186A39E21A4B0FD0052BF02 /* quest.h */, 3186A37C21A4B0FA0052BF02 /* rect.h */, 3186A37B21A4B0FA0052BF02 /* region.h */, @@ -942,7 +918,7 @@ 3189576921A1FCC100FB2ABE /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1130; + LastUpgradeCheck = 1220; ORGANIZATIONNAME = "Bart House"; TargetAttributes = { 3189577021A1FCC100FB2ABE = { @@ -1631,6 +1607,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = NO; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -1714,6 +1691,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = NO; CLANG_WARN_SUSPICIOUS_MOVE = YES; diff --git a/sys/unix/NetHack.xcodeproj/xcshareddata/xcschemes/NetHack.xcscheme b/sys/unix/NetHack.xcodeproj/xcshareddata/xcschemes/NetHack.xcscheme index 7abc16af5..f8a152db6 100644 --- a/sys/unix/NetHack.xcodeproj/xcshareddata/xcschemes/NetHack.xcscheme +++ b/sys/unix/NetHack.xcodeproj/xcshareddata/xcschemes/NetHack.xcscheme @@ -1,6 +1,6 @@ Date: Sun, 13 Dec 2020 13:45:04 -0800 Subject: [PATCH 618/708] Qt: remove "Search [______]" from Help menu Prevent Qt from inserting an extra entry in the Help dropdown menu displayed in the menu bar across the top of the screen when nethack has focus. "Search [______]" lets the user enter a string to search for but doesn't give nethack any control over that so we can't have it. I haven't found a sane way to get rid of it. The insane way of not naming any menu "Help" works. This uses "\177Help" so that it still looks like "Help" but won't match that string. --- doc/fixes37.0 | 4 +++- win/Qt/Qt-issues.txt | 6 ------ win/Qt/qt_main.cpp | 21 +++++++++++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 01ae61a10..2ead283a6 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.386 $ $NHDT-Date: 1607754748 2020/12/12 06:32:28 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.390 $ $NHDT-Date: 1607895902 2020/12/13 21:45:02 $ General Fixes and Modified Features ----------------------------------- @@ -551,6 +551,8 @@ Qt+OSX: add a separate nethack->Quit menu entry with different functionality; Qt+OSX: since menu entry help->"About Qt NetHack" gets hijacked and becomes "nethack->About nethack", add a separate help->_About_Qt_NetHack_ which stays where intended and brings up the same information +Qt+OSX: suppress unwanted "Search [______]" action from being inserted as the + first entry in the menubar's "Help" dropdown menu tiles: add indicator of thonged portion to aklys tile tty: role and race selection menus weren't filtering out potential choices which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index 98c4621a6..c38fca661 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -26,12 +26,6 @@ around by giving focus to some other application (which will put up its own menu bar) and then back to nethack (thereby reloading nethack's menu bar). -On OSX, a "Search [______]" action is inserted as the first entry of -the dropdown Help menu on the toolbar. NetHack has no control over -what it does or where it looks, so it should be eliminated somehow. -(It is not releated to nethack's search command, nor the interception -of an attempt to insert "Search" into the dropdown Action menu.) - Sometimes scrolling a menu leaves the displayed text not matching what nethack thinks is displayed, so making a selection by mouse click may occasionally pick the wrong item. There's usually a visual clue when diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index a8bbebed8..eb6cd8af9 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -781,7 +781,28 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : info->setTitle("Info"); menubar->addMenu(info); menubar->addSeparator(); +#ifndef MACOSX help->setTitle("Help"); +#else + // On OSX, an entry in the menubar called "Help" will get an + // extra action, "Search [______]", inserted as the first entry. + // We have no control over what it does and don't want it. + // + // Using actions() to fetch a list of all entries doesn't find it, + // so we don't have its widget pointer to pass to removeAction(). + // + // Altering the name with an invisible character to inhibit + // string matching is ludicrous but keeps the unwanted action + // from getting inserted into the "Help" menu behind our back. + // Underscore works too and is more robust but unless we prepend + // it to every entry, "_Help" would stand out as strange. + help->setTitle("\177Help"); + // (Renaming back to "Help" after the fact does reset the menu's + // name but it also results in the Search action being added. + // Perhaps a custom context menu that changes its name to "Help" + // as it is being shown--and possibly changes back afterward-- + // would work but the name mangling hack is much simpler.) +#endif menubar->addMenu(help); } From e9d729733b709838612015936232c4bafbe4de65 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 13 Dec 2020 15:51:23 -0800 Subject: [PATCH 619/708] bargethrough/monster-vs-monster displacing Fix the regression that monster movement flag unification introduced for monsters able to swap places with adjacent monsters. It used to be restricted in order to prevent Riders swapping places with other Riders so that they didn't repeatedly exchange places when one was right behind the other and the farther one moved first. Then when displacer beasts were added, that restriction was extended to prevent them swapping places with Riders (but not the other way around.) The flags change inadvertently let any displacer swap with any other displacer. --- doc/fixes37.0 | 3 ++- src/mon.c | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 2ead283a6..5dc248646 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.390 $ $NHDT-Date: 1607895902 2020/12/13 21:45:02 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.391 $ $NHDT-Date: 1607901923 2020/12/13 23:25:23 $ General Fixes and Modified Features ----------------------------------- @@ -432,6 +432,7 @@ dwarves could sometimes pass through walls without digging their way fix genetic engineers dropping Schroedinger's cat box the checks and handling for fountains, sinks, and drawbridges were being missed during liquid_flow +monster movement flags unification allowed displacer beasts to displace Riders curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/mon.c b/src/mon.c index 06a00a4a3..ad126c6c5 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1607374002 2020/12/07 20:46:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.359 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1607901923 2020/12/13 23:25:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.360 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1586,8 +1586,10 @@ struct monst *mtmp; allowflags |= UNLOCKDOOR; if (passes_bars(mtmp->data)) allowflags |= ALLOW_BARS; +#if 0 /* can't do this here; leave it for mfndpos() */ if (is_displacer(mtmp->data)) allowflags |= ALLOW_MDISP; +#endif if (is_minion(mtmp->data) || is_rider(mtmp->data)) allowflags |= ALLOW_SANCT; /* unicorn may not be able to avoid hero on a noteleport level */ @@ -1712,7 +1714,7 @@ long flag; || (m_at(x, ny) && m_at(nx, y) && worm_cross(x, y, nx, ny) && !m_at(nx, ny) && (nx != u.ux || ny != u.uy)))) continue; - if ((is_pool(nx, ny) == wantpool || poolok) + if ((poolok || is_pool(nx, ny) == wantpool) && (lavaok || !is_lava(nx, ny))) { int dispx, dispy; boolean monseeu = (mon->mcansee @@ -1764,6 +1766,7 @@ long flag; info[cnt] |= ALLOW_TM; } } else { + flag &= ~ALLOW_MDISP; /* depends upon defender */ mmflag = flag | mm_displacement(mon, mtmp2); if (!(mmflag & ALLOW_MDISP)) continue; From b18cbdb1605ee9d144cebc0c7705cbd62b9794b0 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 13 Dec 2020 18:55:35 -0800 Subject: [PATCH 620/708] Improvements to azure pipeline. --- azure-pipelines.yml | 85 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index dc9103bf0..eee362290 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1,28 +1,56 @@ strategy: matrix: - linux: + linux_focal_gcc8_minimal: imageName: 'ubuntu-20.04' - mac: + ccName: gcc-8 + cxxName: g++-8 + buildMinimalSetting: true + linux_focal_clang_all: + imageName: 'ubuntu-20.04' + ccName: clang + cxxName: clang++ + buildMinimalSetting: false + linux_focal_gcc8_all: + imageName: 'ubuntu-20.04' + ccName: gcc-8 + cxxName: g++-8 + buildMinimalSetting: false + linux_focal_gcc9_all: + imageName: 'ubuntu-20.04' + ccName: gcc-9 + cxxName: g++-9 + buildMinimalSetting: false + linux_bionic_gcc7_all: + imageName: 'ubuntu-18.04' + ccName: gcc-7 + cxxName: g++-7 + buildMinimalSetting: false +# build is currently broken build +# mac_catalina_gcc8_all: +# imageName: 'macOS-10.15' +# ccName: gcc-8 +# cxxName: g++-8 +# buildMinimalSetting: false + mac_catalina_clang_all: imageName: 'macOS-10.15' + ccName: clang + cxxName: clang++ + buildMinimalSetting: false windows: imageName: 'windows-latest' + buildMinimalSetting: false pool: vmImage: $(imageName) -resources: - repositories: - - repository: luarepo - type: github - name: lua/lua - ref: refs/tags/v5.4.2 - endpoint: github.com_barthouse - variables: + buildMinimal: $(buildMinimalSetting) ${{ if eq( variables['Agent.OS'], 'Windows_NT') }}: NetHackPath: s\NetHack ${{ if ne( variables['Agent.OS'], 'Windows_NT') }}: NetHackPath: s/NetHack + CC: $(ccName) + CXX: $(cxxName) steps: - checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack @@ -54,13 +82,46 @@ steps: sudo apt-get -qq -y update sudo apt-get -qq -y install libncurses5-dev sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools + condition: eq( variables['Agent.OS'], 'Linux' ) + displayName: 'Getting linux build dependencies' + +- bash: | + cd sys/unix + sh setup.sh hints/linux-minimal + cd ../.. + sed -i '/^#define CLIPPING/d' include/config.h + sed -i '/^#define COMPRESS/d' include/config.h + #sed -i '/^#define DOAGAIN/d' include/config.h + sed -i '/^#define DUMPLOG/d' include/config.h + #sed -i '/^#define GDBPATH/d' include/config.h + #sed -i '/^#define GREPPATH/d' include/config.h + sed -i '/^#define INSURANCE/d' include/config.h + sed -i '/^#define LOGFILE/d' include/config.h + sed -i '/^#define NEWS/d' include/config.h + sed -i '/^#define PANICLOG/d' include/config.h + #sed -i '/^#define STATUS_HILITES/d' include/config.h + sed -i '/^#define SYSCF/d' include/config.h + sed -i '/^#define USER_SOUNDS/d' include/config.h + sed -i '/^#define XLOGFILE/d' include/config.h + + sed -i '/^#define MAIL/d' include/unixconf.h + sed -i '/^#define SHELL/d' include/unixconf.h + sed -i '/^#define SUSPEND/d' include/unixconf.h + sed -i 's/^#define TEXTCOLOR//' include/unixconf.h + cat include/config.h + make fetch-lua + make WANT_WIN_ALL=1 all + condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, true)) + displayName: 'Buildig linux minimal build' + +- bash: | cd sys/unix sh setup.sh hints/linux.2020 cd ../.. make fetch-lua make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all - condition: eq( variables['Agent.OS'], 'Linux' ) - displayName: 'Linux Build' + condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, false)) + displayName: 'Building linux full build' - bash: | cd sys/unix From 93a49c784517f5fe3a937e0f6555a4ba2c15d06b Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 13 Dec 2020 19:44:15 -0800 Subject: [PATCH 621/708] Adding pdcurses submodule for MinGW build. --- .gitmodules | 3 +++ submodules/pdcurses | 1 + 2 files changed, 4 insertions(+) create mode 160000 submodules/pdcurses diff --git a/.gitmodules b/.gitmodules index c08764d7e..ef732d5c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "submodules/lua"] path = submodules/lua url = https://github.com/lua/lua.git +[submodule "submodules/pdcurses"] + path = submodules/pdcurses + url = https://github.com/wmcbrine/PDCurses.git diff --git a/submodules/pdcurses b/submodules/pdcurses new file mode 160000 index 000000000..618e0aaa3 --- /dev/null +++ b/submodules/pdcurses @@ -0,0 +1 @@ +Subproject commit 618e0aaa31b4728eb4df78ec4de6c2b873908eda From e5fb08ae4e2a3f38b831cadd108ebd78248a44db Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 13 Dec 2020 20:31:01 -0800 Subject: [PATCH 622/708] Switch mingw build to use submodules in default path. --- sys/winnt/Makefile.gcc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 21ae0aa53..f7c2550e7 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -100,7 +100,7 @@ TARGET_CPU=x86 # your machine. # # ADD_CURSES=Y -# PDCURSES_TOP=../lib/pdcurses +# PDCURSES_TOP=../submodules/pdcurses #4b Qt # @@ -143,7 +143,7 @@ endif # successfully build NetHack-3.7. # ADD_LUA=Y -LUATOP=../lib/lua-$(LUAVER) +LUATOP=../submdules/lua # #============================================================================== # This marks the end of the BUILD DECISIONS section. From d88749e4196a69a24e8cb8287e68f87fce2c0292 Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 13 Dec 2020 20:38:56 -0800 Subject: [PATCH 623/708] Working on getting WinGW building with Azure pipeline. Fix typo recently introduced. Allow LUATOP to be specified by pipeline. --- sys/winnt/Makefile.gcc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index f7c2550e7..785f011cc 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -142,8 +142,11 @@ endif # you'll need to specify the correct spot below in order to # successfully build NetHack-3.7. # +# By default we add lua to the build. +ifndef ADD_LUA ADD_LUA=Y -LUATOP=../submdules/lua +LUATOP=../submodules/lua +endif # #============================================================================== # This marks the end of the BUILD DECISIONS section. From f89005efd7ce511b90870ae1076e4ec8836a8435 Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 14 Dec 2020 00:24:05 -0800 Subject: [PATCH 624/708] Make compiling the lua interpreter optional. --- sys/winnt/Makefile.gcc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 785f011cc..398e17053 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -143,10 +143,26 @@ endif # successfully build NetHack-3.7. # # By default we add lua to the build. +# ifndef ADD_LUA ADD_LUA=Y LUATOP=../submodules/lua endif + +#--------------------------------------------------------------- +# Standalone LUA interpreter +# +# The source for the standalone interpreter (luac.c) is not kept with the +# rest of the LUA source. +# The source is kept at: +# https://github.com/lua/luac +# +# By default we will not build it. +# +ifndef WANT_LUAC +WANT_LUAC=N +endif + # #============================================================================== # This marks the end of the BUILD DECISIONS section. @@ -430,7 +446,11 @@ LUALIB = $(O)lua-$(LUAVER).static.a LUADLL = $(O)lua-$(LUAVER).a LUAINCL = -I$(LUASRC) #LUAFLAGS = unix added -lm here? +ifeq "$(WANT_LUAC)" "Y" LUATARGETS = lua.exe luac.exe $(LUADLL) $(LUALIB) +else +LUATARGETS = lua.exe $(LUADLL) $(LUALIB) +endif LUASRCFILES = lapi.c lauxlib.c lbaselib.c lcode.c \ lcorolib.c lctype.c ldblib.c ldebug.c ldo.c \ From fcd74aedf4bd0a39b30f1aeeea9c31bbfa12a1ef Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 14 Dec 2020 00:28:36 -0800 Subject: [PATCH 625/708] Added mingw build. --- azure-pipelines.yml | 74 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 9 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index eee362290..cfcb1911c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -25,7 +25,7 @@ strategy: ccName: gcc-7 cxxName: g++-7 buildMinimalSetting: false -# build is currently broken build +# build is currently broken # mac_catalina_gcc8_all: # imageName: 'macOS-10.15' # ccName: gcc-8 @@ -36,15 +36,32 @@ strategy: ccName: clang cxxName: clang++ buildMinimalSetting: false - windows: - imageName: 'windows-latest' + windows-visualstudio: + imageName: 'windows-2019' buildMinimalSetting: false + vsBuildSetting: true + mingwBuildSetting: false + windows-mingw: + imageName: 'windows-2019' + buildMinimalSetting: false + vsBuildSetting: false + mingwBuildSetting: true pool: vmImage: $(imageName) +resources: + repositories: + - repository: pdcursesrepo + type: github + name: wmcbrine/PDCurses + ref: refs/heads/master + endpoint: github.com_barthouse + variables: buildMinimal: $(buildMinimalSetting) + mingwBuild: $(mingwBuildSetting) + vsBuild: $(vsBuildSetting) ${{ if eq( variables['Agent.OS'], 'Windows_NT') }}: NetHackPath: s\NetHack ${{ if ne( variables['Agent.OS'], 'Windows_NT') }}: @@ -53,10 +70,22 @@ variables: CXX: $(cxxName) steps: +- bash: | + echo 'mingwBuildSetting' '$(mingwBuildSetting)' + echo 'mingwBuild' '$(mingwBuild)' + echo 'vsBuild' '$(vsBuild)' + echo 'NetHackPath' '$(NetHackPath)' + echo 'CC' '$(CC)' + echo 'CXX' '$(CXX)' + - checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack submodules: true path: $(NetHackPath) +- checkout: pdcursesrepo + path: s\NetHack\lib\pdcurses + condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) + - task: DownloadSecureFile@1 name: storeKey displayName: 'Store Key Download' @@ -65,18 +94,45 @@ steps: condition: eq( variables['Agent.OS'], 'Windows_NT' ) - task: CopyFiles@2 - inputs: + inputs: contents: NetHackPackage_StoreKey.pfx SourceFolder: $(Agent.TempDirectory) TargetFolder: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs condition: eq( variables['Agent.OS'], 'Windows_NT' ) + displayName: 'Copying store key' + +# Temporary need to copy lua files for minGW build +- task: CopyFiles@2 + inputs: + SourceFolder: $(Agent.BuildDirectory)\s\NetHack\submodules\lua + TargetFolder: $(Agent.BuildDirectory)\s\NetHack\lib\lua-5.4.2\src + condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) + displayName: 'Copying lua files' - task: MSBuild@1 inputs: solution: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs\NetHack.sln platform: Win32 configuration: Debug - condition: eq( variables['Agent.OS'], 'Windows_NT' ) + condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.vsBuild, true)) + displayName: 'Windows MSBuild' + +- bash: | + echo '/mingw64/bin' + ls /mingw64/bin + echo '/usr/bin' + ls /usr/bin + echo 'gcc --version' + gcc --version + export ADD_CURSES=Y + export PDCURSES_TOP=../lib/pdcurses + export LUA_VERSION=5.4.2 + export TRAVIS_COMPILER=1 + cd NetHack/src + cp ../sys/winnt/Makefile.gcc ./Makefile + mingw32-make LUA_VERSION=$LUA_VERSION install + condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) + displayName: 'Windows MinGW Build' - bash: | sudo apt-get -qq -y update @@ -86,7 +142,7 @@ steps: displayName: 'Getting linux build dependencies' - bash: | - cd sys/unix + cd NetHack/sys/unix sh setup.sh hints/linux-minimal cd ../.. sed -i '/^#define CLIPPING/d' include/config.h @@ -112,10 +168,10 @@ steps: make fetch-lua make WANT_WIN_ALL=1 all condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, true)) - displayName: 'Buildig linux minimal build' + displayName: 'Building linux minimal build' - bash: | - cd sys/unix + cd NetHack/sys/unix sh setup.sh hints/linux.2020 cd ../.. make fetch-lua @@ -124,7 +180,7 @@ steps: displayName: 'Building linux full build' - bash: | - cd sys/unix + cd NetHack/sys/unix sh setup.sh hints/macos.2020 cd ../.. make fetch-lua From 788e21ac43f2f8faf0c1a859391fd0790be8a463 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Dec 2020 01:00:19 -0800 Subject: [PATCH 626/708] have run #terrain Having recently noticed that using aka aka could work as a command, assign it to #terrain. #terrain was the only command in the "game" subset of commands as shown by '? i' that didn't have any key assignment. Since might be swapped with on some terminals and is a keypad key on the typical PC keyboard, it might not work reliably depending on nethack's number_pad mode or the hardware Num-Lock setting. Players in either of those situations haven't lost anything; they can still use extended command #terrain. --- dat/cmdhelp | 3 ++- doc/Guidebook.mn | 29 ++++++++++++++++++++++++++--- doc/Guidebook.tex | 28 ++++++++++++++++++++++++++-- doc/fixes37.0 | 3 ++- src/cmd.c | 8 ++++++-- 5 files changed, 62 insertions(+), 9 deletions(-) diff --git a/dat/cmdhelp b/dat/cmdhelp index cd0944d2d..d993c313c 100644 --- a/dat/cmdhelp +++ b/dat/cmdhelp @@ -1,4 +1,4 @@ -&# cmdhelp +&# cmdhelp - became obsolete when 'BINDINGS=key:command' got added & Tell what command a keystroke invokes ^ Show the type of an adjacent trap ^[ Cancel command (same as ESCape key) @@ -145,6 +145,7 @@ _ Travel via a shortest-path algorithm to a point on the map * Show all equipment in use (combination of the ),[,=,",( commands) $ Count your gold + List known spells +Del Display map without monsters or objects obstructing the view. # Perform an extended command (use '#?' to list choices) &# number_pad: &# -1 = numpad off, swap y with z (including Y with Z, ^Y with ^Z, M-y &c) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 524cd88c9..dff313965 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.405 $ $NHDT-Date: 1607693152 2020/12/11 13:25:52 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.407 $ $NHDT-Date: 1607936398 2020/12/14 08:59:58 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "December 11, 2020 +.ds f2 "December 13, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1060,6 +1060,20 @@ Show discovered types for one class of objects. .lp ! Escape to a shell. See \(lq#shell\(rq below for more details. +.lp Del +Show map without obstructions. +You can view the explored portion of the current level's map without +monsters; without monsters and objects; or without monsters, objects, +and traps. +.lp "" +The key is also shown as on some keyboards or +on others. +It is sometimes displayed as \(ha? even though that is not an actual +control character. +.lp "" +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 \(lq#terrain\(rq instead. .lp # Perform an extended command. .lp "" @@ -1447,8 +1461,17 @@ Default key is \(oqA\(cq. Teleport around the level. Default key is \(oq\(haT\(cq. .lp "#terrain " -Show bare map without displaying monsters, objects, or traps. +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. +.lp "" +In explore mode, you can choose to view the full map rather than just +its explored portion. +In debug mode there are additional choices. +.lp "" Autocompletes. +Default key is \(oq\(cq or \(oq\(cq (see \fIDel\fP above). .lp #therecmdmenu Show a menu of possible actions in a location next to you. .lp "#throw " diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index bbef61f06..c5b89b555 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{December 11, 2020} +\date{December 13, 2020} \maketitle @@ -1162,6 +1162,21 @@ Show discovered types for one class of objects. Escape to a shell. See ``\#shell'' below for more details. %.lp +\item[\tb{Del}] +Show map without obstructions. +You can view the explored portion of the current level's map without +monsters; without monsters and objects; or without monsters, objects, +and traps.\\ +%.lp "" +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.\\ +%.lp "" +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. +%.lp \item[\tb{\#}] Perform an extended command.\\ %.lp "" @@ -1537,8 +1552,17 @@ Remove all armor. Default key is `{\tt A}'. Teleport around the level. Default key is `{\tt \^{}T}'. %.lp \item[\tb{\#terrain}] -Show bare map without displaying monsters, objects, or traps. +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.\\ +%.lp "" +In explore mode, you can choose to view the full map rather than just +its explored portion. +In debug mode there are additional choices.\\ +%.lp "" Autocompletes. +Default key is `' or `' (see {\it Del\/} above). %.lp \item[\tb{\#therecmdmenu}] Show a menu of possible actions in a location next to you. diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 5dc248646..cfcd3f76c 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.391 $ $NHDT-Date: 1607901923 2020/12/13 23:25:23 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.392 $ $NHDT-Date: 1607936398 2020/12/14 08:59:58 $ General Fixes and Modified Features ----------------------------------- @@ -670,6 +670,7 @@ let tourists read conical hats when "?i" (show key bindings) displays commands and their keys, also show commands without any key (so useable via '#', or possibly menu, only; the majority are debugging commands) +assign default key binding for or to execute #terrain Platform- and/or Interface-Specific New Features diff --git a/src/cmd.c b/src/cmd.c index bdc9d0c9f..581460e4f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607641581 2020/12/10 23:06:21 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.432 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1607936399 2020/12/14 08:59:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.433 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1913,7 +1913,11 @@ struct ext_func_tab extcmdlist[] = { { 'T', "takeoff", "take off one piece of armor", dotakeoff }, { 'A', "takeoffall", "remove all armor", doddoremarm }, { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED }, - { '\0', "terrain", "show map without obstructions", + /* \177 == aka aka ; some terminals have an + option to swap it with so if there's a key labeled + it may or may not actually invoke the #terrain command */ + { '\177', "terrain", + "view map without monsters or objects obstructing it", doterrain, IFBURIED | AUTOCOMPLETE }, { '\0', "therecmdmenu", "menu of commands you can do from here to adjacent spot", From d4313ff828fee4358cba08e96cbd41b69923b76d Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Dec 2020 02:11:53 -0800 Subject: [PATCH 627/708] Qt 'game' menu tweak for OSX Change "_Quit-without-saving" in the Game dropdown menu to be "\177Quit-without-saving". That makes the prefix used on OSX to prevent matching "^[&]?[Qq][Uu][Ii][Tt].*" be invisible. Also change the order of the choices for the command+Q and application dropdown menu entry "quit nethack" so that "cancel and return to game" is the default for arbitrary response to the confirmation prompt. and select "quit without saving". Note that the nethack dropdown menu is OSX-specific (a Qt feature to emulate other OSX applications) and its nethack->Quit action is separate-from/in-addition-to Game->Quit menu action mentioned above (which runs nethack's #quit command). --- win/Qt/qt_main.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index eb6cd8af9..4a43f0a43 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -545,7 +545,7 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : * application menu (and renamed in the process) even if the code * here tries to put them in another menu. * See QtWidgets/doc/qmenubar.html for slightly more information. - * setMenuRole() is supposed to be able to override this behavior. + * setMenuRole() can be used to override this behavior. */ #endif QMenu* game=new QMenu; @@ -578,7 +578,9 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { game, #ifdef MACOSX /* Qt on OSX would rename "Options" to "Preferences..." and - move it from intended destination to the application menu */ + move it from intended destination to the application menu; + the ampersand produces &O which makes Alt+O into a keyboard + shortcut--except those are disabled by default by Qt on OSX */ "Run-time &" // rely on adjacent string concatenation #endif "Options", 3, doset}, @@ -587,9 +589,10 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : { game, "Save-and-exit", 3, dosave}, { game, #ifdef MACOSX - /* need something to prevent matching leading "quit" - so that it isn't hijacked for the application menu */ - "_&" + /* need something to prevent matching leading "quit" so that it + isn't hijacked for the application menu; the ampersand is to + make &Q be a keyboard shortcut (but see Options above) */ + "\177&" #endif "Quit-without-saving", 3, done2}, @@ -986,29 +989,34 @@ void NetHackQtMainWindow::doQuit(bool) { // there is a separate Quit-without-saving menu entry in the game menu // that leads to nethack's "Really quit?" prompt; OSX players can use - // either one, other implementations only have that other one but this - // routine is unconditional in case someone wants to change that + // either one, other implementations only have that other one (plus + // nethack's #quit command itself) but this routine is unconditional + // in case someone wants to change that #ifdef MACOSX QString info; info.sprintf("This will end your NetHack session.%s", !g.program_state.something_worth_saving ? "" : "\n(Cancel quitting and use the Save command" "\nto save your current game.)"); - /* this is similar to closeEvent but the details are different */ + /* this is similar to closeEvent but the details are different; + first choice (Cancel) is the default action for most arbitrary keys; + the second choice (Quit) is the action for or ; + leaves the popup waiting for some other response; + the & settings for Alt+ shortcuts don't work on OSX */ int act = QMessageBox::information(this, "NetHack", info, - "&Quit without saving", "&Cancel and return to game", + "&Quit without saving", 0, 1); switch (act) { case 0: + // cancel + break; // return to game + case 1: // quit -- bypass the prompting preformed by done2() g.program_state.stopprint++; ::done(QUIT); /*NOTREACHED*/ break; - case 1: - // cancel - break; // return to game } #endif return; From aa7f01eed7565748ad3662976e9465caa1201c5a Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Dec 2020 03:30:58 -0800 Subject: [PATCH 628/708] github pull request #417 - disclosing apron text Adopt the patch to show the writing on any alchemy smocks in hero's inventory during end of game disclosure. I also added one more saying among the choices for alchemy smock/apron. It's based on a T-shirt descibed in a movie. (I remember the description of the text but I don't remember noticing anybody wearing the T-shirt that lead to that.) Since so many of the smock quotes are about cooking, it seems better to add it as an alchemy quote instead of just another T-shirt where there'd be no context to explain it. Closes #417 --- include/extern.h | 3 ++- src/objnam.c | 7 +++++-- src/read.c | 14 ++++++++++---- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/extern.h b/include/extern.h index b8f6faaa0..f771e0766 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1607561572 2020/12/10 00:52:52 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.928 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1607945415 2020/12/14 11:30:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.932 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2119,6 +2119,7 @@ E long NDECL(random); E void FDECL(learnscroll, (struct obj *)); E char *FDECL(tshirt_text, (struct obj *, char *)); +E char *FDECL(apron_text, (struct obj *, char *)); E const char *FDECL(candy_wrapper_text, (struct obj *)); E void FDECL(assign_candy_wrapper, (struct obj *)); E int NDECL(doread); diff --git a/src/objnam.c b/src/objnam.c index 0daa19c9a..9efcd4fc6 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 objnam.c $NHDT-Date: 1606765213 2020/11/30 19:40:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.307 $ */ +/* NetHack 3.7 objnam.c $NHDT-Date: 1607945434 2020/12/14 11:30:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.308 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -753,7 +753,10 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ players who aren't aware that something readable is present */ switch (obj->otyp) { case T_SHIRT: - Sprintf(eos(buf), " with text \"%s\"", tshirt_text(obj, tmpbuf)); + case ALCHEMY_SMOCK: + Sprintf(eos(buf), " with text \"%s\"", + (obj->otyp == T_SHIRT) ? tshirt_text(obj, tmpbuf) + : apron_text(obj, tmpbuf)); break; case CANDY_BAR: lbl = candy_wrapper_text(obj); diff --git a/src/read.c b/src/read.c index 49bc07ce7..0c41973aa 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1607200174 2020/12/05 20:29:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.204 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1607945439 2020/12/14 11:30:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.205 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -18,7 +18,6 @@ static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 }; static boolean FDECL(learnscrolltyp, (SHORT_P)); static char *FDECL(erode_obj_text, (struct obj *, char *)); -static char *FDECL(apron_text, (struct obj *, char *)); static void FDECL(stripspe, (struct obj *)); static void FDECL(p_glow1, (struct obj *)); static void FDECL(p_glow2, (struct obj *, const char *)); @@ -118,7 +117,7 @@ char *buf; "Meat is Mordor", "Minetown Better Business Bureau", "Minetown Watch", - "Ms. Palm's House of Negotiable Affection -- A Very Reputable House Of Disrepute", + "Ms. Palm's House of Negotiable Affection--A Very Reputable House Of Disrepute", "Protection Racketeer", "Real men love Crom", "Somebody stole my Mojo!", @@ -157,7 +156,7 @@ char *buf; return erode_obj_text(tshirt, buf); } -static char * +char * apron_text(apron, buf) struct obj *apron; char *buf; @@ -172,6 +171,13 @@ char *buf; "If you can't stand the heat, get out of Gehennom!", "If we weren't meant to eat animals, why are they made out of meat?", "If you don't like the food, I'll stab you", + /* In the movie "The Sum of All Fears", a Russian worker in a weapons + facility wears a T-shirt that a translator says reads, "I am a + bomb technician, if you see me running ... try to catch up." + In nethack, the quote is far more suitable to an alchemy smock + (particularly since so many of these others are about cooking) + than a T-shirt and is paraphrased to simplify/shorten it. */ + "If you see me running, try to keep up...", }; Strcpy(buf, apron_msgs[apron->o_id % SIZE(apron_msgs)]); From 0e048b64e636808b02b2b22ea15a4c7482131700 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Sun, 13 Dec 2020 23:24:07 -0500 Subject: [PATCH 629/708] This is cron-daily v1-Jan-20-2020. files updated: Files --- Files | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Files b/Files index e413ea33c..ae8411092 100644 --- a/Files +++ b/Files @@ -227,8 +227,8 @@ wield.c windows.c wizard.c worm.c worn.c write.c zap.c submodules: -(file in top directory) -lua +(files in top directory) +lua pdcurses sys/libnh: (files in top directory) From b5a085437feaf533c757f5c530fc0e223f0e1760 Mon Sep 17 00:00:00 2001 From: nhw_cron Date: Mon, 14 Dec 2020 04:24:05 -0500 Subject: [PATCH 630/708] This is cron-daily v1-Jan-20-2020. guidebook updated: doc/Guidebook.txt --- doc/Guidebook.txt | 3572 +++++++++++++++++++++++---------------------- 1 file changed, 1819 insertions(+), 1753 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 7b2cb3b1f..a7c24bc21 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - December 11, 2020 + December 13, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -1153,6 +1153,20 @@ ! Escape to a shell. See "#shell" below for more details. + Del Show map without obstructions. You can view the explored + portion 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 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. + # Perform an extended command. @@ -1166,6 +1180,18 @@ Adjust inventory letters (most useful when the fixinv option is "on"). Autocompletes. Default key is `M-a'. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 19 + + + 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 particu- @@ -1180,18 +1206,6 @@ 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, - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 19 - - - 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 eligi- @@ -1232,6 +1246,18 @@ the current level (same as "#annotate"). Default key is `C'. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 20 + + + #cast Cast a spell. Default key is `Z'. @@ -1245,19 +1271,6 @@ List voluntary challenges you have maintained. Autocom- pletes. Default key is `M-C'. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 20 - - - See the section below entitled "Conduct" for details. #dip @@ -1298,6 +1311,19 @@ #force Force a lock. Autocompletes. Default key is `M-f'. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 21 + + + #glance Show what type of thing a map symbol corresponds to. De- fault key is `;'. @@ -1312,18 +1338,6 @@ #history Show long version and game history. Default key is `V'. - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 21 - - - #inventory Show your inventory. Default key is `i'. @@ -1364,6 +1378,18 @@ 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 + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 22 + + + go directly to removing a saddle. Default key is `M-l', and also `l' if number_pad is on. @@ -1378,18 +1404,6 @@ #offer Offer a sacrifice to the gods. Autocompletes. Default key - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 22 - - - is `M-o'. You'll need to find an altar to have any chance at success. @@ -1431,6 +1445,17 @@ Pick up things at the current location. Default key is `,'. The `m' prefix forces use of a menu. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 23 + + + #polyself Polymorph self. Autocompletes. Debug mode only. @@ -1444,18 +1469,6 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 23 - - - you can reset the paranoid_confirmation option to disable it. @@ -1497,6 +1510,18 @@ #ride Ride (or stop riding) a saddled creature. Autocompletes. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 24 + + + Default key is `M-R'. #rub @@ -1510,18 +1535,6 @@ Search for traps and secret doors around you. Default key is `s'. - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 24 - - - #seeall Show all equipment in use. Default key is `*'. @@ -1563,6 +1576,18 @@ objects and monsters temporarily removed, making it possible to see all discovered traps.) Default key is `^'. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 25 + + + #sit Sit down. Autocompletes. Default key is `M-s'. @@ -1576,18 +1601,6 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 25 - - - is `^Z'. #swap @@ -1603,8 +1616,17 @@ Teleport around the level. Default key is `^T'. #terrain - Show bare map without displaying monsters, objects, or - traps. Autocompletes. + Show map without obstructions. In normal play you can view + the explored portion of the current level's map without mon- + sters; without monsters and objects; or without monsters, + objects, and traps. + + In explore mode, you can choose to view the full map rather + than just its explored portion. In debug mode there are ad- + ditional choices. + + Autocompletes. Default key is `' or `' (see + Del above). #therecmdmenu Show a menu of possible actions in a location next to you. @@ -1616,35 +1638,13 @@ Look at the timeout queue. Autocompletes. Debug mode only. #tip - Tip over a container (bag or box) to pour out its contents. - Autocompletes. Default key is `M-T'. The `m' prefix makes + Tip over a container (bag or box) to pour out its contents. + Autocompletes. Default key is `M-T'. The `m' prefix makes the command use a menu. - #travel - Travel to a specific location on the map. Default key is - `_'. Using the "request menu" prefix shows a menu of inter- - esting targets in sight without asking to move the cursor. - When picking a target with cursor and the autodescribe op- - tion is on, the top line will show "(no travel path)" if - your character does not know of a path to that location. - - #turn - Turn undead away. Autocompletes. Default key is `M-t'. - - #twoweapon - 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, or it will be automatically turned off. - - #untrap - Untrap something (trap, door, or chest). Default key is `M- - u', and `u' if number_pad is on. - - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -1654,7 +1654,29 @@ - In some circumstances it can also be used to rescue trapped + #travel + Travel to a specific location on the map. Default key is + `_'. Using the "request menu" prefix shows a menu of inter- + esting targets in sight without asking to move the cursor. + When picking a target with cursor and the autodescribe op- + tion is on, the top line will show "(no travel path)" if + your character does not know of a path to that location. + + #turn + Turn undead away. Autocompletes. Default key is `M-t'. + + #twoweapon + 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, or it will be automatically turned off. + + #untrap + 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 monsters. #up @@ -1666,25 +1688,38 @@ #version Print compile time options for this version of NetHack. - The second paragraph lists the user interface(s) that are - included. If there are more than one, you can use the win- + The second paragraph lists the user interface(s) that are + included. If there are more than one, you can use the win- dowtype 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 ver- + Show the program's version number, plus the date and time + that the running copy was built from sources (not the ver- sion'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 + Rest one move while doing nothing. Default key is `.', and also ` ' if rest_on_space is on. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 27 + + + #wear Wear a piece of armor. Default key is `W'. @@ -1692,7 +1727,7 @@ Tell what a key does. Default key is `&'. #whatis - Show what type of thing a symbol corresponds to. Default + Show what type of thing a symbol corresponds to. Default key is `/'. #wield @@ -1706,28 +1741,17 @@ Debug mode only. #wizbury - Bury objects under and around you. Autocompletes. Debug + Bury objects under and around you. Autocompletes. Debug mode only. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 27 - - - #wizdetect - Search for hidden things (secret doors or traps or unseen - monsters) within a modest radius. Autocompletes. Debug + Search for hidden things (secret doors or traps or unseen + monsters) within a modest radius. Autocompletes. Debug mode only. Default key is `^E'. #wizgenesis Create a monster. May be prefixed by a count to create more - than one. Autocompletes. Debug mode only. Default key is + than one. Autocompletes. Debug mode only. Default key is `^G'. #wizidentify @@ -1743,40 +1767,16 @@ Default key is `^V'. #wizmap - Map the level. Autocompletes. Debug mode only. Default + Map the level. Autocompletes. Debug mode only. Default key is `^F'. #wizrumorcheck - Verify rumor boundaries by displaying first and last true + Verify rumor boundaries by displaying first and last true rumors and first and last false rumors. - Also displays first, second, and last random engravings, - epitaphs, and hallucinatory monsters. - - Autocompletes. Debug mode only. - - #wizseenv - 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. De- - fault key is `^W'. - - #wmode - Show wall modes. Autocompletes. Debug mode only. - - - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -1786,6 +1786,29 @@ + Also displays first, second, and last random engravings, + epitaphs, and hallucinatory monsters. + + Autocompletes. Debug mode only. + + #wizseenv + 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. De- + fault key is `^W'. + + #wmode + Show wall modes. Autocompletes. Debug mode only. + #zap Zap a wand. Default key is `z'. @@ -1795,14 +1818,14 @@ If your keyboard has a meta key (which, when pressed in com- - bination with another key, modifies it by setting the "meta" - [8th, or "high"] bit), you can invoke many extended commands by + bination 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. - In Windows, OS/2, PC and ST NetHack, the "Alt" key can be + In Windows, OS/2, PC and ST NetHack, the "Alt" key can be used in this fashion; on the Amiga, set the altmeta option to get - this behavior. On other systems, if typing "Alt" plus another - key transmits a two character sequence consisting of an Escape + this behavior. 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+key. @@ -1816,6 +1839,19 @@ M-c #chat + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 29 + + + M-C #conduct M-d #dip @@ -1840,18 +1876,6 @@ M-p #pray - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 29 - - - M-q #quit M-r #rub @@ -1872,7 +1896,7 @@ - If the number_pad option is on, some additional letter com- + If the number_pad option is on, some additional letter com- mands are available: h #help @@ -1881,34 +1905,10 @@ k #kick - l #loot - - N #name - - u #untrap - - 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 corridors 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. Multiple search attempts may be needed. When searching is - successful, secret corridors become ordinary open corridor loca- - tions. Mapping magic reveals secret corridors, so converts them - into ordinary corridors 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 - NetHack 3.7 December 11, 2020 + + NetHack 3.7 December 13, 2020 @@ -1918,63 +1918,63 @@ - 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 at- + l #loot + + N #name + + u #untrap + + 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 corridors 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. Multiple search attempts may be needed. When searching is + successful, secret corridors become ordinary open corridor loca- + tions. Mapping magic reveals secret corridors, so converts them + into ordinary corridors 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 stunned or suffer from the fumbling at- tribute. - Open doors cannot be entered diagonally; you must approach - them straight on, horizontally or vertically. Doorways without + 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 + Unlocking magic exists but usually won't be available early on. You can get through a locked door without magic by first us- - ing an unlocking tool with the `a' (apply) command, and then + ing 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. Alternatively, 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 + 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. Alternatively, 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 + 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 effec- - tively forget that a trap was found there.) - - Closed doors can be useful for shutting out monsters. Most - monsters 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. 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 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 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 someone else trigger it, or you discover it with - the `s' (search) command (multiple attempts are often needed; if - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -1984,63 +1984,63 @@ - your luck is poor, many attempts might be needed). Wands of se- - cret door detection and spell of detect unseen also reveal traps - within a modest radius but only if the trap is also within line- + it. If you accede, success will eliminate the trap but failure + will set off the trap's explosion. (If you decline, you effec- + tively forget that a trap was found there.) + + Closed doors can be useful for shutting out monsters. Most + monsters 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. 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 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 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 someone else trigger it, or you discover it with + the `s' (search) command (multiple attempts are often needed; if + your luck is poor, many attempts might be needed). Wands of se- + cret 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 + 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, usual- - ly will avoid moving onto a trap which is shown on your map if + ly 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 adja- + Some traps such as pits, bear traps, and webs hold you in + one place. You can escape by simply trying to move to an adja- cent spot and repeat as needed; eventually you will get free. - Other traps can send you to different locations. Tele- - porters send you elsewhere on the same dungeon level. Level - teleporters send you to a random dungeon level, the destination - chosen from a few levels lower all the way to the top. 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. All of these traps choose a - new destination each time they're activated. Magic portals also - send you to a different level but behave differently. Some por- + Other traps can send you to different locations. Tele- + porters send you elsewhere on the same dungeon level. Level + teleporters send you to a random dungeon level, the destination + chosen from a few levels lower all the way to the top. 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. All of these traps choose a + new destination each time they're activated. Magic portals also + send you to a different level but behave differently. Some por- tals are two-way and their remote destination is always the same: - another portal which can take you back. Others are one-way and + another portal which can take you back. Others are one-way and send you to a specific destination level but not necessarily 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 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 Sokoban game, you can only move in the four - cardinal compass directions, 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 traditional 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 in- - to 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 - - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2050,63 +2050,63 @@ - will lower your luck without any specific message given about - that. See the Conduct section for information about getting + 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 Sokoban game, you can only move in the four + cardinal compass directions, 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 traditional 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 in- + to 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 section 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 + 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 in- - stance, fairly early in the dungeon you will find a level with + to the next level. There are some exceptions though. For in- + stance, fairly early in the dungeon you will find a level with two down staircases, one continuing into the dungeon and the oth- - er 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 dun- + er 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 dun- geon. - When you traverse a set of stairs, or trigger a trap which - sends you to another level, the level you're leaving will be de- - activated and stored in a file on disk. If you're moving to a + When you traverse a set of stairs, or trigger a trap which + sends you to another level, the level you're leaving will be de- + activated 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 created (from scratch for most random + 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 de- - scribed below). Monsters are only active on the current level; + scribed 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 occa- - sionally 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 play. - - 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 picking them up and then using the `p' command. You can - inquire about the price of an item prior to picking it up by us- - ing the "#chat" command while standing on it. Using an item pri- - or 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 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 shopkeeper isn't interested (generally, your item - needs to be compatible with the type of merchandise carried by + 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 - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2116,26 +2116,50 @@ + they're close enough when you travel up or down stairs, and occa- + sionally 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 play. + + 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 picking them up and then using the `p' command. You can + inquire about the price of an item prior to picking it up by us- + ing the "#chat" command while standing on it. Using an item pri- + or 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 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 shopkeeper 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. + 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 shop where it was obtained; other shopkeepers - won't honor it. (If you happen to find a "credit card" in the + 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 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.) - The `$' command, which reports the amount of gold you are + The `$' command, which reports the amount of gold you are carrying (in inventory, not inside bags or boxes), will also show - current shop debt or credit, if any. The "Iu" command lists un- + current shop debt or credit, if any. The "Iu" command lists un- paid items (those which still belong to the shop) if you are car- - rying any. The "Ix" command shows an inventory-like display of - any unpaid items which have been used up, along with other shop + rying any. The "Ix" command shows an inventory-like display of + any unpaid items which have been used up, along with other shop fees, if any. 5.4.1. Shop idiosyncrasies @@ -2144,35 +2168,11 @@ * 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 + * 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 - generally ignore any other customers. - * 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 inven- - tory depletion. - - 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 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 no matter how big a pile is. Note that the - - - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2182,63 +2182,63 @@ - number refers to the count of separate stacks of objects present - rather than the sum of the quantities of those stacks (so 7 ar- - rows 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 loca- + * While the shopkeeper watches you like a hawk, he or she will + generally ignore any other customers. + + * 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 inven- + tory depletion. + + 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 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 no matter how big a pile is. Note that the num- + ber refers to the count of separate stacks of objects present + rather than the sum of the quantities of those stacks (so 7 ar- + rows 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 loca- tion). - The "nopickup" command prefix (default `m') can be used be- - fore a movement direction to step on objects without attempting + The "nopickup" command prefix (default `m') can be used be- + fore 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 + 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 + 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 any- - thing 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 + 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 any- + thing 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 ob- - jects, in which case the back on land circumstance is implied. - - 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-without-attacking prefix and can be used to try to step onto - a visible monster's spot without the move being considered an at- - tack (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 attacking a peaceful or tame - creature. - - The run_mode option controls how frequently the map gets re- - drawn 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 dungeon) is a tribute to the ancestor game hack's + Moving off of any of those back onto "normal" terrain will give + one message too, unless there is feedback about one or more - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2248,63 +2248,63 @@ - inspiration rogue. + objects, in which case the back on land circumstance is implied. - It is usually displayed differently from other levels: pos- - sibly in characters instead of tiles, or without line-drawing + 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-without-attacking prefix and can be used to try to step onto + a visible monster's spot without the move being considered an at- + tack (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 attacking a peaceful or tame + creature. + + The run_mode option controls how frequently the map gets re- + drawn 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 dungeon) is a tribute to the ancestor game hack's inspira- + tion rogue. + + It is usually displayed differently from other levels: pos- + sibly 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 differences 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 + than $ and stairs are shown as % rather than < and >. There are + some minor differences 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 + The slight strangeness of this level is a feature, not a bug.... 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 + 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 do very well). - The commands `/' and `;' may be used to obtain information - about those monsters who are displayed on the screen. The com- - mand "#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 + The commands `/' and `;' may be used to obtain information + about those monsters who are displayed on the screen. The com- + mand "#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 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 mon- - sters 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 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 - monster by moving into its location, you'll be asked to confirm - your intent. By default an answer of `y' acknowledges that in- - tent, which can be error prone if you're using `y' to move. You - can set the paranoid_confirmation option to require a response of - "yes" instead. - - 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 mon- - ster has moved, you will attack empty air. If you guess that the - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2314,63 +2314,63 @@ - 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 re- + don't get to choose what you'll say), but chatting with some mon- + sters 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 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 + monster by moving into its location, you'll be asked to confirm + your intent. By default an answer of `y' acknowledges that in- + tent, which can be error prone if you're using `y' to move. You + can set the paranoid_confirmation option to require a response of + "yes" instead. + + 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 mon- + ster 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 re- member 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 mon- - sters with you. Like you, your pet needs food to survive. Dogs - and cats usually feed themselves on fresh carrion and other - meats; horses need vegetarian food which is harder to come by. - If you're worried about your pet or want to train it, you can + pony (`u'), which follows you about the dungeon and fights mon- + sters with you. Like you, your pet needs food to survive. Dogs + and cats usually feed themselves on fresh carrion and other + meats; horses need vegetarian 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 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 + 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 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 + 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-adjacent pet will be left behind. Your - pet may trigger such traps itself; you will not be carried along + 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 rid- - den 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 or- - der 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 - section on Weapon proficiency for more information about that. - - Use the `a' (apply) command and pick a saddle in your inven- - tory to attempt to put that saddle on an adjacent creature. If - successful, it will be transferred to that creature's inventory. - - 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. - - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2380,63 +2380,63 @@ + 6.3. Steeds + + Some types of creatures in the dungeon can actually be rid- + den 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 or- + der 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 + section on Weapon proficiency for more information about that. + + Use the `a' (apply) command and pick a saddle in your inven- + tory to attempt to put that saddle on an adjacent creature. If + successful, it will be transferred to that creature's inventory. + + 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 adventur- + You may encounter the shades and corpses of other adventur- ers (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 little damage. You can plunder the deceased - adventurer's possessions; however, they are likely to be cursed. + 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 last victory. 6.5. Persistence of Monsters Monsters (a generic reference which also includes humans and - pets) are only shown while they can be seen or otherwise sensed. - Moving to a location where you can't see or sense a monster any - more will result in it disappearing from your map, similarly if + pets) are only shown while they can be seen or otherwise sensed. + Moving 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 who moved rather than you. - 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 per- - sist 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 + 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 per- + sist 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 automatically by - walking over the object (unless you turn off the autopickup op- - tion (see below), or move with the `m' prefix (see above)), or - manually by using the `,' command. - - 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 de- - pends 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 encum- - ber you. Your reactions will get slower and you'll burn calories - faster, requiring food more frequently to cope with it. Eventu- - ally, 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, Overtaxed, or Overloaded will be shown on the bottom - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2446,63 +2446,63 @@ + walking over the object (unless you turn off the autopickup op- + tion (see below), or move with the `m' prefix (see above)), or + manually by using the `,' command. + + 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 de- + pends 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 encum- + ber you. Your reactions will get slower and you'll burn calories + faster, requiring food more frequently to cope with it. Eventu- + ally, 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, Overtaxed, or Overloaded will be shown on the bottom line status display. When you pick up an object, it is assigned an inventory let- - ter. Many commands that operate on objects must ask you to find - out which object you want to use. When NetHack asks you to + ter. 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 pre- - sented with a list of inventory letters to choose from (see Com- + sented with a list of inventory letters to choose from (see Com- mands, above). - Some objects, such as weapons, are easily differentiated. - Others, 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 + Some objects, such as weapons, are easily differentiated. + Others, 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 "#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 in- + 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 in- stead of assigning a new one. 7.1. Curses and Blessings - Any object that you find may be cursed, even if the object + 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 en- - chantments 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, a blessed weapon will do slightly more damage against - demons. - - 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 that you can see them land. + stuck with (and to) the item. Cursed weapons weld themselves to + your hand when wielded, so you cannot unwield them. Any cursed - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2512,63 +2512,63 @@ - An item with unknown status will be reported in your inven- + item you wear is not removable by ordinary means. In addition, + cursed arms and armor usually, but not always, bear negative en- + chantments 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, a blessed weapon will do slightly more damage against + demons. + + 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 that you can see them land. + + An item with unknown status will be reported in your inven- tory with no prefix. An item which you know the state of will be - distinguished 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 + distinguished 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 information is displayed. The implicit_uncursed op- - tion can be used to control this; toggle it off to have uncursed + tion can be used to control 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 "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term + or "BUCX" for Blessed, Uncursed, Cursed, or unknown. (The term beatitude is occasionally used as well.) 7.2. Weapons (`)') - Given a chance, most monsters in the Mazes of Menace will - gratuitously 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 normally do more damage with bare (or gloved) + Given a chance, most monsters in the Mazes of Menace will + gratuitously 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 normally 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 cross- + 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 cross- bow 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 weapon's enchantment is to have it magically iden- - tified somehow. Most 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 (en- - chantment and/or erosion), experience level, strength, dexterity, - encumbrance, and proficiency (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 simul- - taneously as primary and secondary; use the `X' command to engage - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2578,63 +2578,63 @@ - or disengage that. Only some types of characters (barbarians, + 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 iden- + tified somehow. Most 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 (en- + chantment and/or erosion), experience level, strength, dexterity, + encumbrance, and proficiency (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 simul- + taneously as primary and secondary; use the `X' command to engage + or disengage that. Only some types of characters (barbarians, for instance) have the necessary skill available. Even with that - skill, using two weapons at once incurs a penalty in the chance + 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 all. To accomplish that, wield `-', or else use the `A' com- - mand which allows you to unwield the current weapon in addition + There might be times when you'd rather not wield any weapon + at all. To accomplish that, wield `-', or else use the `A' com- + mand which 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 + 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 dam- - age to monsters in NetHack. Some of the more obscure weapons + age to monsters in NetHack. Some of the more obscure weapons (such as the aklys, lucern hammer, and bec-de-corbin) are defined in an appendix to Unearthed Arcana, an AD&D supplement. - The commands to use weapons are `w' (wield), `t' (throw), - `f' (fire, an alternate way of throwing), `Q' (quiver), `x' (ex- + The commands to use weapons are `w' (wield), `t' (throw), + `f' (fire, an alternate way of throwing), `Q' (quiver), `x' (ex- change), `X' (twoweapon), and "#enhance" (see below). 7.2.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 + 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 target. The distance something can be thrown de- + what to throw, you will be prompted for a direction rather than + for a specific target. The distance something can be thrown de- pends 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. - - 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. - - Some characters have the ability to fire a volley of multi- - ple items in a single turn. 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 wield- - ing 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 lim- - it the number of shots by using a numeric prefix before the `t' - or `f' command. For example, "2f" (or "n2f" if using number_pad - mode) would ensure that at most 2 arrows are shot even if you + be thrown by hand, but can be thrown much farther and will be - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2644,63 +2644,63 @@ - could have fired 3. If you specify a larger number than would - have been shot ("4f" in this example), you'll just end up shoot- - ing the same number (3, here) as if no limit had been specified. + more likely to hit when thrown while you are wielding a bow. + + 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. + + Some characters have the ability to fire a volley of multi- + ple items in a single turn. 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 wield- + ing 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 lim- + it the number of shots by using a numeric prefix before the `t' + or `f' command. For 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 shoot- + ing 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 + same direction; if the first ones kill a monster, the others can still continue beyond that spot. 7.2.2. Weapon proficiency You will have varying degrees of skill in the weapons avail- - able. Weapon proficiency, or weapon skills, affect how well you - can use particular types of weapons, and you'll be able to im- - prove your skills as you progress through a game, depending on + able. Weapon proficiency, or weapon skills, affect how well you + can use particular types of weapons, and you'll be able to im- + prove your skills as 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 daggers or staves but not in swords or + 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 + 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" (some- + become eligible to do so. The skill rankings are "none" (some- times also referred to as "restricted", because you won't be able - to advance), "unskilled", "basic", "skilled", and "expert". Re- + to advance), "unskilled", "basic", "skilled", and "expert". Re- stricted skills simply will not appear in the list shown by "#en- hance". (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 "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 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 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 your to- - tal overall skills, so you need to actively choose which skills - to enhance and which to ignore. - - 7.2.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" - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2710,49 +2710,85 @@ - command. But first you need to have a weapon in each hand. - (Note that your two 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 that's been designat- - ed as alternate weapon.) + 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 "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 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 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 your to- + tal overall skills, so you need to actively choose which skills + to enhance and which to ignore. + + 7.2.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" com- + mand. But first you need to have a weapon in each hand. (Note + that your two 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 sec- + ondary 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 + 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 + if neither hand holds the correct weapon, use `w', `x', `w' to first wield the intended secondary, swap it to off hand, and then wield the primary. - The whole process can be simplified via use of the push- + The whole process can be simplified via use of the push- weapon option. When it is enabled, then using `w' to wield some- - thing causes the currently wielded weapon to become your alter- + thing causes the currently wielded weapon to become your alter- nate 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 posi- + want as primary which will push the first into secondary posi- tion. - When in two-weapon combat mode, using the `X' command tog- - gles back to single-weapon mode. Throwing or dropping either of - the weapons or having one of them be stolen or destroyed will al- - so make you revert to single-weapon combat. + When in two-weapon combat mode, using the `X' command tog- + gles back to single-weapon mode. Throwing or dropping either of + the weapons or having one of them be stolen or destroyed will + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 43 + + + + also make you revert to single-weapon combat. 7.3. Armor (`[') Lots of unfriendly things lurk about; you need armor to pro- tect yourself from their blows. Some types of armor offer better - protection than others. Your armor class is a measure of this + protection than others. Your armor class is a measure of this protection. Armor class (AC) is measured as in AD&D, with 10 be- - ing the equivalent of no armor, and lower numbers meaning better - armor. Each suit of armor which exists in AD&D gives the same + ing 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 + Here is a list of the armor class values provided by suits of armor: Dragon scale mail 1 Plate mail, Crystal plate mail 3 @@ -2763,76 +2799,40 @@ Ring mail, Studded leather armor, Dragon scales 7 Leather armor, Orcish ring mail 8 - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 43 - - - 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 even further. Most of these provide a one or two - point improvement to 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. + 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 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 corrosion to suits worn un- der them and against some monster touch attacks. - 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 + 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 immediately find out the armor class and any + your armor class one unit further to 4. When you put on a piece + of armor, you immediately find out the armor class and any "plusses" it provides. Cursed pieces of armor usually have nega- tive enchantments (minuses) in addition 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 in- + Many types of armor are subject to some kind of damage like + rust. Such damage can be repaired. Some types of armor may in- hibit spell casting. - The nudist option can be set (prior to game start) to at- - tempt to play the entire game without wearing any armor (a self- + The nudist option can be set (prior to game start) to at- + tempt to play the entire game without wearing any armor (a self- imposed challenge which is extremely difficult to accomplish). - 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 nor- - mally for accessories 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.4. 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 usual- - ly 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 what you eat." - - Some character roles and some monsters are vegetarian. Veg- - etarian monsters will typically never eat animal corpses, while - vegetarian players can, but with some rather unpleasant side- - NetHack 3.7 December 11, 2020 + + NetHack 3.7 December 13, 2020 @@ -2842,63 +2842,63 @@ - effects. + 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 nor- + mally for accessories 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. - You can name one food item after something you like to eat + 7.4. 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 usual- + ly 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 what you eat." + + Some character roles and some monsters are vegetarian. Veg- + etarian monsters will typically never eat animal corpses, while + vegetarian players can, but with some rather unpleasant side-ef- + fects. + + You can name one food item after something you like to eat with the fruit option. The command to eat food is `e'. 7.5. Scrolls (`?') - Scrolls are labeled with various titles, probably chosen by + 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 + 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, + 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 ob- - jects of subtle enchantment are difficult to identify without + is cursed or blessed, and how many uses it has left. Some ob- + jects of subtle enchantment are difficult to identify without these. 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 + 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" en- vironment variable to the file name of your mailbox. You may al- - so want to set the "MAILREADER" environment variable to the file + so 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. - - The command to read a scroll is `r'. - - 7.6. Potions (`!') - - 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 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. - - The command to drink a potion is `q' (quaff). - - 7.7. 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, however, for this is often unwise. Other types of wands + read the scroll. On versions of NetHack where mail is randomly + generated internal to the game, these environment variables are - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2908,63 +2908,63 @@ - don't require a direction. The number of charges in a wand is + ignored. You can disable the mail daemon by turning off the mail + option. + + The command to read a scroll is `r'. + + 7.6. Potions (`!') + + 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 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. + + The command to drink a potion is `q' (quaff). + + 7.7. 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, however, 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, at- - tempts to use the wand will usually result in nothing happening. + When the number of charges left in a wand becomes zero, at- + tempts to use the wand will usually result in nothing happening. Occasionally, 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 + 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 cer- + 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 cer- tainly cause a catastrophic release of magical energies. - When you have fully identified a particular wand, inventory - display will include additional information in parentheses: the - number of times it has been recharged followed by a colon and + When you have fully identified a particular wand, inventory + display will include additional information in parentheses: the + number of times it has been recharged followed by a colon and then by its current 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 command to use a wand is `z' (zap). To break one, use the `a' (apply) command. 7.8. Rings (`=') - Rings are very useful items, since they are relatively per- - manent magic, unlike the usually fleeting effects of potions, - scrolls, and wands. - - 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 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 manually take them off before putting on or remov- - ing 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). - `A', `W', and `T' can also be used; see Amulets. - - 7.9. Spellbooks (`+') - - 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 backfires. Reading a cursed spellbook or one with mystic + Rings are very useful items, since they are relatively per- + manent magic, unlike the usually fleeting effects of potions, - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -2974,63 +2974,63 @@ + scrolls, and wands. + + 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 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 manually take them off before putting on or remov- + ing 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). + `A', `W', and `T' can also be used; see Amulets. + + 7.9. Spellbooks (`+') + + 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 backfires. Reading a cursed spellbook or one with mystic runes beyond your ken can be harmful to your health! - 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 the energy and the time required in + 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 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 within you. Casting temporarily drains your magical + 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 ad- - ditional food. Casting of spells also requires practice. With - practice, your skill in each category of spell casting will im- - prove. Over time, however, your memory of each spell will dim, + ditional food. Casting of spells also requires practice. With + practice, your skill in each category of spell casting will im- + prove. Over time, however, your memory of each spell will dim, and you will need to relearn it. Some spells require a direction in which to cast them, simi- - lar to wands. To cast one at yourself, just give a `.' or `s' + lar to wands. To cast one at yourself, just give a `.' or `s' for the direction. A few spells require you to pick a target lo- - cation rather than just specify a particular direction. Other + cation 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 + 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".) - - Casting a spell also requires flexible movement, and wearing - various 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 level, skill category, chance of failure when casting, and an - estimate of how strongly it is remembered. The `Z' (cast) com- - mand casts a spell. - - 7.10. Tools (`(') - - Tools are miscellaneous objects with various purposes. Some - tools have a limited number of uses, akin to wand charges. For - example, lamps burn out after a while. Other tools are contain- - ers, 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 + 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 - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -3040,8 +3040,32 @@ + 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".) + + Casting a spell also requires flexible movement, and wearing + various 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 level, skill category, chance of failure when casting, and an + estimate of how strongly it is remembered. The `Z' (cast) com- + mand casts a spell. + + 7.10. Tools (`(') + + Tools are miscellaneous objects with various purposes. Some + tools have a limited number of uses, akin to wand charges. For + example, lamps burn out after a while. Other tools are contain- + ers, 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, pick-axe) become wielded as a weapon even + 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 @@ -3052,14 +3076,14 @@ 7.10.1. Containers - You may encounter bags, boxes, and chests in your travels. - A tool of this sort can be opened with the "#loot" extended com- - mand when you are standing on top of it (that is, on the same - floor spot), or with the `a' (apply) command when you are carry- - ing it. However, chests are often locked, and are in any case - unwieldy objects. You must set one down before unlocking it by + You may encounter bags, boxes, and chests in your travels. + A tool of this sort can be opened with the "#loot" extended com- + mand when you are standing on top of it (that is, on the same + floor spot), or with the `a' (apply) command when you are carry- + ing 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' command, or by using a weapon to force + kicking it with the `^D' command, or by using a weapon to force the lock with the "#force" extended command. Some chests are trapped, causing nasty things to happen when @@ -3068,35 +3092,11 @@ 7.11. Amulets (`"') - Amulets are very similar to rings, and often more powerful. - Like rings, amulets have various magical properties, some benefi- - cial, 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 to grow hungry more rapidly. - - 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 normally 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.12. 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 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 projec- - tile weapons (if you have a sling). In the most desperate of + Amulets are very similar to rings, and often more powerful. + Like rings, amulets have various magical properties, some - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -3106,63 +3106,63 @@ + 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 to grow hungry more rapidly. + + 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 normally 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.12. 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 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 projec- + tile weapons (if you have a sling). In the most desperate of cases, you can still throw them by hand. 7.13. Large rocks (``') - Statues and boulders are not particularly useful, and are - generally heavy. It is rumored that some statues are not what + Statues and boulders are not particularly useful, and are + generally heavy. It is rumored that some statues are not what they seem. - Boulders occasionally block your path. You can push one + 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 pick-axe. Very large humanoids (giants and - their ilk) have been known to pick up boulders and use them as + its path, or you can smash it into a pile of small rocks with + breaking magic or a pick-axe. 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 + 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 + For some configurations of the program, statues are no + longer shown as ``' but by the letter representing the monster they depict instead. 7.14. 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 + 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 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 de- - scribed 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 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.15. Persistence of Objects - - Normally, if you have seen an object at a particular map lo- - cation 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 ex- - ception is that if the object gets covered 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-discov- - er the object and resume remembering it. - - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -3172,63 +3172,63 @@ + Gold pieces are the only type of object where bless/curse + state does not apply. They're always uncursed but never de- + scribed 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 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.15. Persistence of Objects + + Normally, if you have seen an object at a particular map lo- + cation 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 ex- + ception is that if the object gets covered 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-discov- + er 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 op- - tion can be enabled in order to show an item differently when it + only the top item of the pile is displayed. The hilite_pile op- + tion 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 challenges, 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 + 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 challenges, 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 most difficult of these is the foodless challenge. Although + 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 physiological need for water; thus there is no restriction on - drinking beverages, even if they provide some minor food bene- - fits. Calling upon your god for help with starvation does not + a physiological need for water; thus there is no restriction on + drinking beverages, even if they provide some minor food bene- + fits. 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 + A strict vegan diet is one which avoids any food derived from animals. The primary source of nutrition is fruits and veg- etables. 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 normally indigestible material eaten - while polymorphed into a creature that can digest it is also con- - sidered vegan food. Note however that eating such items still - counts against foodless conduct. - - Vegetarians do not eat animals; however, they are less se- - lective 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 - foodless 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 polymorphed is treated as if you ate the creature's - corpse. Eating leather, dragon hide, or bone items while poly- - morphed into a creature that can digest it, or eating monster - brains while polymorphed into a mind flayer, is considered eating - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -3238,63 +3238,63 @@ + 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 normally indigestible material eaten + while polymorphed into a creature that can digest it is also con- + sidered vegan food. Note however that eating such items still + counts against foodless conduct. + + Vegetarians do not eat animals; however, they are less se- + lective 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 + foodless 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 polymorphed is treated as if you ate the creature's + corpse. Eating leather, dragon hide, or bone items while poly- + morphed 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 - indigestible, and others which are hazardous to eat. Using a + Regardless of conduct, there will be some items which are + indigestible, and others which are hazardous to eat. Using a swallow-and-digest attack against a monster is equivalent to eat- - ing 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 + ing 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 contain milk, so they are - compatible with a vegan diet. Slime molds or player-defined - "fruits", although they could be anything from "cherries" to + compatible with a vegan diet. Slime molds or player-defined + "fruits", although they could be anything from "cherries" to "pork chops", are also assumed to be vegan. An atheist is one who rejects religion. This means that you - cannot #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 con- - duct; 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 + cannot #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 con- + duct; 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 be- - ing spoken to by an angry god, priest(ess), or other religious + ing 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. - Most players fight with a wielded weapon (or tool intended + 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 particularly difficult challenge, although it is still - possible to gain experience by other means. - - An illiterate character does not read or write. This in- - cludes reading a scroll, spellbook, fortune cookie message, or t- - shirt; writing 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 men- - tioned 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 + without using such a wielded weapon. You are still permitted to + throw, fire, and kick weapons; use a wand, spell, or other type - NetHack 3.7 December 11, 2020 + NetHack 3.7 December 13, 2020 @@ -3304,22 +3304,45 @@ - diagonally. Other rules can, such as not smashing boulders with - magic or tools, but doing so causes you to receive a luck penal- - ty. No message about that is given at the time, but it is - tracked as a conduct. The #conduct command and end of game dis- - closure will report whether you have abided by the special rules - of Sokoban, and if not, how many times you violated them, provid- - ing you with a way to discover which actions incur bad luck so - that you can be better informed about whether or not to avoid re- - peating 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 disclosed conduct even if you haven't done any- - thing 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).) + 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 particularly difficult challenge, although it is still + possible to gain experience by other means. + + An illiterate character does not read or write. This in- + cludes reading a scroll, spellbook, fortune cookie message, or t- + shirt; writing 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 men- + tioned 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 diago- + nally. 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, providing 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 ac- + tions 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 disclosed conduct even if you haven't done anything interest- + ing there. Ending the game with "never broke the Sokoban rules" + conduct is most meaningful if you also manage to perform the "ob- + tained 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 geno- @@ -3335,6 +3358,18 @@ without an attempt to wish for any items is a challenge, as is a game without wishing for an artifact (even if the artifact imme- diately disappears). When the game offers you an opportunity to + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 52 + + + make a wish for an item, you may choose "nothing" if you want to decline. @@ -3358,18 +3393,6 @@ Sokoban - Entered Sokoban. Big Room - Entered the Big Room. Soko-Prize - Explored to the top of Sokoban - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 52 - - - and found a special item there. Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. @@ -3401,6 +3424,18 @@ There's no guaranteed Novel so the achievement to read one might not always be attainable (except perhaps by wishing). Sim- ilarly, the Big Room level is not always present. Unlike with + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 53 + + + the Novel, there's no way to wish for this opportunity. The "special items" hidden in Mines' End and Sokoban are not @@ -3424,18 +3459,6 @@ Due to variations in personal tastes and conceptions of how NetHack should do things, there are options you can set to change - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 53 - - - how NetHack behaves. 9.1. Setting the options @@ -3466,6 +3489,19 @@ figuration file, NetHack will create the configuration file for you using the default template file. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 54 + + + On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. @@ -3489,19 +3525,6 @@ Here is a list of allowed directives: - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 54 - - - OPTIONS There are two types of options, boolean and compound options. Boolean options toggle a setting on or off, while compound op- @@ -3532,6 +3555,19 @@ The location where saved games are kept. Defaults to HACKDIR, must be writable. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 55 + + + BONESDIR The location that bones files are kept. Defaults to HACKDIR, must be writable. @@ -3555,19 +3591,6 @@ AUTOCOMPLETE=zap,!annotate - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 55 - - - AUTOPICKUP_EXCEPTION Set exceptions to the pickup_types option. See the "Configur- ing Autopickup Exceptions" section. @@ -3598,8 +3621,20 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new - section begins; whatever follows will be common to all sec- - tions. Otherwise the last section extends to the end of the + section begins; whatever follows will be common to all + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 56 + + + + sections. Otherwise the last section extends to the end of the options file. MENUCOLOR @@ -3622,18 +3657,6 @@ Define the directory that contains the sound files. See the "Configuring User Sounds" section. - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 56 - - - SYMBOLS Override one or more symbols in the symbol set used for all dungeon levels except for the special rogue level. See the @@ -3658,6 +3681,25 @@ Here is an example of configuration file contents: + + + + + + + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 57 + + + # Set your character's role, race, gender, and alignment. OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful # @@ -3687,19 +3729,6 @@ equals sign, and then the value of the string. The value is ter- minated by the next comma or the end of string. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 57 - - - 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 @@ -3724,8 +3753,20 @@ 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. If it does start with `/', the at-sign is op- - tional. + as a file name. If it does start with `/', the at-sign is + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 58 + + + + optional. 9.4. Customization options @@ -3755,17 +3796,6 @@ get a location on the map (default true). The whatis_coord op- tion controls whether the description includes map coordinates. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 58 - - - autodig Automatically dig if you are wielding a digging tool and moving into a place that can be dug (default false). Persistent. @@ -3789,6 +3819,19 @@ command instead. If no weapon is found or the option is false, the `t' (throw) command is executed instead. Persistent. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 59 + + + autounlock Walking into a locked door or looting a locked container while carrying an unlocking tool (such as a key) will ask whether to @@ -3819,19 +3862,6 @@ Save game state after each level change, for possible recovery after program crash (default on). Persistent. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 59 - - - clicklook Allows looking at things on the screen by navigating the mouse over them and clicking the right mouse button (default off). @@ -3855,6 +3885,19 @@ sponse of `n' for each candidate). Persistent. The possibili- ties are: + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 60 + + + i - disclose your inventory; a - disclose your attributes; v - summarize monsters that have been vanquished; @@ -3887,17 +3930,6 @@ Order of the disclosure categories does not matter, program display for end-of-game disclosure follows a set sequence. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 60 - - - (for example "disclose:yi na +v -g o") The example sets inven- tory to prompt and default to yes, attributes to prompt and de- fault to no, vanquished to disclose without prompting, genocid- @@ -3919,6 +3951,19 @@ tional interface except that it does not require that you hit Enter. It is implemented for the tty interface (default off). + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 61 + + + For the X11 interface, which always uses a menu for choosing an extended command, it controls whether the menu shows all avail- able commands (on) or just the subset of commands which have @@ -3952,18 +3997,6 @@ option will take precedence. The default is to randomly pick an appropriate gender. If you prefix the value with `!' or "no", you will exclude that gender from being picked randomly. - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 61 - - - Cannot be set with the `O' command. Persistent. goldX @@ -3985,6 +4018,18 @@ herecmd_menu When using a windowport that supports mouse and clicking on yourself or next to you, show a menu of possible actions for + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 62 + + + the location. Same as "#herecmdmenu" and "#therecmdmenu" com- mands. @@ -4019,17 +4064,6 @@ Ignore interrupt signals, including breaks (default off). Per- sistent. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 62 - - - implicit_uncursed Omit "uncursed" from object descriptions when it can be deduced from other aspects of the description (default on). Persis- @@ -4050,6 +4084,18 @@ `a', `b', and `c' keyboard shortcuts rather than the mnemonics `o', `i', and `b' (default off). Persistent. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 63 + + + mail Enable mail delivery during the game (default on). Persistent. @@ -4083,21 +4129,9 @@ class(es) of interest, but then displays a menu of matching ob- jects 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. Partial skips the - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 63 - - - - object class filtering and immediately displays a menu of all - objects. Persistent. + menu of matching objects for selection. Partial skips the ob- + ject class filtering and immediately displays a menu of all ob- + jects. Persistent. menu_deselect_all Menu character accelerator to deselect all items in a menu. @@ -4117,6 +4151,17 @@ are "none", "bold", "dim", "underline", "blink", or "inverse". Not all ports can actually display all types. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 64 + + + menu_invert_all Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `@'. @@ -4151,17 +4196,6 @@ Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default `:'. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 64 - - - menu_select_all Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `.'. @@ -4183,8 +4217,19 @@ 1 - enabled and make OS adjustments to support mouse use 2 - like 1 but does not make any OS adjustments - Omitting a value is the same as specifying 1 and negating - mouse_support is the same as specifying 0. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 65 + + + + Omitting a value is the same as specifying 1 and negating + mouse_support is the same as specifying 0. msghistory The number of top line messages to keep (and be able to recall @@ -4216,18 +4261,6 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 65 - - - setting this with the `O' command. nudist @@ -4249,6 +4282,18 @@ For backward compatibility, omitting a value is the same as specifying 1 and negating number_pad is the same as specifying + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 66 + + + 0. (Settings 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 accommo- @@ -4282,18 +4327,6 @@ bones data when dying in debug mode; attack - require "yes" rather than `y' to confirm attack- ing a peaceful monster; - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 66 - - - wand-break - require "yes" rather than `y' to confirm breaking a wand; eating - require "yes" rather than `y' to confirm whether @@ -4314,6 +4347,19 @@ any of the others, include it in the list, such as "para- noid_confirmation:attack pray Remove". + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 67 + + + perm_invent If true, always display your current inventory in a window. This only makes sense for windowing system interfaces that im- @@ -4348,18 +4394,6 @@ pettype Specify the type of your initial pet, if you are playing a - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 67 - - - 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". If the choice is not allowed for the role @@ -4380,6 +4414,18 @@ pickup_types Specify the object types to be picked up when autopickup is on. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 68 + + + Default is all types. You can use autopickup_exception config- uration file lines to further refine autopickup behavior. Per- sistent. @@ -4414,18 +4460,6 @@ message where play pauses to allow you to browse the map when- ever clairvoyance randomly activates. Some situations, such as being underwater or engulfed, ignore this option. It does not - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 68 - - - affect the clairvoyance spell where pausing to examine revealed objects or monsters is less intrusive. Default is off. Per- sistent. @@ -4446,6 +4480,18 @@ specifying your role. Normally only the first letter of the value is examined; `r' is an exception with "Rogue", "Ranger", and "random" values. If you prefix the value with `!' or "no", + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 69 + + + you will exclude that role from being picked randomly. Cannot be set with the `O' command. Persistent. @@ -4480,18 +4526,6 @@ Prevent you from (knowingly) attacking your pets (default on). Persistent. - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 69 - - - safe_wait Prevents you from waiting or searching when next to a hostile monster (default on). Persistent. @@ -4512,6 +4546,18 @@ showrace Display yourself as the glyph for your race, rather than the + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 70 + + + glyph for your role (default off). Note that this setting af- fects only the appearance of the display, not the way the game treats you. Persistent. @@ -4545,19 +4591,6 @@ standout Boldface monsters and "--More--" (default off). Persistent. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 70 - - - statushilites Controls how many turns status hilite behaviors highlight the field. If negated or set to zero, disables status hiliting. @@ -4578,6 +4611,19 @@ screen. Use "symset:default" to explicitly select the default symbols. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 71 + + + time Show the elapsed game time in turns on bottom line (default off). Persistent. @@ -4611,19 +4657,6 @@ Provide more commentary during the game (default on). Persis- tent. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 71 - - - whatis_coord When using the `/' or `;' commands to look around on the map with autodescribe on, display coordinates after the descrip- @@ -4644,8 +4677,20 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possi- - ble targets. + through next and previous targets, allows filtering the + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 72 + + + + possible targets. n - no filtering [default] v - in view only @@ -4678,18 +4723,6 @@ might enable or disable the availability of various other op- tions. For multiple lines in a configuration file, that would be the first non-comment line. For a comma-separated list in - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 72 - - - NETHACKOPTIONS or an OPTIONS line in a configuration file, that would be the rightmost option in the list. @@ -4711,6 +4744,18 @@ listed here. You can safely add any of these options to your configuration file, and if the window port is capable of adjust- ing to suit your preferences, it will attempt to do so. If it + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 73 + + + 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 @@ -4744,18 +4789,6 @@ font_map if NetHack can, it should use a font by the chosen name for the - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 73 - - - map window. font_menu @@ -4778,6 +4811,17 @@ If NetHack can, it should use this size font for the map win- dow. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 74 + + + font_size_menu If NetHack can, it should use this size font for menu windows. @@ -4810,18 +4854,6 @@ player_selection If NetHack can, it should pop up dialog boxes, or use prompts - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 74 - - - for character selection. popup_dialog @@ -4843,6 +4875,19 @@ cursor is this number of cells away from the edge of the win- dow. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 75 + + + selectsaved If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. @@ -4876,18 +4921,6 @@ be slightly condensed, moving some fields to different lines to eliminate one whole line, reducing the height needed. For Qt, statuslines can only be set in the configuration file or via - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 75 - - - NETHACKOPTIONS, not with the `O' command. term_cols and @@ -4909,6 +4942,18 @@ tile_width Specify the preferred width of each tile in a tile capable port + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 76 + + + tiled_map If NetHack can, it should display the map using tiles graphics rather than simple characters (letters and punctuation, possi- @@ -4943,17 +4988,6 @@ If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 76 - - - OPTION=windowcolors:wintype foreground/background where wintype is one of "menu", "message", "status", or @@ -4972,6 +5006,20 @@ If NetHack can, it should wrap long lines of text if they don't fit in the visible area of the window. + + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 77 + + + 9.6. Platform-specific Customization options Here are explanations of options that are used by specific @@ -5008,18 +5056,6 @@ chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 77 - - - flush (default off, Amiga NetHack only). @@ -5038,6 +5074,18 @@ subkeyvalue (Win32 tty NetHack only). May be used to alter the value of + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 78 + + + keystrokes that the operating system returns to NetHack to help compensate for international keyboard issues. OPTIONS=subkey- value:171/92 will return 92 to NetHack, if 171 was originally @@ -5073,23 +5121,11 @@ command. videoshades - Set the intensity level of the three gray scales available - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 78 - - - - (default dark normal light, PC NetHack only). If the game dis- - play is difficult to read, try adjusting these scales; if this - does not correct the problem, try !color. Cannot be set with - the `O' command. + Set the intensity level of the three gray scales available (de- + fault dark normal light, PC NetHack only). If the game display + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the + `O' command. 9.7. Regular Expressions @@ -5101,6 +5137,21 @@ terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. + + + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 79 + + + 9.8. Configuring Autopickup Exceptions You can further refine the behavior of the autopickup option @@ -5139,20 +5190,8 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 79 - - - - exclusion of items known to be cursed from autopickup. + any corpse from autopickup. The last example results in the ex- + clusion of items known to be cursed from autopickup. 9.9. Changing Key Bindings @@ -5165,6 +5204,20 @@ For example: + + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 80 + + + BIND=^X:getpos.autodescribe BIND={:menu_first_page BIND=v:loot @@ -5205,19 +5258,6 @@ When asked for a direction, the key to show the help. Default is `?'. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 80 - - - getdir.self When asked for a direction, the key to target yourself. De- fault is `.'. @@ -5231,8 +5271,20 @@ fault is `#'. getpos.all.next - When asked for a location, the key to go to next closest inter- - esting thing. Default is `a'. + When asked for a location, the key to go to next closest + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 81 + + + + interesting thing. Default is `a'. getpos.all.prev When asked for a location, the key to go to previous closest @@ -5271,19 +5323,6 @@ ous keys to cycle through targets, toggle showing a menu in- stead. Default is `!'. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 81 - - - 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 @@ -5299,6 +5338,18 @@ When asked for a location, the key to choose the location, and possibly ask for more info. Default is `.'. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 82 + + + getpos.pick.once When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. @@ -5339,17 +5390,6 @@ nopickup Prefix key to move without picking up items. Default is `m'. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 82 - - - redraw Key to redraw the screen. Default is `^R'. @@ -5363,6 +5403,19 @@ reqmenu Prefix key to request menu from some commands. Default is `m'. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 83 + + + run Prefix key to run towards a direction. Default is `G'. @@ -5403,20 +5456,8 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 83 - - - - message is shown in between. + norep - show the message once, but not again if no other mes- + sage is shown in between. Here's an example of message types using NetHack's internal pattern matching facility: @@ -5428,6 +5469,19 @@ the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 84 + + + The order of the defined MSGTYPE lines is important; the last matching rule is used. Put the general case first, exceptions below them. @@ -5471,28 +5525,29 @@ MENUCOLOR="* cursed *"=red MENUCOLOR="* cursed *(being worn)"=red&underline - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 84 - - - - 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 line will be shown in red - color and underlined. You can have multiple MENUCOLOR en- - tries in your configuration file, and the last MENUCOLOR - line that matches a menu line will be used for the line. + 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 line will be shown in red color and under- + lined. You can have multiple MENUCOLOR entries in your config- + uration file, and the last MENUCOLOR line that matches a menu + line will be used for the line. Note that if you intend to have one or more color specifica- tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 85 + + + are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds @@ -5535,19 +5590,6 @@ OPTION=hilite_status:field-name/behavior/color&attributes - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 85 - - - For example, the following line in your configuration file will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: @@ -5561,6 +5603,17 @@ tion file will cause wisdom to be displayed red if it drops and green if it rises: + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 86 + + + OPTION=hilite_status:wisdom/down/red/up/green Allowed colors are black, red, green, brown, blue, magenta, @@ -5602,18 +5655,6 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 86 - - - polymorphed. "experience", "time", and "score" are condition- ally displayed depending upon your other option settings. @@ -5627,6 +5668,18 @@ Allowed behaviors are "always", "up", "down", "changed", a per- centage or absolute number threshold, or text to match against. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 87 + + + * "always" will set the default attributes for that field. * "up", "down" set the field attributes for when the field @@ -5668,18 +5721,6 @@ may optionally be preceded by `='. If the number is pre- ceded by `<=' or `>=' instead, it also matches when value is below or above. If the prefix is `<' or `>', only - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 87 - - - match when strictly above or below. * text match sets the attribute when the field value matches @@ -5694,6 +5735,17 @@ The whole feature can be disabled by setting option sta- tushilites to 0. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 88 + + + Example hilites: OPTION=hilite_status: gold/up/yellow/down/brown @@ -5733,19 +5785,6 @@ NetHack Symbols Symbol Name Description ----------------------------------------------------------------- - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 88 - - - S_air (air) _ S_altar (altar) " S_amulet (amulet) @@ -5760,6 +5799,19 @@ B S_bat (bat or bird) ^ S_bear_trap (bear trap) - S_blcorn (bottom left corner) + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 89 + + + b S_blob (blob) + S_book (spellbook) ) S_boomleft (boomerang open left) @@ -5799,19 +5851,6 @@ ! S_flashbeam (flash beam) % S_food (piece of food) { S_fountain (fountain) - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 89 - - - F S_fungus (fungus or mold) * S_gem (gem or rock) S_ghost (ghost) @@ -5826,6 +5865,19 @@ . S_hodbridge (horizontal lowered drawbridge) | S_hodoor (open door in horizontal wall) ^ S_hole (hole) + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 90 + + + @ S_human (human or elf) h S_humanoid (humanoid) - S_hwall (horizontal wall) @@ -5865,19 +5917,6 @@ q S_quadruped (quadruped) Q S_quantmech (quantum mechanic) = S_ring (ring) - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 90 - - - ` S_rock (boulder or statue) r S_rodent (rodent) ^ S_rolling_boulder_trap (rolling boulder trap) @@ -5892,6 +5931,19 @@ s S_spider (arachnid or centipede) ^ S_spiked_pit (spiked pit) ^ S_squeaky_board (squeaky board) + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 91 + + + 0 S_ss1 (magic shield 1 of 4) # S_ss2 (magic shield 2 of 4) @ S_ss3 (magic shield 3 of 4) @@ -5931,19 +5983,6 @@ + S_vcdoor (closed door in vertical wall) . S_venom (splash of venom) ^ S_vibrating_square (vibrating square) - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 91 - - - . S_vodbridge (vertical lowered drawbridge) - S_vodoor (open door in vertical wall) v S_vortex (vortex) @@ -5958,6 +5997,19 @@ x S_xan (xan or other extraordinary insect) X S_xorn (xorn) Y S_yeti (apelike creature) + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 92 + + + Z S_zombie (zombie) z S_zruty (zruty) S_pet_override (any pet if ACCESSIBILITY=1 is set) @@ -5998,18 +6050,6 @@ NetHack can also be compiled with support for sending the game messages to an external program, such as a text-to-speech - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 92 - - - synthesizer. If the "#version" extended command shows "external program as a message handler", your NetHack has been compiled with the capability. When compiling NetHack from source on Linux @@ -6024,6 +6064,18 @@ ficial distributions of NetHack is a symset called NHAccess. Se- lecting that symset in your configuration file will cause the game to run in a manner accessible to the blind. After you have + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 93 + + + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your configuration file to better suit your preferences. See the pre- @@ -6065,17 +6117,6 @@ When targeting with cursor, describe the cursor position with coordinates relative to your character. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 93 - - - whatis_filter:area When targeting with cursor, filter possible locations so only those in the same area (eg. same room, or same corridor) are @@ -6090,6 +6131,17 @@ screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 94 + + + 9.16. Global Configuration for System Administrators If NetHack is compiled with the SYSCF option, a system ad- @@ -6131,17 +6183,6 @@ each field in little-endian order, "ascii" for writing the bones file content in ascii text. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 94 - - - SUPPORT = A string explaining how to get local support (no de- fault value). @@ -6155,6 +6196,18 @@ ARDS, and SHELLERS check for the player name instead of the us- er's login name. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 95 + + + 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 @@ -6196,18 +6249,6 @@ %T - current time, UNIX timestamp format %d - game start time, YYYYMMDDhhmmss format %D - current time, YYYYMMDDhhmmss format - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 95 - - - %n - player name %N - first character of player name @@ -6221,6 +6262,18 @@ proper place under your current name. How many scores are kept can also be set up when NetHack is compiled. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 96 + + + 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 @@ -6262,18 +6315,6 @@ vide god-like powers 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 96 - - - switch or with the playmode:debug option. For some systems, the player must be logged in under a par- @@ -6284,6 +6325,21 @@ allowed or not available will result in falling back to explore mode instead. + + + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 97 + + + 12. Credits The original hack game was modeled on the Berkeley UNIX @@ -6327,19 +6383,6 @@ archives accessible via ftp and uucp after expiring from the newsgroup. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 97 - - - Later, Mike coordinated a major re-write of the game, head- ing a team which included Ken Arromdee, Jean-Christophe Collet, Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, @@ -6351,6 +6394,18 @@ of them and Kevin Darcy later joined the main NetHack Development Team to produce subsequent revisions of 3.0. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 98 + + + 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 @@ -6395,17 +6450,6 @@ Delahunty, was responsible for the VMS version of NetHack 3.1. Michael Allison ported NetHack 3.1 to Windows NT. - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 98 - - - Dean Luick, with help from David Cohrs, developed NetHack 3.1 for X11. It drew the map as text rather than graphically but included nh10.bdf, an optionally used custom X11 font which has @@ -6416,6 +6460,18 @@ mor and so forth, not separate images for beetles and ants or for cloaks and boots). + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 99 + + + 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 ob- @@ -6459,19 +6515,6 @@ ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 99 - - - Warren Cheung combined SLASH with the Wizard Patch to pro- duce Slash'EM, and with the help of Kevin Hugo, added more fea- tures. Kevin later joined the NetHack Development Team and in- @@ -6483,6 +6526,18 @@ released as a source code patch only, without any ready-to-play distribution for systems that usually had such. + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 100 + + + (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- @@ -6526,18 +6581,6 @@ Pat Rankin maintained 3.4 for VMS. - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 100 - - - Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. @@ -6550,6 +6593,17 @@ face for the Windows port. Alex Kompel also contributed a Win- dows CE port for 3.4.1. + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 101 + + + 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 @@ -6591,22 +6645,10 @@ 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 - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 101 - - - - Stephenson, Janet Walz, and Paul Winner. In early 2015, ahead of - the release of 3.6.0, new members Sean Hunt, Pasi Kallinen, and - Derek S. Ray joined the NetHack Development Team. + Jessie Collet, Ken Lorber, Dean Luick, Pat Rankin, Mike Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the + release of 3.6.0, new members 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 signif- icant inspirations for many of the humorous and fun features @@ -6616,6 +6658,18 @@ 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 + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 102 + + + restructured. The NetHack Development Team, as well as Steve VanDevender @@ -6657,19 +6711,6 @@ NetHack 3.6.3 was released on December 5, 2019 containing over 190 bug fixes to NetHack 3.6.2. - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 102 - - - NetHack 3.6.4 was released on December 18, 2019 containing a security fix and a few bug fixes. @@ -6682,6 +6723,19 @@ The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 103 + + + 12.1. SPECIAL THANKS On behalf of the NetHack community, thank you very much once @@ -6723,19 +6777,6 @@ Dean Luick Kevin Hugo Ross Brown Del Lamb Kevin Sitze Sascha Wostmann Derek S. Ray Kevin Smolkowski Scott Bigham - - - - NetHack 3.7 December 11, 2020 - - - - - - NetHack Guidebook 103 - - - Deron Meranda Kevin Sweet Scott R. Turner Dion Nicolaas Lars Huttar Sean Hunt Dylan O'Donnell Leon Arnott Stephen Spackman @@ -6748,6 +6789,19 @@ Frederick Roeber Merlyn LeRoy Tim Lennan Gil Neiger Michael Allison Timo Hakulinen Greg Laskin Michael Feir Tom Almy + + + + NetHack 3.7 December 13, 2020 + + + + + + NetHack Guidebook 104 + + + Greg Olson Michael Hamel Tom West Gregg Wonderly Michael Sokolov Warren Cheung Hao-yang Wang Mike Engber Warwick Allison @@ -6792,7 +6846,19 @@ - NetHack 3.7 December 11, 2020 + + + + + + + + + + + + + NetHack 3.7 December 13, 2020 From 6abce574d7987ad4c217f9016f83a016f7db2b1b Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 14 Dec 2020 07:20:14 -0500 Subject: [PATCH 631/708] document typo fixes in README.xcode Closes #424 --- sys/unix/README.xcode | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/unix/README.xcode b/sys/unix/README.xcode index 5ba6741e4..0c55704f0 100644 --- a/sys/unix/README.xcode +++ b/sys/unix/README.xcode @@ -5,9 +5,9 @@ Establish a developer team in XCode =================================== Your first step should be to establish a developer team within XCode. -Launch XCode and open the preferences diaglog (XCode Menu->Preferences). +Launch XCode and open the preferences dialog (XCode Menu->Preferences). Select the "Accounts" tab. Add an account (usually this should just be -your apple ID accoung you used to setup the Mac). After adding the account, +your apple ID account you used to setup the Mac). After adding the account, select the account and then add a team (usually this will be just a personal team for Mac Development). From 1b415af3028e5f1a0c45b4a27bb62a125e848284 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 14 Dec 2020 07:46:23 -0500 Subject: [PATCH 632/708] Makefile.msc update for visual studio 16.8.3 --- sys/winnt/Makefile.msc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 6aa6d484b..22b9c2d5a 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -544,7 +544,7 @@ rc=Rc # Visual Studio we are using. We set VSVER to 0000 to flag any version that # is too old or untested. # -#NMAKE version 1428293340 from latest VS 2019 (November 19, 2020 version 16.8.2) +#NMAKE version 1428293350 from latest VS 2019 (December 8, 2020 version 16.8.3) #!MESSAGE $(MAKEFLAGS) #!MESSAGE $(MAKEDIR) @@ -568,9 +568,9 @@ VSVER=2013 VSVER=2015 !ELSEIF ($(MAKEVERSION) > 1411000000) && ($(MAKEVERSION) < 1416270312) VSVER=2017 -!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1428293341) +!ELSEIF ($(MAKEVERSION) > 1416270311) && ($(MAKEVERSION) < 1428293351) VSVER=$(VSNEWEST) -!ELSEIF ($(MAKEVERSION) > 1428293340) +!ELSEIF ($(MAKEVERSION) > 1428293350) VSVER=2999 #untested future version !ENDIF From 480c2539331df1e9c4ed2c3a2f68e5c3821cf4f4 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 14 Dec 2020 17:46:57 +0200 Subject: [PATCH 633/708] Fix segfault when the Wizard tried teleporting on the planes The wizard of Yendor tried teleporting to the stairs on the plane of Earth, but there are none there. This was caused by the stairs structure reworking. Fixes #422 --- src/teleport.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/teleport.c b/src/teleport.c index e5e34c5ae..5c7b84964 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1284,7 +1284,6 @@ struct monst *mtmp; /* mx==0 implies migrating monster arrival */ boolean suppress_impossible; { register int x, y, trycount; - stairway *stway; if (mtmp == u.usteed) { tele(); @@ -1292,19 +1291,19 @@ boolean suppress_impossible; } if (mtmp->iswiz && mtmp->mx) { /* Wizard, not just arriving */ + stairway *stway; + if (!In_W_tower(u.ux, u.uy, &u.uz)) { stway = stairway_find_forwiz(FALSE, TRUE); - x = stway->sx; - y = stway->sy; } else if (!stairway_find_forwiz(TRUE, FALSE)) { /* bottom level of tower */ stway = stairway_find_forwiz(TRUE, TRUE); - x = stway->sx; - y = stway->sy; } else { stway = stairway_find_forwiz(TRUE, FALSE); - x = stway->sx; - y = stway->sy; } + + x = stway ? stway->sx : 0; + y = stway ? stway->sy : 0; + /* if the wiz teleports away to heal, try the up staircase, to block the player's escaping before he's healed (deliberately use `goodpos' rather than `rloc_pos_ok' here) */ From 190f9dc4886e01aa8d9343afa93f93e861e4f969 Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 14 Dec 2020 09:56:59 -0800 Subject: [PATCH 634/708] Modify expectations of where LUA sources are located. We want the build to assume the same basic layout as the lua repository. The sources are immediately at the top of the repository and not in a subdirectory called 'src'. --- sys/winnt/Makefile.gcc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 398e17053..e44851950 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -134,7 +134,10 @@ endif #--------------------------------------------------------------- # Location of LUA # -# Original source needs to be obtained from: +# Using appropriate tag, source can be obtained from the git repository: +# https://github.com/NetHack/NetHack.git +# +# Source for 5.4.2 could also be obtained from: # http://www.lua.org/ftp/lua-5.4.2.tar.gz # # This build assumes that the LUA sources are located @@ -154,8 +157,11 @@ endif # # The source for the standalone interpreter (luac.c) is not kept with the # rest of the LUA source. +# # The source is kept at: -# https://github.com/lua/luac +# https://github.com/lua/luac.git +# +# If building, copy luac.c into the directory LUATOP. # # By default we will not build it. # @@ -441,7 +447,7 @@ OPTIONS_FILE = $(DAT)\options ifndef LUAVER LUAVER = 5.4.2 endif -LUASRC = $(LUATOP)/src +LUASRC = $(LUATOP) LUALIB = $(O)lua-$(LUAVER).static.a LUADLL = $(O)lua-$(LUAVER).a LUAINCL = -I$(LUASRC) From 49460dcafbe602f43291fa581c656b8e65c4534d Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 14 Dec 2020 10:17:02 -0800 Subject: [PATCH 635/708] Final changes needed to enable Windows minGW build. Removed some of the temporary changes necessary due to 4 hour delay. Added the specification of the working directory to avoid the change in working directory behavior that occurs when checking out one repository vs. two. --- azure-pipelines.yml | 58 +++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index cfcb1911c..7897f6492 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -50,13 +50,13 @@ strategy: pool: vmImage: $(imageName) -resources: - repositories: - - repository: pdcursesrepo - type: github - name: wmcbrine/PDCurses - ref: refs/heads/master - endpoint: github.com_barthouse +# resources: +# repositories: +# - repository: pdcursesrepo +# type: github +# name: wmcbrine/PDCurses +# ref: refs/heads/master +# endpoint: github.com_barthouse variables: buildMinimal: $(buildMinimalSetting) @@ -70,21 +70,21 @@ variables: CXX: $(cxxName) steps: -- bash: | - echo 'mingwBuildSetting' '$(mingwBuildSetting)' - echo 'mingwBuild' '$(mingwBuild)' - echo 'vsBuild' '$(vsBuild)' - echo 'NetHackPath' '$(NetHackPath)' - echo 'CC' '$(CC)' - echo 'CXX' '$(CXX)' +# - bash: | +# echo 'mingwBuildSetting' '$(mingwBuildSetting)' +# echo 'mingwBuild' '$(mingwBuild)' +# echo 'vsBuild' '$(vsBuild)' +# echo 'NetHackPath' '$(NetHackPath)' +# echo 'CC' '$(CC)' +# echo 'CXX' '$(CXX)' - checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack submodules: true path: $(NetHackPath) -- checkout: pdcursesrepo - path: s\NetHack\lib\pdcurses - condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) +# - checkout: pdcursesrepo +# path: s\NetHack\lib\pdcurses +# condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) - task: DownloadSecureFile@1 name: storeKey @@ -101,14 +101,6 @@ steps: condition: eq( variables['Agent.OS'], 'Windows_NT' ) displayName: 'Copying store key' -# Temporary need to copy lua files for minGW build -- task: CopyFiles@2 - inputs: - SourceFolder: $(Agent.BuildDirectory)\s\NetHack\submodules\lua - TargetFolder: $(Agent.BuildDirectory)\s\NetHack\lib\lua-5.4.2\src - condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) - displayName: 'Copying lua files' - - task: MSBuild@1 inputs: solution: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs\NetHack.sln @@ -118,21 +110,17 @@ steps: displayName: 'Windows MSBuild' - bash: | - echo '/mingw64/bin' - ls /mingw64/bin - echo '/usr/bin' - ls /usr/bin echo 'gcc --version' gcc --version export ADD_CURSES=Y export PDCURSES_TOP=../lib/pdcurses export LUA_VERSION=5.4.2 export TRAVIS_COMPILER=1 - cd NetHack/src cp ../sys/winnt/Makefile.gcc ./Makefile mingw32-make LUA_VERSION=$LUA_VERSION install condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) displayName: 'Windows MinGW Build' + workingDirectory: $(Agent.BuildDirectory)/s/NetHack/src - bash: | sudo apt-get -qq -y update @@ -140,9 +128,10 @@ steps: sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools condition: eq( variables['Agent.OS'], 'Linux' ) displayName: 'Getting linux build dependencies' + workingDirectory: $(Agent.BuildDirectory)/s/NetHack - bash: | - cd NetHack/sys/unix + cd sys/unix sh setup.sh hints/linux-minimal cd ../.. sed -i '/^#define CLIPPING/d' include/config.h @@ -169,21 +158,24 @@ steps: make WANT_WIN_ALL=1 all condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, true)) displayName: 'Building linux minimal build' + workingDirectory: $(Agent.BuildDirectory)/s/NetHack - bash: | - cd NetHack/sys/unix + cd sys/unix sh setup.sh hints/linux.2020 cd ../.. make fetch-lua make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, false)) displayName: 'Building linux full build' + workingDirectory: $(Agent.BuildDirectory)/s/NetHack - bash: | - cd NetHack/sys/unix + cd sys/unix sh setup.sh hints/macos.2020 cd ../.. make fetch-lua make all condition: eq( variables['Agent.OS'], 'Darwin' ) displayName: 'Mac Build' + workingDirectory: $(Agent.BuildDirectory)/s/NetHack From 496777384bd6de2ce96a062c0598c9c67b8d1ada Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Dec 2020 12:32:43 -0800 Subject: [PATCH 636/708] Qt paper doll bit Override the 'implicit_uncursed' option when formatting an item of equipment for its paper doll tool tip. Each tile is outlined in yellow if known to be uncursed; force "uncursed" in the tool tip text for the same situation. Also add or revise some comments. --- win/Qt/qt_inv.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/win/Qt/qt_inv.cpp b/win/Qt/qt_inv.cpp index 732c66f84..d309b6e52 100644 --- a/win/Qt/qt_inv.cpp +++ b/win/Qt/qt_inv.cpp @@ -2,11 +2,21 @@ // Qt4 conversion copyright (c) Ray Chason, 2012-2014. // NetHack may be freely redistributed. See license for details. -// qt_inv.cpp -- inventory usage window +// qt_inv.cpp -- inventory subset of equipment in use, +// displayed in a rectangular grid of object tiles // // Essentially a "paper doll" style display. [grep fodder] // -// This is at the top center of the main window +// This is at the top center of the main window, between messages and +// status. Qt settings (non-OSX) or Preferences (OSX) has a checkbox to +// show it or hide it, plus the tile size to use (independent of map's +// tile size). Supported tile size is 6..48x6..48 with default of 32x32. +// +// TODO? +// When yn_function() is asking for an inventory letter (not sure whether +// that is currently discernable...), allow clicking on a cell in the +// paper doll grid to return the invlet of the item clicked upon. +// extern "C" { #include "hack.h" @@ -81,10 +91,15 @@ void NetHackQtInvUsageWindow::drawWorn(QPainter &painter, obj *nhobj, : !nhobj->blessed ? BORDER_UNCURSED : BORDER_BLESSED; + // border color is used to indicate BUC state; make tip text match + boolean save_implicit_uncursed = ::flags.implicit_uncursed; + ::flags.implicit_uncursed = FALSE; // set up a tool tip describing the item that will be displayed here Sprintf(tipstr, " %s ", // extra spaces for enhanced readability // xprname: invlet, space, dash, space, object description xprname(nhobj, (char *) NULL, nhobj->invlet, FALSE, 0L, 0L)); + ::flags.implicit_uncursed = save_implicit_uncursed; + // tips are managed with nethack's alloc(); we don't track allocation // amount; allocated buffers get reused when big enough (usual case // since paperdoll updates occur more often than equipment changes) @@ -139,15 +154,15 @@ void NetHackQtInvUsageWindow::paintEvent(QPaintEvent*) // W wielded two-handed weapon // X wielded secondary weapon // - // 3.7: use a different legend for the layout: + // 3.7: use a different layout (also different legend for it, above): // show gloves in only one slot; // move alternate weapon to former right hand glove slot; // move blindfold to former alternate weapon slot; // add quiver to former blindfold slot; // show secondary weapon in shield slot when two-weapon is active; // show two-handed primary weapon in both shield and uwep slots; - // show lit lamp/lantern/candle/candelabrum on lower right side; - // show leash-in-use on lower left side + // add lit lamp/lantern/candle/candelabrum on lower right side; + // add leash-in-use on lower left side // // Actually indexed by grid[column][row]. From 1d48b78dd1dd28c7a12ced0eb1e6224144d9a4af Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 14 Dec 2020 13:12:33 -0800 Subject: [PATCH 637/708] spell learning feedback Tell the player the spell casting letter when learning a new spell: |You add "knock" to your repertoire, as 'e'. Comparable to "k - ring mail" when picking up a suit of ring mail puts it into inventory slot k. --- src/spell.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/spell.c b/src/spell.c index 160a8ed5d..4c92437cc 100644 --- a/src/spell.c +++ b/src/spell.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 spell.c $NHDT-Date: 1596498211 2020/08/03 23:43:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.107 $ */ +/* NetHack 3.7 spell.c $NHDT-Date: 1607980325 2020/12/14 21:12:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.110 $ */ /* Copyright (c) M. Stephenson 1988 */ /* NetHack may be freely redistributed. See license for details. */ @@ -416,7 +416,12 @@ learn(VOID_ARGS) g.spl_book[i].sp_lev = objects[booktype].oc_level; incrnknow(i, 1); book->spestudied++; - You(i > 0 ? "add %s to your repertoire." : "learn %s.", splname); + if (!i) + /* first is always 'a', so no need to mention the letter */ + You("learn %s.", splname); + else + You("add %s to your repertoire, as '%c'.", + splname, spellet(i)); } makeknown((int) booktype); } From 679ffd6719cf2cbc075ef12852eb21ec7425c800 Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 14 Dec 2020 20:46:04 -0800 Subject: [PATCH 638/708] Disable mingw build while we are still getting it to work. --- azure-pipelines.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7897f6492..edb92c7d7 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -41,11 +41,12 @@ strategy: buildMinimalSetting: false vsBuildSetting: true mingwBuildSetting: false - windows-mingw: - imageName: 'windows-2019' - buildMinimalSetting: false - vsBuildSetting: false - mingwBuildSetting: true +# build is currently broken +# windows-mingw: +# imageName: 'windows-2019' +# buildMinimalSetting: false +# vsBuildSetting: false +# mingwBuildSetting: true pool: vmImage: $(imageName) From 9db1aff070b338a515143edde9b8eb3f3e12a886 Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 15 Dec 2020 00:46:55 -0800 Subject: [PATCH 639/708] Use LUASRC variable when generating nhlua.h. --- sys/winnt/Makefile.gcc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index e44851950..0ff95de64 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -833,10 +833,10 @@ $(O)utility.tag: $(INCL)/date.h $(INCL)/onames.h $(INCL)/pm.h \ $(INCL)/nhlua.h: echo /* nhlua.h - generated by top Makefile */ > $@ - @echo #include "../lib/lua-$(LUA_VERSION)/src/lua.h" >> $@ + @echo #include "$(LUASRC)/lua.h" >> $@ @echo LUA_API int (lua_error) (lua_State *L) NORETURN; >>$@ - @echo #include "../lib/lua-$(LUA_VERSION)/src/lualib.h" >> $@ - @echo #include "../lib/lua-$(LUA_VERSION)/src/lauxlib.h" >> $@ + @echo #include "$(LUASRC)/lualib.h" >> $@ + @echo #include "$(LUASRC)/lauxlib.h" >> $@ @echo /*nhlua.h*/ >> $@ tileutil: $(U)gif2txt.exe $(U)gif2tx32.exe $(U)txt2ppm.exe From 746c313aee5b9f63e4937dc7b551ddfcf78ce38e Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 15 Dec 2020 00:53:01 -0800 Subject: [PATCH 640/708] Re-enable mingw pipeline build. Use pdcurses submodule for pipeline mingw build. --- azure-pipelines.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index edb92c7d7..e4dbfe623 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -41,12 +41,11 @@ strategy: buildMinimalSetting: false vsBuildSetting: true mingwBuildSetting: false -# build is currently broken -# windows-mingw: -# imageName: 'windows-2019' -# buildMinimalSetting: false -# vsBuildSetting: false -# mingwBuildSetting: true + windows-mingw: + imageName: 'windows-2019' + buildMinimalSetting: false + vsBuildSetting: false + mingwBuildSetting: true pool: vmImage: $(imageName) @@ -111,10 +110,8 @@ steps: displayName: 'Windows MSBuild' - bash: | - echo 'gcc --version' - gcc --version export ADD_CURSES=Y - export PDCURSES_TOP=../lib/pdcurses + export PDCURSES_TOP=../submodules/pdcurses export LUA_VERSION=5.4.2 export TRAVIS_COMPILER=1 cp ../sys/winnt/Makefile.gcc ./Makefile From bad05e2fb4f2aaeb638f78382b70967ebab503fa Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 15 Dec 2020 01:50:01 -0800 Subject: [PATCH 641/708] Reverting recent changes that hard coded use of submodules. --- sys/winnt/Makefile.gcc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 0ff95de64..96063d7cd 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -134,10 +134,7 @@ endif #--------------------------------------------------------------- # Location of LUA # -# Using appropriate tag, source can be obtained from the git repository: -# https://github.com/NetHack/NetHack.git -# -# Source for 5.4.2 could also be obtained from: +# Original source needs to be obtained from: # http://www.lua.org/ftp/lua-5.4.2.tar.gz # # This build assumes that the LUA sources are located @@ -157,11 +154,8 @@ endif # # The source for the standalone interpreter (luac.c) is not kept with the # rest of the LUA source. -# # The source is kept at: -# https://github.com/lua/luac.git -# -# If building, copy luac.c into the directory LUATOP. +# https://github.com/lua/luac # # By default we will not build it. # @@ -447,7 +441,7 @@ OPTIONS_FILE = $(DAT)\options ifndef LUAVER LUAVER = 5.4.2 endif -LUASRC = $(LUATOP) +LUASRC = $(LUATOP)/src LUALIB = $(O)lua-$(LUAVER).static.a LUADLL = $(O)lua-$(LUAVER).a LUAINCL = -I$(LUASRC) From bc7922908bd7878265c3673d4bfdad7b2f2fe845 Mon Sep 17 00:00:00 2001 From: Bart House Date: Mon, 14 Dec 2020 00:24:05 -0800 Subject: [PATCH 642/708] Revert "Make compiling the lua interpreter optional." This reverts commit f89005efd7ce511b90870ae1076e4ec8836a8435. --- sys/winnt/Makefile.gcc | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 96063d7cd..b4eb3b96c 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -143,26 +143,10 @@ endif # successfully build NetHack-3.7. # # By default we add lua to the build. -# ifndef ADD_LUA ADD_LUA=Y LUATOP=../submodules/lua endif - -#--------------------------------------------------------------- -# Standalone LUA interpreter -# -# The source for the standalone interpreter (luac.c) is not kept with the -# rest of the LUA source. -# The source is kept at: -# https://github.com/lua/luac -# -# By default we will not build it. -# -ifndef WANT_LUAC -WANT_LUAC=N -endif - # #============================================================================== # This marks the end of the BUILD DECISIONS section. @@ -446,11 +430,7 @@ LUALIB = $(O)lua-$(LUAVER).static.a LUADLL = $(O)lua-$(LUAVER).a LUAINCL = -I$(LUASRC) #LUAFLAGS = unix added -lm here? -ifeq "$(WANT_LUAC)" "Y" LUATARGETS = lua.exe luac.exe $(LUADLL) $(LUALIB) -else -LUATARGETS = lua.exe $(LUADLL) $(LUALIB) -endif LUASRCFILES = lapi.c lauxlib.c lbaselib.c lcode.c \ lcorolib.c lctype.c ldblib.c ldebug.c ldo.c \ From be1432ad74ee74589fd879baf6fc910f4a46659f Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 13 Dec 2020 20:38:56 -0800 Subject: [PATCH 643/708] Revert "Working on getting WinGW building with Azure pipeline." This reverts commit d88749e4196a69a24e8cb8287e68f87fce2c0292. --- sys/winnt/Makefile.gcc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index b4eb3b96c..76111e896 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -142,11 +142,8 @@ endif # you'll need to specify the correct spot below in order to # successfully build NetHack-3.7. # -# By default we add lua to the build. -ifndef ADD_LUA ADD_LUA=Y -LUATOP=../submodules/lua -endif +LUATOP=../submdules/lua # #============================================================================== # This marks the end of the BUILD DECISIONS section. From b08b47749f5143cd53d776994c9fecafbfd4db4b Mon Sep 17 00:00:00 2001 From: Bart House Date: Sun, 13 Dec 2020 20:31:01 -0800 Subject: [PATCH 644/708] Revert "Switch mingw build to use submodules in default path." This reverts commit e5fb08ae4e2a3f38b831cadd108ebd78248a44db. --- sys/winnt/Makefile.gcc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 76111e896..19df3a079 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -100,7 +100,7 @@ TARGET_CPU=x86 # your machine. # # ADD_CURSES=Y -# PDCURSES_TOP=../submodules/pdcurses +# PDCURSES_TOP=../lib/pdcurses #4b Qt # @@ -143,7 +143,7 @@ endif # successfully build NetHack-3.7. # ADD_LUA=Y -LUATOP=../submdules/lua +LUATOP=../lib/lua-$(LUAVER) # #============================================================================== # This marks the end of the BUILD DECISIONS section. From a7b47ff071877a7ceb5820856c0f2c50e9c0f4f3 Mon Sep 17 00:00:00 2001 From: Bart House Date: Tue, 15 Dec 2020 02:20:11 -0800 Subject: [PATCH 645/708] Modify mingw makefile to allow caller to specify LUA build parameters. --- azure-pipelines.yml | 4 ++++ sys/winnt/Makefile.gcc | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e4dbfe623..eb3fcef13 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -110,6 +110,10 @@ steps: displayName: 'Windows MSBuild' - bash: | + export ADD_LUA=Y + export WANT_LUAC=N + export LUATOP=../submodules/lua + export LUASRC=../submodules/lua export ADD_CURSES=Y export PDCURSES_TOP=../submodules/pdcurses export LUA_VERSION=5.4.2 diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 19df3a079..8d42e247d 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -142,8 +142,11 @@ endif # you'll need to specify the correct spot below in order to # successfully build NetHack-3.7. # +ifndef ADD_LUA ADD_LUA=Y LUATOP=../lib/lua-$(LUAVER) +WANT_LUAC=Y +endif # #============================================================================== # This marks the end of the BUILD DECISIONS section. @@ -422,12 +425,18 @@ OPTIONS_FILE = $(DAT)\options ifndef LUAVER LUAVER = 5.4.2 endif +ifndef LUASRC LUASRC = $(LUATOP)/src +endif LUALIB = $(O)lua-$(LUAVER).static.a LUADLL = $(O)lua-$(LUAVER).a LUAINCL = -I$(LUASRC) #LUAFLAGS = unix added -lm here? +ifeq "$(WANT_LUAC)" "Y" LUATARGETS = lua.exe luac.exe $(LUADLL) $(LUALIB) +else +LUATARGETS = lua.exe $(LUADLL) $(LUALIB) +endif LUASRCFILES = lapi.c lauxlib.c lbaselib.c lcode.c \ lcorolib.c lctype.c ldblib.c ldebug.c ldo.c \ From ec1d01bbe1580be97967aae616711cd4921e6ddb Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 15 Dec 2020 17:35:07 +0200 Subject: [PATCH 646/708] Fix monster hide status when moving ball & chain --- src/hack.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hack.c b/src/hack.c index 3566831a2..c8c30d900 100644 --- a/src/hack.c +++ b/src/hack.c @@ -572,6 +572,7 @@ register xchar ox, oy; { /* optimize by leaving on the fobj chain? */ remove_object(obj); + maybe_unhide_at(obj->ox, obj->oy); newsym(obj->ox, obj->oy); place_object(obj, ox, oy); newsym(ox, oy); From c8164d86af0c41789a4ad095bd8f6ba8aa151ef7 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 15 Dec 2020 17:50:28 +0200 Subject: [PATCH 647/708] Fix monster hide status when mon relocated --- src/teleport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/teleport.c b/src/teleport.c index 5c7b84964..7af0b7b15 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1250,6 +1250,7 @@ register int x, y; } } + maybe_unhide_at(x, y); newsym(x, y); /* update new location */ set_apparxy(mtmp); /* orient monster */ From 5a6cf6a20f7696c91eb97bfb0d27dd93e059a5f5 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 15 Dec 2020 16:33:51 -0800 Subject: [PATCH 648/708] '? i' refinement Make the key bindings help better able to decide whether a key binding actually works. If you bind some command to a key that is used by default for a prefix, the commands array will indicate that it (the bound key) runs the bound command. But if you don't bind some other key to the prefix action, typing that earlier key will perform the prefix action instead. The code for displaying the list of key bindings needs to know that for the case where no other key runs the command. BINDINGS=M:takeoffall will still report 'A'==takeoffall, which continues to work, but it would not show 'M'==takeoffall because 'M' is still used to run without autopickup which takes precedence over ordinary commands. BINDINGS=A:nothing BINDINGS=M:takeoffall would omit any mention of takeoffall in the '? i' output. Now it will show #takeoffall as a keyless command at the end of the 'Game commands' section. --- src/cmd.c | 97 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index 581460e4f..f8a6fc428 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1607936399 2020/12/14 08:59:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.433 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1608078812 2020/12/16 00:33:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.434 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -181,7 +181,8 @@ static void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P)); static boolean FDECL(help_dir, (CHAR_P, int, const char *)); static void NDECL(commands_init); -static boolean FDECL(keylist_func_has_key, (const struct ext_func_tab *)); +static boolean FDECL(keylist_func_has_key, (const struct ext_func_tab *, + boolean *)); static int FDECL(keylist_putcmds, (winid, BOOLEAN_P, int, int, boolean *)); static int FDECL(ch2spkeys, (CHAR_P, int, int)); static boolean FDECL(prefix_cmd, (CHAR_P)); @@ -2124,12 +2125,16 @@ commands_init() } static boolean -keylist_func_has_key(extcmd) +keylist_func_has_key(extcmd, skip_keys_used) const struct ext_func_tab *extcmd; +boolean *skip_keys_used; /* boolean keys_used[256] */ { int i; - for (i = 0; i < 256; i++) { + for (i = 0; i < 256; ++i) { + if (skip_keys_used[i]) + continue; + if (g.Cmd.commands[i] == extcmd) return TRUE; } @@ -2146,11 +2151,13 @@ boolean *keys_used; /* boolean keys_used[256] */ const struct ext_func_tab *extcmd; int i; char buf[BUFSZ], buf2[QBUFSZ]; + boolean keys_already_used[256]; /* copy of keys_used[] before updates */ int count = 0; for (i = 0; i < 256; i++) { uchar key = (uchar) i; + keys_already_used[i] = keys_used[i]; if (keys_used[i]) continue; if (key == ' ' && !flags.rest_on_space) @@ -2176,8 +2183,10 @@ boolean *keys_used; /* boolean keys_used[256] */ continue; /* can't just check for non-Null extcmd->key; it holds the default assignment and a user-specified binding might hijack - the this command's default key for some other command */ - if (keylist_func_has_key(extcmd)) + this command's default key for some other command; or this + command might have been assigned a key being used for + movement or as a prefix, intercepting that keystroke */ + if (keylist_func_has_key(extcmd, keys_already_used)) continue; /* found a command for current category without any key assignment */ if (docount) { @@ -2234,32 +2243,11 @@ dokeylist(VOID_ARGS) (void) memset((genericptr_t) keys_used, 0, sizeof keys_used); - datawin = create_nhwindow(NHW_TEXT); - putstr(datawin, 0, ""); - Sprintf(buf, "%7s %s", "", " Full Current Key Bindings List"); - putstr(datawin, 0, buf); - for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) - /* this can only check for commands without any key assigned, not - ones whose key has been hijacked by something that's processed - before it (in use as a prefix, for instance) */ - if (!keylist_func_has_key(extcmd)) { - Sprintf(buf, "%7s %s", "", - "(also commands with no key assignment)"); - putstr(datawin, 0, buf); - break; - } - - /* directional keys */ - putstr(datawin, 0, ""); - putstr(datawin, 0, "Directional keys:"); - show_direction_keys(datawin, '.', FALSE); /* '.'==self in direct'n grid */ - keys_used[(uchar) g.Cmd.move_NW] = keys_used[(uchar) g.Cmd.move_N] = keys_used[(uchar) g.Cmd.move_NE] = keys_used[(uchar) g.Cmd.move_W] = keys_used[(uchar) g.Cmd.move_E] = keys_used[(uchar) g.Cmd.move_SW] = keys_used[(uchar) g.Cmd.move_S] = keys_used[(uchar) g.Cmd.move_SE] = TRUE; - if (!iflags.num_pad) { keys_used[(uchar) highc(g.Cmd.move_NW)] = keys_used[(uchar) highc(g.Cmd.move_N)] @@ -2277,20 +2265,54 @@ dokeylist(VOID_ARGS) = keys_used[(uchar) C(g.Cmd.move_SW)] = keys_used[(uchar) C(g.Cmd.move_S)] = keys_used[(uchar) C(g.Cmd.move_SE)] = TRUE; - putstr(datawin, 0, ""); - putstr(datawin, 0, - "Ctrl+ will run in specified direction until something very"); - Sprintf(buf, "%7s %s", "", "interesting is seen."); - putstr(datawin, 0, buf); - Strcpy(buf, "Shift"); } else { /* num_pad */ keys_used[(uchar) M('1')] = keys_used[(uchar) M('2')] = keys_used[(uchar) M('3')] = keys_used[(uchar) M('4')] = keys_used[(uchar) M('6')] = keys_used[(uchar) M('7')] = keys_used[(uchar) M('8')] = keys_used[(uchar) M('9')] = TRUE; + } + for (i = 0; misc_keys[i].desc; ++i) { + key = (uchar) g.Cmd.spkeys[misc_keys[i].nhkf]; + if (key && ((misc_keys[i].numpad && iflags.num_pad) + || !misc_keys[i].numpad)) { + keys_used[key] = TRUE; + } + } +#ifndef NO_SIGNAL + /* this is actually ambiguous; tty raw mode will override SIGINT */ + key = (uchar) C('c'); + keys_used[key] = TRUE; +#endif + + datawin = create_nhwindow(NHW_TEXT); + putstr(datawin, 0, ""); + Sprintf(buf, "%7s %s", "", " Full Current Key Bindings List"); + putstr(datawin, 0, buf); + for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) + if (!keylist_func_has_key(extcmd, keys_used)) { + Sprintf(buf, "%7s %s", "", + "(also commands with no key assignment)"); + putstr(datawin, 0, buf); + break; + } + + /* directional keys */ + putstr(datawin, 0, ""); + putstr(datawin, 0, "Directional keys:"); + show_direction_keys(datawin, '.', FALSE); /* '.'==self in direct'n grid */ + + if (!iflags.num_pad) { putstr(datawin, 0, ""); - Strcpy(buf, "Meta"); + putstr(datawin, 0, + "Ctrl+ will run in specified direction until something very"); + Sprintf(buf, "%7s %s", "", "interesting is seen."); + putstr(datawin, 0, buf); + Strcpy(buf, "Shift"); /* append the rest below */ + } else { + /* num_pad */ + putstr(datawin, 0, ""); + Strcpy(buf, "Meta"); /* append the rest next */ } Strcat(buf, "+ will run in specified direction until you encounter"); @@ -2300,18 +2322,17 @@ dokeylist(VOID_ARGS) putstr(datawin, 0, ""); putstr(datawin, 0, "Miscellaneous keys:"); - for (i = 0; misc_keys[i].desc; i++) { - key = g.Cmd.spkeys[misc_keys[i].nhkf]; + for (i = 0; misc_keys[i].desc; ++i) { + key = (uchar) g.Cmd.spkeys[misc_keys[i].nhkf]; if (key && ((misc_keys[i].numpad && iflags.num_pad) || !misc_keys[i].numpad)) { - keys_used[(uchar) key] = TRUE; Sprintf(buf, "%-7s %s", key2txt(key, buf2), misc_keys[i].desc); putstr(datawin, 0, buf); } } #ifndef NO_SIGNAL + /* (see above) */ key = (uchar) C('c'); - keys_used[key] = TRUE; Sprintf(buf, "%-7s %s", key2txt(key, buf2), "break out of NetHack (SIGINT)"); putstr(datawin, 0, buf); From 3a91d65bb648c5a66d0384789064ed10e1055843 Mon Sep 17 00:00:00 2001 From: Bart House Date: Wed, 16 Dec 2020 00:43:59 -0800 Subject: [PATCH 649/708] Added MSDOS build and made improvements to pipeline configuration. --- azure-pipelines.yml | 177 ++++++++++++++++++++++++++------------------ 1 file changed, 104 insertions(+), 73 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index eb3fcef13..188c39bbc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -2,50 +2,46 @@ strategy: matrix: linux_focal_gcc8_minimal: imageName: 'ubuntu-20.04' - ccName: gcc-8 - cxxName: g++-8 - buildMinimalSetting: true + toolchainName: gcc8 + buildTargetName: minimal linux_focal_clang_all: imageName: 'ubuntu-20.04' - ccName: clang - cxxName: clang++ - buildMinimalSetting: false + toolchainName: clang + buildTargetName: all linux_focal_gcc8_all: imageName: 'ubuntu-20.04' - ccName: gcc-8 - cxxName: g++-8 - buildMinimalSetting: false + toolchainName: gcc8 + buildTargetName: all linux_focal_gcc9_all: imageName: 'ubuntu-20.04' - ccName: gcc-9 - cxxName: g++-9 - buildMinimalSetting: false + toolchainName: gcc9 + buildTargetName: all linux_bionic_gcc7_all: imageName: 'ubuntu-18.04' - ccName: gcc-7 - cxxName: g++-7 - buildMinimalSetting: false + toolchainName: gcc7 + buildTargetName: all # build is currently broken # mac_catalina_gcc8_all: # imageName: 'macOS-10.15' # ccName: gcc-8 # cxxName: g++-8 -# buildMinimalSetting: false +# buildSetting: 'all' mac_catalina_clang_all: imageName: 'macOS-10.15' - ccName: clang - cxxName: clang++ - buildMinimalSetting: false + toolchainName: clang + buildTargetName: all windows-visualstudio: imageName: 'windows-2019' - buildMinimalSetting: false - vsBuildSetting: true - mingwBuildSetting: false + toolchainName: vs + buildTargetName: all windows-mingw: imageName: 'windows-2019' - buildMinimalSetting: false - vsBuildSetting: false - mingwBuildSetting: true + toolchainName: mingw + buildTargetName: all + linux_focal_cross_msdos: + imageName: 'ubuntu-20.04' + toolchainName: cross + buildTargetName: msdos pool: vmImage: $(imageName) @@ -59,55 +55,78 @@ pool: # endpoint: github.com_barthouse variables: - buildMinimal: $(buildMinimalSetting) - mingwBuild: $(mingwBuildSetting) - vsBuild: $(vsBuildSetting) - ${{ if eq( variables['Agent.OS'], 'Windows_NT') }}: - NetHackPath: s\NetHack - ${{ if ne( variables['Agent.OS'], 'Windows_NT') }}: - NetHackPath: s/NetHack - CC: $(ccName) - CXX: $(cxxName) + toolchain: $(toolchainName) + buildTarget: $(buildTargetName) + netHackPath: s/NetHack steps: -# - bash: | -# echo 'mingwBuildSetting' '$(mingwBuildSetting)' -# echo 'mingwBuild' '$(mingwBuild)' -# echo 'vsBuild' '$(vsBuild)' -# echo 'NetHackPath' '$(NetHackPath)' -# echo 'CC' '$(CC)' -# echo 'CXX' '$(CXX)' +- bash: | + if [ "$(toolchain)" == "gcc7" ] + then + echo "##vso[task.setvariable variable=CC]gcc-7" + echo "##vso[task.setvariable variable=CXX]g++-7" + fi + if [ "$(toolchain)" == "gcc8" ] + then + echo "##vso[task.setvariable variable=CC]gcc-8" + echo "##vso[task.setvariable variable=CXX]g++-8" + fi + if [ "$(toolchain)" == "gcc9" ] + then + echo "##vso[task.setvariable variable=CC]gcc-9" + echo "##vso[task.setvariable variable=CXX]g++-9" + fi + if [ "$(toolchain)" == "gcc10" ] + then + echo "##vso[task.setvariable variable=CC]gcc-10" + echo "##vso[task.setvariable variable=CXX]g++-10" + fi + if [ "$(toolchain)" == "clang" ] + then + echo "##vso[task.setvariable variable=CC]clang" + echo "##vso[task.setvariable variable=CXX]clang++" + fi + if [ "$(toolchain)" == "cross" ] + then + echo "##vso[task.setvariable variable=CC]gcc-8" + echo "##vso[task.setvariable variable=CXX]g++-8" + fi + displayName: 'Setting variables' -- checkout: git://NetHack/NetHack@NetHack-3.7 # $(Agent.BuildDirectory)\s\NetHack +- bash: | + echo "toolchain: $(toolchain)" + echo "buildTarget: $(buildTarget)" + echo "netHackPath: $NETHACKPATH" + echo "CC: $CC" + echo "CXX: $CXX" + displayName: 'Echoing variables' + +- checkout: git://NetHack/NetHackTest@pipeline-test submodules: true - path: $(NetHackPath) - -# - checkout: pdcursesrepo -# path: s\NetHack\lib\pdcurses -# condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) + path: $(netHackPath) # $(Agent.BuildDirectory)/$(netHackPath) - task: DownloadSecureFile@1 name: storeKey - displayName: 'Store Key Download' inputs: secureFile: 'NetHackPackage_StoreKey.pfx' - condition: eq( variables['Agent.OS'], 'Windows_NT' ) + condition: eq( variables.toolchain, 'vs' ) + displayName: 'Store Key Download' - task: CopyFiles@2 inputs: contents: NetHackPackage_StoreKey.pfx SourceFolder: $(Agent.TempDirectory) - TargetFolder: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs - condition: eq( variables['Agent.OS'], 'Windows_NT' ) + TargetFolder: $(Agent.BuildDirectory)/$(netHackPath)/win/win32/vs + condition: eq( variables.toolchain, 'vs' ) displayName: 'Copying store key' - task: MSBuild@1 inputs: - solution: $(Agent.BuildDirectory)\s\NetHack\win\win32\vs\NetHack.sln + solution: $(Agent.BuildDirectory)/$(netHackPath)/win/win32/vs/NetHack.sln platform: Win32 configuration: Debug - condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.vsBuild, true)) - displayName: 'Windows MSBuild' + condition: eq( variables.toolchain, 'vs' ) + displayName: 'Visual Studio Build' - bash: | export ADD_LUA=Y @@ -120,17 +139,27 @@ steps: export TRAVIS_COMPILER=1 cp ../sys/winnt/Makefile.gcc ./Makefile mingw32-make LUA_VERSION=$LUA_VERSION install - condition: and( eq( variables['Agent.OS'], 'Windows_NT' ), eq( variables.mingwBuild, true)) - displayName: 'Windows MinGW Build' - workingDirectory: $(Agent.BuildDirectory)/s/NetHack/src + condition: eq( variables.toolchain, 'mingw' ) + workingDirectory: $(Agent.BuildDirectory)/$(netHackPath)/src + displayName: 'MinGW Build' - bash: | sudo apt-get -qq -y update sudo apt-get -qq -y install libncurses5-dev sudo apt-get -qq -y install libx11-dev libxaw7-dev xfonts-utils qtbase5-dev qtmultimedia5-dev qtbase5-dev-tools condition: eq( variables['Agent.OS'], 'Linux' ) + workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) displayName: 'Getting linux build dependencies' - workingDirectory: $(Agent.BuildDirectory)/s/NetHack + +- bash: | + cd sys/unix + sh setup.sh hints/linux.2020 + cd ../.. + make fetch-lua + make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all + condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildTarget, 'all')) + workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) + displayName: 'Building linux full build' - bash: | cd sys/unix @@ -155,22 +184,11 @@ steps: sed -i '/^#define SHELL/d' include/unixconf.h sed -i '/^#define SUSPEND/d' include/unixconf.h sed -i 's/^#define TEXTCOLOR//' include/unixconf.h - cat include/config.h make fetch-lua make WANT_WIN_ALL=1 all - condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, true)) + condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildTarget, 'minimal')) displayName: 'Building linux minimal build' - workingDirectory: $(Agent.BuildDirectory)/s/NetHack - -- bash: | - cd sys/unix - sh setup.sh hints/linux.2020 - cd ../.. - make fetch-lua - make WANT_WIN_ALL=1 QT_SELECT=5 MOC=moc all - condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.buildMinimal, false)) - displayName: 'Building linux full build' - workingDirectory: $(Agent.BuildDirectory)/s/NetHack + workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) - bash: | cd sys/unix @@ -179,5 +197,18 @@ steps: make fetch-lua make all condition: eq( variables['Agent.OS'], 'Darwin' ) - displayName: 'Mac Build' - workingDirectory: $(Agent.BuildDirectory)/s/NetHack + workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) + displayName: 'Building mac full build' + +- bash: | + export GCCVER=gcc1010 + cd sys/unix + sh setup.sh hints/linux.2020 + cd ../.. + make fetch-lua + sh sys/msdos/fetch-cross-compiler.sh + make LUA_VERSION=5.4.2 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 all + make LUA_VERSION=5.4.2 WANT_WIN_TTY=1 WANT_WIN_CURSES=1 CROSS_TO_MSDOS=1 package + condition: and(eq( variables['Agent.OS'], 'Linux' ), eq( variables.toolchain, 'cross')) + workingDirectory: $(Agent.BuildDirectory)/$(netHackPath) + displayName: 'Building MSDOS build' From 4f0e47fd0c34ee935a6d0d542ef1dd0cd437a515 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 16 Dec 2020 02:49:00 -0800 Subject: [PATCH 650/708] extra ^X feedback Report "abnormal" play (wizard mode or explore mode) in ^X output or end of game dumplog. Omitted for normal play. --- src/insight.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/insight.c b/src/insight.c index 519a64be4..b95791968 100644 --- a/src/insight.c +++ b/src/insight.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 insight.c $NHDT-Date: 1596334662 2020/08/02 02:17:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.22 $ */ +/* NetHack 3.7 insight.c $NHDT-Date: 1608115734 2020/12/16 10:48:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -259,9 +259,7 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ characteristics_enlightenment(mode, final); } /* expanded status line information, including things which aren't - included there due to space considerations--such as obvious - alternative movement indicators (riding, levitation, &c), and - various troubles (turning to stone, trapped, confusion, &c); + included there due to space considerations; shown for both basic and magic enlightenment */ status_enlightenment(mode, final); /* remaining attributes; shown for potion,&c or wizard mode and @@ -270,6 +268,13 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ /* intrinsics and other traditional enlightenment feedback */ attributes_enlightenment(mode, final); } + /* reminder to player and/or information for dumplog */ + if ((mode & BASICENLIGHTENMENT) != 0 && (wizard || discover)) { + enlght_out(""); /* separator */ + enlght_out("Miscellaneous:"); + Sprintf(buf, "running in %s mode", wizard ? "debug" : "explore"); + you_are(buf, ""); + } if (!g.en_via_menu) { display_nhwindow(g.en_win, TRUE); From 48d39b2ffdc6eefe86cd179a8f3e2415e207b64e Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 16 Dec 2020 03:07:55 -0800 Subject: [PATCH 651/708] allow #exploremode from wizard mode Allow changing form debug mode to explore mode without resorting to a debugger. The same caveat, "you won't be able to change back," applies as when in normal play. Character's name will remain "wizard" rather than reverting to whatever it would have been if not starting in wizard mode. --- src/cmd.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index f8a6fc428..275c71e46 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1608078812 2020/12/16 00:33:32 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.434 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1608116853 2020/12/16 11:07:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.435 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -750,30 +750,37 @@ domonability(VOID_ARGS) int enter_explore_mode(VOID_ARGS) { - if (wizard) { - You("are in debug mode."); - } else if (discover) { + if (discover) { You("are already in explore mode."); } else { + const char *oldmode = !wizard ? "normal game" : "debug mode"; + #ifdef SYSCF #if defined(UNIX) if (!sysopt.explorers || !sysopt.explorers[0] || !check_user_string(sysopt.explorers)) { - You("cannot access explore mode."); - return 0; + if (!wizard) { + You("cannot access explore mode."); + return 0; + } else { + pline( + "Note: normally you wouldn't be allowed into explore mode."); + /* keep going */ + } } #endif #endif - pline( - "Beware! From explore mode there will be no return to normal game."); + pline("Beware! From explore mode there will be no return to %s,", + oldmode); if (paranoid_query(ParanoidQuit, "Do you want to enter explore mode?")) { + discover = TRUE; + wizard = FALSE; clear_nhwindow(WIN_MESSAGE); You("are now in non-scoring explore mode."); - discover = TRUE; } else { clear_nhwindow(WIN_MESSAGE); - pline("Resuming normal game."); + pline("Continuing with %s.", oldmode); } } return 0; From d27b8cb04351aa1b7391b54b2cd3c679e9e8598f Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 16 Dec 2020 19:22:04 -0800 Subject: [PATCH 652/708] adopt some orphan commands '? i' shows three keyless commands in the General section. This makes M-X the key for #exploremode. #herecmdmenu and #therecmdmenu are still keyless but now autocomplete. A ridiculous amount of documentation for a three line code change. --- dat/cmdhelp | 1 + doc/Guidebook.mn | 54 ++++++++++++++++++++++++++++++++++++----------- doc/Guidebook.tex | 50 +++++++++++++++++++++++++++++++++++-------- doc/fixes37.0 | 4 +++- src/cmd.c | 8 +++---- 5 files changed, 91 insertions(+), 26 deletions(-) diff --git a/dat/cmdhelp b/dat/cmdhelp index d993c313c..134866d01 100644 --- a/dat/cmdhelp +++ b/dat/cmdhelp @@ -223,3 +223,4 @@ M-T Tip: empty a container M-u Untrap something (trap, door, or chest) M-v Print compile time options for this version of NetHack M-w Wipe off your face +M-X Switch from normal play to explore mode diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index dff313965..4fab00cd7 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.407 $ $NHDT-Date: 1607936398 2020/12/14 08:59:58 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.408 $ $NHDT-Date: 1608175317 2020/12/17 03:21:57 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "December 13, 2020 +.ds f2 "December 16, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -969,9 +969,9 @@ the exchange still takes place. Toggle two-weapon combat, if your character can do it. Also available via the \(lq#twoweapon\(rq extended command. .lp "" -(In versions prior to 3.6 this was the command to switch from normal +(In versions prior to 3.6 this keystroke ran the command to switch from normal play to \(lqexplore mode\(rq, also known as \(lqdiscovery mode\(rq, -which has now been moved to \(lq#exploremode\(rq.) +which has now been moved to \(lq#exploremode\(rq and M-X.) .lp \(haX Display basic information about your character. .lp "" @@ -1199,7 +1199,8 @@ Advance or check weapon and spell skills. Autocompletes. Default key is \(oqM-e\(cq. .lp #exploremode -Enter the explore mode. +Switch from normal play to non-scoring explore mode. +Default key is \(oqM-X\(cq. .lp "" Requires confirmation; default response is \f(CRn\fP (no). To really switch to explore mode, respond with \f(CRy\fP. @@ -1222,7 +1223,15 @@ Default key is \(oq?\(cq, and also \(oqh\(cq if .op number_pad is on. .lp #herecmdmenu -Show a menu of possible actions in your current location. +Show a menu of possible actions directed at your current location. +The menu is limited to a subset of the likeliest actions, not an +exhaustive set of all possibilities. +Autocompletes. +.lp "" +If mouse support is enabled and the +.op herecmd_menu +option is On, clicking on the hero (or steed when mounted) will +execute this command. .lp "#history " Show long version and game history. Default key is \(oqV\(cq. @@ -1473,7 +1482,15 @@ In debug mode there are additional choices. Autocompletes. Default key is \(oq\(cq or \(oq\(cq (see \fIDel\fP above). .lp #therecmdmenu -Show a menu of possible actions in a location next to you. +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. +.\"--invoking it by mouse seems to be broken +.\" .lp "" +.\" If mouse support is enabled and the +.\" .op herecmd_menu +.\" option is On, clicking on an adjacent location will execute this command. .lp "#throw " Throw something. Default key is \(oqt\(cq. @@ -1642,16 +1659,27 @@ with another key, modifies it by setting the \(lqmeta\(rq [8th, or \(lqhigh\(rq] bit), you can invoke many extended commands by meta-ing the first letter of the command. .pg -In \fIWindows\fP, \fIOS/2\fP, \fIPC\fP and \fIST\fP \fINetHack\fP, -the \(lqAlt\(rq key can be used in this fashion; -on the \fIAmiga\fP, set the -.op altmeta -option to get this behavior. +On \fIWindows\fP and \fIMS-DOS\fP, +the \(lqAlt\(rq key can be used in this fashion. +.\" On the \fIAmiga\fP, set the +.\" .op altmeta +.\" option to get this behavior. On other systems, if typing \(lqAlt\(rq plus another key transmits a two character sequence consisting of an \fBEscape\fP followed by the other key, you may set the .op altmeta option to have NetHack combine them into meta+key. +(This combining action only takes place when NetHack is expecting a +command to execute, not when accepting input to name something or to +make a wish.) +.pg +Unlike control characters, where \(hax and \(haX 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 used for +another command, so the three key combination meta+shift+letter is needed. +.BR 1 +. .lp M-? #? (not supported by all platforms) .lp M-2 @@ -1706,6 +1734,8 @@ option is enabled) #version .lp M-w #wipe +.lp M-X +#exploremode .lp "" .pg If the diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index c5b89b555..a3dd3fecc 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{December 13, 2020} +\date{December 16, 2020} \maketitle @@ -1059,9 +1059,9 @@ the exchange still takes place. Toggle two-weapon combat, if your character can do it. Also available via the ``{\tt \#twoweapon}'' extended command.\\ %.lp "" -(In versions prior to 3.6 this was the command to switch from normal +(In versions prior to 3.6 this keystroke ran the command to switch from normal play to ``explore mode'', also known as ``discovery mode'', which has now -been moved to ``{\tt \#exploremode}''.) +been moved to ``{\tt \#exploremode}'' and M-X.) %.lp \item[\tb{\^{}X}] Display basic information about your character.\\ @@ -1282,7 +1282,8 @@ Advance or check weapon and spell skills. Autocompletes. Default key is `{\tt M-e}'. %.lp \item[\tb{\#exploremode}] -Enter the explore mode.\\ +Switch from normal play to non-scoring explore mode. +Default key is `{\tt M-X}'.\\ %.lp "" Requires confirmation; default response is `{\tt n}' (no). To really switch to explore mode, respond with `{\tt y}'. @@ -1305,7 +1306,14 @@ Default key is `{\tt ?}', and also `{\tt h}' if {\it number\verb+_+pad\/} is on. %.lp \item[\tb{\#herecmdmenu}] -Show a menu of possible actions in your current location. +Show a menu of possible actions directed at your current location. +The menu is limited to a subset of the likeliest actions, not an +exhaustive set of all possibilities. +Autocompletes.\\ +%.lp "" +If mouse support is enabled and the {\it herecmd\verb+_+menu\/} +option is On, clicking on the hero (or steed when mounted) will +execute this command. %.lp \item[\tb{\#history}] Show long version and game history. Default key is `{\tt V}'. @@ -1565,7 +1573,15 @@ Autocompletes. Default key is `' or `' (see {\it Del\/} above). %.lp \item[\tb{\#therecmdmenu}] -Show a menu of possible actions in a location next to you. +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. +%%--invoking it by mouse seems to be broken +%% \\ +%% .lp "" +%% If mouse support is enabled and the {\it herecmd\verb+_+menu\/} +%% option is On, clicking on an adjacent location will execute this command. %.lp \item[\tb{\#throw}] Throw something. Default key is `{\tt t}'. @@ -1750,13 +1766,26 @@ Help menu: get the list of available extended commands. 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. -In {\it Windows, OS/2, PC\/ {\rm and} ST NetHack}, -the `Alt' key can be used in this fashion; -on the {\it Amiga}, set the {\it altmeta\/} option to get this behavior. + +On {\it Windows\/} and {\it MS-DOS\/}, +the `Alt' key can be used in this fashion. +%% On the {\it Amiga}, set the {\it altmeta\/} option to get this behavior. On other systems, if typing `Alt' plus another key transmits a two character sequence consisting of an {\tt Escape} followed by the other key, you may set the {\it altmeta\/} option to have {\it NetHack\/} combine them into meta\+key. +(This combining action only takes place when NetHack is expecting a +command to execute, not when accepting input to name something or to +make a wish.) + +%.pg +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 used for +another command, so the three key combination meta+shift+letter is needed. + +%.BR 1 \blist{} %.lp \item[\tb{M-?}] @@ -1836,6 +1865,9 @@ option to have {\it NetHack\/} combine them into meta\+key. %.lp \item[\tb{M-w}] {\tt\#wipe} +%.lp +\item[\tb{M-X}] +{\tt\#exploremode} \elist %.pg diff --git a/doc/fixes37.0 b/doc/fixes37.0 index cfcd3f76c..696c3e1af 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.392 $ $NHDT-Date: 1607936398 2020/12/14 08:59:58 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.393 $ $NHDT-Date: 1608175317 2020/12/17 03:21:57 $ General Fixes and Modified Features ----------------------------------- @@ -671,6 +671,8 @@ when "?i" (show key bindings) displays commands and their keys, also show commands without any key (so useable via '#', or possibly menu, only; the majority are debugging commands) assign default key binding for or to execute #terrain +assign M-X to #exploremode +make #herecmdmenu and #therecmdmenu autocomplete Platform- and/or Interface-Specific New Features diff --git a/src/cmd.c b/src/cmd.c index 275c71e46..7e98f675d 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1608116853 2020/12/16 11:07:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.435 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1608175318 2020/12/17 03:21:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.436 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1817,7 +1817,7 @@ struct ext_func_tab extcmdlist[] = { { 'E', "engrave", "engrave writing on the floor", doengrave }, { M('e'), "enhance", "advance or check weapon and spell skills", enhance_weapon_skill, IFBURIED | AUTOCOMPLETE }, - { '\0', "exploremode", "enter explore (discovery) mode", + { M('X'), "exploremode", "enter explore (discovery) mode", enter_explore_mode, IFBURIED | GENERALCMD }, { 'f', "fire", "fire ammunition from quiver", dofire }, { M('f'), "force", "force a lock", doforce, AUTOCOMPLETE }, @@ -1825,7 +1825,7 @@ struct ext_func_tab extcmdlist[] = { doquickwhatis, IFBURIED | GENERALCMD }, { '?', "help", "give a help message", dohelp, IFBURIED | GENERALCMD }, { '\0', "herecmdmenu", "show menu of commands you can do here", - doherecmdmenu, IFBURIED | GENERALCMD }, + doherecmdmenu, IFBURIED | AUTOCOMPLETE | GENERALCMD }, { 'V', "history", "show long version and game history", dohistory, IFBURIED | GENERALCMD }, { 'i', "inventory", "show your inventory", ddoinv, IFBURIED }, @@ -1929,7 +1929,7 @@ struct ext_func_tab extcmdlist[] = { doterrain, IFBURIED | AUTOCOMPLETE }, { '\0', "therecmdmenu", "menu of commands you can do from here to adjacent spot", - dotherecmdmenu, GENERALCMD }, + dotherecmdmenu, AUTOCOMPLETE | GENERALCMD }, { 't', "throw", "throw something", dothrow }, { '\0', "timeout", "look at timeout queue and hero's timed intrinsics", wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, From 00c4e832c5a35e6e9a5eca1ed109abe8cbad311c Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Dec 2020 11:38:18 -0800 Subject: [PATCH 653/708] click_to_cmd() vs #therecmdmenu Clicking on an adjacent location while 'herecmd_menu' is On didn't run therecmd as intended. If it had, maybe somebody would have noticed how broken it is. This reorganizes the mouse click handling but leaves therecmd commented out since it hasn't been fixed. The #therecmdmenu command and tentative click handling for adjacent spots should probably be removed. They've been in place for slightly over three years and nobody has ever reported that they don't work properly. --- src/cmd.c | 56 +++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index 7e98f675d..65c05546b 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1608175318 2020/12/17 03:21:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.436 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1608233885 2020/12/17 19:38:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.437 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -4001,6 +4001,9 @@ const char *text; } } +/* offer choice of actions to perform at adjacent location ; + does not work as intended because the actions that get invoked + ask for a direction or target instead of using our */ static char there_cmd_menu(doit, x, y) boolean doit; @@ -4074,6 +4077,18 @@ int x, y; add_herecmd_menuitem(win, doapply, buf); } #if 0 + if (mtmp) { + Sprintf(buf, "%s %s", mon_nam(mtmp), + !has_mname(mtmp) ? "Name" : "Rename"), ++K; + /* need a way to pass mtmp or to an 'int f()' function + as well as reorganizinging do_mname() to use that function */ + add_herecmd_menuitem(win, XXX(), buf); + } +#endif +#if 0 + /* these are necessary if click_to_cmd() is deferring to us; however, + moving/fighting aren't implmented as independent commands so don't + fit our menu's use of command functions */ if (mtmp || glyph_is_invisible(glyph_at(x, y))) { /* "Attack %s", mtmp ? mon_nam(mtmp) : "unseen creature" */ } else { @@ -4089,7 +4104,7 @@ int x, y; npick = 0; } destroy_nhwindow(win); - ch = '\0'; + ch = '\033'; if (npick > 0) { int NDECL((*func)) = picks->item.a_nfunc; free((genericptr_t) picks); @@ -4183,7 +4198,7 @@ boolean doit; end_menu(win, "What do you want to do?"); npick = select_menu(win, PICK_ONE, &picks); destroy_nhwindow(win); - ch = '\0'; + ch = '\033'; if (npick > 0) { int NDECL((*func)) = picks->item.a_nfunc; free((genericptr_t) picks); @@ -4208,16 +4223,33 @@ int x, y, mod; { static char cmd[4]; struct obj *o; - int dir; - - cmd[1] = '\0'; + int dir, udist; + cmd[0] = cmd[1] = '\0'; if (iflags.clicklook && mod == CLICK_2) { g.clicklook_cc.x = x; g.clicklook_cc.y = y; cmd[0] = g.Cmd.spkeys[NHKF_CLICKLOOK]; return cmd; } + /* this used to be inside the 'if (flags.travelcmd)' block, but + handle click-on-self even when travel is disabled; unlike + accidentally zooming across the level because of a stray click, + clicking on self can easily be cancelled if it wasn't intended */ + if (iflags.herecmd_menu && isok(x, y)) { + udist = distu(x, y); + if (!udist) { + cmd[0] = here_cmd_menu(FALSE); + return cmd; + } else if (udist <= 2) { +#if 0 /* there_cmd_menu() is broken; the commands it invokes + * tend to ask for a direction or target instead of using + * the adjacent coordinates that are being passed to it */ + cmd[0] = there_cmd_menu(FALSE, x, y); + return cmd; +#endif + } + } x -= u.ux; y -= u.uy; @@ -4233,11 +4265,6 @@ int x, y, mod; } if (x == 0 && y == 0) { - if (iflags.herecmd_menu) { - cmd[0] = here_cmd_menu(FALSE); - return cmd; - } - /* here */ if (IS_FOUNTAIN(levl[u.ux][u.uy].typ) || IS_SINK(levl[u.ux][u.uy].typ)) { @@ -4264,17 +4291,10 @@ int x, y, mod; /* directional commands */ dir = xytod(x, y); - if (!m_at(u.ux + x, u.uy + y) && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) { cmd[1] = g.Cmd.dirchars[dir]; cmd[2] = '\0'; - if (iflags.herecmd_menu) { - cmd[0] = there_cmd_menu(FALSE, u.ux + x, u.uy + y); - if (cmd[0] == '\0') - cmd[1] = '\0'; - return cmd; - } if (IS_DOOR(levl[u.ux + x][u.uy + y].typ)) { /* slight assistance to player: choose kick/open for them */ From 65763f9bec2d679c985fe1122064bc6f7b1f4618 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Dec 2020 12:21:35 -0800 Subject: [PATCH 654/708] fix the tail-less long worm placement warning Hidden tail segment was taken off the map as intended but the check and warning in place_wormtail_randonly() didn't expect to see that. A post-3.6 issue. Also fix the spelling error in the warning message. --- doc/fixes37.0 | 4 +++- src/worm.c | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 696c3e1af..b873c0833 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.393 $ $NHDT-Date: 1608175317 2020/12/17 03:21:57 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.394 $ $NHDT-Date: 1608236443 2020/12/17 20:20:43 $ General Fixes and Modified Features ----------------------------------- @@ -433,6 +433,8 @@ fix genetic engineers dropping Schroedinger's cat box the checks and handling for fountains, sinks, and drawbridges were being missed during liquid_flow monster movement flags unification allowed displacer beasts to displace Riders +a long worm with no visible segments (but one internal segment) might trigger + warning: tail 'segement' at <0,some_y>, worm at if teleported curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/worm.c b/src/worm.c index 9027f925b..9081a9919 100644 --- a/src/worm.c +++ b/src/worm.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 worm.c $NHDT-Date: 1599559380 2020/09/08 10:03:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.48 $ */ +/* NetHack 3.7 worm.c $NHDT-Date: 1608236444 2020/12/17 20:20:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.49 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2009. */ /* NetHack may be freely redistributed. See license for details. */ @@ -755,15 +755,17 @@ xchar x, y; return; } if (wtails[wnum] == wheads[wnum]) { - /* single segment, co-located with worm so nothing to place */ - if (curr->wx != worm->mx || curr->wy != worm->my) { + /* single segment, co-located with worm; + should either have same coordinates or have seg->wx==0 + to indicate that it is not currently on the map */ + if (curr->wx && (curr->wx != worm->mx || curr->wy != worm->my)) { impossible( - "place_worm_tail_randomly: tail segement at <%d,%d>, worm at <%d,%d>", + "place_worm_tail_randomly: tail segment at <%d,%d>, worm at <%d,%d>", curr->wx, curr->wy, worm->mx, worm->my); if (m_at(curr->wx, curr->wy) == worm) remove_monster(curr->wx, curr->wy); - curr->wx = worm->mx, curr->wy = worm->my; } + curr->wx = worm->mx, curr->wy = worm->my; return; } /* remove head segment from map in case we end up calling toss_wsegs(); From ee9fa9ebe365e184a6b8247a27a838c4860ca346 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 17 Dec 2020 13:55:10 -0800 Subject: [PATCH 655/708] Qt text window search Fix the strangeness where typing ':' in a menu window initiated the menu search operation but typing ':' in a text window saw the shift key be pressed but not the ';' that went with it, even though they both called the same key decoding routine. That made typing ':' to initiate text search be impossible. Menu windows did more input focus manipulation in their constructor. Mimicking that in text windows fixes the problem with keys not being seen by the text window's keystroke handler. --- win/Qt/qt_menu.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/win/Qt/qt_menu.cpp b/win/Qt/qt_menu.cpp index 1a549a8e0..e02cd3d40 100644 --- a/win/Qt/qt_menu.cpp +++ b/win/Qt/qt_menu.cpp @@ -999,6 +999,8 @@ NetHackQtTextWindow::NetHackQtTextWindow(QWidget *parent) : // we don't want keystrokes being sent to the main window for use as // commands while this text window is popped up setFocusPolicy(Qt::StrongFocus); + // needed so that keystrokes get sent to our keyPressEvent() + lines->setFocusPolicy(Qt::NoFocus); } void NetHackQtTextWindow::doUpdate() @@ -1183,11 +1185,12 @@ void NetHackQtTextWindow::Search() // Force text window to be on top. Without this, it moves behind // the map after the string requestor completes. Then it can't // be seen or accessed (unless the game window is minimized or - // possibly dragged out of the way). Unfortunately the window - // noticeably vanishes and then immediately gets redrawn. - if (!this->isActiveWindow()) + // dragged out of the way). Unfortunately the window noticeably + // vanishes and then immediately gets redrawn. + if (!this->isActiveWindow()) { this->activateWindow(); - this->raise(); + this->raise(); + } if (get_a_line) { int linecount = lines->count(); @@ -1226,12 +1229,6 @@ void NetHackQtTextWindow::keyPressEvent(QKeyEvent *key_event) { uchar key = keyValue(key_event); - // - // FIXME: - // Typing ':' doesn't produce ':' so key won't match MENU_SEARCH, - // despite the fact that it does produce ':' for menu input and - // we're calling the exact same code for both types of window...? - // if (key == MENU_SEARCH) { if (!use_rip) Search(); From f60ecfc3e75d08672f1535c0a4b49e41a78dc79b Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 18 Dec 2020 19:31:47 +0200 Subject: [PATCH 656/708] Fix monster hide state when chain is moved --- src/ball.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ball.c b/src/ball.c index 60099a83b..6eeafe6fa 100644 --- a/src/ball.c +++ b/src/ball.c @@ -168,6 +168,7 @@ unplacebc_core() obj_extract_self(uchain); if (Blind && (u.bc_felt & BC_CHAIN)) /* drop glyph */ levl[uchain->ox][uchain->oy].glyph = u.cglyph; + maybe_unhide_at(uchain->ox, uchain->oy); newsym(uchain->ox, uchain->oy); u.bc_felt = 0; /* feel nothing */ From c709c45780141a5e595729abf7bc9d7552d128cb Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Dec 2020 15:05:54 -0800 Subject: [PATCH 657/708] concealed monster sanity checks Add some more checks to sanity_check_single_mon(). If mon->data is discovered to be bad, panic instead of just issuing a warning since a subsequent crash would be inevitable. Make sure hidden ceiling hiders have a ceiling to hide at (so not on the planes of air or water; some quest levels should probably be classified as "no ceiling" but currently aren't). Perform a few mimic checks. Protection from shape changers had a couple of minor bugs. A mimic hidden at a spot the hero couldn't see would be allowed to remain hidden (and stay that way once within view because protection from shape changers isn't re-checked during ordinary activity). Also, if a pet was shape-changed while eating a mimic corpse at the time protection from shape changers started, it would fall into untimed sleep as part of being forced back to normal shape [rescham()] if its location could be seen. --- doc/fixes37.0 | 6 +++- src/mon.c | 82 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 71 insertions(+), 17 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index b873c0833..2b498f61e 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.394 $ $NHDT-Date: 1608236443 2020/12/17 20:20:43 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.395 $ $NHDT-Date: 1608332750 2020/12/18 23:05:50 $ General Fixes and Modified Features ----------------------------------- @@ -337,6 +337,10 @@ when water damage wet a towel, the new wetness might randomly become less when the wetness of a towel in inventory changed, persistent inventory wasn't updated to show that make Death revive earlier, and all the Riders after 67 turns at latest +when protection from shape changers begins, force mimic out of concealment + even if hero can't see its location; for locations that can be seen, + don't make double-trouble Wizard concealed as another monster--or pet + temporarily mimicking something while eating mimic corpse--fall asleep Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/mon.c b/src/mon.c index ad126c6c5..1676dc072 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1607901923 2020/12/13 23:25:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.360 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1608332750 2020/12/18 23:05:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.361 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -46,11 +46,16 @@ struct monst *mtmp; boolean chk_geno; const char *msg; { - if (mtmp->data < &mons[LOW_PM] || mtmp->data >= &mons[NUMMONS]) { - impossible("illegal mon data %s; mnum=%d (%s)", - fmt_ptr((genericptr_t) mtmp->data), mtmp->mnum, msg); + struct permonst *mptr = mtmp->data; + int mx = mtmp->mx, my = mtmp->my; + + if (!mptr || mptr < &mons[LOW_PM] || mptr >= &mons[NUMMONS]) { + /* most sanity checks issue warnings if they detect a problem, + but this would be too extreme to keep going */ + panic("illegal mon data %s; mnum=%d (%s)", + fmt_ptr((genericptr_t) mptr), mtmp->mnum, msg); } else { - int mndx = monsndx(mtmp->data); + int mndx = monsndx(mptr); if (mtmp->mnum != mndx) { impossible("monster mnum=%d, monsndx=%d (%s)", @@ -79,7 +84,7 @@ const char *msg; /* bad if not fmons list or if not vault guard */ if (strcmp(msg, "fmon") || !mtmp->isgd) impossible("dead monster on %s; %s at <%d,%d>", - msg, mons[mndx].mname, mtmp->mx, mtmp->my); + msg, mons[mndx].mname, mx, my); #endif return; } @@ -103,7 +108,7 @@ const char *msg; if (mtmp->mtrapped) { if (mtmp->wormno) { /* TODO: how to check worm in trap? */ - } else if (!t_at(mtmp->mx, mtmp->my)) + } else if (!t_at(mx, my)) impossible("trapped without a trap (%s)", msg); } @@ -111,17 +116,54 @@ const char *msg; if (mtmp->mundetected) { struct trap *t; + if (!isok(mx, my)) /* caller will have checked this but not fixed it */ + mx = my = 0; if (mtmp == u.ustuck) impossible("hiding monster stuck to you (%s)", msg); - if (m_at(mtmp->mx, mtmp->my) == mtmp && hides_under(mtmp->data) && !OBJ_AT(mtmp->mx, mtmp->my)) + if (m_at(mx, my) == mtmp && hides_under(mptr) && !OBJ_AT(mx, my)) impossible("mon hiding under nonexistent obj (%s)", msg); - if (mtmp->data->mlet == S_EEL && !is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz)) + if (mptr->mlet == S_EEL + && !is_pool(mx, my) && !Is_waterlevel(&u.uz)) impossible("eel hiding out of water (%s)", msg); - if (mtmp->mtrapped && (t = t_at(mtmp->mx, mtmp->my)) != 0 + if (ceiling_hider(mptr) + /* normally !accessible would be overridable with passes_walls, + but not for hiding on the ceiling */ + && (!has_ceiling(&u.uz) || !accessible(mx, my))) + impossible("ceiling hider hiding %s (%s)", + !has_ceiling(&u.uz) ? "without ceiling" + : "in solid stone", + msg); + if (mtmp->mtrapped && (t = t_at(mx, my)) != 0 && !(t->ttyp == PIT || t->ttyp == SPIKED_PIT)) impossible("hiding while trapped in a non-pit (%s)", msg); - } + } else if (M_AP_TYPE(mtmp) != M_AP_NOTHING) { + boolean is_mimic = (mptr->mlet == S_MIMIC); + const char *what = (M_AP_TYPE(mtmp) == M_AP_FURNITURE) ? "furniture" + : (M_AP_TYPE(mtmp) == M_AP_MONSTER) ? "a monster" + : (M_AP_TYPE(mtmp) == M_AP_OBJECT) ? "an object" + : "something strange"; + if (Protection_from_shape_changers) + impossible( + "mimic%s concealed as %s despite Prot-from-shape-changers %s", + is_mimic ? "" : "ker", what, msg); + /* pet's quickmimic can take on furniture and object shapes, + but only until the pet finishes eating a mimic corpse */ + if (!(is_mimic || mtmp->meating)) + impossible("non-mimic (%s) posing as %s (%s)", + mptr->mname, what, msg); + if (!(accessible(mx, my) || passes_walls(mptr))) { + char buf[BUFSZ]; + const char *typnam = levltyp_to_name(levl[mx][my].typ); + + if (!typnam) { + Sprintf(buf, "[%d]", levl[mx][my].typ); + typnam = buf; + } + impossible("mimic%s concealed in inaccessible location: %s (%s)", + is_mimic ? "" : "ker", typnam, msg); + } + } } void @@ -3569,11 +3611,19 @@ rescham() } if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) new_were(mtmp); - if (M_AP_TYPE(mtmp) && cansee(mtmp->mx, mtmp->my)) { - seemimic(mtmp); - /* we pretend that the mimic doesn't - know that it has been unmasked */ - mtmp->msleeping = 1; + if (M_AP_TYPE(mtmp) != M_AP_NOTHING) { + /* this used to include a cansee() check but Protection_from_ + _shape_changers shouldn't be trumped by being unseen */ + if (!mtmp->meating) { + /* make revealed mimic fall asleep in lieu of shape change */ + if (M_AP_TYPE(mtmp) != M_AP_MONSTER) + mtmp->msleeping = 1; + seemimic(mtmp); + } else { + /* quickmimic: pet is midst of eating a mimic corpse; + this terminates the meal early */ + finish_meating(mtmp); + } } } } From b9535a84f1d8bfe64ed9bd65065d05dd93a355f7 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Dec 2020 15:46:13 -0800 Subject: [PATCH 658/708] displacing pets into water Don't let hero at water or lava location swap places with a pet that can't survive there. This was a regression to 3.4.3 behavior introduced when displacer beast monster was added. I can't remember whether the regression was intentional at the time, but guess not because I'm fairly sure that I would have included a comment about it. --- doc/fixes37.0 | 4 +++- src/hack.c | 10 ++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 2b498f61e..9b619329b 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.395 $ $NHDT-Date: 1608332750 2020/12/18 23:05:50 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.396 $ $NHDT-Date: 1608335163 2020/12/18 23:46:03 $ General Fixes and Modified Features ----------------------------------- @@ -439,6 +439,8 @@ the checks and handling for fountains, sinks, and drawbridges were being monster movement flags unification allowed displacer beasts to displace Riders a long worm with no visible segments (but one internal segment) might trigger warning: tail 'segement' at <0,some_y>, worm at if teleported +adding displacer beast inadvertently introduced a regression in swapping with + pets, allowing them to be pulled into water by hero on/over water curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/hack.c b/src/hack.c index c8c30d900..5fbc39741 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1605305491 2020/11/13 22:11:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.270 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1608335164 2020/12/18 23:46:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.273 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1889,14 +1889,12 @@ domove_core() /* can't swap places when pet won't fit thru the opening */ You("stop. %s won't fit through.", upstart(y_monnam(mtmp))); didnt_move = TRUE; - } else if ((mtmp->mpeaceful || mtmp->mtame) && mtmp->mtrapped) { - /* Since peaceful monsters simply being unable to move out of traps - * was inconsistent with pets being able to but being untamed in - * the process, apply this logic equally to pets and peacefuls. */ + } else if (mtmp->mpeaceful && mtmp->mtrapped) { + /* all mtame are also mpeaceful, so this affects pets too */ You("stop. %s can't move out of that trap.", upstart(y_monnam(mtmp))); didnt_move = TRUE; - } else if (mtmp->mpeaceful && !mtmp->mtame + } else if (mtmp->mpeaceful && (!goodpos(u.ux0, u.uy0, mtmp, 0) || t_at(u.ux0, u.uy0) != NULL || mundisplaceable(mtmp))) { From 143850e3c9f656466c13e6d42415ebedc29f2ea5 Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 18 Dec 2020 21:01:10 -0500 Subject: [PATCH 659/708] cron daily updates to Files and doc/Guidebook --- Files | 21 +- doc/Guidebook.txt | 3864 ++++++++++++++++++++++----------------------- 2 files changed, 1943 insertions(+), 1942 deletions(-) diff --git a/Files b/Files index ae8411092..7972c7373 100644 --- a/Files +++ b/Files @@ -441,16 +441,17 @@ afterrecover.proj aftertile2bmp.proj aftertilemap.proj afteruudecode.proj build.bat common.props config.props console.props -default.props default_dll.props -default_lib.props dirs.props -dlb.vcxproj dll.props -files.props makedefs.vcxproj -nh340key.def nh340key.vcxproj -nhdefkey.def nhdefkey.vcxproj -nhraykey.def nhraykey.vcxproj -recover.vcxproj tile2bmp.vcxproj -tilemap.vcxproj tiles.vcxproj -travisci.sh uudecode.vcxproj +cpp.hint default.props +default_dll.props default_lib.props +dirs.props dlb.vcxproj +dll.props files.props +makedefs.vcxproj nh340key.def +nh340key.vcxproj nhdefkey.def +nhdefkey.vcxproj nhraykey.def +nhraykey.vcxproj recover.vcxproj +tile2bmp.vcxproj tilemap.vcxproj +tiles.vcxproj travisci.sh +uudecode.vcxproj win/win32/vs/Images: (files for Visual Studio 2017 or 2019 Community Edition builds) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index a7c24bc21..91b1b2f2c 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - December 13, 2020 + December 16, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1060,22 +1060,23 @@ - (In versions prior to 3.6 this was the command to switch - from normal play to "explore mode", also known as "discovery - mode", which has now been moved to "#exploremode".) + (In versions prior to 3.6 this keystroke ran the command to + switch from normal play to "explore mode", also known as + "discovery 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 align- - ment, along with your patron deity and his or her opposi- - tion. It also shows most of the various items of informa- + Displays name, role, race, gender (unless role name makes + that redundant, such as Caveman or Priestess), and align- + ment, along with your patron deity and his or her opposi- + tion. It also shows most of the various items of informa- tion from the status line(s) in a less terse form, including - several additional things which don't appear in the normal + several additional things which don't appear in the normal status display due to space considerations. - In normal play, that's all that `^X' displays. In explore - mode, the role and status feedback is augmented by the in- + In normal play, that's all that `^X' displays. In explore + mode, the role and status feedback is augmented by the in- formation provided by enlightenment magic. z Zap a wand. @@ -1086,7 +1087,7 @@ Z. - to cast at yourself, use `.' for the direction. - ^Z Suspend the game (UNIX(R) versions with job control only). + ^Z Suspend the game (UNIX(R) versions with job control only). See "#suspend" below for more details. : Look at what is here. @@ -1109,14 +1110,13 @@ " Tell what amulet you are wearing. - ( Tell what tools you are using. __________ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1126,6 +1126,8 @@ + ( Tell what tools you are using. + * Tell what equipment you are using. Combines the preceding five type-specific commands into one. @@ -1135,16 +1137,16 @@ + 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 an- - other to swap places with it. Swapping pairs of spells + 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 an- + other to swap places with it. Swapping pairs of spells changes their casting letters, so the change lasts after the - current `+' command finishes. Sorting the whole list is - temporary. To make the most recent sort order persist be- - yond 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 + current `+' command finishes. Sorting the whole list is + temporary. To make the most recent sort order persist be- + yond 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. @@ -1153,36 +1155,34 @@ ! Escape to a shell. See "#shell" below for more details. - Del Show map without obstructions. You can view the explored + Del Show map without obstructions. You can view the explored portion of the current level's map without monsters; without - monsters and objects; or without monsters, objects, and + 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 + 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 + 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 let- + As you can see, the authors of NetHack used up all the let- ters, so this is a way to introduce the less frequently used com- mands. What extended commands are available depends on what fea- tures the game was compiled with. #adjust Adjust inventory letters (most useful when the fixinv option - is "on"). Autocompletes. Default key is `M-a'. - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1192,46 +1192,48 @@ - This command allows you to move an item from one particular - inventory slot to another so that it has a letter which is + 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 particu- lar location when inventory listings are displayed. You can move to a currently empty slot, or if the destination is oc- cupied--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 + 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 letter. - Adjusting without a count used to collect all compatible - stacks when moving to the destination. That behavior has + 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 eligi- - ble. In either case, otherwise compatible stacks with a - different name will not be merged. This contrasts with us- + 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 eligi- + ble. In either case, otherwise compatible stacks with a + different name will not be merged. This contrasts with us- ing "#adjust" to move from one slot to a different slot. In - that situation, moving (no count given) a compatible stack + that situation, moving (no count given) a compatible 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 + 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 current dungeon level. All levels with annotations are dis- - played by the "#overview" command. Autocompletes. Default + played by the "#overview" command. Autocompletes. Default key is `M-A', and also `^N' if number_pad is on. #apply - Apply (use) a tool such as a pick-axe, a key, or a lamp. + Apply (use) a tool such as a pick-axe, a key, or a lamp. Default key is `a'. - If the tool used acts on items on the floor, using the `m' + 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 + If used on a wand, that wand will be broken, releasing its magic in the process. Confirmation is required. #attributes @@ -1241,14 +1243,12 @@ Toggle the autopickup option on/off. Default key is `@'. #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 level (same as "#annotate"). Default key is - `C'. + 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 - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1258,6 +1258,8 @@ + `C'. + #cast Cast a spell. Default key is `Z'. @@ -1268,13 +1270,13 @@ Close a door. Default key is `c'. #conduct - List voluntary challenges you have maintained. Autocom- + List voluntary challenges you have maintained. Autocom- pletes. Default key is `M-C'. See the section below entitled "Conduct" for details. #dip - Dip an object into something. Autocompletes. Default key + Dip an object into something. Autocompletes. Default key is `M-d'. #down @@ -1287,18 +1289,19 @@ Drop specific item types. Default key is `D'. #eat - Eat something. Default key is `e'. The `m' prefix skips + 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 - Enter the explore mode. + Switch from normal play to non-scoring explore mode. De- + fault key is `M-X'. Requires confirmation; default response is n (no). To real- ly switch to explore mode, respond with y. You can set the @@ -1308,13 +1311,10 @@ #fire Fire ammunition from quiver. Default key is `f'. - #force - Force a lock. Autocompletes. Default key is `M-f'. - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1324,6 +1324,9 @@ + #force + Force a lock. Autocompletes. Default key is `M-f'. + #glance Show what type of thing a map symbol corresponds to. De- fault key is `;'. @@ -1333,7 +1336,14 @@ number_pad is on. #herecmdmenu - Show a menu of possible actions in your current location. + Show a menu of possible actions directed at your current lo- + cation. The menu is limited to a subset of the likeliest + actions, not an exhaustive set of all possibilities. Auto- + completes. + + If mouse support is enabled and the herecmd_menu option is + On, clicking on the hero (or steed when mounted) will exe- + cute this command. #history Show long version and game history. Default key is `V'. @@ -1345,15 +1355,15 @@ Inventory specific item types. Default key is `I'. #invoke - Invoke an object's special powers. Autocompletes. Default + Invoke an object's special powers. Autocompletes. Default key is `M-i'. #jump - Jump to another location. Autocompletes. Default key is + 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 + Kick something. Default key is `^D', and `k' if number_pad is on. #known @@ -1365,22 +1375,12 @@ is ``'. #levelchange - Change your experience level. Autocompletes. Debug mode + Change your experience level. Autocompletes. Debug mode only. - #lightsources - Show mobile light sources. Autocompletes. Debug mode only. - - #look - Look at what is here, under you. Default key is `:'. - - #loot - 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 - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1390,24 +1390,34 @@ + #lightsources + Show mobile light sources. Autocompletes. Debug mode only. + + #look + Look at what is here, under you. Default key is `:'. + + #loot + 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 number_pad is on. #monster - Use a monster's special ability (when polymorphed into mon- + Use a monster's special ability (when polymorphed into mon- ster form). Autocompletes. Default key is `M-m'. #name - Name a monster, an individual object, or a type of object. - Same as "#call". Autocompletes. Default keys are `N', `M- + 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 + 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 + 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 al- @@ -1420,33 +1430,23 @@ Show and change option settings. Default key is `O'. #overview - Display information you've discovered about the dungeon. - Any visited level (unless forgotten due to amnesia) with an - annotation is included, and many things (altars, thrones, - fountains, and so on; extra stairs leading to another dun- - geon branch) trigger an automatic annotation. If dungeon + Display information you've discovered about the dungeon. + Any visited level (unless forgotten due to amnesia) with an + annotation is included, and many things (altars, thrones, + fountains, and so on; extra stairs leading to another dun- + geon branch) trigger an automatic annotation. If dungeon overview is chosen during end-of-game disclosure, every vis- - ited level will be included regardless of annotations. Au- + ited level will be included regardless of annotations. Au- tocompletes. Default keys are `^O', and `M-O'. #panic Test the panic routine. Terminates the current game. Auto- completes. Debug mode only. - Asks for confirmation; default is n (no); continue playing. - To really panic, respond with y. You can set the para- - noid_confirmation:quit option to require a response of yes - instead. - - #pay - Pay your shopping bill. Default key is `p'. - - #pickup - Pick up things at the current location. Default key is `,'. - The `m' prefix forces use of a menu. - NetHack 3.7 December 13, 2020 + + NetHack 3.7 December 16, 2020 @@ -1456,63 +1456,63 @@ + Asks for confirmation; default is n (no); continue playing. + To really panic, respond with y. You can set the para- + noid_confirmation:quit option to require a response of yes + instead. + + #pay + Pay your shopping bill. Default key is `p'. + + #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 + 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 re- + Praying too soon after receiving prior help is a bad idea. + (Hint: entering the dungeon alive is treated as having re- ceived 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 + 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 - Show previously displayed game messages. Default key is + Show previously displayed game messages. Default key is `^P'. #puton - Put on an accessory (ring, amulet, etc). Default key is + Put on an accessory (ring, amulet, etc). Default key is `P'. #quaff Quaff (drink) something. Default key is `q'. #quit - Quit the program without saving your game. Autocompletes. + Quit the program without saving your game. Autocompletes. Default key is `M-q'. - Since using this command by accident would throw away the - current game, you are asked to confirm your intent before + 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_con- + really quit, respond with y. You can set the paranoid_con- firmation: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 `r'. - - #redraw - Redraw the screen. Default key is `^R', and also `^L' if - number_pad is on. - - #remove - Remove an accessory (ring, amulet, etc). Default key is - `R'. - - #ride - Ride (or stop riding) a saddled creature. Autocompletes. + Read a scroll, a spellbook, or something else. Default key - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1522,17 +1522,29 @@ + is `r'. + + #redraw + Redraw the screen. Default key is `^R', and also `^L' if + number_pad is on. + + #remove + Remove an accessory (ring, amulet, etc). Default key is + `R'. + + #ride + 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- + Rub a lamp or a stone. Autocompletes. Default key is `M- r'. #save Save the game and exit the program. Default key is `S'. #search - Search for traps and secret doors around you. Default key + Search for traps and secret doors around you. Default key is `s'. #seeall @@ -1554,31 +1566,19 @@ Show the weapon currently wielded. Default key is `)'. #shell - Do a shell escape, switching from NetHack to a subprocess. - Can be disabled at the time the program is built. When en- - abled, access for specific users can be controlled by the - system configuration file. Use the shell command `exit' to + Do a shell escape, switching from NetHack to a subprocess. + Can be disabled at the time the program is built. When en- + abled, access for specific users can be controlled by the + system configuration file. Use the shell command `exit' to return to the game. Default key is `!'. #showgold - Report the gold in your inventory and if you are inside a + Report the gold in your inventory and if you are inside a shop, report any credit or debt you have in that shop. Does - not report on any gold inside containers you're carrying. - Default key is `$'. - - #showspells - List and reorder known spells. Default key is `+'. - - #showtrap - Describe an adjacent trap, possibly covered by objects or a - monster. To be eligible, the trap must already be discov- - ered. (The "#terrain" command can display your map with all - objects and monsters temporarily removed, making it possible - to see all discovered traps.) Default key is `^'. + not report on any gold inside containers you're carrying. - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -1588,19 +1588,31 @@ + Default key is `$'. + + #showspells + List and reorder known spells. Default key is `+'. + + #showtrap + Describe an adjacent trap, possibly covered by objects or a + monster. To be eligible, the trap must already be discov- + ered. (The "#terrain" command can display your map with all + objects and monsters temporarily removed, making it possible + to see all discovered traps.) Default key is `^'. + #sit Sit down. Autocompletes. Default key is `M-s'. #stats - Show memory usage statistics. Autocompletes. Debug mode + 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 + 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 @@ -1616,20 +1628,35 @@ Teleport around the level. Default key is `^T'. #terrain - Show map without obstructions. In normal play you can view + Show map without obstructions. In normal play you can view the explored portion of the current level's map without mon- - sters; without monsters and objects; or without monsters, + sters; without monsters and objects; or without monsters, objects, and traps. - In explore mode, you can choose to view the full map rather + In explore mode, you can choose to view the full map rather than just its explored portion. In debug mode there are ad- ditional choices. - Autocompletes. Default key is `' or `' (see + Autocompletes. Default key is `' or `' (see Del above). #therecmdmenu - Show a menu of possible actions in a location next to you. + Show a menu of possible actions directed at a location next + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 26 + + + + to you. The menu is limited to a subset of the likeliest + actions, not an exhaustive set of all possibilities. Auto- + completes. #throw Throw something. Default key is `t'. @@ -1642,18 +1669,6 @@ Autocompletes. Default key is `M-T'. The `m' prefix makes the command use a menu. - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 26 - - - #travel Travel to a specific location on the map. Default key is `_'. Using the "request menu" prefix shows a menu of inter- @@ -1693,6 +1708,18 @@ dowtype option in your run-time configuration file to select the one you want. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 27 + + + Autocompletes. Default key is `M-v'. #versionshort @@ -1707,19 +1734,6 @@ Rest one move while doing nothing. Default key is `.', and also ` ' if rest_on_space is on. - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 27 - - - #wear Wear a piece of armor. Default key is `W'. @@ -1760,6 +1774,18 @@ #wizintrinsic Set one or more intrinsic attributes. Autocompletes. Debug + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 28 + + + mode only. #wizlevelport @@ -1774,18 +1800,6 @@ Verify rumor boundaries by displaying first and last true rumors and first and last false rumors. - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 28 - - - Also displays first, second, and last random engravings, epitaphs, and hallucinatory monsters. @@ -1822,12 +1836,33 @@ [8th, or "high"] bit), you can invoke many extended commands by meta-ing the first letter of the command. - In Windows, OS/2, PC and ST NetHack, the "Alt" key can be - used in this fashion; on the Amiga, set the altmeta option to get - this behavior. 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+key. + 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 fol- + lowed by the other key, you may set the altmeta option to have + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 29 + + + + NetHack combine them into meta+key. (This combining action only + takes place when NetHack is expecting a command to execute, not + when accepting input to name something 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 low- + er-case equivalent is used for another command, so the three key + combination meta+shift+letter is needed. + M-? #? (not supported by all platforms) @@ -1839,19 +1874,6 @@ M-c #chat - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 29 - - - M-C #conduct M-d #dip @@ -1884,6 +1906,18 @@ M-s #sit + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 30 + + + M-t #turn M-T #tip @@ -1894,6 +1928,8 @@ M-w #wipe + M-X #exploremode + If the number_pad option is on, some additional letter com- @@ -1905,19 +1941,6 @@ k #kick - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 30 - - - l #loot N #name @@ -1950,6 +1973,17 @@ if you are confused or stunned or suffer from the fumbling at- tribute. + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 31 + + + 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 @@ -1972,18 +2006,6 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 31 - - - it. If you accede, success will eliminate the trap but failure will set off the trap's explosion. (If you decline, you effec- tively forget that a trap was found there.) @@ -2015,6 +2037,19 @@ of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 32 + + + 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, usual- @@ -2039,17 +2074,6 @@ send you to a specific destination level but not necessarily to a specific location there. - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 32 - - - 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 @@ -2078,6 +2102,20 @@ that. See the Conduct section for information about getting feedback for your actions in Sokoban. + + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 33 + + + 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase @@ -2104,18 +2142,6 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 33 - - - they're close enough when you travel up or down stairs, and occa- sionally one of these creatures will displace you during the climb. When that occurs, the pet or other monster will arrive on @@ -2144,6 +2170,18 @@ If you drop something in a shop by accident, the shopkeeper will usually claim ownership without offering any compensation. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 34 + + + You'll have to buy it back if you want to reclaim it. Shopkeepers sometime run out of money. When that happens, @@ -2171,17 +2209,6 @@ * A shopkeeper treats the spot immediately inside the door as if it were outside the shop. - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 34 - - - * While the shopkeeper watches you like a hawk, he or she will generally ignore any other customers. @@ -2208,8 +2235,20 @@ ber refers to the count of separate stacks of objects present rather than the sum of the quantities of those stacks (so 7 ar- rows 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 loca- - tion). + 25, respectively, and total to 2 when both are at the same + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 35 + + + + location). The "nopickup" command prefix (default `m') can be used be- fore a movement direction to step on objects without attempting @@ -2235,20 +2274,8 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 35 - - - - objects, in which case the back on land circumstance is implied. + one message too, unless there is feedback about one or more ob- + jects, in which case the back on land circumstance is implied. 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 @@ -2275,6 +2302,18 @@ It is usually displayed differently from other levels: pos- sibly in characters instead of tiles, or without line-drawing + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 36 + + + symbols if already in characters; also, gold is shown as * rather than $ and stairs are shown as % rather than < and >. There are some minor differences in actual game play: doorways lack doors; @@ -2302,18 +2341,6 @@ The extended command "#chat" can be used to interact with an adjacent monster. There is no actual dialog (in other words, you - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 36 - - - don't get to choose what you'll say), but chatting with some mon- sters such as a shopkeeper or the Oracle of Delphi can produce useful results. @@ -2342,6 +2369,17 @@ member a monster but want to try fighting anyway, you can use the `F' command. + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 37 + + + 6.2. Your pet You start the game with a little dog (`d'), kitten (`f'), or @@ -2367,19 +2405,6 @@ pet may trigger such traps itself; you will not be carried along with it even if adjacent at the time. - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 37 - - - 6.3. Steeds Some types of creatures in the dungeon can actually be rid- @@ -2409,6 +2434,18 @@ ers (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 little damage. You can plunder the deceased + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 38 + + + 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 last victory. @@ -2434,18 +2471,6 @@ When you find something in the dungeon, it is common to want to pick it up. In NetHack, this is accomplished automatically by - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 38 - - - walking over the object (unless you turn off the autopickup op- tion (see below), or move with the `m' prefix (see above)), or manually by using the `,' command. @@ -2474,9 +2499,21 @@ When you pick up an object, it is assigned an inventory let- ter. 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 pre- - sented with a list of inventory letters to choose from (see Com- - mands, above). + choose a particular object you are carrying, you are usually + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 39 + + + + presented with a list of inventory letters to choose from (see + Commands, above). Some objects, such as weapons, are easily differentiated. Others, like scrolls and potions, are given descriptions which @@ -2500,18 +2537,6 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 39 - - - item you wear is not removable by ordinary means. In addition, cursed arms and armor usually, but not always, bear negative en- chantments that make them less effective in combat. Other cursed @@ -2541,6 +2566,18 @@ distinguished 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 + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 40 + + + enough other information is displayed. The implicit_uncursed op- tion can be used to control this; toggle it off to have uncursed be displayed even when that can be deduced from other attributes. @@ -2566,18 +2603,6 @@ first wield a bow, then throw the arrow. Crossbows shoot cross- bow bolts. Slings hurl rocks and (other) stones (like gems). - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 40 - - - 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 @@ -2607,6 +2632,18 @@ 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. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 41 + + + There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' com- mand which allows you to unwield the current weapon in addition @@ -2632,18 +2669,6 @@ for a specific target. The distance something can be thrown de- pends mainly on the type of object and your strength. Arrows can be thrown by hand, but can be thrown much farther and will be - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 41 - - - more likely to hit when thrown while you are wielding a bow. You can simplify the throwing operation by using the `Q' @@ -2673,6 +2698,18 @@ ing 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 + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 42 + + + still continue beyond that spot. 7.2.2. Weapon proficiency @@ -2698,18 +2735,6 @@ to advance), "unskilled", "basic", "skilled", and "expert". Re- stricted skills simply will not appear in the list shown by "#en- hance". (Divine intervention might unrestrict a particular - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 42 - - - 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 "grand master". @@ -2739,6 +2764,18 @@ 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 + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 43 + + + weapons at once. The primary is your wielded weapon and the sec- ondary is just an item in your inventory that's been designated as alternate weapon.) @@ -2763,20 +2800,8 @@ When in two-weapon combat mode, using the `X' command tog- gles back to single-weapon mode. Throwing or dropping either of - the weapons or having one of them be stolen or destroyed will - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 43 - - - - also make you revert to single-weapon combat. + the weapons or having one of them be stolen or destroyed will al- + so make you revert to single-weapon combat. 7.3. Armor (`[') @@ -2805,6 +2830,18 @@ 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 + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 44 + + + point improvement to 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. @@ -2829,19 +2866,6 @@ tempt to play the entire game without wearing any armor (a self- imposed challenge which is extremely difficult to accomplish). - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 44 - - - 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 nor- @@ -2871,6 +2895,19 @@ You can name one food item after something you like to eat with the fruit option. + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 45 + + + The command to eat food is `e'. 7.5. Scrolls (`?') @@ -2896,18 +2933,6 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 45 - - - ignored. You can disable the mail daemon by turning off the mail option. @@ -2937,6 +2962,18 @@ When the number of charges left in a wand becomes zero, at- tempts to use the wand will usually result in nothing happening. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 46 + + + Occasionally, 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 @@ -2962,18 +2999,6 @@ Rings are very useful items, since they are relatively per- manent magic, unlike the usually fleeting effects of potions, - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 46 - - - scrolls, and wands. Putting on a ring activates its magic. You can wear at most @@ -3003,6 +3028,18 @@ 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 + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 47 + + + type, or cast it at a time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. @@ -3028,18 +3065,6 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 47 - - - 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 @@ -3068,6 +3093,19 @@ in some cases (again, pick-axe) become wielded as a weapon even when applied. + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 48 + + + 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 challenge which is very difficult to accomplish). @@ -3093,20 +3131,8 @@ 7.11. Amulets (`"') Amulets are very similar to rings, and often more powerful. - Like rings, amulets have various magical properties, some - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 48 - - - - beneficial, some harmful, which are activated by putting them on. + Like rings, amulets have various magical properties, some benefi- + cial, 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, @@ -3132,6 +3158,20 @@ tile weapons (if you have a sling). In the most desperate of cases, you can still throw them by hand. + + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 49 + + + 7.13. Large rocks (``') Statues and boulders are not particularly useful, and are @@ -3160,18 +3200,6 @@ be influenced by the amount of gold you are carrying (shopkeepers aside). - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 49 - - - Gold pieces are the only type of object where bless/curse state does not apply. They're always uncursed but never de- scribed as uncursed even if you turn off the implicit_uncursed @@ -3197,9 +3225,21 @@ er 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 op- - tion can be enabled in order to show an item differently when it - is the top one of a pile. + only the top item of the pile is displayed. The hilite_pile + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 50 + + + + option can be enabled in order to show an item differently when + it is the top one of a pile. 8. Conduct @@ -3226,18 +3266,6 @@ A strict vegan diet is one which avoids any food derived from animals. The primary source of nutrition is fruits and veg- etables. The corpses and tins of blobs (`b'), jellies (`j'), and - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 50 - - - 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- @@ -3264,6 +3292,18 @@ brains while polymorphed into a mind flayer, is considered eating an animal, although wax is only an animal byproduct. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 51 + + + Regardless of conduct, there will be some items which are indigestible, and others which are hazardous to eat. Using a swallow-and-digest attack against a monster is equivalent to eat- @@ -3292,18 +3332,6 @@ 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 - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 51 - - - of item; or fight with your hands and feet. In NetHack, a pacifist refuses to cause the death of any @@ -3330,6 +3358,18 @@ can't be bypassed, such as being unable to push a boulder diago- nally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes you to receive a luck penalty. No + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 52 + + + 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, @@ -3358,18 +3398,6 @@ without an attempt to wish for any items is a challenge, as is a game without wishing for an artifact (even if the artifact imme- diately disappears). When the game offers you an opportunity to - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 52 - - - make a wish for an item, you may choose "nothing" if you want to decline. @@ -3396,6 +3424,18 @@ and found a special item there. Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 53 + + + Medusa - Defeated Medusa. Bell - Acquired the Bell of Opening. Gehennom - Entered Gehennom. @@ -3424,18 +3464,6 @@ There's no guaranteed Novel so the achievement to read one might not always be attainable (except perhaps by wishing). Sim- ilarly, the Big Room level is not always present. Unlike with - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 53 - - - the Novel, there's no way to wish for this opportunity. The "special items" hidden in Mines' End and Sokoban are not @@ -3461,6 +3489,19 @@ NetHack should do things, there are options you can set to change how NetHack behaves. + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 54 + + + 9.1. Setting the options Options may be set in a number of ways. Within the game, @@ -3489,19 +3530,6 @@ figuration file, NetHack will create the configuration file for you using the default template file. - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 54 - - - On MS-DOS, it is "defaults.nh" in the same folder as nethack.exe. @@ -3527,8 +3555,20 @@ OPTIONS There are two types of options, boolean and compound options. - Boolean options toggle a setting on or off, while compound op- - tions take more diverse values. Prefix a boolean option with + Boolean options toggle a setting on or off, while compound + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 55 + + + + 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 per- sistent, and apply only to new games. You can specify multiple @@ -3555,19 +3595,6 @@ The location where saved games are kept. Defaults to HACKDIR, must be writable. - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 55 - - - BONESDIR The location that bones files are kept. Defaults to HACKDIR, must be writable. @@ -3595,6 +3622,18 @@ Set exceptions to the pickup_types option. See the "Configur- ing Autopickup Exceptions" section. + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 56 + + + BINDINGS Change the key bindings of some special keys, menu accelera- tors, or extended commands. You can specify multiple bindings. @@ -3621,20 +3660,8 @@ OPTIONS=!rest_on_space If [] is present, the preceding section is closed and no new - section begins; whatever follows will be common to all - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 56 - - - - sections. Otherwise the last section extends to the end of the + section begins; whatever follows will be common to all sec- + tions. Otherwise the last section extends to the end of the options file. MENUCOLOR @@ -3662,6 +3689,17 @@ dungeon levels except for the special rogue level. See the "Modifying NetHack Symbols" section. + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 57 + + + Example: # replace small punctuation (tick marks) with digits @@ -3681,25 +3719,6 @@ Here is an example of configuration file contents: - - - - - - - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 57 - - - # Set your character's role, race, gender, and alignment. OPTIONS=role:Valkyrie, race:Human, gender:female, align:lawful # @@ -3735,6 +3754,18 @@ % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 58 + + + in csh (note the need to escape the `!' since it's special to that shell), or the pair of commands @@ -3753,20 +3784,8 @@ 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. If it does start with `/', the at-sign is - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 58 - - - - optional. + as a file name. If it does start with `/', the at-sign is op- + tional. 9.4. Customization options @@ -3800,6 +3819,19 @@ Automatically dig if you are wielding a digging tool and moving into a place that can be dug (default false). Persistent. + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 59 + + + autoopen Walking into a closed door attempts to open it (default true). Persistent. @@ -3819,19 +3851,6 @@ command instead. If no weapon is found or the option is false, the `t' (throw) command is executed instead. Persistent. - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 59 - - - autounlock Walking into a locked door or looting a locked container while carrying an unlocking tool (such as a key) will ask whether to @@ -3866,6 +3885,19 @@ Allows looking at things on the screen by navigating the mouse over them and clicking the right mouse button (default off). + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 60 + + + cmdassist Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default @@ -3885,19 +3917,6 @@ sponse of `n' for each candidate). Persistent. The possibili- ties are: - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 60 - - - i - disclose your inventory; a - disclose your attributes; v - summarize monsters that have been vanquished; @@ -3932,29 +3951,10 @@ (for example "disclose:yi na +v -g o") The example sets inven- tory to prompt and default to yes, attributes to prompt and de- - fault to no, vanquished to disclose without prompting, genocid- - ed 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 by traps and each other as well as by you. And the dun- - geon overview shows all levels you had visited but does not re- - veal things about them that you hadn't discovered. - - dogname - 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 - available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit - Enter. It is implemented for the tty interface (default off). + fault to no, vanquished to disclose without prompting, - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -3964,63 +3964,63 @@ + 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 by traps and each other as well as by you. And the dun- + geon overview shows all levels you had visited but does not re- + veal things about them that you hadn't discovered. + + dogname + 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 + available commands. It is keystroke compatible with the tradi- + tional 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 avail- - able commands (on) or just the subset of commands which have + able commands (on) or just the subset of commands which have traditionally been considered extended ones (off). female - An obsolete synonym for "gender:female". Cannot be set with + An obsolete synonym for "gender:female". Cannot be set with the `O' command. fixinv - An object's inventory letter sticks to it when it's dropped - (default on). If this is off, dropping an object shifts all + 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 inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a + 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 - "fruit:mango") (default "slime mold"). Basically a nostalgic - whimsy that NetHack uses from time to time. You should set - this to something you find more appetizing than slime mold. - Apples, oranges, pears, bananas, and melons already exist in + 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 something 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 - specify just the first letter. Although you can still denote + Your starting gender (gender:male or gender:female). You may + specify just the first letter. Although you can still denote your gender using the "male" and "female" options, the "gender" - option will take precedence. The default is to randomly pick - an appropriate gender. If you prefix the value with `!' or - "no", you will exclude that gender from being picked randomly. + option will take precedence. The default is to randomly pick + an appropriate gender. If you prefix the value with `!' or + "no", you will exclude that gender from being picked randomly. 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 de- - fault). Gold is never blessed or cursed, but it is not de- - scribed 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). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the "More info?" prompt, but it also - means that you might miss some interesting and/or important in- - formation. Persistent. - - herecmd_menu - When using a windowport that supports mouse and clicking on - yourself or next to you, show a menu of possible actions for - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4030,63 +4030,63 @@ - the location. Same as "#herecmdmenu" and "#therecmdmenu" com- + 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 de- + fault). Gold is never blessed or cursed, but it is not de- + scribed 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). Turn- + ing help off makes just looking at things faster, since you + aren't interrupted with the "More info?" prompt, but it also + means that you might miss some interesting and/or important in- + formation. Persistent. + + 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. Same as "#herecmdmenu" and "#therecmdmenu" com- mands. hilite_pet - Visually distinguish pets from similar animals (default off). - The behavior of this option depends on the type of windowing + 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 + is often used; with tiles, generally displays a heart symbol near pets. - With the curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option + With the curses interface, the petattr option controls how to + 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 + 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 + 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. Only - available for TTY and Windows GUI, and only when statushilites + Show a hit point bar graph behind your name and title. Only + available for TTY and Windows GUI, and only when statushilites is on. horsename - Name your starting horse (for example "horsename:Trigger"). + Name your starting horse (for example "horsename:Trigger"). Cannot be set with the `O' command. ignintr Ignore interrupt signals, including breaks (default off). Per- sistent. - implicit_uncursed - Omit "uncursed" from object descriptions when it can be deduced - from other aspects of the description (default on). Persis- - tent. - - If you use menu coloring, you may want to turn this off. - - legacy - Display an introductory message when starting the game (default - on). Persistent. - - lit_corridor - Show corridor squares seen by night vision or a light source - held by 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', and `b' (default off). Persistent. - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4096,63 +4096,63 @@ + implicit_uncursed + Omit "uncursed" from object descriptions when it can be deduced + from other aspects of the description (default on). Persis- + tent. + + If you use menu coloring, you may want to turn this off. + + legacy + Display an introductory message when starting the game (default + on). Persistent. + + lit_corridor + Show corridor squares seen by night vision or a light source + held by 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', 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 + 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 de- - scribed when covered by one or more objects (default off). + Give feedback when walking onto various dungeon features such + as stairs, fountains, or altars which are ordinarily only de- + scribed when covered by one or more objects (default off). Persistent. mention_walls - Give feedback when walking against a wall (default off). Per- + Give feedback when walking against a wall (default off). Per- sistent. menucolors - Enable coloring menu lines (default off). See "Configuring + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for 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 + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for 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 interest, but then displays a menu of matching ob- - jects 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. Partial skips the ob- - ject class filtering and immediately displays a menu of all ob- - jects. Persistent. - - menu_deselect_all - Menu character accelerator to deselect all items in a menu. - Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. - - menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- - fault `\'. - - menu_first_page - Menu character accelerator to jump to the first page in a menu. - Implemented by the Amiga, Gem and tty ports. Default `^'. - - menu_headings - Controls how the headings in a menu are highlighted. Values - are "none", "bold", "dim", "underline", "blink", or "inverse". - Not all ports can actually display all types. + jects 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. Partial skips the - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4162,30 +4162,51 @@ + object class filtering and immediately displays a menu of all + objects. Persistent. + + menu_deselect_all + Menu character accelerator to deselect all items in a menu. + Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. + + menu_deselect_page + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- + fault `\'. + + menu_first_page + Menu character accelerator to jump to the first page in a menu. + Implemented by the Amiga, Gem and tty ports. Default `^'. + + menu_headings + Controls how the headings in a menu are highlighted. Values + are "none", "bold", "dim", "underline", "blink", or "inverse". + Not all ports can actually display all types. + menu_invert_all - Menu character accelerator to invert all items in a menu. Im- + Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `@'. menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `~'. menu_last_page - Menu character accelerator to jump to the last page in a menu. + Menu character accelerator to jump to the last page in a menu. Implemented by the Amiga, Gem and tty ports. Default `|'. menu_next_page - Menu character accelerator to goto the next menu page. Imple- + Menu character accelerator to goto the next menu page. Imple- mented by the Amiga, Gem and tty ports. Default `>'. menu_objsyms - Show object symbols in menu headings in menus where the object + Show object symbols in menu headings in menus where the object symbols act as menu accelerators (default off). menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- fault on) menu_previous_page @@ -4193,32 +4214,11 @@ plemented by the Amiga, Gem and tty ports. Default `<'. menu_search - Menu character accelerator to search for a menu item. Imple- + Menu character accelerator to search for a menu item. Imple- mented by the Amiga, Gem, X11 and tty ports. Default `:'. - menu_select_all - Menu character accelerator to select all items in a menu. Im- - plemented by the Amiga, Gem, X11 and tty ports. Default `.'. - menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default - `,'. - - monpolycontrol - Prompt for new form whenever any monster changes shape (default - off). Debug mode only. - - mouse_support - Allow use of the mouse for input and travel. Valid settings - are: - - 0 - disabled - 1 - enabled and make OS adjustments to support mouse use - 2 - like 1 but does not make any OS adjustments - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4228,17 +4228,38 @@ - Omitting a value is the same as specifying 1 and negating - mouse_support is the same as specifying 0. + menu_select_all + Menu character accelerator to select all items in a menu. Im- + plemented by the Amiga, Gem, X11 and tty ports. Default `.'. + + menu_select_page + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default + `,'. + + monpolycontrol + Prompt for new form whenever any monster changes shape (default + off). Debug mode only. + + mouse_support + Allow use of the mouse for input and travel. Valid settings + are: + + 0 - disabled + 1 - enabled and make OS adjustments to support mouse use + 2 - like 1 but does not make any OS adjustments + + Omitting a value is the same as specifying 1 and negating + mouse_support is the same as specifying 0. msghistory - The number of top line messages to keep (and be able to recall + 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. - Currently it is only supported for tty (all four choices) and - for curses (`f' and `r' choices, default `r'). The possible + Allows you to change the way recalled messages are displayed. + Currently 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); @@ -4246,45 +4267,24 @@ 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 + For backward compatibility, no value needs to be specified + (which defaults to "full"), or it can be negated (which defaults to "single"). 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 + 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. Cannot + -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. 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 this with the `O' command. - - nudist - Start the character with no armor (default false). Persistent. - - null - Send padding nulls to the terminal (default on). Persistent. - - number_pad - Use digit keys instead of letters to move (default 0 or off). - Valid settings are: - - 0 - move by letters; "yuhjklbn" - 1 - move by numbers; digit `5' acts as `G' movement prefix - 2 - like 1 but `5' works as `g' prefix instead of as `G' - 3 - by numbers using phone key layout; 123 above, 789 below - 4 - combines 3 with 2; phone layout plus MS-DOS compatibility - -1 - by letters but use `z' to go northwest, `y' to zap wands - - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4294,63 +4294,63 @@ - 0. (Settings 2 and 4 are for compatibility with MS-DOS or old + setting this with the `O' command. + + nudist + Start the character with no armor (default false). Persistent. + + null + Send padding nulls to the terminal (default on). Persistent. + + number_pad + Use digit keys instead of letters to move (default 0 or off). + Valid settings are: + + 0 - move by letters; "yuhjklbn" + 1 - move by numbers; digit `5' acts as `G' movement prefix + 2 - like 1 but `5' works as `g' prefix instead of as `G' + 3 - by numbers using phone key layout; 123 above, 789 below + 4 - combines 3 with 2; phone layout plus MS-DOS compatibility + -1 - by letters but use `z' to go northwest, `y' to zap wands + + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 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 accommo- - date some QWERTZ keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a + date some QWERTZ keyboards 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' + 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 containing the symbols for the various object types. Any omit- ted 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_confirma- + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma- tion:pray. - Confirm - for any prompts which are set to require "yes" - rather than `y', also require "no" to reject in- + Confirm - for any prompts which are set to require "yes" + rather than `y', also require "no" to reject in- stead of accepting any non-yes response as no quit - require "yes" rather than `y' to confirm quitting - the game or switching into non-scoring explore + the game or switching into non-scoring explore mode; - die - require "yes" rather than `y' to confirm dying - (not useful in normal play; applies to explore + 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 - require "yes" rather than `y' to confirm saving bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attack- + attack - require "yes" rather than `y' to confirm attack- ing a peaceful monster; - wand-break - require "yes" rather than `y' to confirm breaking - a wand; - 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; - Remove - require selection from inventory for `R' and `T' - commands even when wearing just one applicable - item. - all - turn on all of the above. - - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use - "paranoid_confirmation:none". To keep it enabled while setting - any of the others, include it in the list, such as "para- - noid_confirmation:attack pray Remove". - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4360,14 +4360,34 @@ + wand-break - require "yes" rather than `y' to confirm breaking + a wand; + 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; + Remove - require selection from inventory for `R' and `T' + commands even when wearing just one applicable + item. + all - turn on all of the above. + + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use + "paranoid_confirmation:none". To keep it enabled while setting + any of the others, include it in the list, such as "para- + noid_confirmation:attack pray Remove". + perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. petattr - Specifies one or more text highlighting attributes to use when - showing pets on the map. Effectively a superset of the + Specifies one or more text highlighting attributes to use when + showing pets on the map. Effectively a superset of the hilite_pet boolean option. Curses interface only; value is one or more of the following letters. @@ -4381,42 +4401,22 @@ l - Left line indicator r - Right line indicator - Some of those choices might not work, particularly the final - three, depending upon terminal hardware or terminal emulation + Some of those choices might not work, particularly the final + three, depending upon terminal hardware or terminal emulation software. - Currently multiple highlight-style letters can be combined by - simply stringing them together (for example, "bk"), but in the - future they might require being separated by plus signs (such - as "b+k", which works already). When using the `n' choice, it - should be specified on its own, not in combination with any of + Currently multiple highlight-style letters can be combined by + simply stringing them together (for example, "bk"), but in the + future they might require being separated by plus signs (such + as "b+k", which works already). When using the `n' choice, it + should be specified on its own, not in combination with any of the other letters. 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". If the choice is not allowed for the role - you are currently playing, it will be silently ignored. For - example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. - (Default `S'). Persistent. - - 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 an autopickup exception. Default is on. Persistent. - - pickup_types - Specify the object types to be picked up when autopickup is on. + Specify the type of your initial pet, if you are playing a - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4426,63 +4426,63 @@ + 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". If the choice is not allowed for the role + you are currently playing, it will be silently ignored. For + example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. + (Default `S'). Persistent. + + 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 an autopickup exception. Default is on. Persistent. + + pickup_types + Specify the object types to be picked up when autopickup is on. Default is all types. You can use autopickup_exception config- uration file lines to further refine autopickup behavior. Per- sistent. 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 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. + 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 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. playmode - Values are "normal", "explore", or "debug". Allows selection - of explore mode (also known as discovery mode) or debug mode + 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 + 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 it when not allowed or not possible re- + entirely. Requesting it when not allowed or not possible re- sults in explore mode instead. Default is normal play. pushweapon - Using the `w' (wield) command when already wielding something - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the + Using the `w' (wield) command when already wielding something + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the applied item to become wielded. Persistent. quick_farsight - When set, usually prevents the "you sense your surroundings" - message where play pauses to allow you to browse the map when- + When set, usually prevents the "you sense your surroundings" + message where play pauses to allow you to browse the map when- ever clairvoyance randomly activates. Some situations, such as - being underwater or engulfed, ignore this option. It does not - affect the clairvoyance spell where pausing to examine revealed - objects or monsters is less intrusive. Default is off. Per- - sistent. - - race - Selects your race (for example, "race:human"). Default is ran- - dom. If you prefix the value with `!' or "no", you will ex- - clude that race from being picked randomly. Cannot be set with - the `O' command. Persistent. - - rest_on_space - Make the space bar a synonym for the `.' (#wait) command (de- - fault off). Persistent. - - role - Pick your type of character (for example "role:Samurai"); syn- - onym for "character". See "name" for an alternate method of - specifying your role. Normally only the first letter of the - value is examined; `r' is an exception with "Rogue", "Ranger", - and "random" values. If you prefix the value with `!' or "no", + being underwater or engulfed, ignore this option. It does not - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4492,23 +4492,43 @@ - you will exclude that role from being picked randomly. Cannot + affect the clairvoyance spell where pausing to examine revealed + objects or monsters is less intrusive. Default is off. Per- + sistent. + + race + Selects your race (for example, "race:human"). Default is ran- + dom. If you prefix the value with `!' or "no", you will ex- + clude that race from being picked randomly. Cannot be set with + the `O' command. Persistent. + + rest_on_space + Make the space bar a synonym for the `.' (#wait) command (de- + fault off). Persistent. + + role + Pick your type of character (for example "role:Samurai"); syn- + onym for "character". See "name" for an alternate method of + specifying your role. Normally only the first letter of the + value is examined; `r' is an exception with "Rogue", "Ranger", + and "random" values. If you prefix the value with `!' or "no", + you will exclude that role from being picked randomly. Cannot be set with the `O' command. Persistent. roguesymset - This option may be used to select one of the named symbol sets - found within "symbols" to alter the symbols displayed on the + This option may be used to select one of the named symbol sets + found within "symbols" to alter the symbols displayed on the screen on the rogue level. rlecomp When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has + 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 - control+direction and so forth, or via the travel command or + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -4517,38 +4537,18 @@ crawl - like walk, but pause briefly after each step. This option only affects the game's screen display, not the ac- - tual results of moving. The default is "run"; versions prior - to 3.4.1 used "teleport" only. Whether or not the effect is + tual 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. Persistent. safe_pet - Prevent you from (knowingly) attacking your pets (default on). + Prevent you from (knowingly) attacking your pets (default on). Persistent. - safe_wait - Prevents you from waiting or searching when next to a hostile - monster (default on). Persistent. - - sanity_check - 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. Persistent. - - showexp - Show your accumulated experience points on bottom line (default - off). Persistent. - - showrace - Display yourself as the glyph for your race, rather than the - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4558,8 +4558,28 @@ - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game + safe_wait + Prevents you from waiting or searching when next to a hostile + monster (default on). Persistent. + + sanity_check + 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. Persistent. + + showexp + 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 af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4571,50 +4591,30 @@ sortloot Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible + 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, + 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. sortpack - Sort the pack contents by type when displaying inventory (de- + Sort the pack contents by type when displaying inventory (de- fault on). Persistent. sparkle Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- + hit by an attack to which it is resistant (default on). Per- sistent. standout Boldface monsters and "--More--" (default off). Persistent. - statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. - See "Configuring Status Hilites" for further information. - - status_updates - 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 versions (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 "symset:default" to explicitly select the default - symbols. - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4624,14 +4624,34 @@ + statushilites + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. + See "Configuring Status Hilites" for further information. + + status_updates + 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 versions (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 "symset:default" to explicitly select the default + symbols. + time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface + When pausing momentarily for display effect, such as with ex- + plosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface only; "X11" interface always uses a timer based delay. The de- fault is on if configured into the program.) Persistent. @@ -4641,26 +4661,39 @@ toptenwin Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around after game end on a terminal or emulating window. travel Allow the travel command via mouse click (default on). Turning this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map win- - dow. Does not affect traveling via the `_' ("#travel") com- + ed moves if you make inadvertent mouse clicks on the map win- + dow. Does not affect traveling via the `_' ("#travel") com- mand. Persistent. verbose - Provide more commentary during the game (default on). Persis- + Provide more commentary during the game (default on). Persis- tent. + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 72 + + + whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -4677,76 +4710,43 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 72 - - - - possible targets. + through next and previous targets, allows filtering the possi- + ble 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 + 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 + Filtering can also be changed when getting a location with the "getpos.filter" key. whatis_menu - When getting a location on the map, and using a key to cycle + 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. (default off) whatis_moveskip - When getting a location on the map, and using shifted movement + 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 de- + select which one to use, such as "tty" or "X11" (default de- pends 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 op- - tions. 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 option in the list. - - wizweight - 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 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 can safely add any of these options to your - configuration file, and if the window port is capable of adjust- - ing to suit your preferences, it will attempt to do so. If it + When used, it should be the first option set since its value + might enable or disable the availability of various other op- + tions. For multiple lines in a configuration file, that would + be the first non-comment line. For a comma-separated list in - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4756,25 +4756,46 @@ - 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 + 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 + 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 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 can safely add any of these options to your + configuration file, and if the window port is capable of adjust- + ing 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. Some options - are dynamic and can be specified during the game with the `O' + 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, + 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, + 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 charac- - ters (letters and punctuation) rather than tiles graphics. In - some cases, characters can be augmented with line-drawing sym- - bols; use the symset option to select a symbol set such as + If NetHack can, it should display the map using simple charac- + ters (letters and punctuation) rather than tiles graphics. In + some cases, characters can be augmented with line-drawing sym- + bols; use the symset option to select a symbol set such as DECgraphics or IBMgraphics if your display supports them. Set- ting ascii_map to True forces tiled_map to be False. @@ -4783,16 +4804,28 @@ monsters, objects, and dungeon features. eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to your terminal (default off). font_map if NetHack can, it should use a font by the chosen name for the + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 74 + + + map window. font_menu - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -4804,81 +4837,48 @@ status window. font_text - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for text windows. font_size_map - If NetHack can, it should use this size font for the map win- + If NetHack can, it should use this size font for the map win- dow. - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 74 - - - 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 + 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 + 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. fullscreen - If NetHack can, it should try and display on the entire screen + If NetHack can, it should try and display on the entire screen rather than in a window. guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- terface only; default is on. large_font If NetHack can, it should use a large font. map_mode - If NetHack can, it should display the map in the manner speci- + If NetHack can, it should display the map in the manner speci- fied. player_selection - 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 exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more - memory. (default on). Cannot be set with the `O' command. - - scroll_amount - If NetHack can, it should scroll the display by this number of - cells when the hero reaches the scroll_margin. - - scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- - dow. + If NetHack can, it should pop up dialog boxes, or use prompts - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4888,13 +4888,34 @@ + 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 exam- + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more + memory. (default on). Cannot be set with the `O' command. + + scroll_amount + If NetHack can, it should scroll the display by this number of + cells when the hero reaches the scroll_margin. + + scroll_margin + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- + dow. + selectsaved - If NetHack can, it should display a menu of existing saved + If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. softkeyboard - Display an onscreen keyboard. Handhelds are most likely to + Display an onscreen keyboard. Handhelds are most likely to support this option. splash_screen @@ -4902,49 +4923,28 @@ it starts up (default yes). statuslines - Number of lines for traditional below-the-map status display. + Number of lines for traditional below-the-map status display. Acceptable values are 2 and 3 (default is 2). - For 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 + For 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 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 + 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 uses the statuslines value differently. A value of 3 ren- - ders status in the Qt interface's original format, with the + The Qt interface already displays more than 3 lines for status + so uses the statuslines value differently. A value of 3 ren- + ders 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, reducing the height needed. For Qt, - statuslines can only be set in the configuration file or via - NETHACKOPTIONS, not 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 spec- - ified 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 - default. - - tile_height - Specify the preferred height of each tile in a tile capable - port. - - tile_width - Specify the preferred width of each tile in a tile capable port + eliminate one whole line, reducing the height needed. For Qt, + statuslines can only be set in the configuration file or via - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -4954,63 +4954,63 @@ + NETHACKOPTIONS, not 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 spec- + ified 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 + default. + + tile_height + Specify the preferred height of each tile in a tile capable + port. + + tile_width + 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, possi- - bly augmented by line-drawing symbols). Setting tiled_map to + If NetHack can, it should display the map using tiles graphics + rather than simple characters (letters and punctuation, possi- + bly 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). use_inverse - If NetHack can, it should display inverse when the game speci- + If NetHack can, it should display inverse when the game speci- fies it. vary_msgcount - If NetHack can, it should display this number of messages at a + 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 in- + Whether to draw boxes around the map, status area, message + area, and persistent inventory window if enabled. Curses in- terface only. Acceptable values are 0 - off, never show borders 1 - on, always show borders 2 - auto, on if display is at least (24+2)x(80+2) (default) - (The 26x82 size threshold for `2' refers to number of rows and - columns of the display. A width of at least 110 columns + (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 for align_status set to left or right.) windowcolors - If NetHack can, it should display windows with the specified + If NetHack can, it should display windows with the specified foreground/background colors. Windows GUI only. The format is - OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- - text). - - wraptext - If NetHack can, it should wrap long lines of text if they don't - fit in the visible area of the window. - - - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5020,14 +5020,32 @@ + OPTION=windowcolors:wintype foreground/background + + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- + text). + + 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. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without the .dll extension and without any path information. Cannot be set with the `O' command. @@ -5037,25 +5055,37 @@ altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 78 + + + flush (default off, Amiga NetHack only). @@ -5066,83 +5096,53 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 78 - - - + (Win32 tty NetHack only). May be used to alter the value of keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assign- - ments in the configuration file if needed. Cannot be set with + ments in the configuration file if needed. Cannot be set with the `O' command. video Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause + tect", "default", "vga", or "vesa". Setting "vesa" will cause the game to display tiles, using the full capability of the VGA - hardware. Setting "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 of those modes works. Cannot be set + hardware. Setting "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 of those modes works. Cannot be set with the `O' command. video_height - Set the VGA mode resolution height (MS-DOS only, with + Set the VGA mode resolution height (MS-DOS only, with video:vesa) video_width - Set the VGA mode resolution width (MS-DOS only, with + 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 bright.cyan. Cannot be set with the `O' + 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 (de- - fault dark normal light, PC NetHack only). If the game display - is difficult to read, try adjusting these scales; if this does - not correct the problem, try !color. Cannot be set with the - `O' command. - - 9.7. Regular Expressions - - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- - terns. This applies to Autopickup exceptions, Message types, Menu - colors, and User sounds. + Set the intensity level of the three gray scales available - - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5152,34 +5152,49 @@ + (default dark normal light, PC NetHack only). If the game dis- + play is difficult to read, try adjusting these scales; if this + does not correct the problem, try !color. Cannot be set with + the `O' command. + + 9.7. Regular Expressions + + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- + terns. This applies to Autopickup exceptions, Message types, Menu + colors, and User sounds. + 9.8. Configuring Autopickup Exceptions 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 + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as a pattern to match against the singular form of + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as 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 oc- + In addition, some characters are treated specially if they oc- cur 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 + 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 save and then restore your game. autopickup_ex- + 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 save and then restore your game. autopickup_ex- ception rules and not saved with the game. Here are some examples: @@ -5188,27 +5203,12 @@ autopickup_exception=">*corpse" autopickup_exception=">* cursed*" - 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 ex- - clusion of items known to be cursed from autopickup. - - 9.9. 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"), or a three-digit decimal ASCII code. - - For example: + 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 - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5218,30 +5218,43 @@ + exclusion of items known to be cursed from autopickup. + + 9.9. 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"), or a three-digit decimal ASCII code. + + For example: + BIND=^X:getpos.autodescribe BIND={:menu_first_page BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a key by using "nothing" as the extended command to bind - to. You can also bind the "", "", and "" + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- + The menu control or accelerator keys can also be rebound via + OPTIONS lines in the configuration file. You cannot bind ob- ject symbols into menu accelerators. 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 "context", and if bound to same keys, only one of those - commands will be available. Special command can only be bound + 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 "context", 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 + Prefix key to start a count, to repeat a command this many times. With number_pad only. Default is `n'. doinv @@ -5251,30 +5264,17 @@ Prefix key to force fight a direction. Default is `F'. fight.numpad - Prefix key to force fight a direction. With number_pad only. + Prefix key to force fight a direction. With number_pad only. Default is `-'. getdir.help - When asked for a direction, the key to show the help. Default + When asked for a direction, the key to show the help. Default is `?'. - getdir.self - When asked for a direction, the key to target yourself. De- - fault is `.'. - - getdir.self2 - When asked for a direction, the key to target yourself. De- - fault is `s'. - - getpos.autodescribe - When asked for a location, the key to toggle autodescribe. De- - fault is `#'. - - getpos.all.next - When asked for a location, the key to go to next closest - NetHack 3.7 December 13, 2020 + + NetHack 3.7 December 16, 2020 @@ -5284,63 +5284,63 @@ - interesting thing. Default is `a'. + getdir.self + When asked for a direction, the key to target yourself. De- + fault is `.'. + + getdir.self2 + When asked for a direction, the key to target yourself. De- + fault is `s'. + + getpos.autodescribe + When asked for a location, the key to toggle autodescribe. De- + fault is `#'. + + getpos.all.next + When asked for a location, the key to go to next closest inter- + esting thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest interesting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door + When asked for a location, the key to go to next closest door or doorway. Default is `d'. getpos.door.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest door or doorway. Default is `D'. getpos.help - When asked for a location, the key to show help. Default is + 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 mon- + When asked for a location, the key to go to next closest mon- ster. Default is `m'. getpos.mon.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest monster. Default is `M'. getpos.obj.next - When asked for a location, the key to go to next closest ob- + When asked for a location, the key to go to next closest ob- ject. Default is `o'. getpos.obj.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest object. Default is `O'. getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- stead. 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 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. Default is `"'. - - getpos.pick - When asked for a location, the key to choose the location, and - possibly ask for more info. Default is `.'. - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5350,17 +5350,32 @@ - getpos.pick.once + 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 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. Default is `"'. + + getpos.pick When asked for a location, the key to choose the location, and + possibly ask for more info. Default is `.'. + + getpos.pick.once + When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. getpos.pick.quick When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- + asking for more info, and exit the location asking loop. De- fault is `;'. getpos.pick.verbose - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and show more info without asking. Default is `:'. getpos.self @@ -5368,45 +5383,30 @@ fault is `@'. getpos.unexplored.next - When asked for a location, the key to go to next closest unex- + When asked for a location, the key to go to next closest unex- plored location. Default is `x'. getpos.unexplored.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest unexplored location. Default is `X'. getpos.valid - When asked for a location, the key to go to show valid target + When asked for a location, the key to go to show valid target locations. Default is `$'. getpos.valid.next - When asked for a location, the key to go to next closest valid + When asked for a location, the key to go to next closest valid location. Default is `z'. getpos.valid.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest valid location. Default is `Z'. nopickup Prefix key to move without picking up items. Default is `m'. - redraw - Key to redraw the screen. Default is `^R'. - redraw.numpad - Key to redraw the screen. With number_pad only. Default is - `^L'. - - repeat - Key to repeat previous command. Default is `^A'. - - reqmenu - Prefix key to request menu from some commands. Default is `m'. - - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5416,17 +5416,30 @@ + redraw + Key to redraw the screen. Default is `^R'. + + redraw.numpad + Key to redraw the screen. With number_pad only. Default is + `^L'. + + repeat + Key to repeat previous command. Default is `^A'. + + reqmenu + Prefix key to request menu from some commands. Default is `m'. + run Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad Prefix key to run towards a direction. With number_pad only. - Default is `5' when number_pad is set to 1 or 3, otherwise + Default is `5' when number_pad is set to 1 or 3, otherwise `M-5' when it is set to 2 or 4. rush @@ -5435,7 +5448,7 @@ rush.numpad Prefix key to rush towards a direction. With number_pad only. - Default is `M-5' when number_pad is set to 1 or 3, otherwise + Default is `M-5' when number_pad is set to 1 or 3, otherwise `5' when it is set to 2 or 4. 9.10. Configuring Message Types @@ -5443,7 +5456,7 @@ 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 + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5456,23 +5469,10 @@ 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 mes- - sage is shown in between. - - 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 displaced ." is not shown at all. + norep - show the message once, but not again if no other - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5482,63 +5482,63 @@ - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + message is shown in between. + + 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 displaced ." is not shown at all. + + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when 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 + 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 pat- + color - the color to use for lines matching the pat- tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if left out, you must also leave out the preced- - ing ampersand. If no attribute is defined, + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- - genta, light-cyan, and white. And no-color, the default fore- - ground color, which isn't necessarily the same as any of the + Allowed colors are black, red, green, brown, blue, magenta, + cyan, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the other colors. - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the platform used may interpret the attributes any way it wants. - Here's an example of menu colors using NetHack's internal pat- + Here's an example of menu colors using NetHack's internal pat- tern 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 be shown in green color, lines with " cursed " will be - shown in red, and lines with " cursed " followed by "(being - worn)" on the same line will be shown in red color and under- - lined. You can have multiple MENUCOLOR entries in your config- - uration file, and the last MENUCOLOR line that matches a menu - line will be used for the line. - Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- - plicit_uncursed option off so that all items known to be uncursed - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5548,33 +5548,44 @@ + 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 line will be shown in red + color and underlined. You can have multiple MENUCOLOR en- + tries in your configuration file, and the last MENUCOLOR + line that matches a menu line will be used for the line. + + Note that if you intend to have one or more color specifica- + tions match " uncursed ", you will probably want to turn the im- + plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message 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 + The following configuration file entries are relevant to mapping user sounds to messages: SOUNDDIR The directory that houses the sound files to be played. SOUND - An entry that maps a sound file to a user-specified message - pattern. Each SOUND entry is broken down into the following + 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 3.6); pattern - the pattern to match; sound file - the sound file to play; - volume - the volume to be set while playing the sound + volume - the volume to be set while playing the sound file; - sound index - optional; the index corresponding to a sound + sound index - optional; the index corresponding to a sound file. The pattern should be a POSIX extended regular expression. @@ -5582,7 +5593,7 @@ 9.13. 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 + "Status Hilites". If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. @@ -5590,21 +5601,10 @@ 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 hitpoints 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- - color&normal for >30%.) - - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and - green if it rises: - NetHack 3.7 December 13, 2020 + + NetHack 3.7 December 16, 2020 @@ -5614,34 +5614,47 @@ + For example, the following line in your configuration file + will cause the hitpoints field to display in the color red if + your hitpoints 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- + color&normal for >30%.) + + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground 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, blink, - and inverse. "Normal" is a synonym for "none"; they should not + Allowed attributes are none, bold, dim, underline, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5652,25 +5665,12 @@ 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 condition- - ally displayed depending upon your other option settings. - - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- - nor_troubles" for blind through hallu, "movement" for lev, fly, - and ride, and "all" for every condition. - - Allowed behaviors are "always", "up", "down", "changed", a per- - centage or absolute number threshold, or text to match against. + 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 - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5680,63 +5680,63 @@ + polymorphed. "experience", "time", and "score" are condition- + ally displayed depending upon your other option settings. + + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- + nor_troubles" for blind through hallu, "movement" for lev, fly, + and ride, and "all" for every condition. + + Allowed behaviors are "always", "up", "down", "changed", a per- + centage or absolute number threshold, or text to match against. + * "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 + * "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 val- - ue 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 val- + ue 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 val- ue, 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 be- - tween 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 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 corresponding maxi- - mum field. Percentage highlight rules are also allowed + * percentage sets the field attribute when the field value + matches the percentage. It is specified as a number be- + tween 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 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 corresponding maxi- + mum 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 ex- perience level to the start of the next level. So if lev- - el 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 + el 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 + a rule for =100% is allowed and matches the special case of being exactly 1 experience point short of the next lev- el. - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only - match when strictly above or below. - - * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". 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 - syntax for a configuration file. - - The whole feature can be disabled by setting option sta- - tushilites to 0. + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -5746,6 +5746,20 @@ + match when strictly above or below. + + * text match sets the attribute when the field value matches + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + syntax for a configuration file. + + The whole feature can be disabled by setting option sta- + tushilites to 0. + Example hilites: OPTION=hilite_status: gold/up/yellow/down/brown @@ -5763,28 +5777,41 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols Symbol Name Description ----------------------------------------------------------------- + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 89 + + + S_air (air) _ S_altar (altar) " S_amulet (amulet) @@ -5799,19 +5826,6 @@ B S_bat (bat or bird) ^ S_bear_trap (bear trap) - S_blcorn (bottom left corner) - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 89 - - - b S_blob (blob) + S_book (spellbook) ) S_boomleft (boomerang open left) @@ -5851,6 +5865,19 @@ ! S_flashbeam (flash beam) % S_food (piece of food) { S_fountain (fountain) + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 90 + + + F S_fungus (fungus or mold) * S_gem (gem or rock) S_ghost (ghost) @@ -5865,19 +5892,6 @@ . S_hodbridge (horizontal lowered drawbridge) | S_hodoor (open door in horizontal wall) ^ S_hole (hole) - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 90 - - - @ S_human (human or elf) h S_humanoid (humanoid) - S_hwall (horizontal wall) @@ -5917,6 +5931,19 @@ q S_quadruped (quadruped) Q S_quantmech (quantum mechanic) = S_ring (ring) + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 91 + + + ` S_rock (boulder or statue) r S_rodent (rodent) ^ S_rolling_boulder_trap (rolling boulder trap) @@ -5931,19 +5958,6 @@ s S_spider (arachnid or centipede) ^ S_spiked_pit (spiked pit) ^ S_squeaky_board (squeaky board) - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 91 - - - 0 S_ss1 (magic shield 1 of 4) # S_ss2 (magic shield 2 of 4) @ S_ss3 (magic shield 3 of 4) @@ -5983,6 +5997,19 @@ + S_vcdoor (closed door in vertical wall) . S_venom (splash of venom) ^ S_vibrating_square (vibrating square) + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 92 + + + . S_vodbridge (vertical lowered drawbridge) - S_vodoor (open door in vertical wall) v S_vortex (vortex) @@ -5997,19 +6024,6 @@ x S_xan (xan or other extraordinary insect) X S_xorn (xorn) Y S_yeti (apelike creature) - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 92 - - - Z S_zombie (zombie) z S_zruty (zruty) S_pet_override (any pet if ACCESSIBILITY=1 is set) @@ -6018,55 +6032,41 @@ Notes: * 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 en- + space character, except for S_pet_override and S_hero_override + which don't have any default value and can only be used if en- abled 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 de- - pict. So S_rock is only used for boulders and not used at all + * 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 de- + pict. So S_rock is only used for boulders and not used at all if overridden by the more specific S_boulder. 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. 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 charac- + NetHack can be set up to use only standard ASCII characters + for making maps of the dungeons. This makes the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- ter 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 + 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 location of items on the screen. - 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 message 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 environment variable NETHACK_MSGHANDLER - to an executable, which will be executed with the game message as - the program's only parameter. - - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task - somewhat daunting. Included within the "symbols" file of all of- - ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have + NetHack can also be compiled with support for sending the + game messages to an external program, such as a text-to-speech - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6076,22 +6076,36 @@ - gained some experience with the game and with editing files, you + synthesizer. If the "#version" extended command shows "external + program as a message 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 environment variable NETHACK_MSGHANDLER + to an executable, which will be executed with the game message as + the program's only parameter. + + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task + somewhat daunting. Included within the "symbols" file of all of- + ficial distributions of NetHack is a symset called NHAccess. Se- + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- abled in the sysconf file. - The most crucial settings to make the game more accessible + The most crucial settings to make the game more accessible are: symset:NHAccess Load a symbol set appropriate for use by blind players. roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for + Load a symbol set for the rogue level that is appropriate for use by blind players. menustyle:traditional @@ -6101,38 +6115,24 @@ 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 + 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. autodescribe - Automatically describe the terrain under the cursor when tar- + Automatically describe the terrain under the cursor when tar- geting. mention_walls - Give feedback messages when walking towards a wall or when + 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 + When targeting with cursor, describe the cursor position with coordinates relative to your character. - whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are - considered. - whatis_moveskip - When targeting with cursor and using fast-move, skip the same - glyphs 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 in- - formation can be seen via the "#attributes" command. - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6142,18 +6142,32 @@ + whatis_filter:area + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are + considered. + + whatis_moveskip + When targeting with cursor and using fast-move, skip the same + glyphs 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 in- + formation can be seen via the "#attributes" command. + 9.16. Global Configuration for System Administrators - If NetHack is compiled with the SYSCF option, a system ad- - ministrator should set up a global configuration; this is a file + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 + same directory as the other NetHack support files. The options recognized in this file are listed below. Any option not set us- - es a compiled-in default (which may not be appropriate for your + es a compiled-in default (which may not be appropriate for your system). - WIZARDS = A space-separated list of user names who are allowed + 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. @@ -6161,44 +6175,30 @@ SHELLERS = A list of users who are allowed to use the shell es- cape command (!). The syntax is the same as WIZARDS. - EXPLORERS = A list of users who are allowed to use the explore + EXPLORERS = A list of users who are allowed to use the explore mode. The syntax is the same as WIZARDS. MAXPLAYERS = Limit the maximum number of games that can be run- ning at the same time. SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the save file content in ascii text. - BONESFORMAT = A list of up to two bones file formats separated + BONESFORMAT = A list of up to two bones file formats separated by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in + read. The second format will be read only if no bones files in the first format exist. Valid choices are "historical" for bi- nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the + each field in little-endian order, "ascii" for writing the bones file content in ascii text. - SUPPORT = A string explaining how to get local support (no de- - fault value). - 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 - option. When disabled, incubi and succubi behave like nymphs. - - CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- - ARDS, and SHELLERS check for the player name instead of the us- - er's login name. - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6208,9 +6208,22 @@ + SUPPORT = A string explaining how to get local support (no de- + fault value). + + 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 + option. When disabled, incubi and succubi behave like nymphs. + + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- + ARDS, and SHELLERS check for the player name instead of the us- + er's login name. + 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6219,26 +6232,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6249,22 +6262,9 @@ %T - current time, UNIX timestamp format %d - game start time, YYYYMMDDhhmmss format %D - current time, YYYYMMDDhhmmss format - %n - player name - %N - first character of player name - - 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 is compiled. - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6274,63 +6274,63 @@ - Your score is chiefly based upon how much experience you + %n - player name + %N - first character of player name + + 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 is compiled. + + 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 + 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 all your gold, but if + 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 + 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 + 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 paltry cost of not getting on the high score + "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 game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - other benefits of explore mode are left for the trepid reader to + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to discover. 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 + 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 pro- - vide god-like powers 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 par- - ticular 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. + vide god-like powers 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 - - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6340,63 +6340,63 @@ + switch or with the playmode:debug option. + + For some systems, the player must be logged in under a par- + ticular 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. + 12. Credits - 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 + 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 Dungeons of Doom, by Ken Arromdee. NetHack is the product of literally scores of people's work. - Main events in the course of the game development are described + Main events in the course of the game development are described below: - Jay Fenlason wrote the original Hack, with help from Kenny + Jay Fenlason wrote the original Hack, with help from Kenny Woodland, Mike Thome, and Jon Payne. - Andries Brouwer did a major re-write while at Stichting + Andries Brouwer did a major re-write while at Stichting Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming Hack into a very different game. He published the Hack - source code for use on UNIX systems by posting that to Usenet + forming 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 ver- sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 1.0.3 in July of 1985. Usenet newsgroup net.games.hack - (later renamed rec.games.hack, eventually replaced by + nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- + Don G. Kneller ported Hack 1.0.3 to Microsoft C and MS-DOS, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- sion 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, - incorporating many of the added features, and produced NetHack - version 1.4 in 1987. He then coordinated a cast of thousands in + 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the + 2.2 and 2.3. Like Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the newsgroup. - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, 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 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6406,63 +6406,63 @@ - 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 + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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. + + 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-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" + 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 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, + 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-structured 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 + 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 Addison, Mike Passaretti, and Olaf Seibert, developed + Ken Lorber, Gregg Wonderly and Greg Olson, with help from + Richard Addison, Mike Passaretti, and Olaf Seibert, developed NetHack 3.1 for the Amiga. - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported NetHack 3.1 to the PC. Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, David Hairston, Michael Hamel, Jonathan Handler, Johnny - Lee, Tim Lennan, Rob Menke, and Andy Swanson, developed NetHack + Engber, 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 de- velopment, Bart House added a Think C port. Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- - mor and so forth, not separate images for beetles and ants or for - cloaks and boots). - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6472,63 +6472,63 @@ - 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 ob- + Dean Luick, with help from David Cohrs, developed NetHack + 3.1 for X11. It drew the map as text rather than graphically but + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- + mor 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 ob- jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support was then implemented on other - platforms (initially MS-DOS but eventually Windows, Qt, and X11 + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic Smith, Mike Stephenson, Janet Walz, and Paul Winner, released + ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and + 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 cancer and passed away. That + release of the game was dedicated to him by the development and porting teams. Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned + Many bugs were fixed, abuses eliminated, and game features tuned for better game play. During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and + asts of the game added their own modifications to the game and made these "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 + 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 cast- - ing system with the Wizard Patch. Warwick Allison also ported + Larry Stewart-Zerba and Warwick Allison improved the spell cast- + ing system with the Wizard Patch. Warwick Allison also ported NetHack to use the Qt interface. - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- - corporated 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 systems that usually had such. - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6538,63 +6538,63 @@ - (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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion of new high scores and with retrieval of old character - names to use for random ghost and statue names in the current + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- + corporated 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 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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, Dean Luick, Pat Rankin, Eric Smith, Mike Stephenson, Janet - Walz, and Paul Winner, released 3.3.0 in December 1999 and 3.3.1 + The 3.3 NetHack Development Team, consisting of Michael Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 - separate race and profession. The Elf class was removed in pref- + separate race and profession. The Elf class was removed in pref- erence 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, Barbar- - ians, 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 listing 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 + made their first appearance in the game alongside the familiar + human race. Monk and Ranger roles joined Archeologists, Barbar- + ians, 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 listing 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 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 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 plat- - form. Paul Winner and Yitzhak Sapir provided encouragement. - - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- - hanced 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- - dows CE port for 3.4.1. - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6604,13 +6604,25 @@ + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- + form. Paul Winner and Yitzhak Sapir provided encouragement. + + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + hanced 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 inter- + face for the Windows port. Alex Kompel also contributed a Win- + dows 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 + 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 + 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 af- @@ -6619,48 +6631,36 @@ The release of NetHack 3.4.3 in December 2003 marked the be- ginning 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 continued to work on the game behind the scenes during - the tenure of 3.4.3. It was during that same period that several + for more than a decade. The NetHack Development Team slowly and + quietly continued 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 con- - tinue to be developed, maintained, and enjoyed by the community + and its successors originally by Daniel Thaler and then by Alex + Smith, and Dynahack by Tung Nguyen. Some of those variants con- + tinue to be developed, maintained, and enjoyed by the community to this day. In September 2014, an interim snapshot of the code under de- - velopment 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 + velopment 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 Development Team's official nethack.org - website to that effect, stating that there would never be a + 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 + 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 Stephen- - son, Janet Walz, and Paul Winner. In early 2015, ahead of the - release of 3.6.0, new members 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 signif- - icant 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 + 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 - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6670,63 +6670,63 @@ + Stephenson, Janet Walz, and Paul Winner. In early 2015, ahead of + the release of 3.6.0, new members 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 signif- + icant 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 restructured. - The NetHack Development Team, as well as Steve VanDevender + The NetHack Development Team, as well as Steve VanDevender and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- ate on various UNIX flavors and maintained the X11 interface. - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- tained the port of NetHack 3.6 for Mac OSX. - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- tained the port of NetHack 3.6 for Microsoft Windows. - Pat Rankin attempted to keep the VMS port running for + Pat Rankin attempted to keep the VMS port running for NetHack 3.6, hindered by limited access. Kevin Smolkowski has up- - dated and tested it for the most recent version of OpenVMS (V8.4 + dated 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 contrib- + Ray Chason resurrected the MS-DOS port for 3.6 and contrib- uted 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. + 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 con- - sisted 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 + sisted 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 en- - hancements and the adopted curses window port, were released as + hancements and the adopted curses window port, were released as 3.6.2. - Bart House, who had contributed to the game as a porting + 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 + 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 - security fix and a few bug fixes. - - 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 se- - curity fix and some bug fixes. - - The official NetHack web site is maintained by Ken Lorber at - https://www.nethack.org/. - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 @@ -6736,22 +6736,34 @@ + 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 security fixes and a small number of bug fixes. + + NetHack 3.6.6 was released on March 8, 2020 containing a se- + curity fix and some bug fixes. + + 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6777,6 +6789,19 @@ Dean Luick Kevin Hugo Ross Brown Del Lamb Kevin Sitze Sascha Wostmann Derek S. Ray Kevin Smolkowski Scott Bigham + + + + NetHack 3.7 December 16, 2020 + + + + + + NetHack Guidebook 104 + + + Deron Meranda Kevin Sweet Scott R. Turner Dion Nicolaas Lars Huttar Sean Hunt Dylan O'Donnell Leon Arnott Stephen Spackman @@ -6789,19 +6814,6 @@ Frederick Roeber Merlyn LeRoy Tim Lennan Gil Neiger Michael Allison Timo Hakulinen Greg Laskin Michael Feir Tom Almy - - - - NetHack 3.7 December 13, 2020 - - - - - - NetHack Guidebook 104 - - - Greg Olson Michael Hamel Tom West Gregg Wonderly Michael Sokolov Warren Cheung Hao-yang Wang Mike Engber Warwick Allison @@ -6809,7 +6821,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6846,19 +6858,7 @@ - - - - - - - - - - - - - NetHack 3.7 December 13, 2020 + NetHack 3.7 December 16, 2020 From 803119a72b73e621ffb5c2ef1c89c1c8334bf62e Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 18 Dec 2020 18:04:34 -0800 Subject: [PATCH 660/708] callable venom Allow the two venoms to be given type names. Only matters if player manages to get either of them into inventory. --- src/do_name.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/do_name.c b/src/do_name.c index 8484419b4..7a053186f 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1606504240 2020/11/27 19:10:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.184 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1608343467 2020/12/19 02:04:27 $ $NHDT-Branch: NetHack-3.7 $:$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. */ @@ -1335,7 +1335,7 @@ const char *name; static NEARDATA const char callable[] = { SCROLL_CLASS, POTION_CLASS, WAND_CLASS, RING_CLASS, AMULET_CLASS, - GEM_CLASS, SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, 0 + GEM_CLASS, SPBOOK_CLASS, ARMOR_CLASS, TOOL_CLASS, VENOM_CLASS, 0 }; boolean From 44f4085f691e0aeaaa53ca4eb0d76dff3ceab80a Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 19 Dec 2020 13:11:36 +0200 Subject: [PATCH 661/708] Add a new themed room: "Twin business" This themed room boasts two shops, a weapons and an armor store, that can generate in a number of different configurations. Makes the random corridor joining routine obey unjoined areas. Fixes a bug in shopkeeper naming routine, where multiple shops of the same type on the same level might reuse the shopkeeper name. This is modified and consolidated commit from xNetHack by copperwater . --- dat/themerms.lua | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/mklev.c | 34 +++++++++++++++++++++++++++++-- src/shknam.c | 7 +++++-- 3 files changed, 90 insertions(+), 4 deletions(-) diff --git a/dat/themerms.lua b/dat/themerms.lua index 4f4f59029..fa85a44df 100644 --- a/dat/themerms.lua +++ b/dat/themerms.lua @@ -545,6 +545,59 @@ xx|.....|xx end }); end, + -- Twin businesses + { + mindiff = 4; -- arbitrary + contents = function() + -- Due to the way room connections work in mklev.c, we must guarantee + -- that the "aisle" between the shops touches all four walls of the + -- larger room. Thus it has an extra width and height. + des.room({ type="themed", w=9, h=5, contents = function() + -- There are eight possible placements of the two shops, four of + -- which have the vertical aisle in the center. + southeast = function() return percent(50) and "south" or "east" end + northeast = function() return percent(50) and "north" or "east" end + northwest = function() return percent(50) and "north" or "west" end + southwest = function() return percent(50) and "south" or "west" end + placements = { + { lx = 1, ly = 1, rx = 4, ry = 1, lwall = "south", rwall = southeast() }, + { lx = 1, ly = 2, rx = 4, ry = 2, lwall = "north", rwall = northeast() }, + { lx = 1, ly = 1, rx = 5, ry = 1, lwall = southeast(), rwall = southwest() }, + { lx = 1, ly = 1, rx = 5, ry = 2, lwall = southeast(), rwall = northwest() }, + { lx = 1, ly = 2, rx = 5, ry = 1, lwall = northeast(), rwall = southwest() }, + { lx = 1, ly = 2, rx = 5, ry = 2, lwall = northeast(), rwall = northwest() }, + { lx = 2, ly = 1, rx = 5, ry = 1, lwall = southwest(), rwall = "south" }, + { lx = 2, ly = 2, rx = 5, ry = 2, lwall = northwest(), rwall = "north" } + } + ltype,rtype = "weapon shop","armor shop" + if percent(50) then + ltype,rtype = rtype,ltype + end + shopdoorstate = function() + if percent(1) then + return "locked" + elseif percent(50) then + return "closed" + else + return "open" + end + end + p = placements[d(#placements)] + des.room({ type=ltype, x=p["lx"], y=p["ly"], w=3, h=3, filled=1, joined=0, + contents = function() + des.door({ state=shopdoorstate(), wall=p["lwall"] }) + end + }); + des.room({ type=rtype, x=p["rx"], y=p["ry"], w=3, h=3, filled=1, joined=0, + contents = function() + des.door({ state=shopdoorstate(), wall=p["rwall"] }) + end + }); + end + }); + end + }, + }; function is_eligible(room) diff --git a/src/mklev.c b/src/mklev.c index bfb0c085c..51616aaf4 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -35,6 +35,7 @@ static void FDECL(do_room_or_subroom, (struct mkroom *, int, int, int, int, BOOLEAN_P, SCHAR_P, BOOLEAN_P, BOOLEAN_P)); static void NDECL(makerooms); +static boolean FDECL(door_into_nonjoined, (XCHAR_P, XCHAR_P)); static void FDECL(finddpos, (coord *, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P)); static void FDECL(mkinvpos, (XCHAR_P, XCHAR_P, int)); @@ -68,6 +69,33 @@ const genericptr vy; #endif /* LINT */ } +/* Return TRUE if a door placed at (x, y) which otherwise passes okdoor() checks + * would be connecting into an area that was declared as joined = 0. + * Checking for this in finddpos() enables us to have rooms with sub-areas (such + * as shops) that will never randomly generate unwanted doors in order to + * connect them up to other areas. + */ +static boolean +door_into_nonjoined(x, y) +xchar x, y; +{ + xchar tx, ty, diridx; + + for (diridx = 0; diridx <= 6; diridx += 2) { + tx = x + xdir[diridx]; + ty = y + ydir[diridx]; + if (!isok(tx, ty) || IS_ROCK(levl[tx][ty].typ)) + continue; + + /* Is this connecting to a room that doesn't want joining? */ + if (levl[tx][ty].roomno >= ROOMOFFSET && + !g.rooms[levl[tx][ty].roomno - ROOMOFFSET].needjoining) { + return TRUE; + } + } + return FALSE; +} + static void finddpos(cc, xl, yl, xh, yh) coord *cc; @@ -77,12 +105,12 @@ xchar xl, yl, xh, yh; x = rn1(xh - xl + 1, xl); y = rn1(yh - yl + 1, yl); - if (okdoor(x, y)) + if (okdoor(x, y) && !door_into_nonjoined(x, y)) goto gotit; for (x = xl; x <= xh; x++) for (y = yl; y <= yh; y++) - if (okdoor(x, y)) + if (okdoor(x, y) && !door_into_nonjoined(x, y)) goto gotit; for (x = xl; x <= xh; x++) @@ -92,6 +120,8 @@ xchar xl, yl, xh, yh; /* cannot find something reasonable -- strange */ x = xl; y = yh; + impossible("finddpos: couldn't find door pos within (%d,%d,%d,%d)", + xl, yl, xh, yh); gotit: cc->x = x; cc->y = y; diff --git a/src/shknam.c b/src/shknam.c index 69b217ffb..b8a4386c4 100644 --- a/src/shknam.c +++ b/src/shknam.c @@ -495,7 +495,7 @@ const char *const *nlp; int i, trycnt, names_avail; const char *shname = 0; struct monst *mtmp; - int name_wanted; + int name_wanted = shk->m_id; s_level *sptr; if (nlp == shklight && In_mines(&u.uz) @@ -510,7 +510,7 @@ const char *const *nlp; use ledger_no rather than depth to keep minetown distinct. */ int nseed = (int) ((long) ubirthday / 257L); - name_wanted = ledger_no(&u.uz) + (nseed % 13) - (nseed % 5); + name_wanted += ledger_no(&u.uz) + (nseed % 13) - (nseed % 5); if (name_wanted < 0) name_wanted += (13 + 5); shk->female = name_wanted & 1; @@ -518,6 +518,8 @@ const char *const *nlp; for (names_avail = 0; nlp[names_avail]; names_avail++) continue; + name_wanted = name_wanted % names_avail; + for (trycnt = 0; trycnt < 50; trycnt++) { if (nlp == shktools) { shname = shktools[rn2(names_avail)]; @@ -545,6 +547,7 @@ const char *const *nlp; continue; if (strcmp(ESHK(mtmp)->shknam, shname)) continue; + name_wanted = names_avail; /* try a random name */ break; } if (!mtmp) From 4cf6727b4e845b2c43145c9db73b3591f69976ac Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 19 Dec 2020 17:45:49 -0800 Subject: [PATCH 662/708] re-implement pull req #334 - sorting discoveries The pull request changed \ and ` output to unconditionally show discoveries in alphabetical order. That's nearly useless except when looking at prediscovered weapons and armor that fighter types start out knowing. This allows the player to choose sorting order via the new 'sortdiscoveries' option. In addition to setting it via config file or 'O', it can be set via 'm' prefix for \ and `. Choices are: o - sort by class, by order of discovery in class (default); s - sort by 'sortloot' classification which groups sub-class items (so all helmets before any other armor, then all gloves, then boots, and so on); within each sub-class, or whole class for classes which don't subdivide so usefully, partly-discovered types (where a name has been assigned) come before fully ID'd types; c - sort by class, alphabetically within class; a - sort alphabetically across all classes. Turned out to be a large amount of work for fairly little gain, although I suspect that 'sortdiscoveries:s' will eventually be more popular than the default. Invalidates existing save files so that current sort setting can persist across save/restore cycles. Closes #334 --- dat/opthelp | 9 ++ doc/Guidebook.mn | 50 +++++++- doc/Guidebook.tex | 47 +++++++- doc/fixes37.0 | 1 + include/extern.h | 2 + include/flag.h | 4 +- include/optlist.h | 2 + include/patchlevel.h | 2 +- src/cmd.c | 2 + src/invent.c | 3 +- src/o_init.c | 263 ++++++++++++++++++++++++++++++++++++++----- src/options.c | 60 ++++++++++ 12 files changed, 402 insertions(+), 43 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index f3debdc5d..c752a8d2e 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -205,6 +205,15 @@ scores the parts of the score list you wish [!own/3 top/2 around] to see when the game ends. You choose a combination of top scores, scores around the top scores, and all of your own scores. +sortdiscoveries preferred order when viewing list of discovered objects [o] + o -- in order of discovery within each class + s -- sortloot's "loot" order + c -- alphabetized within each class + a -- alphabetized across all classes +sortloot preferred order when examining a set of objects [n] + none -- no sorting + loot -- sort piles of objects on floor and in containers + full -- 'loot' plus objects in inventory statushilites whether to display status highlights (when non-zero) and [0] also how many turns to display temporary highlights (for 'up', 'down', and 'changed' hilite_status rules) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 4fab00cd7..dab9e06da 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -35,7 +35,7 @@ .ds vr "NetHack 3.7 .ds f0 "\*(vr .ds f1 -.ds f2 "December 16, 2020 +.ds f2 "December 19, 2020 . .\" A note on some special characters: .\" \(lq = left double quote @@ -1055,8 +1055,12 @@ be added to the end of the list rather than be inserted into the sorted ordering.) .lp \\\\ Show what types of objects have been discovered. +.lp "" +May be preceded by \(oq\f(CRm\fP\(cq to select preferred display order. .lp \` Show discovered types for one class of objects. +.lp "" +May be preceded by \(oq\f(CRm\fP\(cq to select preferred display order. .lp ! Escape to a shell. See \(lq#shell\(rq below for more details. @@ -1258,10 +1262,16 @@ Default key is \(oq\(haD\(cq, and \(oqk\(cq if is on. .lp "#known " Show what object types have been discovered. -Default key is \(oq\\\(cq. +Default key is \(oq\f(CR\\\fP\(cq. +.lp "" +The \(oq\f(CRm\fP\(cq prefix allows assigning a new value to the +.op sortdiscoveries +option to control the order in which the discoveries are displayed. .lp #knownclass Show discovered types for one class of objects. -Default key is \(oq\`\(cq. +Default key is \(oq\f(CR\`\fP\(cq. +.lp "" +The \(oq\f(CRm\fP\(cq prefix operates the same as for \(lq#known\(rq. .lp #levelchange Change your experience level. Autocompletes. @@ -4109,19 +4119,47 @@ Persistent. Show your approximate accumulated score on bottom line (default off). Persistent. .lp "silent " -Suppress terminal beeps (default on). Persistent. +Suppress terminal beeps (default on). +Persistent. +.lp sortdiscoveries +Controls the sorting behavior for the output of the \(oq\f(CR\\\fP\(cq +and \(oq\f(CR\`\fP\(cq commands. +Persistent. +.lp "" +The possible values are: +.PS o +.PL o +list object types by class, in discovery order within each class; +default; +.PL s +list object types by +.op 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; +.PL c +list by class, alphabetically within each class; +.PL a +list alphabetically across all classes. +.PE +Can be interactively set via the \(oq\f(CRO\fP\(cq command or via using +the \(oq\f(CRm\fP\(cq prefix before the \(oq\f(CR\\\fP\(cq +or \(oq\f(CR\`\fP\(cq command. .lp sortloot Controls the sorting behavior of the pickup lists for inventory and #loot commands and some others. Persistent. +.lp "" The possible values are: -.PS full +.PS none \" note: with proportional font, "none" is wider than "full" or "loot" .PL full always sort the lists; .PL loot only sort the lists that don't use inventory letters, like with the #loot and pickup commands; .PL none -show lists the traditional way without sorting. +show lists the traditional way without sorting; +default. .PE .lp sortpack Sort the pack contents by type when displaying inventory (default on). diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index a3dd3fecc..b1606a34c 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.7 by Mike Stephenson and others)} -\date{December 16, 2020} +\date{December 19, 2020} \maketitle @@ -1154,9 +1154,15 @@ ordering.) %.lp \item[\tb{$\backslash$}] Show what types of objects have been discovered. +\\ +%.lp "" +May be preceded by `{\tt m}' to select preferred display order. %.lp \item[\tb{\`}] Show discovered types for one class of objects. +\\ +.lp "" +May be preceded by `{\tt m}' to select preferred display order. %.lp \item[\tb{!}] Escape to a shell. @@ -1340,10 +1346,18 @@ and also `{\tt k}' if {\it number\verb+_+pad\/} is on. \item[\tb{\#known}] Show what object types have been discovered. Default key is `{\tt $\backslash$}'. +\\ +%.lp "" +The `{\tt m}' prefix allows assigning a new value to the +{\it sortdiscoveries\/} +option to control the order in which the discoveries are displayed. %.lp \item[\tb{\#knownclass}] Show discovered types for one class of objects. Default key is `{\tt `}'. +\\ +%.lp "" +The `{\tt m}' prefix operates the same as for \(lq#known\(rq. %.lp \item[\tb{\#levelchange}] Change your experience level. @@ -4450,17 +4464,44 @@ Persistent. \item[\ib{silent}] Suppress terminal beeps (default on). Persistent. %.lp +\item[\ib{sortdiscoveries}] +Controls the sorting behavior for the output of the `{\tt $\backslash$}' +and `{\tt \`}' commands. +Persistent. +\\ +%.lp "" +The possible values are: +%.PS o +%.PL o +(\tt o} --- list object types by class, in discovery order within each class; +default; +%.PL s +{\tt s} --- list object types by {\it 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; +\\ +%.PL c +{\tt c} --- list by class, alphabetically within each class;\\ +%.PL a +{\tt a} --- list alphabetically across all classes.\\ +%.PE +Can be interactively set via the `{\tt O}' command or via using +the `{\tt m}' prefix before the `{\tt $\backslash$}' +or `{\tt \`}' command. +%.lp \item[\ib{sortloot}] Controls the sorting behavior of pickup lists for inventory and \#loot commands and some others. Persistent. - +\\ The possible values are: %.sd %.si {\tt full} --- always sort the lists;\\ {\tt loot} --- only sort the lists that don't use inventory letters, like with the \#loot and pickup commands;\\ -{\tt none} --- show lists the traditional way without sorting. +{\tt none} --- show lists the traditional way without sorting; default. %.ei %.ed %.lp diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9b619329b..23868980b 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -681,6 +681,7 @@ when "?i" (show key bindings) displays commands and their keys, also show assign default key binding for or to execute #terrain assign M-X to #exploremode make #herecmdmenu and #therecmdmenu autocomplete +add 'sortdiscoveries' option to control output of '\' and '`' commands Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index f771e0766..cc7fd8be9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -972,6 +972,7 @@ E void NDECL(ustatusline); /* ### invent.c ### */ +E void FDECL(loot_classify, (Loot *, struct obj *)); E Loot *FDECL(sortloot, (struct obj **, unsigned, BOOLEAN_P, boolean (*)(OBJ_P))); E void FDECL(unsortloot, (Loot **)); @@ -1743,6 +1744,7 @@ E void FDECL(savenames, (NHFILE *)); E void FDECL(restnames, (NHFILE *)); E void FDECL(discover_object, (int, BOOLEAN_P, BOOLEAN_P)); E void FDECL(undiscover_object, (int)); +E int FDECL(choose_disco_sort, (int)); E int NDECL(dodiscovered); E int NDECL(doclassdisco); E void NDECL(rename_disco); diff --git a/include/flag.h b/include/flag.h index 5a0f0213e..4122dd046 100644 --- a/include/flag.h +++ b/include/flag.h @@ -80,6 +80,7 @@ struct flag { #define PARANOID_EATING 0x0200 int pickup_burden; /* maximum burden before prompt */ int pile_limit; /* controls feedback when walking over objects */ + char discosort; /* order of dodiscovery/doclassdisco output: o,s,c,a */ char sortloot; /* 'n'=none, 'l'=loot (pickup), 'f'=full ('l'+invent) */ char inv_order[MAXOCLASSES]; char pickup_types[MAXOCLASSES]; @@ -93,8 +94,7 @@ struct flag { char end_disclose[NUM_DISCLOSURE_OPTIONS + 1]; /* disclose various info upon exit */ char menu_style; /* User interface style setting */ - boolean made_fruit; /* don't easily let the user overflow the number of - fruits */ + boolean made_fruit; /* don't easily let user overflow fruit limit */ /* KMH, role patch -- Variables used during startup. * diff --git a/include/optlist.h b/include/optlist.h index 7ae20db6e..9bf4a057d 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -406,6 +406,8 @@ pfx_##a, &flags.silent) NHOPTB(softkeyboard, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias, &iflags.wc2_softkeyboard) + NHOPTC(sortdiscoveries, 0, opt_in, set_in_game, Yes, Yes, No, Yes, + NoAlias, "preferred order when displaying discovered objects") NHOPTC(sortloot, 4, opt_in, set_in_game, No, Yes, No, Yes, NoAlias, "sort object selection lists by description") NHOPTB(sortpack, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, diff --git a/include/patchlevel.h b/include/patchlevel.h index 47f5d5235..d6969198b 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 28 +#define EDITLEVEL 29 /* * Development status possibilities. diff --git a/src/cmd.c b/src/cmd.c index 65c05546b..94f5a0068 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3236,6 +3236,8 @@ int NDECL((*cmd_func)); /* 'm' for removing saddle from adjacent monster without checking for containers at */ || cmd_func == doloot + /* offer menu to choose discoveries sort order */ + || cmd_func == dodiscovered || cmd_func == doclassdisco /* travel: pop up a menu of interesting targets in view */ || cmd_func == dotravel /* wait and search: allow even if next to a hostile monster */ diff --git a/src/invent.c b/src/invent.c index f7be4f669..63f7904a9 100644 --- a/src/invent.c +++ b/src/invent.c @@ -13,7 +13,6 @@ #define CONTAINED_SYM '>' /* designator for inside a container */ #define HANDS_SYM '-' -static void FDECL(loot_classify, (Loot *, struct obj *)); static char *FDECL(loot_xname, (struct obj *)); static int FDECL(invletter_value, (CHAR_P)); static int FDECL(CFDECLSPEC sortloot_cmp, (const genericptr, @@ -54,7 +53,7 @@ static char FDECL(obj_to_let, (struct obj *)); static const char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */ /* sortloot() classification; called at most once [per sort] for each object */ -static void +void loot_classify(sort_item, obj) Loot *sort_item; struct obj *obj; diff --git a/src/o_init.c b/src/o_init.c index 0ef30c222..5806e9ee3 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -9,6 +9,8 @@ static void FDECL(setgemprobs, (d_level *)); static void FDECL(shuffle, (int, int, BOOLEAN_P)); static void NDECL(shuffle_all); static boolean FDECL(interesting_to_discover, (int)); +static int FDECL(CFDECLSPEC discovered_cmp, (const genericptr, + const genericptr)); static char *FDECL(oclass_to_name, (CHAR_P, char *)); #ifdef USE_TILES @@ -465,37 +467,167 @@ static const short uniq_objs[] = { BELL_OF_OPENING, }; +/* discoveries qsort comparison function */ +static int CFDECLSPEC +discovered_cmp(v1, v2) +const genericptr v1; +const genericptr v2; +{ + const char *s1 = *(const char **) v1; + const char *s2 = *(const char **) v2; + /* each element starts with "* " or " " but we don't sort by those */ + int res = strcmpi(s1 + 2, s2 + 2); + + if (res == 0) { + ; /* no tie-breaker needed */ + } + return res; +} + +static char * +sortloot_descr(otyp, outbuf) +int otyp; +char *outbuf; +{ + Loot sl_cookie; + struct obj o; + + o = cg.zeroobj; + o.otyp = otyp; + o.oclass = objects[otyp].oc_class; + o.dknown = 1; + o.known = (objects[otyp].oc_name_known || !objects[otyp].oc_uses_known) + ? 1 : 0; + o.corpsenm = NON_PM; /* suppress statue and figurine details */ + /* but suppressing fruit details leads to "bad fruit #0" */ + if (otyp == SLIME_MOLD) + o.spe = g.context.current_fruit; + + (void) memset((genericptr_t) &sl_cookie, 0, sizeof sl_cookie); + sl_cookie.obj = (struct obj *) 0; + sl_cookie.str = (char *) 0; + + loot_classify(&sl_cookie, &o); + Sprintf(outbuf, "%02d%02d%1d ", + sl_cookie.orderclass, sl_cookie.subclass, sl_cookie.disco); + return outbuf; +} + +#define DISCO_BYCLASS 0 /* by discovery order within each class */ +#define DISCO_SORTLOOT 1 /* by discovery order within each subclass */ +#define DISCO_ALPHABYCLASS 2 /* alphabetized within each class */ +#define DISCO_ALPHABETIZED 3 /* alphabetized across all classes */ +/* also used in options.c (optfn_sortdiscoveries) */ +const char disco_order_let[] = "osca"; +const char *const disco_orders_descr[] = { + "by order of discovery within each class", + "sortloot order (by class with some sub-class groupings)", + "alphabetical within each class", + "alphabetical across all classes", + (char *) 0 +}; + +int +choose_disco_sort(mode) +int mode; /* 0 => 'O' cmd, 1 => full discoveries; 2 => class discoveries */ +{ + winid tmpwin; + menu_item *selected; + anything any; + int i, n, choice; + + tmpwin = create_nhwindow(NHW_MENU); + start_menu(tmpwin, MENU_BEHAVE_STANDARD); + any = cg.zeroany; /* zero out all bits */ + for (i = 0; disco_orders_descr[i]; ++i) { + any.a_int = disco_order_let[i]; + add_menu(tmpwin, NO_GLYPH, &any, (char) any.a_int, 0, ATR_NONE, + disco_orders_descr[i], + (disco_order_let[i] == flags.discosort) + ? MENU_ITEMFLAGS_SELECTED + : MENU_ITEMFLAGS_NONE); + } + if (mode == 2) { + /* called via 'm `' where full alphabetize doesn't make sense + (only showing one class so can't span all classes) but the + chosen sort will stick and also apply to '\' usage */ + any = cg.zeroany; + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "", MENU_ITEMFLAGS_NONE); + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "Note: full alphabetical and alphabetical within class", + MENU_ITEMFLAGS_NONE); + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + " are equivalent for single class discovery, but", + MENU_ITEMFLAGS_NONE); + add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + " will matter for future use of total discoveries.", + MENU_ITEMFLAGS_NONE); + } + end_menu(tmpwin, "Ordering of discoveries"); + + n = select_menu(tmpwin, PICK_ONE, &selected); + destroy_nhwindow(tmpwin); + if (n > 0) { + choice = selected[0].item.a_int; + /* skip preselected entry if we have more than one item chosen */ + if (n > 1 && choice == (int) flags.discosort) + choice = selected[1].item.a_int; + free((genericptr_t) selected); + flags.discosort = choice; + } + return n; +} + /* the '\' command - show discovered object types */ int dodiscovered() /* free after Robert Viduya */ { - register int i, dis; - int ct = 0; - char *s, oclass, prev_class, classes[MAXOCLASSES], buf[BUFSZ]; winid tmpwin; + char *s, *p, oclass, prev_class, + classes[MAXOCLASSES], buf[BUFSZ], + *sorted_lines[NUM_OBJECTS]; /* overkill */ + int i, j, sortindx, dis, ct, uniq_ct, arti_ct, sorted_ct; + boolean alphabetized, alphabyclass, lootsort; + + if (!flags.discosort || !(p = index(disco_order_let, flags.discosort))) + flags.discosort = 'o'; + + if (iflags.menu_requested) { + if (choose_disco_sort(1) < 0) + return 0; + } + alphabyclass = (flags.discosort == 'c'); + alphabetized = (flags.discosort == 'a' || alphabyclass); + lootsort = (flags.discosort == 's'); + sortindx = index(disco_order_let, flags.discosort) - disco_order_let; tmpwin = create_nhwindow(NHW_MENU); - putstr(tmpwin, 0, "Discoveries"); + Sprintf(buf, "Discoveries, %s", disco_orders_descr[sortindx]); + putstr(tmpwin, 0, buf); putstr(tmpwin, 0, ""); /* gather "unique objects" into a pseudo-class; note that they'll also be displayed individually within their regular class */ + uniq_ct = 0; for (i = dis = 0; i < SIZE(uniq_objs); i++) if (objects[uniq_objs[i]].oc_name_known) { if (!dis++) putstr(tmpwin, iflags.menu_headings, "Unique items"); + ++uniq_ct; Sprintf(buf, " %s", OBJ_NAME(objects[uniq_objs[i]])); putstr(tmpwin, 0, buf); - ++ct; } /* display any known artifacts as another pseudo-class */ - ct += disp_artifact_discoveries(tmpwin); + arti_ct = disp_artifact_discoveries(tmpwin); /* several classes are omitted from packorder; one is of interest here */ Strcpy(classes, flags.inv_order); if (!index(classes, VENOM_CLASS)) (void) strkitten(classes, VENOM_CLASS); /* append char to string */ + ct = uniq_ct + arti_ct; + sorted_ct = 0; for (s = classes; *s; s++) { oclass = *s; prev_class = oclass + 1; /* forced different from oclass */ @@ -504,21 +636,63 @@ dodiscovered() /* free after Robert Viduya */ if ((dis = g.disco[i]) != 0 && interesting_to_discover(dis)) { ct++; if (oclass != prev_class) { - putstr(tmpwin, iflags.menu_headings, - let_to_name(oclass, FALSE, FALSE)); - prev_class = oclass; + if ((alphabyclass || lootsort) && sorted_ct) { + /* output previous class */ + qsort(sorted_lines, sorted_ct, sizeof (char *), + discovered_cmp); + for (j = 0; j < sorted_ct; ++j) { + p = sorted_lines[j]; + if (lootsort) { + p[6] = p[0]; /* '*' or ' ' */ + p += 6; + } + putstr(tmpwin, 0, p); + free(sorted_lines[j]), sorted_lines[j] = 0; + } + sorted_ct = 0; + } + if (!alphabetized || alphabyclass) { + /* header for new class */ + putstr(tmpwin, iflags.menu_headings, + let_to_name(oclass, FALSE, FALSE)); + prev_class = oclass; + } } - Sprintf(buf, "%s %s", - (objects[dis].oc_pre_discovered ? "*" : " "), - obj_typename(dis)); - putstr(tmpwin, 0, buf); + Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); + if (lootsort) + (void) sortloot_descr(dis, &buf[2]); + Strcat(buf, obj_typename(dis)); + + if (!alphabetized && !lootsort) + putstr(tmpwin, 0, buf); + else + sorted_lines[sorted_ct++] = dupstr(buf); } } } if (ct == 0) { You("haven't discovered anything yet..."); - } else + } else { + if (sorted_ct) { + /* if we're alphabetizing by class, we've already shown the + relevant header above; if we're alphabetizing across all + classes, we normally don't need a header; but it we showed + any unique items or any artifacts then we do need one */ + if ((uniq_ct || arti_ct) && !alphabyclass) + putstr(tmpwin, iflags.menu_headings, "Discovered items"); + qsort(sorted_lines, sorted_ct, sizeof (char *), discovered_cmp); + for (j = 0; j < sorted_ct; ++j) { + p = sorted_lines[j]; + if (lootsort) { + p[6] = p[0]; /* '*' or ' ' */ + p += 6; + } + putstr(tmpwin, 0, p); + free(sorted_lines[j]), sorted_lines[j] = 0; + } + } display_nhwindow(tmpwin, TRUE); + } destroy_nhwindow(tmpwin); return 0; @@ -547,13 +721,24 @@ doclassdisco() havent_discovered_any[] = "haven't discovered any %s yet.", unique_items[] = "unique items", artifact_items[] = "artifacts"; - char *s, c, oclass, menulet, allclasses[MAXOCLASSES], - discosyms[2 + MAXOCLASSES + 1], buf[BUFSZ]; - int i, ct, dis, xtras; - boolean traditional; winid tmpwin = WIN_ERR; - anything any; menu_item *pick_list = 0; + anything any; + char *p, *s, c, oclass, menulet, allclasses[MAXOCLASSES], + discosyms[2 + MAXOCLASSES + 1], buf[BUFSZ], + *sorted_lines[NUM_OBJECTS]; /* overkill */ + int i, ct, dis, xtras, sorted_ct; + boolean traditional, alphabetized, lootsort; + + if (!flags.discosort || !(p = index(disco_order_let, flags.discosort))) + flags.discosort = 'o'; + + if (iflags.menu_requested) { + if (choose_disco_sort(2) < 0) + return 0; + } + alphabetized = (flags.discosort == 'a' || flags.discosort == 'c'); + lootsort = (flags.discosort == 's'); discosyms[0] = '\0'; traditional = (flags.menu_style == MENU_TRADITIONAL @@ -670,9 +855,9 @@ doclassdisco() upstart(strcpy(buf, unique_items))); for (i = 0; i < SIZE(uniq_objs); i++) if (objects[uniq_objs[i]].oc_name_known) { + ++ct; Sprintf(buf, " %s", OBJ_NAME(objects[uniq_objs[i]])); putstr(tmpwin, 0, buf); - ++ct; } if (!ct) You(havent_discovered_any, unique_items); @@ -685,20 +870,40 @@ doclassdisco() break; default: oclass = def_char_to_objclass(c); - Sprintf(buf, "Discovered %s", let_to_name(oclass, FALSE, FALSE)); - putstr(tmpwin, iflags.menu_headings, buf); - for (i = g.bases[(int) oclass]; - i < NUM_OBJECTS && objects[i].oc_class == oclass; ++i) { + Sprintf(buf, "Discovered %s in %s", let_to_name(oclass, FALSE, FALSE), + (flags.discosort == 'o') ? "order of discovery" + : (flags.discosort == 's') ? "'sortloot' order" + : "alphabetical order"); + putstr(tmpwin, 0, buf); /* skip iflags.menu_headings */ + sorted_ct = 0; + for (i = g.bases[(int) oclass]; i < g.bases[oclass + 1] - 1; ++i) { if ((dis = g.disco[i]) != 0 && interesting_to_discover(dis)) { - Sprintf(buf, "%s %s", - objects[dis].oc_pre_discovered ? "*" : " ", - obj_typename(dis)); - putstr(tmpwin, 0, buf); ++ct; + Strcpy(buf, objects[dis].oc_pre_discovered ? "* " : " "); + if (lootsort) + (void) sortloot_descr(dis, &buf[2]); + Strcat(buf, obj_typename(dis)); + + if (!alphabetized && !lootsort) + putstr(tmpwin, 0, buf); + else + sorted_lines[sorted_ct++] = dupstr(buf); } } - if (!ct) + if (!ct) { You(havent_discovered_any, oclass_to_name(oclass, buf)); + } else if (sorted_ct) { + qsort(sorted_lines, sorted_ct, sizeof (char *), discovered_cmp); + for (i = 0; i < sorted_ct; ++i) { + p = sorted_lines[i]; + if (lootsort) { + p[6] = p[0]; /* '*' or ' ' */ + p += 6; + } + putstr(tmpwin, 0, p); + free(sorted_lines[i]), sorted_lines[i] = 0; + } + } break; } if (ct) diff --git a/src/options.c b/src/options.c index 90d2c5b97..c1ce9eefb 100644 --- a/src/options.c +++ b/src/options.c @@ -3256,6 +3256,66 @@ char *op; return optn_ok; } +int +optfn_sortdiscoveries(optidx, req, negated, opts, op) +int optidx; +int req; +boolean negated; +char *opts; +char *op; +{ + if (req == do_init) { + flags.discosort = 'o'; + return optn_ok; + } + if (req == do_set) { + op = string_for_env_opt(allopt[optidx].name, opts, FALSE); + if (negated) { + flags.discosort = 'o'; + } else if (op != empty_optstr) { + switch (lowc(*op)) { + case '0': + case 'o': /* order of discovery */ + flags.discosort = 'o'; + break; + case '1': + case 's': /* sortloot order (subclasses for some classes) */ + flags.discosort = 's'; + break; + case '2': + case 'c': /* alphabetical within each class */ + flags.discosort = 'c'; + break; + case '3': + case 'a': /* alphabetical across all classes */ + flags.discosort = 'a'; + break; + default: + config_error_add("Unknown %s parameter '%s'", + allopt[optidx].name, op); + return optn_silenterr; + } + } else + return optn_err; + return optn_ok; + } + if (req == get_val) { + extern const char *const disco_orders_descr[]; /* o_init.c */ + extern const char disco_order_let[]; + const char *p = index(disco_order_let, flags.discosort); + + if (!p) + flags.discosort = 'o', p = disco_order_let; + Strcpy(opts, disco_orders_descr[p - disco_order_let]); + return optn_ok; + } + if (req == do_handler) { + /* return handler_sortdiscoveries(); */ + (void) choose_disco_sort(0); /* o_init.c */ + } + return optn_ok; +} + int optfn_sortloot(optidx, req, negated, opts, op) int optidx; From 957990c14d4e33c965bc1ff7d6bc6947197dedcf Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 20 Dec 2020 12:23:09 +0200 Subject: [PATCH 663/708] More futureproofing hypotheticals If you set COLNO larger than BUFSZ, few places cause a buffer overrun. Add a new buffer size definition, COLBUFSZ, which is the larger of COLNO and BUFSZ, used in places that care about a screen-wide string. --- include/global.h | 7 +++++++ src/cmd.c | 2 +- src/detect.c | 2 +- src/options.c | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/global.h b/include/global.h index 1cdc6a168..c1b9ae14d 100644 --- a/include/global.h +++ b/include/global.h @@ -370,6 +370,13 @@ struct savefile_info { #define TBUFSZ 300 /* g.toplines[] buffer max msg: 3 81char names */ /* plus longest prefix plus a few extra words */ +/* COLBUFSZ is the larger of BUFSZ and COLNO */ +#if BUFSZ > COLNO +#define COLBUFSZ BUFSZ +#else +#define COLBUFSZ COLNO +#endif + #define PL_NSIZ 32 /* name of player, ghost, shopkeeper */ #define PL_CSIZ 32 /* sizeof pl_character */ #define PL_FSIZ 32 /* fruit name */ diff --git a/src/cmd.c b/src/cmd.c index 94f5a0068..2192f499c 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1330,7 +1330,7 @@ wiz_map_levltyp(VOID_ARGS) } { - char dsc[BUFSZ]; + char dsc[COLBUFSZ]; s_level *slev = Is_special(&u.uz); Sprintf(dsc, "D:%d,L:%d", u.uz.dnum, u.uz.dlevel); diff --git a/src/detect.c b/src/detect.c index 4bf7e0a0b..ddf52e59f 100644 --- a/src/detect.c +++ b/src/detect.c @@ -1988,7 +1988,7 @@ dump_map() int x, y, glyph, skippedrows, lastnonblank; int subset = TER_MAP | TER_TRP | TER_OBJ | TER_MON; int default_glyph = cmap_to_glyph(g.level.flags.arboreal ? S_tree : S_stone); - char buf[BUFSZ]; + char buf[COLBUFSZ]; boolean blankrow, toprow; /* diff --git a/src/options.c b/src/options.c index c1ce9eefb..6560681a0 100644 --- a/src/options.c +++ b/src/options.c @@ -8307,7 +8307,7 @@ const char *str; char *s; if (!buf) - *(buf = (char *) alloc(BUFSZ)) = '\0'; + *(buf = (char *) alloc(COLBUFSZ)) = '\0'; if (!*str) { s = eos(buf); From 1c7420af7fadd26cc691250025a2ef3ddb492371 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 20 Dec 2020 21:24:51 -0500 Subject: [PATCH 664/708] cron daily Guidebook.txt update --- doc/Guidebook.txt | 4228 +++++++++++++++++++++++---------------------- 1 file changed, 2147 insertions(+), 2081 deletions(-) diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index 91b1b2f2c..e31cd4137 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -15,7 +15,7 @@ Original version - Eric S. Raymond (Edited and expanded for 3.7 by Mike Stephenson and others) - December 16, 2020 + December 19, 2020 @@ -126,7 +126,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -192,7 +192,7 @@ you have seen on the current dungeon level; as you explore more - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -258,7 +258,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -324,7 +324,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -390,7 +390,7 @@ you have available for spell casting. Again, resting will - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -456,7 +456,7 @@ scribe things that are impossible to represent visually. If you - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -522,7 +522,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -588,7 +588,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -654,7 +654,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -720,7 +720,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -786,7 +786,7 @@ Da - drop all objects, without asking for confirmation. - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -852,7 +852,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -918,7 +918,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -984,7 +984,7 @@ an arrow while not wielding a bow, you are throwing it by - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1050,7 +1050,7 @@ - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1116,7 +1116,7 @@ (R)UNIX is a registered trademark of The Open Group. - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1151,8 +1151,12 @@ \ Show what types of objects have been discovered. + May be preceded by `m' to select preferred display order. + ` Show discovered types for one class of objects. + May be preceded by `m' to select preferred display order. + ! Escape to a shell. See "#shell" below for more details. Del Show map without obstructions. You can view the explored @@ -1175,14 +1179,10 @@ As you can see, the authors of NetHack used up all the let- ters, so this is a way to introduce the less frequently used com- - mands. What extended commands are available depends on what fea- - tures the game was compiled with. - - #adjust - Adjust inventory letters (most useful when the fixinv option + mands. What extended commands are available depends on what - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1192,6 +1192,10 @@ + features the game was compiled with. + + #adjust + 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 @@ -1242,13 +1246,9 @@ #autopickup Toggle the autopickup option on/off. Default key is `@'. - #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 level (same as "#annotate"). Default key is - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1258,6 +1258,10 @@ + #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 level (same as "#annotate"). Default key is `C'. #cast @@ -1308,13 +1312,9 @@ paranoid_confirmation:quit option to require a response of yes instead. - #fire - Fire ammunition from quiver. Default key is `f'. - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1324,6 +1324,9 @@ + #fire + Fire ammunition from quiver. Default key is `f'. + #force Force a lock. Autocompletes. Default key is `M-f'. @@ -1370,17 +1373,14 @@ Show what object types have been discovered. Default key is `\'. - #knownclass - Show discovered types for one class of objects. Default key - is ``'. - - #levelchange - Change your experience level. Autocompletes. Debug mode - only. + The `m' prefix allows assigning a new value to the sortdis- + coveries option to control the order in which the discover- + ies are displayed. - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -1390,6 +1390,16 @@ + #knownclass + Show discovered types for one class of objects. Default key + is ``'. + + The `m' prefix operates the same as for "#known". + + #levelchange + Change your experience level. Autocompletes. Debug mode + only. + #lightsources Show mobile light sources. Autocompletes. Debug mode only. @@ -1433,20 +1443,10 @@ Display information you've discovered about the dungeon. Any visited level (unless forgotten due to amnesia) with an annotation is included, and many things (altars, thrones, - fountains, and so on; extra stairs leading to another dun- - geon branch) trigger an automatic annotation. If dungeon - overview is chosen during end-of-game disclosure, every vis- - ited level will be included regardless of annotations. Au- - tocompletes. Default keys are `^O', and `M-O'. - - #panic - Test the panic routine. Terminates the current game. Auto- - completes. Debug mode only. + fountains, and so on; extra stairs leading to another - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1456,6 +1456,15 @@ + dungeon branch) trigger an automatic annotation. If dungeon + overview is chosen during end-of-game disclosure, every vis- + ited level will be included regardless of annotations. Au- + tocompletes. Default keys are `^O', and `M-O'. + + #panic + Test the panic routine. Terminates the current game. Auto- + completes. Debug mode only. + Asks for confirmation; default is n (no); continue playing. To really panic, respond with y. You can set the para- noid_confirmation:quit option to require a response of yes @@ -1501,18 +1510,9 @@ 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_con- - firmation: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 - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1522,6 +1522,15 @@ + quitting. Default response is n (no); continue playing. To + really quit, respond with y. You can set the paranoid_con- + firmation: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 `r'. #redraw @@ -1567,18 +1576,9 @@ #shell Do a shell escape, switching from NetHack to a subprocess. - Can be disabled at the time the program is built. When en- - abled, access for specific users can be controlled by the - system configuration file. Use the shell command `exit' to - return to the game. Default key is `!'. - - #showgold - Report the gold in your inventory and if you are inside a - shop, report any credit or debt you have in that shop. Does - not report on any gold inside containers you're carrying. - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1588,6 +1588,15 @@ + Can be disabled at the time the program is built. When en- + abled, access for specific users can be controlled by the + system configuration file. Use the shell command `exit' to + return to the game. Default key is `!'. + + #showgold + Report the gold in your inventory and if you are inside a + shop, report any credit or debt you have in that shop. Does + not report on any gold inside containers you're carrying. Default key is `$'. #showspells @@ -1633,18 +1642,9 @@ sters; without monsters and objects; or without monsters, objects, and traps. - In explore mode, you can choose to view the full map rather - than just its explored portion. In debug mode there are ad- - ditional choices. - - Autocompletes. Default key is `' or `' (see - Del above). - - #therecmdmenu - Show a menu of possible actions directed at a location next - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1654,6 +1654,15 @@ + In explore mode, you can choose to view the full map rather + than just its explored portion. In debug mode there are ad- + ditional choices. + + 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, not an exhaustive set of all possibilities. Auto- completes. @@ -1700,17 +1709,8 @@ #vanquished List vanquished monsters. Autocompletes. Debug mode only. - #version - Print compile time options for this version of NetHack. - The second paragraph lists the user interface(s) that are - included. If there are more than one, you can use the win- - dowtype option in your run-time configuration file to select - the one you want. - - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1720,6 +1720,14 @@ + #version + Print compile time options for this version of NetHack. + + The second paragraph lists the user interface(s) that are + included. If there are more than one, you can use the win- + dowtype option in your run-time configuration file to select + the one you want. + Autocompletes. Default key is `M-v'. #versionshort @@ -1766,17 +1774,9 @@ #wizgenesis Create a monster. May be prefixed by a count to create more than one. Autocompletes. Debug mode only. Default key is - `^G'. - - #wizidentify - Identify all items in inventory. Autocompletes. Debug mode - only. Default key is `^I'. - - #wizintrinsic - Set one or more intrinsic attributes. Autocompletes. Debug - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -1786,6 +1786,14 @@ + `^G'. + + #wizidentify + Identify all items in inventory. Autocompletes. Debug mode + only. Default key is `^I'. + + #wizintrinsic + Set one or more intrinsic attributes. Autocompletes. Debug mode only. #wizlevelport @@ -1831,18 +1839,10 @@ - If your keyboard has a meta key (which, when pressed in com- - bination 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 fol- - lowed by the other key, you may set the altmeta option to have - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -1852,6 +1852,15 @@ + If your keyboard has a meta key (which, when pressed in com- + bination 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 fol- + lowed by the other key, you may set the altmeta option to have NetHack combine them into meta+key. (This combining action only takes place when NetHack is expecting a command to execute, not when accepting input to name something or to make a wish.) @@ -1896,6 +1905,19 @@ M-O #overview + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 30 + + + M-p #pray M-q #quit @@ -1906,18 +1928,6 @@ M-s #sit - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 30 - - - M-t #turn M-T #tip @@ -1961,6 +1971,19 @@ tions. Mapping magic reveals secret corridors, so converts them into ordinary corridors and shows them as such. + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 31 + + + 5.1. Doorways Doorways connect rooms and corridors. Some doorways have no @@ -1973,17 +1996,6 @@ if you are confused or stunned or suffer from the fumbling at- tribute. - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 31 - - - 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 @@ -2023,6 +2035,21 @@ in all ways equivalent to normal doors. Mapping magic does not reveal secret doors. + + + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 32 + + + 5.2. Traps (`^') There are traps throughout the dungeon to snare the unwary @@ -2037,19 +2064,6 @@ of-sight (whether you can see at the time or not). There is also other magic which can reveal traps. - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 32 - - - 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, usual- @@ -2090,6 +2104,18 @@ access to that spot. With careful foresight, it is possible to complete all of the levels according to the traditional rules of Sokoban. (Hint: to solve Sokoban puzzles, you often need to move + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 33 + + + 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. @@ -2102,20 +2128,6 @@ that. See the Conduct section for information about getting feedback for your actions in Sokoban. - - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 33 - - - 5.3. Stairs and ladders (`<', `>') In general, each level in the dungeon will have a staircase @@ -2157,22 +2169,10 @@ 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 us- - ing the "#chat" command while standing on it. Using an item pri- - or 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 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 shopkeeper 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. + ing the "#chat" command while standing on it. Using an item - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -2182,22 +2182,35 @@ + 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 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 shopkeeper 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 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 shop where it was obtained; other shopkeepers - won't honor it. (If you happen to find a "credit card" in the + 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 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.) - The `$' command, which reports the amount of gold you are + The `$' command, which reports the amount of gold you are carrying (in inventory, not inside bags or boxes), will also show - current shop debt or credit, if any. The "Iu" command lists un- + current shop debt or credit, if any. The "Iu" command lists un- paid items (those which still belong to the shop) if you are car- - rying any. The "Ix" command shows an inventory-like display of - any unpaid items which have been used up, along with other shop + rying any. The "Ix" command shows an inventory-like display of + any unpaid items which have been used up, along with other shop fees, if any. 5.4.1. Shop idiosyncrasies @@ -2206,13 +2219,13 @@ * 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 + * 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 + * While the shopkeeper watches you like a hawk, he or she will generally ignore any other customers. - * If a shop is "closed for inventory," it will not open of its + * 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 inven- @@ -2220,25 +2233,12 @@ 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 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 no matter how big a pile is. Note that the num- - ber refers to the count of separate stacks of objects present - rather than the sum of the quantities of those stacks (so 7 ar- - rows 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 + 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 - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -2248,63 +2248,63 @@ - location). + a spot where a monster is located. There are several options + which can be used to augment the normal feedback. - The "nopickup" command prefix (default `m') can be used be- - fore a movement direction to step on objects without attempting + 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 num- + ber refers to the count of separate stacks of objects present + rather than the sum of the quantities of those stacks (so 7 ar- + rows 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 loca- + tion). + + The "nopickup" command prefix (default `m') can be used be- + fore 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 + 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 + 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 any- - thing 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 + 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 any- + thing 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 ob- + Moving off of any of those back onto "normal" terrain will give + one message too, unless there is feedback about one or more ob- jects, in which case the back on land circumstance is implied. - 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 + 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 + 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 at- - tack (see the Fighting subsection of Monsters below). The - "fight" command prefix (default `F'; also `-' if number_pad is + tack (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 attacking a peaceful or tame + monster is or when deliberately attacking a peaceful or tame creature. - The run_mode option controls how frequently the map gets re- - drawn 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 dungeon) is a tribute to the ancestor game hack's inspira- - tion rogue. - - It is usually displayed differently from other levels: pos- - sibly in characters instead of tiles, or without line-drawing - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -2314,63 +2314,63 @@ + The run_mode option controls how frequently the map gets re- + drawn 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 dungeon) is a tribute to the ancestor game hack's inspira- + tion rogue. + + It is usually displayed differently from other levels: pos- + sibly 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 differences 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 + than $ and stairs are shown as % rather than < and >. There are + some minor differences 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 + The slight strangeness of this level is a feature, not a bug.... 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 + 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 do very well). - The commands `/' and `;' may be used to obtain information - about those monsters who are displayed on the screen. The com- - mand "#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 + The commands `/' and `;' may be used to obtain information + about those monsters who are displayed on the screen. The com- + mand "#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 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 mon- - sters such as a shopkeeper or the Oracle of Delphi can produce + sters 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 + 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 - monster by moving into its location, you'll be asked to confirm - your intent. By default an answer of `y' acknowledges that in- - tent, which can be error prone if you're using `y' to move. You - can set the paranoid_confirmation option to require a response of - "yes" instead. - - 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 mon- - ster 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 re- - member a monster but want to try fighting anyway, you can use the - `F' command. + In most circumstances, if you attempt to attack a peaceful + monster by moving into its location, you'll be asked to confirm + your intent. By default an answer of `y' acknowledges that in- + tent, which can be error prone if you're using `y' to move. You - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -2380,63 +2380,63 @@ + can set the paranoid_confirmation option to require a response of + "yes" instead. + + 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 mon- + ster 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 re- + member 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 mon- - sters with you. Like you, your pet needs food to survive. Dogs - and cats usually feed themselves on fresh carrion and other - meats; horses need vegetarian food which is harder to come by. - If you're worried about your pet or want to train it, you can + pony (`u'), which follows you about the dungeon and fights mon- + sters with you. Like you, your pet needs food to survive. Dogs + and cats usually feed themselves on fresh carrion and other + meats; horses need vegetarian 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 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 + 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 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 + 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-adjacent pet will be left behind. Your - pet may trigger such traps itself; you will not be carried along + 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 rid- + Some types of creatures in the dungeon can actually be rid- den 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 or- + 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 or- der to forge the alliance. Once you do have the beast under your - control however, you can easily climb in and out of the saddle + 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 + Riding skill is managed by the "#enhance" command. See the section on Weapon proficiency for more information about that. - Use the `a' (apply) command and pick a saddle in your inven- - tory to attempt to put that saddle on an adjacent creature. If - successful, it will be transferred to that creature's inventory. - - 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 adventur- - ers (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 little damage. You can plunder the deceased - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -2446,63 +2446,63 @@ - adventurer's possessions; however, they are likely to be cursed. + Use the `a' (apply) command and pick a saddle in your inven- + tory to attempt to put that saddle on an adjacent creature. If + successful, it will be transferred to that creature's inventory. + + 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 adventur- + ers (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 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 last victory. 6.5. Persistence of Monsters Monsters (a generic reference which also includes humans and - pets) are only shown while they can be seen or otherwise sensed. - Moving to a location where you can't see or sense a monster any - more will result in it disappearing from your map, similarly if + pets) are only shown while they can be seen or otherwise sensed. + Moving 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 who moved rather than you. - 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 per- - sist 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 + 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 per- + sist 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 automatically by - walking over the object (unless you turn off the autopickup op- - tion (see below), or move with the `m' prefix (see above)), or + walking over the object (unless you turn off the autopickup op- + tion (see below), or move with the `m' prefix (see above)), or manually by using the `,' command. - 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 + 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 de- - pends on your strength and your constitution. The stronger and - sturdier you are, the less the additional load will affect you. + As you add items to your inventory, you also add the weight + of that object to your load. The amount that you can carry de- + pends 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 encum- - ber you. Your reactions will get slower and you'll burn calories - faster, requiring food more frequently to cope with it. Eventu- - ally, 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, Overtaxed, or Overloaded will be shown on the bottom - line status display. - - When you pick up an object, it is assigned an inventory let- - ter. 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 + you are carrying around with you through the dungeon will - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -2512,8 +2512,23 @@ - presented with a list of inventory letters to choose from (see - Commands, above). + 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 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, Overtaxed, or Overloaded will be shown on the bottom + line status display. + + When you pick up an object, it is assigned an inventory let- + ter. 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 pre- + sented with a list of inventory letters to choose from (see Com- + mands, above). Some objects, such as weapons, are easily differentiated. Others, like scrolls and potions, are given descriptions which @@ -2551,6 +2566,18 @@ 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" + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 40 + + + situation; make of that what you will. There are magical means of bestowing or removing curses upon @@ -2566,18 +2593,6 @@ distinguished 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 40 - - - enough other information is displayed. The implicit_uncursed op- tion can be used to control this; toggle it off to have uncursed be displayed even when that can be deduced from other attributes. @@ -2617,6 +2632,18 @@ encumbrance, and proficiency (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 + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 41 + + + vulnerable to certain types of weapons. Many weapons can be wielded in one hand; some require both @@ -2632,18 +2659,6 @@ 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. - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 41 - - - There might be times when you'd rather not wield any weapon at all. To accomplish that, wield `-', or else use the `A' com- mand which allows you to unwield the current weapon in addition @@ -2683,6 +2698,18 @@ Some characters have the ability to fire a volley of multi- ple items in a single turn. Knowing how to load several rounds of ammunition at once--or hold several missiles in your hand--and + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 42 + + + 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 @@ -2698,18 +2725,6 @@ ing 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 42 - - - still continue beyond that spot. 7.2.2. Weapon proficiency @@ -2749,6 +2764,18 @@ 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 + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 43 + + + use "#enhance" to increase one or more skills. Such skills are not increased automatically because there is a limit to your to- tal overall skills, so you need to actively choose which skills @@ -2764,18 +2791,6 @@ 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 43 - - - weapons at once. The primary is your wielded weapon and the sec- ondary is just an item in your inventory that's been designated as alternate weapon.) @@ -2815,6 +2830,18 @@ Here is a list of the armor class values provided by suits of armor: + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 44 + + + Dragon scale mail 1 Plate mail, Crystal plate mail 3 Bronze plate mail, Splint mail, @@ -2830,18 +2857,6 @@ 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 44 - - - point improvement to 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. @@ -2882,6 +2897,17 @@ ly stay fresh, but ice boxes are heavy, and tins take a while to open. + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 45 + + + 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 @@ -2895,19 +2921,6 @@ You can name one food item after something you like to eat with the fruit option. - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 45 - - - The command to eat food is `e'. 7.5. Scrolls (`?') @@ -2949,6 +2962,18 @@ things to throw (`t') at them. It is also sometimes very useful to dip ("#dip") an object into a potion. + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 46 + + + The command to drink a potion is `q' (quaff). 7.7. Wands (`/') @@ -2962,18 +2987,6 @@ When the number of charges left in a wand becomes zero, at- tempts to use the wand will usually result in nothing happening. - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 46 - - - Occasionally, 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 @@ -3014,6 +3027,19 @@ ing a ring and then re-wear them after. That's done implicitly to avoid unnecessary tedium. + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 47 + + + The commands to use rings are `P' (put on) and `R' (remove). `A', `W', and `T' can also be used; see Amulets. @@ -3028,18 +3054,6 @@ 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 47 - - - type, or cast it at a time when your luck is particularly bad, you can end up wasting both the energy and the time required in casting. @@ -3079,6 +3093,19 @@ estimate of how strongly it is remembered. The `Z' (cast) com- mand casts a spell. + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 48 + + + 7.10. Tools (`(') Tools are miscellaneous objects with various purposes. Some @@ -3093,19 +3120,6 @@ in some cases (again, pick-axe) become wielded as a weapon even when applied. - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 48 - - - 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 challenge which is very difficult to accomplish). @@ -3146,6 +3160,18 @@ shown as likely candidates in a prompt for choosing what to wear or take off. + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 49 + + + 7.12. Gems (`*') Some gems are valuable, and can be sold for a lot of gold. @@ -3158,20 +3184,6 @@ tile weapons (if you have a sling). In the most desperate of cases, you can still throw them by hand. - - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 49 - - - 7.13. Large rocks (``') Statues and boulders are not particularly useful, and are @@ -3214,6 +3226,18 @@ cation 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 + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 50 + + + more--perhaps a monster has picked it up or it has rotted away-- until you can see or feel that location again. One notable ex- ception is that if the object gets covered by the "remembered, @@ -3225,21 +3249,9 @@ er 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 50 - - - - option can be enabled in order to show an item differently when - it is the top one of a pile. + only the top item of the pile is displayed. The hilite_pile op- + tion can be enabled in order to show an item differently when it + is the top one of a pile. 8. Conduct @@ -3280,6 +3292,18 @@ (`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 + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 51 + + + observe a vegetarian diet. Eating any kind of meat violates the vegetarian, vegan, and @@ -3292,18 +3316,6 @@ brains while polymorphed into a mind flayer, is considered eating an animal, although wax is only an animal byproduct. - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 51 - - - Regardless of conduct, there will be some items which are indigestible, and others which are hazardous to eat. Using a swallow-and-digest attack against a monster is equivalent to eat- @@ -3346,6 +3358,18 @@ 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) + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 52 + + + in your starting inventory is assumed to be learned from your teachers prior to the start of the game and isn't counted. @@ -3358,18 +3382,6 @@ can't be bypassed, such as being unable to push a boulder diago- nally. Other rules can, such as not smashing boulders with magic or tools, but doing so causes you to receive a luck penalty. No - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 52 - - - 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, @@ -3412,6 +3424,18 @@ necessarily in the order in which you might accomplish them. - Attained rank title . + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 53 + + + Shop - Entered a shop. Temple - Entered a temple. Mines - Entered the Gnomish Mines. @@ -3424,18 +3448,6 @@ and found a special item there. Mines' End - Explored to the bottom of the Gnomish Mines and found a special item there. - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 53 - - - Medusa - Defeated Medusa. Bell - Acquired the Bell of Opening. Gehennom - Entered Gehennom. @@ -3477,22 +3489,10 @@ dies. Blind and Nudist are also conducts, and they can only be en- - abled by setting the correspondingly named option in NETHACKOP- - TIONS or run-time configuration file prior to game start. In the - case of Blind, the option also enforces the conduct. They aren't - really significant accomplishments unless/until you make substan- - tial 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 NetHack behaves. + abled by setting the correspondingly named option in - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -3502,6 +3502,17 @@ + NETHACKOPTIONS or run-time configuration file prior to game + start. In the case of Blind, the option also enforces the con- + duct. They aren't really significant accomplishments unless/un- + til 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 NetHack behaves. + 9.1. Setting the options Options may be set in a number of ways. Within the game, @@ -3546,19 +3557,8 @@ tered or the file ends. Lines within sections are ignored unless a CHOOSE directive has selected that section. - You can use different configuration directives in the file, - some of which can be used multiple times. In general, the direc- - tives 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 - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -3568,7 +3568,17 @@ - options take more diverse values. Prefix a boolean option with + You can use different configuration directives in the file, + some of which can be used multiple times. In general, the direc- + tives 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 op- + tions 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 per- sistent, and apply only to new games. You can specify multiple @@ -3612,6 +3622,18 @@ pletion has no effect for the X11 windowport. You can specify multiple autocompletions. To enable autocompletion, list the extended command. Prefix the command with "!" to disable the + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 56 + + + autocompletion for that command. Example: @@ -3622,18 +3644,6 @@ Set exceptions to the pickup_types option. See the "Configur- ing Autopickup Exceptions" section. - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 56 - - - BINDINGS Change the key bindings of some special keys, menu accelera- tors, or extended commands. You can specify multiple bindings. @@ -3677,8 +3687,20 @@ BOLS below. SOUND - Define a sound mapping. See the "Configuring User Sounds" sec- - tion. + Define a sound mapping. See the "Configuring User Sounds" + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 57 + + + + section. SOUNDDIR Define the directory that contains the sound files. See the @@ -3689,17 +3711,6 @@ dungeon levels except for the special rogue level. See the "Modifying NetHack Symbols" section. - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 57 - - - Example: # replace small punctuation (tick marks) with digits @@ -3742,8 +3753,20 @@ 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" be- - fore the name. Others take a character string as a value. You + option to the list, and turn it off by typing a `!' or "no" + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 58 + + + + 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 ter- minated by the next comma or the end of string. @@ -3754,18 +3777,6 @@ % setenv NETHACKOPTIONS "color,\!leg,name:Blue Meanie,fruit:lime" - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 58 - - - in csh (note the need to escape the `!' since it's special to that shell), or the pair of commands @@ -3810,19 +3821,8 @@ ment from being picked randomly. Cannot be set with the `O' command. Persistent. - autodescribe - Automatically describe the terrain under cursor when asked to - get a location on the map (default true). The whatis_coord op- - tion controls 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 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -3832,6 +3832,15 @@ + autodescribe + Automatically describe the terrain under cursor when asked to + get a location on the map (default true). The whatis_coord op- + tion controls 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. + autoopen Walking into a closed door attempts to open it (default true). Persistent. @@ -3877,18 +3886,9 @@ Synonym for "role" to pick the type of your character (for ex- ample "character:Monk"). See role for more details. - checkpoint - Save game state after each level change, for possible recovery - after program crash (default on). Persistent. - - clicklook - Allows looking at things on the screen by navigating the mouse - over them and clicking the right mouse button (default off). - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -3898,6 +3898,14 @@ + checkpoint + Save game state after each level change, for possible recovery + after program crash (default on). Persistent. + + clicklook + Allows looking at things on the screen by navigating the mouse + over them and clicking the right mouse button (default off). + cmdassist Have the game provide some additional command assistance for new players if it detects some anticipated mistakes (default @@ -3944,17 +3952,9 @@ answering `y' rather than `a', will default to showing monsters in the traditional order, from high level to low level. - Omitted categories are implicitly added with `n' prefix. Spec- - ified 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 inven- - tory to prompt and default to yes, attributes to prompt and de- - fault to no, vanquished to disclose without prompting, - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -3964,11 +3964,18 @@ - genocided to not disclose and not prompt, conduct to implicitly - prompt and default to no, and overview to disclose without - prompting. + Omitted categories are implicitly added with `n' prefix. Spec- + ified 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. - Note that the vanquished monsters list includes all monsters + (for example "disclose:yi na +v -g o") The example sets inven- + tory to prompt and default to yes, attributes to prompt and de- + fault to no, vanquished to disclose without prompting, genocid- + ed 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 by traps and each other as well as by you. And the dun- geon overview shows all levels you had visited but does not re- veal things about them that you hadn't discovered. @@ -3978,49 +3985,42 @@ set with the `O' command. extmenu - Changes the extended commands interface to pop-up a menu of + Changes the extended commands interface to pop-up a menu of available commands. It is keystroke compatible with the tradi- - tional interface except that it does not require that you hit + tional 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 avail- - able commands (on) or just the subset of commands which have + able commands (on) or just the subset of commands which have traditionally been considered extended ones (off). female - An obsolete synonym for "gender:female". Cannot be set with + An obsolete synonym for "gender:female". Cannot be set with the `O' command. fixinv - An object's inventory letter sticks to it when it's dropped - (default on). If this is off, dropping an object shifts all + 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 inventory letters. Persistent. force_invmenu - Commands asking for an inventory item show a menu instead of a + 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 - "fruit:mango") (default "slime mold"). Basically a nostalgic - whimsy that NetHack uses from time to time. You should set - this to something you find more appetizing than slime mold. - Apples, oranges, pears, bananas, and melons already exist in + 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 something 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 - specify just the first letter. Although you can still denote - your gender using the "male" and "female" options, the "gender" - option will take precedence. The default is to randomly pick - an appropriate gender. If you prefix the value with `!' or - "no", you will exclude that gender from being picked randomly. - Cannot be set with the `O' command. Persistent. + Your starting gender (gender:male or gender:female). You may - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4030,63 +4030,63 @@ + specify just the first letter. Although you can still denote + your gender using the "male" and "female" options, the "gender" + option will take precedence. The default is to randomly pick + an appropriate gender. If you prefix the value with `!' or + "no", you will exclude that gender from being picked randomly. + 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 de- - fault). Gold is never blessed or cursed, but it is not de- + 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 de- + fault). Gold is never blessed or cursed, but it is not de- scribed as "uncursed" even when the implicit_uncursed option is "off". help - If more information is available for an object looked at with + If more information is available for an object looked at with the `/' command, ask if you want to see it (default on). Turn- - ing help off makes just looking at things faster, since you - aren't interrupted with the "More info?" prompt, but it also + ing help off makes just looking at things faster, since you + aren't interrupted with the "More info?" prompt, but it also means that you might miss some interesting and/or important in- formation. Persistent. 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. Same as "#herecmdmenu" and "#therecmdmenu" com- + When using a windowport that supports mouse and clicking on + yourself or next to you, show a menu of possible actions for + the location. Same as "#herecmdmenu" and "#therecmdmenu" com- mands. hilite_pet - Visually distinguish pets from similar animals (default off). - The behavior of this option depends on the type of windowing + 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 + is often used; with tiles, generally displays a heart symbol near pets. - With the curses interface, the petattr option controls how to - highlight pets and setting it will turn the hilite_pet option + With the curses interface, the petattr option controls how to + 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 + 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 + 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. Only - available for TTY and Windows GUI, and only when statushilites + Show a hit point bar graph behind your name and title. Only + available for TTY and Windows GUI, and only when statushilites is on. horsename - Name your starting horse (for example "horsename:Trigger"). - Cannot be set with the `O' command. - - ignintr - Ignore interrupt signals, including breaks (default off). Per- - sistent. + Name your starting horse (for example "horsename:Trigger"). - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4096,9 +4096,15 @@ + Cannot be set with the `O' command. + + ignintr + Ignore interrupt signals, including breaks (default off). Per- + sistent. + implicit_uncursed Omit "uncursed" from object descriptions when it can be deduced - from other aspects of the description (default on). Persis- + from other aspects of the description (default on). Persis- tent. If you use menu coloring, you may want to turn this off. @@ -4108,51 +4114,45 @@ on). Persistent. lit_corridor - Show corridor squares seen by night vision or a light source + Show corridor squares seen by night vision or a light source held by 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 + 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 + 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 de- - scribed when covered by one or more objects (default off). + Give feedback when walking onto various dungeon features such + as stairs, fountains, or altars which are ordinarily only de- + scribed when covered by one or more objects (default off). Persistent. mention_walls - Give feedback when walking against a wall (default off). Per- + Give feedback when walking against a wall (default off). Per- sistent. menucolors - Enable coloring menu lines (default off). See "Configuring + Enable coloring menu lines (default off). See "Configuring Menu Colors" on how to configure the colors. menustyle Controls the interface used when you need to choose various ob- - jects (in response to the Drop command, for instance). The - value specified should be the first letter of one of the fol- - lowing: traditional, combination, full, or partial. Tradi- - tional was the only interface available for 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 interest, but then displays a menu of matching ob- - jects 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. Partial skips the + jects (in response to the Drop command, for instance). The + value specified should be the first letter of one of the fol- + lowing: traditional, combination, full, or partial. Tradi- + tional was the only interface available for early versions; it + consists of a prompt for object class characters, followed by - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4162,16 +4162,22 @@ - object class filtering and immediately displays a menu of all - objects. Persistent. + an object-by-object prompt for all items matching the selected + object class(es). Combination starts with a prompt for object + class(es) of interest, but then displays a menu of matching ob- + jects 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. Partial skips the ob- + ject class filtering and immediately displays a menu of all ob- + jects. Persistent. menu_deselect_all - Menu character accelerator to deselect all items in a menu. + Menu character accelerator to deselect all items in a menu. Implemented by the Amiga, Gem, X11 and tty ports. Default `-'. menu_deselect_page - Menu character accelerator to deselect all items on this page - of a menu. Implemented by the Amiga, Gem and tty ports. De- + Menu character accelerator to deselect all items on this page + of a menu. Implemented by the Amiga, Gem and tty ports. De- fault `\'. menu_first_page @@ -4179,46 +4185,40 @@ Implemented by the Amiga, Gem and tty ports. Default `^'. menu_headings - Controls how the headings in a menu are highlighted. Values - are "none", "bold", "dim", "underline", "blink", or "inverse". + Controls how the headings in a menu are highlighted. Values + are "none", "bold", "dim", "underline", "blink", or "inverse". Not all ports can actually display all types. menu_invert_all - Menu character accelerator to invert all items in a menu. Im- + Menu character accelerator to invert all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `@'. menu_invert_page - Menu character accelerator to invert all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to invert all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `~'. menu_last_page - Menu character accelerator to jump to the last page in a menu. + Menu character accelerator to jump to the last page in a menu. Implemented by the Amiga, Gem and tty ports. Default `|'. menu_next_page - Menu character accelerator to goto the next menu page. Imple- + Menu character accelerator to goto the next menu page. Imple- mented by the Amiga, Gem and tty ports. Default `>'. menu_objsyms - Show object symbols in menu headings in menus where the object + Show object symbols in menu headings in menus where the object symbols act as menu accelerators (default off). menu_overlay - Do not clear the screen before drawing menus, and align menus - to the right edge of the screen. Only for the tty port. (de- + Do not clear the screen before drawing menus, and align menus + to the right edge of the screen. Only for the tty port. (de- fault on) - menu_previous_page - Menu character accelerator to goto the previous menu page. Im- - plemented by the Amiga, Gem and tty ports. Default `<'. - - menu_search - Menu character accelerator to search for a menu item. Imple- - mented by the Amiga, Gem, X11 and tty ports. Default `:'. - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -4228,13 +4228,21 @@ + menu_previous_page + Menu character accelerator to goto the previous menu page. Im- + plemented by the Amiga, Gem and tty ports. Default `<'. + + menu_search + Menu character accelerator to search for a menu item. Imple- + mented by the Amiga, Gem, X11 and tty ports. Default `:'. + menu_select_all - Menu character accelerator to select all items in a menu. Im- + Menu character accelerator to select all items in a menu. Im- plemented by the Amiga, Gem, X11 and tty ports. Default `.'. menu_select_page - Menu character accelerator to select all items on this page of - a menu. Implemented by the Amiga, Gem and tty ports. Default + Menu character accelerator to select all items on this page of + a menu. Implemented by the Amiga, Gem and tty ports. Default `,'. monpolycontrol @@ -4242,24 +4250,24 @@ off). Debug mode only. mouse_support - Allow use of the mouse for input and travel. Valid settings + Allow use of the mouse for input and travel. Valid settings are: 0 - disabled 1 - enabled and make OS adjustments to support mouse use 2 - like 1 but does not make any OS adjustments - Omitting a value is the same as specifying 1 and negating + Omitting a value is the same as specifying 1 and negating mouse_support is the same as specifying 0. msghistory - The number of top line messages to keep (and be able to recall + 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. - Currently it is only supported for tty (all four choices) and - for curses (`f' and `r' choices, default `r'). The possible + Allows you to change the way recalled messages are displayed. + Currently 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); @@ -4267,24 +4275,16 @@ 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 + For backward compatibility, no value needs to be specified + (which defaults to "full"), or it can be negated (which defaults to "single"). 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 one will be automatically chosen. 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 + Set your character's name (defaults to your user name). You + can also set your character's role by appending a dash and one - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4294,6 +4294,14 @@ + 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. 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 this with the `O' command. nudist @@ -4303,7 +4311,7 @@ Send padding nulls to the terminal (default on). Persistent. number_pad - Use digit keys instead of letters to move (default 0 or off). + Use digit keys instead of letters to move (default 0 or off). Valid settings are: 0 - move by letters; "yuhjklbn" @@ -4313,44 +4321,36 @@ 4 - combines 3 with 2; phone layout plus MS-DOS compatibility -1 - by letters but use `z' to go northwest, `y' to zap wands - For backward compatibility, omitting a value is the same as - specifying 1 and negating number_pad is the same as specifying - 0. (Settings 2 and 4 are for compatibility with MS-DOS or old + For backward compatibility, omitting a value is the same as + specifying 1 and negating number_pad is the same as specifying + 0. (Settings 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 accommo- - date some QWERTZ keyboards which have the location of the `y' - and `z' keys swapped.) When moving by numbers, to enter a + date some QWERTZ keyboards 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' + 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 containing the symbols for the various object types. Any omit- ted 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_confirma- + A space separated list of specific situations where alternate + prompting is desired. The default is paranoid_confirma- tion:pray. - Confirm - for any prompts which are set to require "yes" - rather than `y', also require "no" to reject in- + Confirm - for any prompts which are set to require "yes" + rather than `y', also require "no" to reject in- stead of accepting any non-yes response as no 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 useful in normal play; applies to explore - mode); - bones - require "yes" rather than `y' to confirm saving - bones data when dying in debug mode; - attack - require "yes" rather than `y' to confirm attack- - ing a peaceful monster; + the game or switching into non-scoring explore - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4360,34 +4360,42 @@ + mode; + 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 data when dying in debug mode; + attack - require "yes" rather than `y' to confirm attack- + ing a peaceful monster; wand-break - require "yes" rather than `y' to confirm breaking a wand; - eating - require "yes" rather than `y' to confirm whether + 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 + form due to lycanthropy when hero has polymorph control; - pray - require `y' to confirm an attempt to pray rather + pray - require `y' to confirm an attempt to pray rather than immediately praying; on by default; - Remove - require selection from inventory for `R' and `T' - commands even when wearing just one applicable + Remove - require selection from inventory for `R' and `T' + commands even when wearing just one applicable item. all - turn on all of the above. - By default, the pray choice is enabled, the others disabled. - To disable it without setting any of the other choices, use + By default, the pray choice is enabled, the others disabled. + To disable it without setting any of the other choices, use "paranoid_confirmation:none". To keep it enabled while setting - any of the others, include it in the list, such as "para- + any of the others, include it in the list, such as "para- noid_confirmation:attack pray Remove". perm_invent - If true, always display your current inventory in a window. - This only makes sense for windowing system interfaces that im- + If true, always display your current inventory in a window. + This only makes sense for windowing system interfaces that im- plement this feature. petattr - Specifies one or more text highlighting attributes to use when - showing pets on the map. Effectively a superset of the + Specifies one or more text highlighting attributes to use when + showing pets on the map. Effectively a superset of the hilite_pet boolean option. Curses interface only; value is one or more of the following letters. @@ -4401,22 +4409,14 @@ l - Left line indicator r - Right line indicator - Some of those choices might not work, particularly the final - three, depending upon terminal hardware or terminal emulation + Some of those choices might not work, particularly the final + three, depending upon terminal hardware or terminal emulation software. - Currently multiple highlight-style letters can be combined by - simply stringing them together (for example, "bk"), but in the - future they might require being separated by plus signs (such - as "b+k", which works already). When using the `n' choice, it - should be specified on its own, not in combination with any of - the other letters. - - pettype - Specify the type of your initial pet, if you are playing a - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -4426,22 +4426,31 @@ - character class that uses multiple types of pets; or choose to - have no initial pet at all. Possible values are "cat", "dog", + Currently multiple highlight-style letters can be combined by + simply stringing them together (for example, "bk"), but in the + future they might require being separated by plus signs (such + as "b+k", which works already). When using the `n' choice, it + should be specified on its own, not in combination with any of + the other letters. + + 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". If the choice is not allowed for the role - you are currently playing, it will be silently ignored. For - example, "horse" will only be honored when playing a knight. + you are currently playing, it will be silently ignored. For + example, "horse" will only be honored 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 overLoaded), you will be asked if you want to continue. + When you pick up an item that would exceed this encumbrance + level (Unencumbered, Burdened, streSsed, straiNed, overTaxed, + or overLoaded), you will be asked if you want to continue. (Default `S'). Persistent. 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 + 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 @@ -4451,38 +4460,29 @@ sistent. 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 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. + 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 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. playmode - Values are "normal", "explore", or "debug". Allows selection - of explore mode (also known as discovery mode) or debug mode + 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 + 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 it when not allowed or not possible re- + entirely. Requesting it when not allowed or not possible re- sults in explore mode instead. Default is normal play. pushweapon - Using the `w' (wield) command when already wielding something - pushes the old item into your alternate weapon slot (default - off). Likewise for the `a' (apply) command if it causes the - applied item to become wielded. Persistent. - - quick_farsight - When set, usually prevents the "you sense your surroundings" - message where play pauses to allow you to browse the map when- - ever clairvoyance randomly activates. Some situations, such as - being underwater or engulfed, ignore this option. It does not + Using the `w' (wield) command when already wielding something - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4492,43 +4492,52 @@ + pushes the old item into your alternate weapon slot (default + off). Likewise for the `a' (apply) command if it causes the + applied item to become wielded. Persistent. + + quick_farsight + When set, usually prevents the "you sense your surroundings" + message where play pauses to allow you to browse the map when- + ever clairvoyance randomly activates. Some situations, such as + being underwater or engulfed, ignore this option. It does not affect the clairvoyance spell where pausing to examine revealed - objects or monsters is less intrusive. Default is off. Per- + objects or monsters is less intrusive. Default is off. Per- sistent. race Selects your race (for example, "race:human"). Default is ran- - dom. If you prefix the value with `!' or "no", you will ex- + dom. If you prefix the value with `!' or "no", you will ex- clude that race from being picked randomly. Cannot be set with the `O' command. Persistent. rest_on_space - Make the space bar a synonym for the `.' (#wait) command (de- + Make the space bar a synonym for the `.' (#wait) command (de- fault off). Persistent. role - Pick your type of character (for example "role:Samurai"); syn- - onym for "character". See "name" for an alternate method of - specifying your role. Normally only the first letter of the - value is examined; `r' is an exception with "Rogue", "Ranger", + Pick your type of character (for example "role:Samurai"); syn- + onym for "character". See "name" for an alternate method of + specifying your role. Normally only the first letter of the + value is examined; `r' is an exception with "Rogue", "Ranger", and "random" values. If you prefix the value with `!' or "no", - you will exclude that role from being picked randomly. Cannot + you will exclude that role from being picked randomly. Cannot be set with the `O' command. Persistent. roguesymset - This option may be used to select one of the named symbol sets - found within "symbols" to alter the symbols displayed on the + This option may be used to select one of the named symbol sets + found within "symbols" to alter the symbols displayed on the screen on the rogue level. rlecomp When writing out a save file, perform run length compression of - the map. Not all ports support run length compression. It has + 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 - control+direction and so forth, or via the travel command or + Controls the amount of screen updating for the map window when + engaged in multi-turn movement (running via shift+direction or + control+direction and so forth, or via the travel command or mouse click). The possible values are: teleport - update the map after movement has finished; @@ -4536,19 +4545,10 @@ 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 ac- - tual 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. Persistent. - - safe_pet - Prevent you from (knowingly) attacking your pets (default on). - Persistent. + This option only affects the game's screen display, not the - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4558,8 +4558,17 @@ + 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. Persistent. + + safe_pet + Prevent you from (knowingly) attacking your pets (default on). + Persistent. + safe_wait - Prevents you from waiting or searching when next to a hostile + Prevents you from waiting or searching when next to a hostile monster (default on). Persistent. sanity_check @@ -4567,8 +4576,8 @@ 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 + 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. @@ -4577,9 +4586,9 @@ off). Persistent. showrace - Display yourself as the glyph for your race, rather than the - glyph for your role (default off). Note that this setting af- - fects only the appearance of the display, not the way the game + Display yourself as the glyph for your race, rather than the + glyph for your role (default off). Note that this setting af- + fects only the appearance of the display, not the way the game treats you. Persistent. showscore @@ -4589,32 +4598,23 @@ silent Suppress terminal beeps (default on). Persistent. - sortloot - Controls the sorting behavior of the pickup lists for inventory - and #loot commands and some others. Persistent. The possible - values are: + sortdiscoveries + Controls the sorting behavior for the output of the `\' and ``' + commands. Persistent. - full - always sort the lists; - 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. + The possible values are: - sortpack - Sort the pack contents by type when displaying inventory (de- - fault on). Persistent. - - sparkle - Display a sparkly effect when a monster (including yourself) is - hit by an attack to which it is resistant (default on). Per- - sistent. - - standout - Boldface monsters and "--More--" (default off). Persistent. + 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 fully identified types; + c - list by class, alphabetically within each class; - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4624,63 +4624,63 @@ + a - list alphabetically across all classes. + + 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 #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 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 (de- + fault on). Persistent. + + sparkle + Display a sparkly effect when a monster (including yourself) is + hit by an attack to which it is resistant (default on). Per- + sistent. + + standout + Boldface monsters and "--More--" (default off). Persistent. + statushilites - Controls how many turns status hilite behaviors highlight the - field. If negated or set to zero, disables status hiliting. + Controls how many turns status hilite behaviors highlight the + field. If negated or set to zero, disables status hiliting. See "Configuring 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 + This option may be set to a NetHack version level to suppress + alert notification messages about feature changes for that and prior versions (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 "symset:default" to explicitly select the default + 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 "symset:default" to explicitly select the default symbols. time - Show the elapsed game time in turns on bottom line (default + Show the elapsed game time in turns on bottom line (default off). Persistent. timed_delay - When pausing momentarily for display effect, such as with ex- - plosions and moving objects, use a timer rather than sending - extra characters to the screen. (Applies to "tty" interface - only; "X11" interface always uses a timer based delay. The de- - fault is on if configured into the program.) Persistent. - - tombstone - Draw a tombstone graphic upon your death (default on). Persis- - tent. - - toptenwin - Put the ending display in a NetHack window instead of on stdout - (default off). Setting this option makes the score list visi- - ble when a windowing version of NetHack is started without a - parent window, but it no longer leaves the score list around - after game end on a terminal or emulating window. - - travel - Allow the travel command via mouse click (default on). Turning - this option off will prevent the game from attempting unintend- - ed moves if you make inadvertent mouse clicks on the map win- - dow. Does not affect traveling via the `_' ("#travel") com- - mand. Persistent. - - verbose - Provide more commentary during the game (default on). Persis- - tent. + When pausing momentarily for display effect, such as with - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4690,10 +4690,37 @@ + explosions and moving objects, use a timer rather than sending + extra characters to the screen. (Applies to "tty" interface + only; "X11" interface always uses a timer based delay. The de- + fault is on if configured into the program.) Persistent. + + tombstone + Draw a tombstone graphic upon your death (default on). Persis- + tent. + + toptenwin + Put the ending display in a NetHack window instead of on stdout + (default off). Setting this option makes the score list visi- + ble when a windowing version of NetHack is started without a + parent window, but it no longer leaves the score list around + after game end on a terminal or emulating window. + + travel + Allow the travel command via mouse click (default on). Turning + this option off will prevent the game from attempting unintend- + ed moves if you make inadvertent mouse clicks on the map win- + dow. Does not affect traveling via the `_' ("#travel") com- + mand. Persistent. + + verbose + Provide more commentary during the game (default on). Persis- + tent. + whatis_coord - When using the `/' or `;' commands to look around on the map - with autodescribe on, display coordinates after the descrip- - tion. Also works in other situations where you are asked to + When using the `/' or `;' commands to look around on the map + with autodescribe on, display coordinates after the descrip- + tion. Also works in other situations where you are asked to pick a location. The possible settings are: @@ -4710,43 +4737,16 @@ whatis_filter When getting a location on the map, and using the keys to cycle - through next and previous targets, allows filtering the possi- + through next and previous targets, allows filtering the possi- ble 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 were last moving towards. - - Filtering can also be changed when getting a location with the - "getpos.filter" key. - - 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. (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 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 de- - pends 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 op- - tions. For multiple lines in a configuration file, that would - be the first non-comment line. For a comma-separated list in - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4756,6 +4756,33 @@ + 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 + "getpos.filter" key. + + 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. (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 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 de- + pends 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 op- + tions. 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 option in the list. @@ -4764,55 +4791,28 @@ 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 + 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 + 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 adjust- - ing 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 + 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 adjust- + ing 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. Some options - are dynamic and can be specified during the game with the `O' + 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). - - ascii_map - If NetHack can, it should display the map using simple charac- - ters (letters and punctuation) rather than tiles graphics. In - some cases, characters can be augmented with line-drawing sym- - bols; use the symset option to select a symbol set such as - DECgraphics or IBMgraphics if your display supports them. Set- - ting ascii_map to True forces tiled_map to be False. - - color - If NetHack can, it should display color if it can for different - monsters, objects, and dungeon features. - - eight_bit_tty - If NetHack can, it should pass eight-bit character values (for - example, specified with the traps option) straight through to - your terminal (default off). - - font_map - if NetHack can, it should use a font by the chosen name for the - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4822,10 +4822,37 @@ + 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). + + ascii_map + If NetHack can, it should display the map using simple charac- + ters (letters and punctuation) rather than tiles graphics. In + some cases, characters can be augmented with line-drawing sym- + bols; use the symset option to select a symbol set such as + DECgraphics or IBMgraphics if your display supports them. Set- + ting ascii_map to True forces tiled_map to be False. + + color + If NetHack can, it should display color if it can for different + monsters, objects, and dungeon features. + + eight_bit_tty + If NetHack can, it should pass eight-bit character values (for + example, specified with the traps option) straight through to + your terminal (default off). + + font_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 + If NetHack can, it should use a font by the chosen name for menu windows. font_message @@ -4837,48 +4864,21 @@ status window. font_text - If NetHack can, it should use a font by the chosen name for + If NetHack can, it should use a font by the chosen name for text windows. font_size_map - If NetHack can, it should use this size font for the map win- + If NetHack can, it should use this size font for the map win- dow. 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. - - font_size_text - If NetHack can, it should use this size font for text windows. - - fullscreen - If NetHack can, it should try and display on the entire screen - rather than in a window. - - guicolor - Use color text and/or highlighting attributes when displaying - some non-map data (such as menu selector letters). Curses in- - terface only; default is on. - - large_font - If NetHack can, it should use a large font. - - map_mode - If NetHack can, it should display the map in the manner speci- - fied. - - player_selection - If NetHack can, it should pop up dialog boxes, or use prompts + If NetHack can, it should use this size font for the message - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -4888,6 +4888,33 @@ + 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. + + fullscreen + If NetHack can, it should try and display on the entire screen + rather than in a window. + + guicolor + Use color text and/or highlighting attributes when displaying + some non-map data (such as menu selector letters). Curses in- + terface only; default is on. + + large_font + If NetHack can, it should use a large font. + + map_mode + If NetHack can, it should display the map in the manner speci- + fied. + + player_selection + If NetHack can, it should pop up dialog boxes, or use prompts for character selection. popup_dialog @@ -4895,56 +4922,29 @@ preload_tiles If NetHack can, it should preload tiles into memory. For exam- - ple, in the protected mode MS-DOS version, control whether - tiles get pre-loaded into RAM at the start of the game. Doing - so enhances performance of the tile graphics, but uses more + ple, in the protected mode MS-DOS version, control whether + tiles get pre-loaded into RAM at the start of the game. Doing + so enhances performance of the tile graphics, but uses more memory. (default on). Cannot be set with the `O' command. scroll_amount - If NetHack can, it should scroll the display by this number of + If NetHack can, it should scroll the display by this number of cells when the hero reaches the scroll_margin. scroll_margin - If NetHack can, it should scroll the display when the hero or - cursor is this number of cells away from the edge of the win- + If NetHack can, it should scroll the display when the hero or + cursor is this number of cells away from the edge of the win- dow. selectsaved - If NetHack can, it should display a menu of existing saved + If NetHack can, it should display a menu of existing saved games for the player to choose from at game startup, if it can. Not all ports support this option. - softkeyboard - 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). - - statuslines - Number of lines for traditional below-the-map status display. - Acceptable values are 2 and 3 (default is 2). - - For 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 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 uses the statuslines value differently. A value of 3 ren- - ders 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, reducing the height needed. For Qt, - statuslines can only be set in the configuration file or via - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -4954,63 +4954,63 @@ + softkeyboard + 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). + + statuslines + Number of lines for traditional below-the-map status display. + Acceptable values are 2 and 3 (default is 2). + + For 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 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 uses the statuslines value differently. A value of 3 ren- + ders 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, reducing the height needed. For Qt, + statuslines can only be set in the configuration file or via NETHACKOPTIONS, not with the `O' command. term_cols and term_rows - Curses interface only. Number of columns and rows to use for + Curses interface only. Number of columns and rows to use for the display. Curses will attempt to resize to the values spec- - ified but will settle for smaller sizes if they are too big. + ified 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. tile_height - Specify the preferred height of each tile in a tile capable + Specify the preferred height of each tile in a tile capable port. tile_width 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, possi- - bly augmented by line-drawing symbols). Setting tiled_map to + If NetHack can, it should display the map using tiles graphics + rather than simple characters (letters and punctuation, possi- + bly 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). - use_inverse - If NetHack can, it should display inverse when the game speci- - fies it. - - vary_msgcount - 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 in- - terface only. Acceptable values are - - 0 - off, never show borders - 1 - on, always show borders - 2 - auto, on if display is at least (24+2)x(80+2) (default) - - (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 for align_status set to left or right.) - - windowcolors - If NetHack can, it should display windows with the specified - foreground/background colors. Windows GUI only. The format is - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -5020,18 +5020,46 @@ + 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 speci- + fies it. + + vary_msgcount + 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 in- + terface only. Acceptable values are + + 0 - off, never show borders + 1 - on, always show borders + 2 - auto, on if display is at least (24+2)x(80+2) (default) + + (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 for align_status set to left or right.) + + windowcolors + If NetHack can, it should display windows with the specified + foreground/background colors. Windows GUI only. The format is + OPTION=windowcolors:wintype foreground/background - where wintype is one of "menu", "message", "status", or - "text", and foreground and background are colors, either a hexa- - decimal \'#rrggbb', one of the named colors (black, red, green, - brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- - blue, brightmagenta, brightcyan, white, trueblack, gray, purple, - silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one - of Windows UI colors (activeborder, activecaption, appworkspace, - background, btnface, btnshadow, btntext, captiontext, graytext, - greytext, highlight, highlighttext, inactiveborder, inactivecap- - tion, menu, menutext, scrollbar, window, windowframe, window- + where wintype is one of "menu", "message", "status", or + "text", and foreground and background are colors, either a hexa- + decimal \'#rrggbb', one of the named colors (black, red, green, + brown, blue, magenta, cyan, orange, brightgreen, yellow, bright- + blue, brightmagenta, brightcyan, white, trueblack, gray, purple, + silver, maroon, fuchsia, lime, olive, navy, teal, aqua), or one + of Windows UI colors (activeborder, activecaption, appworkspace, + background, btnface, btnshadow, btntext, captiontext, graytext, + greytext, highlight, highlighttext, inactiveborder, inactivecap- + tion, menu, menutext, scrollbar, window, windowframe, window- text). wraptext @@ -5040,12 +5068,24 @@ 9.6. Platform-specific Customization options - Here are explanations of options that are used by specific + Here are explanations of options that are used by specific platforms or ports to customize and change the port behavior. altkeyhandler - Select an alternate keystroke handler dll to load (Win32 tty - NetHack only). The name of the handler is specified without + Select an alternate keystroke handler dll to load (Win32 tty + NetHack only). The name of the handler is specified without + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 78 + + + the .dll extension and without any path information. Cannot be set with the `O' command. @@ -5055,37 +5095,25 @@ altmeta On other (non-Amiga) 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 + 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 + 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 + 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 sec- - ond ESC to finish cancelling such a count. At other prompts a + the count by typing ESC will leave NetHack waiting for another + character to complete the two character sequence. Type a sec- + ond 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 ma- - chines with an IBM PC compatible BIOS ROM (default off, OS/2, + the keyboard (allowing the use of arrow keys to move) on ma- + chines with an IBM PC compatible BIOS ROM (default off, OS/2, PC, and ST NetHack only). - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 78 - - - flush (default off, Amiga NetHack only). @@ -5096,53 +5124,25 @@ (default on, Mac NetHack only). rawio - Force raw (non-cbreak) mode for faster output and more bullet- - proof 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 + Force raw (non-cbreak) mode for faster output and more bullet- + proof 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. subkeyvalue - (Win32 tty NetHack only). May be used to alter the value of + (Win32 tty NetHack only). May be used to alter the value of keystrokes that the operating system returns to NetHack to help - compensate for international keyboard issues. OPTIONS=subkey- - value:171/92 will return 92 to NetHack, if 171 was originally + compensate for international keyboard issues. OPTIONS=subkey- + value:171/92 will return 92 to NetHack, if 171 was originally going to be returned. You can use multiple subkeyvalue assign- - ments in the configuration file if needed. Cannot be set with + ments in the configuration file if needed. Cannot be set with the `O' command. - video - Set the video mode used (PC NetHack only). Values are "autode- - tect", "default", "vga", or "vesa". Setting "vesa" will cause - the game to display tiles, using the full capability of the VGA - hardware. Setting "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 of those modes works. Cannot be set - with the `O' command. - - video_height - Set the VGA mode resolution height (MS-DOS only, with - video:vesa) - - video_width - 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 bright.cyan. Cannot be set with the `O' - command. - - videoshades - Set the intensity level of the three gray scales available - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -5152,18 +5152,47 @@ - (default dark normal light, PC NetHack only). If the game dis- - play is difficult to read, try adjusting these scales; if this - does not correct the problem, try !color. Cannot be set with - the `O' command. + video + Set the video mode used (PC NetHack only). Values are "autode- + tect", "default", "vga", or "vesa". Setting "vesa" will cause + the game to display tiles, using the full capability of the VGA + hardware. Setting "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 of those modes works. Cannot be set + with the `O' command. + + video_height + Set the VGA mode resolution height (MS-DOS only, with + video:vesa) + + video_width + 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 bright.cyan. Cannot be set with the `O' + command. + + videoshades + Set the intensity level of the three gray scales available (de- + fault dark normal light, PC NetHack only). If the game display + is difficult to read, try adjusting these scales; if this does + not correct the problem, try !color. Cannot be set with the + `O' command. 9.7. Regular Expressions - Regular expressions are normally POSIX extended regular ex- - pressions. It is possible to compile NetHack without regular ex- - pression support on a platform where there is no regular expres- - sion library. While this is not true of any modern platform, if - your NetHack was built this way, patterns are instead glob pat- + Regular expressions are normally POSIX extended regular ex- + pressions. It is possible to compile NetHack without regular ex- + pression support on a platform where there is no regular expres- + sion library. While this is not true of any modern platform, if + your NetHack was built this way, patterns are instead glob pat- terns. This applies to Autopickup exceptions, Message types, Menu colors, and User sounds. @@ -5172,43 +5201,14 @@ 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 + By placing autopickup_exception lines in your configuration + file, you can define patterns to be checked when the game is about to autopickup something. - autopickup_exception - Sets an exception to the pickup_types option. The autopick- - up_exception option should be followed by a regular expression - to be used as 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 oc- - cur 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 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 save and then restore your game. autopickup_ex- - ception rules and not saved with the game. - - Here are some examples: - - autopickup_exception="<*arrow" - autopickup_exception=">*corpse" - autopickup_exception=">* cursed*" - - 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 - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -5218,14 +5218,44 @@ - exclusion of items known to be cursed from autopickup. + autopickup_exception + Sets an exception to the pickup_types option. The autopick- + up_exception option should be followed by a regular expression + to be used as 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 oc- + cur 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 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 save and then restore your game. autopickup_ex- + ception rules and not saved with the game. + + Here are some examples: + + autopickup_exception="<*arrow" + autopickup_exception=">*corpse" + autopickup_exception=">* cursed*" + + 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 ex- + clusion of items known to be cursed from autopickup. 9.9. 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 + 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"), or a three-digit decimal ASCII code. @@ -5236,45 +5266,15 @@ BIND=v:loot Extended command keys - You can bind multiple keys to the same extended command. Un- - bind a key by using "nothing" as the extended command to bind - to. You can also bind the "", "", and "" + You can bind multiple keys to the same extended command. Un- + bind a 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 lines in the configuration file. You cannot bind ob- - ject symbols into menu accelerators. - - 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 "context", 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. With number_pad only. Default is `n'. - - doinv - Show inventory. With number_pad only. Default is `0'. - - fight - Prefix key to force fight a direction. Default is `F'. - - fight.numpad - Prefix key to force fight a direction. With number_pad only. - Default is `-'. - - getdir.help - When asked for a direction, the key to show the help. Default - is `?'. - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -5284,12 +5284,42 @@ + Menu accelerator keys + The menu control or accelerator keys can also be rebound via + OPTIONS lines in the configuration file. You cannot bind ob- + ject symbols into menu accelerators. + + 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 "context", 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. With number_pad only. Default is `n'. + + doinv + Show inventory. With number_pad only. Default is `0'. + + fight + Prefix key to force fight a direction. Default is `F'. + + fight.numpad + Prefix key to force fight a direction. With number_pad only. + Default is `-'. + + getdir.help + When asked for a direction, the key to show the help. Default + is `?'. + getdir.self - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `.'. getdir.self2 - When asked for a direction, the key to target yourself. De- + When asked for a direction, the key to target yourself. De- fault is `s'. getpos.autodescribe @@ -5301,46 +5331,16 @@ esting thing. Default is `a'. getpos.all.prev - When asked for a location, the key to go to previous closest + When asked for a location, the key to go to previous closest interesting thing. Default is `A'. getpos.door.next - When asked for a location, the key to go to next closest door + When asked for a location, the key to go to next closest door or 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'. - - getpos.help - 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 mon- - ster. Default is `m'. - - getpos.mon.prev - When asked for a location, the key to go to previous closest - monster. Default is `M'. - - getpos.obj.next - When asked for a location, the key to go to next closest ob- - ject. Default is `o'. - - getpos.obj.prev - When asked for a location, the key to go to previous closest - object. Default is `O'. - - getpos.menu - When asked for a location, and using one of the next or previ- - ous keys to cycle through targets, toggle showing a menu in- - stead. Default is `!'. - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -5350,63 +5350,63 @@ + getpos.door.prev + When asked for a location, the key to go to previous closest + door or doorway. Default is `D'. + + getpos.help + 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 mon- + ster. Default is `m'. + + getpos.mon.prev + When asked for a location, the key to go to previous closest + monster. Default is `M'. + + getpos.obj.next + When asked for a location, the key to go to next closest ob- + ject. Default is `o'. + + getpos.obj.prev + When asked for a location, the key to go to previous closest + object. Default is `O'. + + getpos.menu + When asked for a location, and using one of the next or previ- + ous keys to cycle through targets, toggle showing a menu in- + stead. 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 + 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 + 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 + When asked for a location, the key to choose the location, and possibly ask for more info. Default is `.'. getpos.pick.once - When asked for a location, the key to choose the location, and + When asked for a location, the key to choose the location, and skip asking for more info. Default is `,'. getpos.pick.quick When asked for a location, the key to choose the location, skip - asking for more info, and exit the location asking loop. De- + asking for more info, and exit the location asking loop. De- fault is `;'. - getpos.pick.verbose - 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. De- - fault is `@'. - - getpos.unexplored.next - When asked for a location, the key to go to next closest unex- - plored location. Default is `x'. - - getpos.unexplored.prev - When asked for a location, the key to go to previous closest - unexplored location. Default is `X'. - - getpos.valid - When asked for a location, the key to go to show valid target - locations. Default is `$'. - - getpos.valid.next - When asked for a location, the key to go to next closest valid - location. Default is `z'. - - getpos.valid.prev - When asked for a location, the key to go to previous closest - valid location. Default is `Z'. - - nopickup - Prefix key to move without picking up items. Default is `m'. - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -5416,11 +5416,42 @@ + getpos.pick.verbose + 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. De- + fault is `@'. + + getpos.unexplored.next + When asked for a location, the key to go to next closest unex- + plored location. Default is `x'. + + getpos.unexplored.prev + When asked for a location, the key to go to previous closest + unexplored location. Default is `X'. + + getpos.valid + When asked for a location, the key to go to show valid target + locations. Default is `$'. + + getpos.valid.next + When asked for a location, the key to go to next closest valid + location. Default is `z'. + + getpos.valid.prev + When asked for a location, the key to go to previous closest + valid location. Default is `Z'. + + nopickup + Prefix key to move without picking up items. Default is `m'. + redraw Key to redraw the screen. Default is `^R'. redraw.numpad - Key to redraw the screen. With number_pad only. Default is + Key to redraw the screen. With number_pad only. Default is `^L'. repeat @@ -5433,13 +5464,25 @@ Prefix key to run towards a direction. Default is `G'. run.nopickup - Prefix key to run towards a direction without picking up items + Prefix key to run towards a direction without picking up items on the way. Default is `M'. run.numpad Prefix key to run towards a direction. With number_pad only. - Default is `5' when number_pad is set to 1 or 3, otherwise + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 84 + + + + Default is `5' when number_pad is set to 1 or 3, otherwise `M-5' when it is set to 2 or 4. rush @@ -5448,7 +5491,7 @@ rush.numpad Prefix key to rush towards a direction. With number_pad only. - Default is `M-5' when number_pad is set to 1 or 3, otherwise + Default is `M-5' when number_pad is set to 1 or 3, otherwise `5' when it is set to 2 or 4. 9.10. Configuring Message Types @@ -5456,7 +5499,7 @@ 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 + In general, the configuration file entries to describe the message types look like this: MSGTYPE=type "pattern" type - how the message should be shown; @@ -5469,76 +5512,33 @@ 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 + norep - show the message once, but not again if no other mes- + sage is shown in between. - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 84 - - - - message is shown in between. - - Here's an example of message types using NetHack's internal + 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 + specifies that whenever a message "You feel hungry" is shown, + the user is prompted with more-prompt, and a message matching "You displaced ." is not shown at all. - The order of the defined MSGTYPE lines is important; the last - matching rule is used. Put the general case first, exceptions + The order of the defined MSGTYPE lines is important; the last + matching rule is used. Put the general case first, exceptions below them. 9.11. 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 + when 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 color mappings look like this: - - MENUCOLOR="pattern"=color&attribute - - pattern - the pattern to match; - color - the color to use for lines matching the pat- - tern; - attribute - the attribute to use for lines matching the - pattern. The attribute is optional, and if - left out, you must also leave out the preced- - ing 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, gray, orange, light-green, yellow, light-blue, light-ma- - genta, light-cyan, and white. And no-color, the default fore- - ground color, which isn't necessarily the same as any of the - other colors. - - Allowed attributes are none, bold, dim, underline, blink, and - inverse. "Normal" is a synonym for "none". Note that the - platform used may interpret the attributes any way it wants. - - Here's an example of menu colors using NetHack's internal pat- - tern matching facility: - - MENUCOLOR="* blessed *"=green - MENUCOLOR="* cursed *"=red - MENUCOLOR="* cursed *(being worn)"=red&underline - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -5548,63 +5548,63 @@ - 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 line will be shown in red - color and underlined. You can have multiple MENUCOLOR en- - tries in your configuration file, and the last MENUCOLOR - line that matches a menu line will be used for the line. + 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 pat- + tern; + attribute - the attribute to use for lines matching the + pattern. The attribute is optional, and if + left out, you must also leave out the preced- + ing 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, gray, orange, light-green, yellow, light-blue, light-ma- + genta, light-cyan, and white. And no-color, the default fore- + ground color, which isn't necessarily the same as any of the + other colors. + + Allowed attributes are none, bold, dim, underline, blink, and + inverse. "Normal" is a synonym for "none". Note that the + platform used may interpret the attributes any way it wants. + + Here's an example of menu colors using NetHack's internal pat- + tern 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 be shown in green color, lines with " cursed " will be + shown in red, and lines with " cursed " followed by "(being + worn)" on the same line will be shown in red color and under- + lined. You can have multiple MENUCOLOR entries in your config- + uration file, and the last MENUCOLOR line that matches a menu + line will be used for the line. Note that if you intend to have one or more color specifica- - tions match " uncursed ", you will probably want to turn the im- + tions match " uncursed ", you will probably want to turn the im- plicit_uncursed option off so that all items known to be uncursed are actually displayed with the "uncursed" description. 9.12. Configuring User Sounds - Some platforms allow you to define sound files to be played - when a message that matches a user-defined pattern is delivered + Some platforms allow you to define sound files to be played + when a message that matches a user-defined pattern is delivered to the message 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 user sounds to messages: - - SOUNDDIR - The directory that houses the sound files to be played. - - SOUND - 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 - 3.6); - pattern - the pattern to match; - sound file - the sound file to play; - volume - the volume to be set while playing the sound - file; - sound index - optional; the index corresponding to a sound - file. - - The pattern should be a POSIX extended regular expression. - - 9.13. 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 - setting thresholds to change the color or appearance of fields in - the status display. - - The format for defining status colors is: - - OPTION=hilite_status:field-name/behavior/color&attributes - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -5614,8 +5614,41 @@ - For example, the following line in your configuration file - will cause the hitpoints field to display in the color red if + The following configuration file entries are relevant to + mapping user sounds to messages: + + SOUNDDIR + The directory that houses the sound files to be played. + + SOUND + 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 + 3.6); + pattern - the pattern to match; + sound file - the sound file to play; + volume - the volume to be set while playing the sound + file; + sound index - optional; the index corresponding to a sound + file. + + The pattern should be a POSIX extended regular expression. + + 9.13. 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 + setting thresholds to change the color or appearance of fields in + the status display. + + The format for defining status colors is: + + 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 hitpoints drop to or below a threshold of 30%: OPTION=hilite_status:hitpoints/<=30%/red/normal @@ -5623,38 +5656,50 @@ (That example is actually specifying red&normal for <=30% and no- color&normal for >30%.) - For another example, the following line in your configura- - tion file will cause wisdom to be displayed red if it drops and + For another example, the following line in your configura- + tion 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, + Allowed colors are black, red, green, brown, blue, magenta, cyan, gray, orange, light-green, yellow, light-blue, light-magen- - ta, light-cyan, and white. And "no-color", the default fore- + ta, light-cyan, and white. And "no-color", the default fore- ground 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, blink, - and inverse. "Normal" is a synonym for "none"; they should not + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 87 + + + + Allowed attributes are none, bold, dim, underline, blink, + 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. + 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 - interpret the attributes any way it wants. For example, on some + Note that the display may substitute or ignore particular + attributes 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 ver- sa. On others, issuing an attribute request while another is al- - ready set up will replace the earlier attribute rather than com- - bine with it. Since NetHack issues attribute requests sequen- + ready set up will replace the earlier attribute rather than com- + bine with it. Since NetHack issues attribute requests sequen- tially (at least with the tty interface) rather than all at once, the only way a situation like that can be controlled is to speci- fy just one attribute. - You can adjust the appearance of the following status + You can adjust the appearance of the following status fields: title dungeon-level experience-level strength gold experience @@ -5665,28 +5710,16 @@ 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 - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 87 - - - - polymorphed. "experience", "time", and "score" are condition- + 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 condition- ally displayed depending upon your other option settings. - Instead of a behavior, "condition" takes the following condi- - tion flags: stone, slime, strngl, foodpois, termill, blind, - deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- - jor_troubles" as an alias for stone through termill, "mi- + Instead of a behavior, "condition" takes the following condi- + tion flags: stone, slime, strngl, foodpois, termill, blind, + deaf, stun, conf, hallu, lev, fly, and ride. You can use "ma- + jor_troubles" as an alias for stone through termill, "mi- nor_troubles" for blind through hallu, "movement" for lev, fly, and ride, and "all" for every condition. @@ -5695,48 +5728,15 @@ * "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 + * "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 val- - ue 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 val- - ue, 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 be- - tween 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 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 corresponding maxi- - mum 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 ex- - perience level to the start of the next level. So if lev- - el 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 experience point short of the next lev- - el. - - * absolute value sets the attribute when the field value - matches that number. The number must be 0 or higher, ex- - cept for "armor-class' which allows negative values, and - may optionally be preceded by `='. If the number is pre- - ceded by `<=' or `>=' instead, it also matches when value - is below or above. If the prefix is `<' or `>', only + ue changes. This attribute times out after statushilites - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -5746,22 +5746,72 @@ + turns. (If a field has both a "changed" rule and an "up" + or "down" rule which matches a change in the field's val- + ue, 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 be- + tween 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 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 corresponding maxi- + mum 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 ex- + perience level to the start of the next level. So if lev- + el 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 experience point short of the next lev- + el. + + * absolute value sets the attribute when the field value + matches that number. The number must be 0 or higher, ex- + cept for "armor-class' which allows negative values, and + may optionally be preceded by `='. If the number is pre- + ceded by `<=' or `>=' instead, it also matches when value + is below or above. If the prefix is `<' or `>', only match when strictly above or below. * text match sets the attribute when the field value matches - the text. Text matches can only be used for "alignment", - "carrying-capacity", "hunger", "dungeon-level", and "ti- - tle". For title, only the role's rank title is tested; + the text. Text matches can only be used for "alignment", + "carrying-capacity", "hunger", "dungeon-level", and "ti- + tle". 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 + The in-game options menu can help you determine the correct syntax for a configuration file. - The whole feature can be disabled by setting option sta- + The whole feature can be disabled by setting option sta- tushilites to 0. Example hilites: + + + + + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 89 + + + OPTION=hilite_status: gold/up/yellow/down/brown OPTION=hilite_status: characteristics/up/green/down/red OPTION=hilite_status: hitpoints/100%/gray&normal @@ -5777,41 +5827,28 @@ NetHack can load entire symbol sets from the symbol file. - The options that are used to select a particular symbol set + 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 dis- + Set the name of the symbol set that you want to load for dis- play on the rogue level. - You can also override one or more symbols using the SYMBOLS - and ROGUESYMBOLS configuration file options. Symbols are speci- + You can also override one or more symbols using the SYMBOLS + and ROGUESYMBOLS configuration file options. Symbols are speci- fied 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 + 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 as a control character. NetHack Symbols Symbol Name Description ----------------------------------------------------------------- - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 89 - - - S_air (air) _ S_altar (altar) " S_amulet (amulet) @@ -5828,6 +5865,19 @@ - S_blcorn (bottom left corner) b S_blob (blob) + S_book (spellbook) + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 90 + + + ) S_boomleft (boomerang open left) ( S_boomright (boomerang open right) ` S_boulder (boulder) @@ -5865,19 +5915,6 @@ ! S_flashbeam (flash beam) % S_food (piece of food) { S_fountain (fountain) - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 90 - - - F S_fungus (fungus or mold) * S_gem (gem or rock) S_ghost (ghost) @@ -5894,6 +5931,19 @@ ^ S_hole (hole) @ S_human (human or elf) h S_humanoid (humanoid) + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 91 + + + - S_hwall (horizontal wall) . S_ice (ice) i S_imp (imp or minor demon) @@ -5931,19 +5981,6 @@ q S_quadruped (quadruped) Q S_quantmech (quantum mechanic) = S_ring (ring) - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 91 - - - ` S_rock (boulder or statue) r S_rodent (rodent) ^ S_rolling_boulder_trap (rolling boulder trap) @@ -5960,6 +5997,19 @@ ^ S_squeaky_board (squeaky board) 0 S_ss1 (magic shield 1 of 4) # S_ss2 (magic shield 2 of 4) + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 92 + + + @ S_ss3 (magic shield 3 of 4) * S_ss4 (magic shield 4 of 4) ^ S_statue_trap (statue trap) @@ -5997,19 +6047,6 @@ + S_vcdoor (closed door in vertical wall) . S_venom (splash of venom) ^ S_vibrating_square (vibrating square) - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 92 - - - . S_vodbridge (vertical lowered drawbridge) - S_vodoor (open door in vertical wall) v S_vortex (vortex) @@ -6026,47 +6063,10 @@ Y S_yeti (apelike creature) Z S_zombie (zombie) z S_zruty (zruty) - S_pet_override (any pet if ACCESSIBILITY=1 is set) - S_hero_override (hero if ACCESSIBILITY=1 is set) - - Notes: - - * 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 en- - abled 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 de- - pict. So S_rock is only used for boulders and not used at all - if overridden by the more specific S_boulder. - - 9.15. 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 the MS-DOS versions - of NetHack completely 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 capabili- - ties of their screen-readers to be quite valuable. 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 charac- - ter 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 location of items on the screen. - - NetHack can also be compiled with support for sending the - game messages to an external program, such as a text-to-speech - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -6076,63 +6076,63 @@ - synthesizer. If the "#version" extended command shows "external - program as a message handler", your NetHack has been compiled + S_pet_override (any pet if ACCESSIBILITY=1 is set) + S_hero_override (hero if ACCESSIBILITY=1 is set) + + Notes: + + * 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 en- + abled 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 de- + pict. So S_rock is only used for boulders and not used at all + if overridden by the more specific S_boulder. + + 9.15. 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 the MS-DOS versions + of NetHack completely 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 capabili- + ties of their screen-readers to be quite valuable. 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 charac- + ter 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 location of items on the screen. + + 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 message 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 environment variable NETHACK_MSGHANDLER + and other POSIX systems, define MSGHANDLER to enable it. To use + the capability, set the environment variable NETHACK_MSGHANDLER to an executable, which will be executed with the game message as the program's only parameter. - While it is not difficult for experienced users to edit the - defaults.nh file to accomplish this, novices may find this task + While it is not difficult for experienced users to edit the + defaults.nh file to accomplish this, novices may find this task somewhat daunting. Included within the "symbols" file of all of- ficial distributions of NetHack is a symset called NHAccess. Se- - lecting that symset in your configuration file will cause the - game to run in a manner accessible to the blind. After you have - gained some experience with the game and with editing files, you + lecting that symset in your configuration file will cause the + game to run in a manner accessible to the blind. After you have + gained some experience with the game and with editing files, you may want to alter settings via SYMBOLS= and ROGUESYMBOLS= in your - configuration file to better suit your preferences. See the pre- - vious section for the special symbols S_pet_override to force a - consistent symbol for all pets and S_hero_override to force a - unique symbol for the player character if accessibility is en- - abled in the sysconf file. - - The most crucial settings to make the game more accessible - are: - - symset:NHAccess - Load a symbol set appropriate for use by blind players. - - roguesymset:NHAccess - Load a symbol set for the rogue level that is appropriate for - use by blind players. - - menustyle:traditional - This will assist in the interface to speech synthesizers. - - nomenu_overlay - 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 the traditional Rogue-like commands. - - autodescribe - Automatically describe the terrain under the cursor when tar- - geting. - - mention_walls - 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 - coordinates relative to your character. - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6142,63 +6142,63 @@ + configuration file to better suit your preferences. See the pre- + vious section for the special symbols S_pet_override to force a + consistent symbol for all pets and S_hero_override to force a + unique symbol for the player character if accessibility is en- + abled in the sysconf file. + + The most crucial settings to make the game more accessible + are: + + symset:NHAccess + Load a symbol set appropriate for use by blind players. + + roguesymset:NHAccess + Load a symbol set for the rogue level that is appropriate for + use by blind players. + + menustyle:traditional + This will assist in the interface to speech synthesizers. + + nomenu_overlay + 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 the traditional Rogue-like commands. + + autodescribe + Automatically describe the terrain under the cursor when tar- + geting. + + mention_walls + 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 + coordinates relative to your character. + whatis_filter:area - When targeting with cursor, filter possible locations so only - those in the same area (eg. same room, or same corridor) are + When targeting with cursor, filter possible locations so only + those in the same area (eg. same room, or same corridor) are considered. whatis_moveskip - When targeting with cursor and using fast-move, skip the same + When targeting with cursor and using fast-move, skip the same glyphs 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 in- + Prevent updates to the status lines at the bottom of the + screen, if your screen-reader reads those lines. The same in- formation can be seen via the "#attributes" command. - 9.16. Global Configuration for System Administrators - - If NetHack is compiled with the SYSCF option, a system ad- - ministrator 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 us- - es 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 mode. - - SHELLERS = A list of users who are allowed to use the shell es- - cape 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. - - MAXPLAYERS = Limit the maximum number of games that can be run- - ning at the same time. - - SAVEFORMAT = A list of up to two save file formats separated by - space. The first format in the list will written as well as - read. The second format will be read only if no save file in - the first format exists. Valid choices are "historical" for - binary writing of entire structs, "lendian" for binary writing - of each field in little-endian order, "ascii" for writing the - save file content in ascii text. - - BONESFORMAT = A list of up to two bones file formats separated - by space. The first format in the list will written as well as - read. The second format will be read only if no bones files in - the first format exist. Valid choices are "historical" for bi- - nary writing of entire structs, "lendian" for binary writing of - each field in little-endian order, "ascii" for writing the - bones file content in ascii text. - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -6208,22 +6208,75 @@ - SUPPORT = A string explaining how to get local support (no de- + 9.16. Global Configuration for System Administrators + + If NetHack is compiled with the SYSCF option, a system ad- + ministrator 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 us- + es 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 mode. + + SHELLERS = A list of users who are allowed to use the shell es- + cape 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. + + MAXPLAYERS = Limit the maximum number of games that can be run- + ning at the same time. + + SAVEFORMAT = A list of up to two save file formats separated by + space. The first format in the list will written as well as + read. The second format will be read only if no save file in + the first format exists. Valid choices are "historical" for + binary writing of entire structs, "lendian" for binary writing + of each field in little-endian order, "ascii" for writing the + save file content in ascii text. + + BONESFORMAT = A list of up to two bones file formats separated + by space. The first format in the list will written as well as + read. The second format will be read only if no bones files in + the first format exist. Valid choices are "historical" for bi- + nary writing of entire structs, "lendian" for binary writing of + each field in little-endian order, "ascii" for writing the + bones file content in ascii text. + + SUPPORT = A string explaining how to get local support (no de- fault value). - RECOVER = A string explaining how to recover a game on this + 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, WIZ- + CHECK_PLNAME = Setting this to 1 will make the EXPLORERS, WIZ- ARDS, and SHELLERS check for the player name instead of the us- er's login name. + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 96 + + + 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 + UID (used identification number) checking for save files (to + verify that the user who is restoring is the same one who saved). The following options affect the score file: @@ -6232,26 +6285,26 @@ ENTRYMAX = Maximum number of entries in the score file. - POINTSMIN = Minimum number of points to get an entry in the + POINTSMIN = Minimum number of points to get an entry in the score file. - PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- + PERS_IS_UID = 0 or 1 to use user names or numeric userids, re- spectively, to identify unique people for the score file. - MAX_STATUENAME_RANK = Maximum number of score file entries to + MAX_STATUENAME_RANK = Maximum number of score file entries to use for random statue names (default is 10). - ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the - ability for players to set S_pet_override and S_hero_override + ACCESSIBILITY = 0 or 1 to disable or enable, respectively, the + ability for players to set S_pet_override and S_hero_override symbols in their configuration file. - PORTABLE_DEVICE_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 rather than at the standard loca- + PORTABLE_DEVICE_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 rather than at the standard loca- tions. DUMPLOGFILE = A filename where the end-of-game dumplog is - saved. Not defining this will prevent dumplog from being cre- + saved. Not defining this will prevent dumplog from being cre- ated. Only available if your game is compiled with DUMPLOG. Al- lows the following placeholders: @@ -6262,75 +6315,22 @@ %T - current time, UNIX timestamp format %d - game start time, YYYYMMDDhhmmss format %D - current time, YYYYMMDDhhmmss format - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 96 - - - %n - player name %N - first character of player name 10. Scoring - NetHack maintains a list of the top scores or scorers on + 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 + 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, 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 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 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 paltry cost of not getting on the high score - list. - - There are two ways of enabling explore mode. One is to - start the game with the -X command-line switch or with the play- - mode:explore option. The other is to issue the "#exploremode" - extended command while already playing the game. Starting a new - game in explore mode provides your character with a wand of wish- - ing in initial inventory; switching during play does not. The - other benefits of explore mode are left for the trepid reader to - discover. - - 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 pro- - vide god-like powers 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 - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6340,63 +6340,63 @@ + 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 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 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 paltry cost of not getting on the high score + list. + + There are two ways of enabling explore mode. One is to + start the game with the -X command-line switch or with the play- + mode:explore option. The other is to issue the "#exploremode" + extended command while already playing the game. Starting a new + game in explore mode provides your character with a wand of wish- + ing in initial inventory; switching during play does not. The + other benefits of explore mode are left for the trepid reader to + discover. + + 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 pro- + vide god-like powers 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 par- - ticular 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 + For some systems, the player must be logged in under a par- + ticular 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. - 12. Credits - - 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 Dungeons of Doom, by Ken Arromdee. - - 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 - Woodland, Mike Thome, and Jon Payne. - - Andries Brouwer did a major re-write while at Stichting - Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- - forming 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 ver- - sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- - nally 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, - producing PC HACK 1.01e, added support for DEC Rainbow graphics - in version 1.03g, and went on to produce at least four more ver- - sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- - sion numbers, not contemporary NetHack ones). - - 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, - 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 Hack, they were released by posting their - source code to Usenet where they remained available in various - archives accessible via ftp and uucp after expiring from the - newsgroup. - NetHack 3.7 December 16, 2020 + + NetHack 3.7 December 19, 2020 @@ -6406,63 +6406,63 @@ - Later, Mike coordinated a major re-write of the game, head- - ing a team which included Ken Arromdee, Jean-Christophe Collet, - Steve Creps, Eric Hendrickson, Izchak Miller, Eric S. Raymond, - John Rupley, Mike Threepoint, and Janet Walz, to produce NetHack + 12. Credits + + 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 Dungeons of Doom, by Ken Arromdee. + + 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 + Woodland, Mike Thome, and Jon Payne. + + Andries Brouwer did a major re-write while at Stichting + Mathematisch Centrum (now Centrum Wiskunde & Informatica), trans- + forming 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 ver- + sion 1.0 in December of 1984, then versions 1.0.1, 1.0.2, and fi- + nally 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, + producing PC HACK 1.01e, added support for DEC Rainbow graphics + in version 1.03g, and went on to produce at least four more ver- + sions (3.0, 3.2, 3.51, and 3.6; note that these are old Hack ver- + sion numbers, not contemporary NetHack ones). + + 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, + 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 Hack, they were released by posting their + source code to Usenet where they remained available in various + archives accessible via ftp and uucp after expiring from the + newsgroup. + + Later, Mike coordinated a major re-write of the game, head- + ing a team which included Ken Arromdee, Jean-Christophe Collet, + Steve Creps, 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 + 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. 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-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 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-structured 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 Addison, Mike Passaretti, and Olaf Seibert, developed - NetHack 3.1 for the Amiga. - - Norm Meluch and Kevin Smolkowski, with help from Carl Sche- - lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported - NetHack 3.1 to the PC. - - Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike - Engber, 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 de- - velopment, Bart House added a Think C port. - - Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- - ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua - Delahunty, was responsible for the VMS version of NetHack 3.1. - Michael Allison ported NetHack 3.1 to Windows NT. - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6472,63 +6472,63 @@ - Dean Luick, with help from David Cohrs, developed NetHack + 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-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 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-structured 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 Addison, Mike Passaretti, and Olaf Seibert, developed + NetHack 3.1 for the Amiga. + + Norm Meluch and Kevin Smolkowski, with help from Carl Sche- + lin, Stephen Spackman, Steve VanDevender, and Paul Winner, ported + NetHack 3.1 to the PC. + + Jon W{tte and Hao-yang Wang, with help from Ross Brown, Mike + Engber, 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 de- + velopment, Bart House added a Think C port. + + Timo Hakulinen ported NetHack 3.1 to OS/2. Eric Smith port- + ed NetHack 3.1 to the Atari. Pat Rankin, with help from Joshua + 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 X11. It drew the map as text rather than graphically but - included 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 ob- - ject types, just replacements for monster and object classes (so - one custom image for all "a" insects and another for all "[" ar- + included 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 ob- + ject types, just replacements for monster and object classes (so + one custom image for all "a" insects and another for all "[" ar- mor 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 ob- - jects rather than just their classes. He contributed them to the - NetHack Development Team which rechristened them "tiles", origi- - nal usage which has subsequently been picked up by various other - games. NetHack's tiles support 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 Alli- - son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin - Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- - ic 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 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 cancer and passed away. That - release of the game was dedicated to him by the development and - porting teams. - - Version 3.2 proved to be more stable than previous versions. - Many bugs were fixed, abuses eliminated, and game features tuned - for better game play. - - During the lifespan of NetHack 3.1 and 3.2, several enthusi- - asts of the game added their own modifications to the game and - made these "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 cast- - ing system with the Wizard Patch. Warwick Allison also ported - NetHack to use the Qt interface. - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6538,63 +6538,63 @@ - Warren Cheung combined SLASH with the Wizard Patch to pro- - duce Slash'EM, and with the help of Kevin Hugo, added more fea- - tures. Kevin later joined the NetHack Development Team and in- + 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 ob- + jects rather than just their classes. He contributed them to the + NetHack Development Team which rechristened them "tiles", origi- + nal usage which has subsequently been picked up by various other + games. NetHack's tiles support 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 Alli- + son, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, Kevin + Darcy, Timo Hakulinen, Steve Linhart, Dean Luick, Pat Rankin, Er- + ic 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 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 cancer and passed away. That + release of the game was dedicated to him by the development and + porting teams. + + Version 3.2 proved to be more stable than previous versions. + Many bugs were fixed, abuses eliminated, and game features tuned + for better game play. + + During the lifespan of NetHack 3.1 and 3.2, several enthusi- + asts of the game added their own modifications to the game and + made these "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 cast- + ing system with the Wizard Patch. Warwick Allison also ported + NetHack to use the Qt interface. + + Warren Cheung combined SLASH with the Wizard Patch to pro- + duce Slash'EM, and with the help of Kevin Hugo, added more fea- + tures. Kevin later joined the NetHack Development Team and in- corporated 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 + 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 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 intro- - duced an extra column in the file layout which prevented score - entries from being read back in correctly, interfering with in- - sertion 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 Al- - lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, - Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- - ber, 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 - separate race and profession. The Elf class was removed in pref- - erence 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, Barbar- - ians, 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 listing 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 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 NetHack runs on: - - Pat Rankin maintained 3.4 for VMS. - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6604,63 +6604,63 @@ - Michael Allison maintained NetHack 3.4 for the MS-DOS plat- + (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 intro- + duced an extra column in the file layout which prevented score + entries from being read back in correctly, interfering with in- + sertion 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 Al- + lison, Ken Arromdee, David Cohrs, Jessie Collet, Steve Creps, + Kevin Darcy, Timo Hakulinen, Kevin Hugo, Steve Linhart, Ken Lor- + ber, 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 + separate race and profession. The Elf class was removed in pref- + erence 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, Barbar- + ians, 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 listing 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 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 NetHack runs on: + + Pat Rankin maintained 3.4 for VMS. + + Michael Allison maintained NetHack 3.4 for the MS-DOS plat- form. Paul Winner and Yitzhak Sapir provided encouragement. - Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- + Dean Luick, Mark Modrall, and Kevin Hugo maintained and en- hanced 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 + 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 inter- - face for the Windows port. Alex Kompel also contributed a Win- + face for the Windows port. Alex Kompel also contributed a Win- dows 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 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 af- - ter he resurrected it for 3.3.1. - - The release of NetHack 3.4.3 in December 2003 marked the be- - ginning 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 continued 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 con- - tinue to be developed, maintained, and enjoyed by the community - to this day. - - In September 2014, an interim snapshot of the code under de- - velopment 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 Development 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. - - 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 - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6670,63 +6670,63 @@ - Stephenson, Janet Walz, and Paul Winner. In early 2015, ahead of - the release of 3.6.0, new members Sean Hunt, Pasi Kallinen, and - Derek S. Ray joined the NetHack Development Team. + 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. + + Christian "Marvin" Bressler maintained 3.4 for the Atari af- + ter he resurrected it for 3.3.1. + + The release of NetHack 3.4.3 in December 2003 marked the be- + ginning 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 continued 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 con- + tinue to be developed, maintained, and enjoyed by the community + to this day. + + In September 2014, an interim snapshot of the code under de- + velopment 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 Development 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. + + 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 Stephen- + son, Janet Walz, and Paul Winner. In early 2015, ahead of the + release of 3.6.0, new members 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 signif- - icant inspirations for many of the humorous and fun features - found in the game, author Terry Pratchett, passed away. NetHack + icant 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 + 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 - restructured. - - The NetHack Development Team, as well as Steve VanDevender - and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- - ate on various UNIX flavors and maintained the X11 interface. - - Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- - tained the port of NetHack 3.6 for Mac OSX. - - Michael Allison, David Cohrs, Bart House, Pasi Kallinen, - Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- - tained 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 up- - dated 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 contrib- - uted 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 con- - sisted 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 en- - hancements 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 May 2019. - - NetHack 3.6.3 was released on December 5, 2019 containing - over 190 bug fixes to NetHack 3.6.2. - - - NetHack 3.7 December 16, 2020 + NetHack 3.7 December 19, 2020 @@ -6736,10 +6736,51 @@ + restructured. + + The NetHack Development Team, as well as Steve VanDevender + and Kevin Smolkowski, ensured that NetHack 3.6 continued to oper- + ate on various UNIX flavors and maintained the X11 interface. + + Ken Lorber, Haoyang Wang, Pat Rankin, and Dean Luick main- + tained the port of NetHack 3.6 for Mac OSX. + + Michael Allison, David Cohrs, Bart House, Pasi Kallinen, + Alex Kompel, Dion Nicolaas, Derek S. Ray and Yitzhak Sapir main- + tained 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 up- + dated 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 contrib- + uted 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 con- + sisted 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 en- + hancements 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 May 2019. + + 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 security fix and a few bug fixes. - NetHack 3.6.5 was released on January 27, 2020 containing + 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 se- @@ -6748,22 +6789,35 @@ The official NetHack web site is maintained by Ken Lorber at https://www.nethack.org/. + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 104 + + + 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 + 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 dun- - geoneers who invest their time and effort into annual NetHack - tournaments such as Junethack, The November NetHack Tournament, + geoneers 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). - - - - - - - - - - - From time to time, some depraved individual out there in - netland sends a particularly intriguing modification to help out + 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 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 @@ -6789,19 +6843,6 @@ Dean Luick Kevin Hugo Ross Brown Del Lamb Kevin Sitze Sascha Wostmann Derek S. Ray Kevin Smolkowski Scott Bigham - - - - NetHack 3.7 December 16, 2020 - - - - - - NetHack Guidebook 104 - - - Deron Meranda Kevin Sweet Scott R. Turner Dion Nicolaas Lars Huttar Sean Hunt Dylan O'Donnell Leon Arnott Stephen Spackman @@ -6814,6 +6855,19 @@ Frederick Roeber Merlyn LeRoy Tim Lennan Gil Neiger Michael Allison Timo Hakulinen Greg Laskin Michael Feir Tom Almy + + + + NetHack 3.7 December 19, 2020 + + + + + + NetHack Guidebook 105 + + + Greg Olson Michael Hamel Tom West Gregg Wonderly Michael Sokolov Warren Cheung Hao-yang Wang Mike Engber Warwick Allison @@ -6821,7 +6875,7 @@ Irina Rempt-Drijfhout Mike Passaretti Izchak Miller Mike Stephenson - Brand and product names are trademarks or registered trade- + Brand and product names are trademarks or registered trade- marks of their respective holders. @@ -6858,7 +6912,19 @@ - NetHack 3.7 December 16, 2020 + + + + + + + + + + + + + NetHack 3.7 December 19, 2020 From ae23330adc476a04e031644ee7e7398a6bc9b63d Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 21 Dec 2020 14:09:17 -0800 Subject: [PATCH 665/708] AC and obj->spe limits: +127/-128 -> +99/-99 Cap overall AC at -99 instead of -128. Put the same limit of 99 on enchantment and charge count of individual objects. ^X now reports if/when AC has reached its limit since players could see that reaching that limit and then enchanting worn items will change the worn items but not the total. (Same thing would have happened with -128, just without any explanation and less likely to accomplish.) Won't affect normal play for any reasonable definition of normal. --- doc/fixes37.0 | 7 +++++-- include/obj.h | 21 ++++++++++++--------- include/you.h | 14 +++++++++++--- src/do_wear.c | 25 ++++++++++++++++--------- src/insight.c | 4 ++++ src/objnam.c | 29 ++++++++++++++++++----------- src/read.c | 43 ++++++++++++++++++++++++++++++++++--------- src/worn.c | 3 +++ 8 files changed, 103 insertions(+), 43 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 23868980b..9c4f6f44a 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -341,6 +341,9 @@ when protection from shape changers begins, force mimic out of concealment even if hero can't see its location; for locations that can be seen, don't make double-trouble Wizard concealed as another monster--or pet temporarily mimicking something while eating mimic corpse--fall asleep +best possible armor class reduced from -127 to -99; worst from +127 to +99; + charged or enchanted individual items also capped at +/- 99 (affects + wizard mode wishing, negligible effect on normal play) Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -676,8 +679,8 @@ mild zombie apocalypse list lamps and lanterns in charging prompt let tourists read conical hats when "?i" (show key bindings) displays commands and their keys, also show - commands without any key (so useable via '#', or possibly menu, only; - the majority are debugging commands) + commands without any key (so ones useable via '#', or possibly menu, + only; the majority are debugging commands) assign default key binding for or to execute #terrain assign M-X to #exploremode make #herecmdmenu and #therecmdmenu autocomplete diff --git a/include/obj.h b/include/obj.h index 89d932251..9205c8151 100644 --- a/include/obj.h +++ b/include/obj.h @@ -40,16 +40,19 @@ struct obj { unsigned owt; long quan; /* number of items */ +#define SPE_LIM 99 /* abs(obj->spe) <= 99, cap for enchanted and charged + * objects (and others; named fruit index excepted) */ schar spe; /* quality of weapon, weptool, armor or ring (+ or -); - number of charges for wand or charged tool ( >= -1 ); - number of candles attached to candelabrum; - marks your eggs, tin variety and spinach tins; - candy bar wrapper index; - Schroedinger's Box (1) or royal coffers for a court (2); - tells which fruit a fruit is; - special for uball and amulet; - scroll of mail (normal==0, bones or wishing==1, written==2); - historic and gender for statues */ + * number of charges for wand or charged tool ( >= -1 ); + * number of candles attached to candelabrum; + * marks your eggs, tin variety and spinach tins; + * candy bar wrapper index; + * Schroedinger's Box (1) or royal coffers for a court (2); + * tells which fruit a fruit is; + * special for uball and amulet; + * scroll of mail (normal==0, bones or wishing==1, written==2); + * splash of venom (normal==0, wishing==1); + * historic and gender for statues */ #define STATUE_HISTORIC 0x01 #define STATUE_MALE 0x02 #define STATUE_FEMALE 0x04 diff --git a/include/you.h b/include/you.h index c8d4c4fe6..0d9686f88 100644 --- a/include/you.h +++ b/include/you.h @@ -93,7 +93,9 @@ enum achivements { ACH_NOVL = 20, /* read at least one passage from a Discworld novel */ ACH_SOKO = 21, /* entered Sokoban */ ACH_BGRM = 22, /* entered Bigroom (not guaranteed to be in every dgn) */ - /* 23..30 are negated if hero is female at the time new rank is gained */ + /* role's rank titles, beyond first (#0 at level one, not an achievement); + 23..30 are negated if hero is female at the time new rank is gained + so that disclosing them can use the gender which applied at the time */ ACH_RNK1 = 23, ACH_RNK2 = 24, ACH_RNK3 = 25, ACH_RNK4 = 26, ACH_RNK5 = 27, ACH_RNK6 = 28, ACH_RNK7 = 29, ACH_RNK8 = 30, /* foo=31, 1 available potential achievement; #32 currently off-limits */ @@ -102,6 +104,8 @@ enum achivements { /* * Other potential achievements to track (this comment briefly resided * in encodeachieve(topten.c) and has been revised since moving here: + * AC <= 0, AC <= -10, AC <= -20 (stop there; lower is better but + * not something to encourage with achievements), * got quest summons, * entered quest branch, * chatted with leader, @@ -431,14 +435,18 @@ struct you { #define A_CURRENT 0 aligntyp ualignbase[CONVERT]; /* for ualign conversion record */ schar uluck, moreluck; /* luck and luck bonus */ + /* default u.uluck is 0 except on special days (full moon: +1, Fri 13: -1, + both: 0); equilibrium for luck timeout is changed to those values, + but Luck max and min stay at 10+3 and -10-3 even on those days */ #define Luck (u.uluck + u.moreluck) #define LUCKADD 3 /* value of u.moreluck when carrying luck stone; - + when blessed or uncursed, - when cursed */ -#define LUCKMAX 10 /* maximum value of u.ulUck */ + * +3 when blessed or uncursed, -3 when cursed */ +#define LUCKMAX 10 /* maximum value of u.uluck */ #define LUCKMIN (-10) /* minimum value of u.uluck */ schar uhitinc; schar udaminc; schar uac; +#define AC_MAX 99 /* abs(u.uac) <= 99; likewise for monster AC */ uchar uspellprot; /* protection by SPE_PROTECTION */ uchar usptime; /* #moves until uspellprot-- */ uchar uspmtime; /* #moves between uspellprot-- */ diff --git a/src/do_wear.c b/src/do_wear.c index 77e7251ae..670fc6aa8 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -2213,19 +2213,26 @@ find_ac() uac -= u.ublessed; uac -= u.uspellprot; - /* [The magic binary numbers 127 and -128 should be replaced with the - * mystic decimal numbers 99 and -99 which require no explanation to - * the uninitiated and would cap the width of a status line value at - * one less character.] - */ - if (uac < -128) - uac = -128; /* u.uac is an schar */ - else if (uac > 127) - uac = 127; /* for completeness */ + /* put a cap on armor class [3.7: was +127,-128, now reduced to +/- 99 */ + if (abs(uac) > AC_MAX) + uac = sgn(uac) * AC_MAX; if (uac != u.uac) { u.uac = uac; g.context.botl = 1; +#if 0 + /* these could conceivably be achieved out of order (by being near + threshold and putting on +N dragon scale mail from bones, for + instance), but if that happens, that's the order it happened; + also, testing for these in the usual order would result in more + record_achievement() attempts and rejects for duplication */ + if (u.uac <= -20) + record_achievement(ACH_AC_20); + else if (u.uac <= -10) + record_achievement(ACH_AC_10); + else if (u.uac <= 0) + record_achievement(ACH_AC_00); +#endif } } diff --git a/src/insight.c b/src/insight.c index b95791968..57cd5596e 100644 --- a/src/insight.c +++ b/src/insight.c @@ -590,7 +590,11 @@ int final; you_have(buf, ""); } + find_ac(); /* enforces AC_MAX cap */ Sprintf(buf, "%d", u.uac); + if (abs(u.uac) == AC_MAX) + Sprintf(eos(buf), ", the %s possible", + (u.uac < 0) ? "best" : "worst"); enl_msg("Your armor class ", "is ", "was ", buf, ""); /* gold; similar to doprgold(#seegold) but without shop billing info; diff --git a/src/objnam.c b/src/objnam.c index 9efcd4fc6..a99523ef5 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -3431,8 +3431,11 @@ struct _readobjnam_data *d; { if (strlen(d->bp) > 1 && (d->p = rindex(d->bp, '(')) != 0) { boolean keeptrailingchars = TRUE; + int idx = 0; - d->p[(d->p > d->bp && d->p[-1] == ' ') ? -1 : 0] = '\0'; /*terminate bp */ + if (d->p > d->bp && d->p[-1] == ' ') + idx = -1; + d->p[idx] = '\0'; /* terminate bp */ ++d->p; /* advance past '(' */ if (!strncmpi(d->p, "lit)", 4)) { d->islit = 1; @@ -3478,8 +3481,9 @@ struct _readobjnam_data *d; d->spesgn = -1; /* cheaters get what they deserve */ d->spe = abs(d->spe); } - if (d->spe > SCHAR_LIM) - d->spe = SCHAR_LIM; + /* cap on obj->spe is independent of (and less than) SCHAR_LIM */ + if (d->spe > SPE_LIM) + d->spe = SPE_LIM; /* slime mold uses d.ftype, so not affected */ if (d->rechrg < 0 || d->rechrg > 7) d->rechrg = 7; /* recharge_limit */ } @@ -4225,13 +4229,11 @@ struct obj *no_wish; || d.typ == ROCK || is_missile(d.otmp))))) d.otmp->quan = (long) d.cnt; - if (d.oclass == VENOM_CLASS) - d.otmp->spe = 1; - if (d.spesgn == 0) { + /* spe not specifed; retain the randomly assigned value */ d.spe = d.otmp->spe; } else if (wizard) { - ; /* no alteration to spe */ + ; /* no restrictions except SPE_LIM */ } else if (d.oclass == ARMOR_CLASS || d.oclass == WEAPON_CLASS || is_weptool(d.otmp) || (d.oclass == RING_CLASS && objects[d.typ].oc_charged)) { @@ -4240,7 +4242,8 @@ struct obj *no_wish; if (d.spe > 2 && Luck < 0) d.spesgn = -1; } else { - if (d.oclass == WAND_CLASS) { + /* crystal ball cancels like a wand, to (n:-1) */ + if (d.oclass == WAND_CLASS || d.typ == CRYSTAL_BALL) { if (d.spe > 1 && d.spesgn == -1) d.spe = 1; } else { @@ -4281,12 +4284,16 @@ struct obj *no_wish; /* otmp->cobj already done in mksobj() */ break; #ifdef MAIL_STRUCTURES + /* scroll of mail: 0: delivered in-game via external event (or randomly + for fake mail); 1: from bones or wishing; 2: written with marker */ case SCR_MAIL: - /* 0: delivered in-game via external event (or randomly for fake mail); - 1: from bones or wishing; 2: written with marker */ + /*FALLTHRU*/ +#endif + /* splash of venom: 0: normal, and transitory; 1: wishing */ + case ACID_VENOM: + case BLINDING_VENOM: d.otmp->spe = 1; break; -#endif case WAN_WISHING: if (!wizard) { d.otmp->spe = (rn2(10) ? -1 : 0); diff --git a/src/read.c b/src/read.c index 0c41973aa..6f8505dba 100644 --- a/src/read.c +++ b/src/read.c @@ -17,6 +17,7 @@ static NEARDATA const char readable[] = { ALL_CLASSES, SCROLL_CLASS, static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 }; static boolean FDECL(learnscrolltyp, (SHORT_P)); +static void FDECL(cap_spe, (struct obj *)); static char *FDECL(erode_obj_text, (struct obj *, char *)); static void FDECL(stripspe, (struct obj *)); static void FDECL(p_glow1, (struct obj *)); @@ -54,6 +55,17 @@ struct obj *sobj; (void) learnscrolltyp(sobj->otyp); } +/* max spe is +99, min is -99 */ +static void +cap_spe(obj) +struct obj *obj; +{ + if (obj) { + if (abs(obj->spe) > SPE_LIM) + obj->spe = sgn(obj->spe) * SPE_LIM; + } +} + static char * erode_obj_text(otmp, buf) struct obj *otmp; @@ -679,11 +691,10 @@ int curse_bless; case MAGIC_MARKER: case TINNING_KIT: case EXPENSIVE_CAMERA: - if (is_cursed) + if (is_cursed) { stripspe(obj); - else if (rechrg - && obj->otyp - == MAGIC_MARKER) { /* previously recharged */ + } else if (rechrg && obj->otyp == MAGIC_MARKER) { + /* previously recharged */ obj->recharged = 1; /* override increment done above */ if (obj->spe < 3) Your("marker seems permanently dried out."); @@ -709,8 +720,9 @@ int curse_bless; obj->spe = 50; else { int chrg = (int) obj->spe; - if ((chrg + n) > 127) - obj->spe = 127; + + if (chrg + n > SPE_LIM) + obj->spe = SPE_LIM; else obj->spe += n; } @@ -824,9 +836,12 @@ int curse_bless; } /* switch */ } else { - not_chargable: + not_chargable: You("have a feeling of loss."); } + + /* prevent enchantment from getting out of range */ + cap_spe(obj); } /* @@ -1039,6 +1054,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ otmp->otyp += GRAY_DRAGON_SCALE_MAIL - GRAY_DRAGON_SCALES; if (sblessed) { otmp->spe++; + cap_spe(otmp); if (!otmp->blessed) bless(otmp); } else if (otmp->cursed) @@ -1050,7 +1066,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ break; } pline("%s %s%s%s%s for a %s.", Yname2(otmp), - s == 0 ? "violently " : "", + (s == 0) ? "violently " : "", otense(otmp, Blind ? "vibrate" : "glow"), (!Blind && !same_color) ? " " : "", (Blind || same_color) @@ -1067,8 +1083,15 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ else if (!scursed && otmp->cursed) uncurse(otmp); if (s) { + int oldspe = otmp->spe; + /* despite being schar, it shouldn't be possible for spe to wrap + here because it has been capped at 99 and s is quite small; + however, might need to change s if it takes spe past 99 */ otmp->spe += s; - adj_abon(otmp, s); + cap_spe(otmp); /* make sure that it doesn't exceed SPE_LIM */ + s = otmp->spe - oldspe; /* cap_spe() might have throttled 's' */ + if (s) /* skip if it got changed to 0 */ + adj_abon(otmp, s); /* adjust armor bonus for Dex or Int+Wis */ g.known = otmp->known; /* update shop bill to reflect new higher price */ if (s > 0 && otmp->unpaid) @@ -1331,6 +1354,8 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ : sblessed ? rnd(3 - uwep->spe / 3) : 1)) sobj = 0; /* nothing enchanted: strange_feeling -> useup */ + if (uwep) + cap_spe(uwep); break; case SCR_TAMING: case SPE_CHARM_MONSTER: { diff --git a/src/worn.c b/src/worn.c index f5c4c3a1d..82abcf26c 100644 --- a/src/worn.c +++ b/src/worn.c @@ -472,6 +472,9 @@ register struct monst *mon; /* since ARM_BONUS is positive, subtracting it increases AC */ } } + /* same cap as for hero [find_ac(do_wear.c)] */ + if (abs(base) > AC_MAX) + base = sgn(base) * AC_MAX; return base; } From 430edb5a740bf82d77e6f8d733d73efc57c163f0 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 21 Dec 2020 19:02:11 -0800 Subject: [PATCH 666/708] option help I stated out by changing dat/opthelp to stop shouting the boolean defaults: [TRUE] -> [True], [FALSE] -> [False]. I ended up doing a partical reconcilliation between ?g (dynamic list of options) and ?h (dat/opthelp). There were several inapplicable options in the dynamic list, so this changes option_help() to avoid those. I barely glanced at the compound options so they may not sync up. --- dat/opthelp | 176 +++++++++++++++++++++++++++------------------- include/optlist.h | 2 + src/options.c | 27 ++++--- 3 files changed, 121 insertions(+), 84 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index c752a8d2e..5ac1e653e 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -2,122 +2,150 @@ Boolean options not under specific compile flags (with default values in []): (You can learn which options exist in your version by checking your current option setting, which is reached via the 'O' command.) -acoustics can your character hear anything [TRUE] -autodescribe describe the terrain under cursor [FALSE] -autodig dig if moving and wielding digging tool [FALSE] -autoopen walking into a door attempts to open it [TRUE] -autopickup automatically pick up objects you move over [TRUE] -autoquiver when firing with an empty quiver, select some [FALSE] +acoustics can your character hear anything [True] +autodescribe describe the terrain under cursor [False] +autodig dig if moving and wielding digging tool [False] +autoopen walking into a door attempts to open it [True] +autopickup automatically pick up objects you move over [True] +autoquiver when firing with an empty quiver, select some [False] suitable inventory weapon to fill the quiver -autounlock when opening a locked door or looting a locked [TRUE] +autounlock when opening a locked door or looting a locked [True] container while carrying a key, offer to use it -BIOS allow the use of IBM ROM BIOS calls [FALSE] -blind your character is permanently blind [FALSE] -bones allow loading bones files [TRUE] -clicklook look at map by clicking right mouse button [FALSE] -cmdassist give help for errors on direction & other commands [TRUE] -confirm ask before hitting tame or peaceful monsters [TRUE] -dark_room show floor not in sight in different color [TRUE] -eight_bit_tty send 8-bit characters straight to terminal [FALSE] -extmenu tty, curses: use menu for # (extended commands) [FALSE] +BIOS allow the use of IBM ROM BIOS calls [False] +blind your character is permanently blind [False] +bones allow loading bones files [True] +clicklook look at map by clicking right mouse button [False] +cmdassist give help for errors on direction & other commands [True] +confirm ask before hitting tame or peaceful monsters [True] +dark_room show floor not in sight in different color [True] +eight_bit_tty send 8-bit characters straight to terminal [False] +extmenu tty, curses: use menu for # (extended commands) [False] X11: menu has all commands (T) or traditional subset (F) -fixinv try to retain the same letter for the same object [TRUE] -force_invmenu commands asking for inventory item show a menu [FALSE] -goldX when filtering objects by bless/curse state, [FALSE] +female deprecated; use compound option gender:female [False] +fixinv try to retain the same letter for the same object [True] +force_invmenu commands asking for inventory item show a menu [False] +goldX when filtering objects by bless/curse state, [False] whether to classify gold as X (unknown) or U (uncursed) -help print all available info when using the / command [TRUE] +help print all available info when using the / command [True] herecmd_menu show menu of some possible commands when clicking - on yourself or next to you with mouse [FALSE] -ignintr ignore interrupt signal, including breaks [FALSE] -implicit_uncursed omit "uncursed" from inventory, if possible [TRUE] -legacy print introductory message [TRUE] -lit_corridor show a dark corridor as lit if in sight [FALSE] -lootabc use a/b/c rather than o/i/b when looting [FALSE] -mail enable the mail daemon [TRUE] -mention_decor give feedback when walking across stairs, altars, [FALSE] + on yourself or next to you with mouse [False] +ignintr ignore interrupt signal, including breaks [False] +implicit_uncursed omit "uncursed" from inventory, if possible [True] +legacy print introductory message [True] +lit_corridor show a dark corridor as lit if in sight [False] +lootabc use a/b/c rather than o/i/b when looting [False] +mail enable the mail daemon [True] +mention_decor give feedback when walking across stairs, altars, [False] fountains, and such even when not obscured by objects -mention_walls give feedback when walking against a wall [FALSE] -menu_objsyms show object symbols in menus if it is selectable [FALSE] -menu_overlay overlay menus on the screen and align to right [TRUE] -nudist start your character without armor [FALSE] -null allow nulls to be sent to your terminal [TRUE] +mention_walls give feedback when walking against a wall [False] +menu_objsyms show object symbols in menus if it is selectable [False] +menu_overlay overlay menus on the screen and align to right [True] +menucolors enable MENUCOLOR pattern matching to highlight [False] + lines in object menus like inventory; might highlight with + bold, inverse, &c even when color is unavailable or toggled off +nudist start your character without armor [False] +null allow nulls to be sent to your terminal [True] try turning this option off (forcing NetHack to use its own delay code) if moving objects seem to teleport across rooms -perm_invent keep inventory in a permanent window [FALSE] -pickup_thrown override pickup_types for thrown objects [TRUE] -pushweapon when wielding a new weapon, put your previously [FALSE] +perm_invent keep inventory in a permanent window [False] +pickup_thrown override pickup_types for thrown objects [True] +pushweapon when wielding a new weapon, put your previously [False] wielded weapon into the secondary weapon slot -quick_farsight usually skip the chance to browse the map when [FALSE] +quick_farsight usually skip the chance to browse the map when [False] randomly triggered clairvoyance takes place -rawio allow the use of raw I/O [FALSE] -rest_on_space count the space bar as a rest character [FALSE] -safe_pet prevent you from (knowingly) attacking your pet(s) [TRUE] -safe_wait require use of 'm' prefix before '.' or 's' to [TRUE] +rawio allow the use of raw I/O [False] +rest_on_space count the space bar as a rest character [False] +safe_pet prevent you from (knowingly) attacking your pet(s) [True] +safe_wait require use of 'm' prefix before '.' or 's' to [True] wait or search when adjacent to a hostile monster -sanity_check perform data sanity checks [FALSE] -showexp display your accumulated experience points [FALSE] -showrace show yourself by your race rather than by role [FALSE] -silent don't use your terminal's bell sound [TRUE] -sortpack group similar kinds of objects in inventory [TRUE] -sparkle display sparkly effect for resisted magical [TRUE] +sanity_check perform data sanity checks [False] +showexp display your accumulated experience points [False] +showrace show yourself by your race rather than by role [False] +silent don't use your terminal's bell sound [True] +sortpack group similar kinds of objects in inventory [True] +sparkle display sparkly effect for resisted magical [True] attacks (e.g. fire attack on fire-resistant monster) -standout use standout mode for --More-- on messages [FALSE] -status_updates update the status lines [TRUE] -time display elapsed game time, in moves [FALSE] -tombstone print tombstone when you die [TRUE] -toptenwin print topten in a window rather than stdout [FALSE] -travel enables travelling via mouse click if supported; [TRUE] +standout use standout mode for --More-- on messages [False] +status_updates update the status lines [True] +time display elapsed game time, in moves [False] +tombstone print tombstone when you die [True] +toptenwin print topten in a window rather than stdout [False] +travel enables travelling via mouse click if supported; [True] can be toggled off to prevent mouse clicks on the map from attempting to move the hero; does not affect travel via '_' -use_darkgray use bold black instead of blue for black glyphs. [TRUE] -use_inverse display detected monsters in highlighted manner [FALSE] -verbose print more commentary during the game [TRUE] -whatis_menu show menu when getting a map location [FALSE] -whatis_moveskip skip same glyphs when getting a map location [FALSE] +use_darkgray use bold black instead of blue for black glyphs. [True] +use_inverse display detected monsters in highlighted manner [False] +verbose print more commentary during the game [True] +whatis_menu show menu when getting a map location [False] +whatis_moveskip skip same glyphs when getting a map location [False] There are further boolean options controlled by compilation flags. Boolean option if INSURANCE was set at compile time: -checkpoint save game state after each level change, for [TRUE] +checkpoint save game state after each level change, for [True] possible recovery after program crash Boolean option if NEWS was set at compile time: -news print any news from game administrator on startup [TRUE] +news print any news from game administrator on startup [True] Boolean option if SCORE_ON_BOTL was set at compile time: -showscore display your approximate accumulated score [FALSE] +showscore display your approximate accumulated score [False] Boolean options if TEXTCOLOR was set at compile time: -color use different colors for objects on screen [TRUE for micros] -hilite_pet display pets in a highlighted manner [FALSE] -hilite_pile display item piles in a highlighted manner [FALSE] +color use different colors for objects on screen [True for micros] +hilite_pet display pets in a highlighted manner [False] +hilite_pile display item piles in a highlighted manner [False] Boolean option if TIMED_DELAY was set at compile time (tty interface only): -timed_delay on unix and VMS, use a timer instead of sending [TRUE] +timed_delay on unix and VMS, use a timer instead of sending [True] extra screen output when attempting to pause for display effect. on MSDOS without the termcap lib, whether or not to pause for visual effect. Boolean option for Amiga, or for others if ALTMETA was set at compile time: -altmeta For Amiga, treat Alt+key as Meta+key. [TRUE] +altmeta For Amiga, treat Alt+key as Meta+key. [True] altmeta For unix and VMS, treat two character sequence - "ESC c" as M-c (Meta+c, 8th bit set) when nethack [FALSE] + "ESC c" as M-c (Meta+c, 8th bit set) when nethack [False] obtains a command from player's keyboard. Boolean option if USE_TILES was set at compile time (MSDOS protected mode): -preload_tiles control whether tiles get pre-loaded into RAM at [TRUE] +preload_tiles control whether tiles get pre-loaded into RAM at [True] the start of the game. Doing so enhances performance of the tile graphics, but uses more memory. Boolean option if TTY_TILES_ESCCODES was set at compile time (tty only): -vt_tiledata insert extra data escape code markers into output [FALSE] +vt_tiledata insert extra data escape code markers into output [False] Boolean option if TTY_SOUND_ESCCODES was set at compile time (tty only): -vt_sounddata insert sound data escape code markers into output [FALSE] +vt_sounddata insert sound data escape code markers into output [False] -Any Boolean option can be negated by prefixing it with a '!' or 'no'. +Boolean options which may be available depending upon which interfaces +the program has been built to support. If it supports multiple such, +some of these may show as available for setting but not do anything if +you happen to be using a different interface than the one(s) they're for: +ascii_map show map as text, forces tiles_map Off; Qt, X11 +guicolor curses +hitpointbar curses, tty, Windows GUI if statushilites enabled; + Qt without statushilites; X11 if 'fancy_status' disabled + (via X application defaults) and statushilities enabled +popup_dialog curses, Qt, Windows GUI +selectsaved tty (Qt and Windows GUI do this unconditionally) +splash_screen curses, Qt, Windows GUI +tiled_map show map as tiles, forces ascii_map Off; Qt, X11 +Boolean options available when running in debug mode (aka wizard mode): +menu_tab_sep menu formatting--do not touch +monpolycontrol have player choose shape-changing monsters' new shapes +travel_debug not implemented? +wizweight include item weights in inventory display + +Any Boolean option can be set to True by including it among options being +set, or negated (set to False) by prefixing its name with a '!' or 'no'. +Alternatively, the compound option syntax can be used: 'optname:true' and +'optname:false'. + + - - - - - Compound options are written as option_name:option_value. @@ -131,8 +159,8 @@ disclose the types of information you want [ni na nv ng nc no] 'n' prompt with default "no", 'y' prompt with default "yes", 'a' prompt to select sorting order (for suffix 'v' only); suffix: 'i' inventory, 'a' attributes, 'v' vanquished - monsters, 'g' genocided and extinct monsters, 'c' conduct, - 'o' dungeon overview) + monsters, 'g' genocided and extinct monsters, 'c' conduct + and achievements, 'o' dungeon overview) fruit the name of a fruit you enjoy eating [slime mold] (basically a whimsy which NetHack uses from time to time). hilite_status specifies a rule for highlighting a status field [] @@ -298,7 +326,7 @@ statuslines whether to use expanded (3) or condensed (2) status [2] startup; also unlike tty and curses, 2 is recommended over 3) windowtype windowing system to be used [depends on operating system and compile-time setup] if more than one choice is available. - Most instances of the program support only one window-type; + Some instances of the program support only one window-type; when that is the case, you don't need to specify anything. The list of supported window-types in your program can be seen while the program is running by using the #version diff --git a/include/optlist.h b/include/optlist.h index 9bf4a057d..4dc6ae115 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -228,8 +228,10 @@ pfx_##a, #endif NHOPTB(implicit_uncursed, 0, opt_out, set_in_game, On, Yes, No, No, NoAlias, &flags.implicit_uncursed) +#if 0 /* obsolete - pre-OSX Mac */ NHOPTB(large_font, 0, opt_in, set_in_config, Off, Yes, No, No, NoAlias, &iflags.obsolete) +#endif NHOPTB(legacy, 0, opt_out, set_in_config, On, Yes, No, No, NoAlias, &flags.legacy) NHOPTB(lit_corridor, 0, opt_in, set_in_game, Off, Yes, No, No, NoAlias, diff --git a/src/options.c b/src/options.c index 6560681a0..ed0101c4b 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 options.c $NHDT-Date: 1607692223 2020/12/11 13:10:23 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.486 $ */ +/* NetHack 3.7 options.c $NHDT-Date: 1608606126 2020/12/22 03:02:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.489 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2008. */ /* NetHack may be freely redistributed. See license for details. */ @@ -8226,6 +8226,7 @@ void option_help() { char buf[BUFSZ], buf2[BUFSZ]; + const char *optname; register int i; winid datawin; @@ -8237,22 +8238,28 @@ option_help() /* Boolean options */ for (i = 0; allopt[i].name; i++) { - if (allopt[i].addr) { - if (allopt[i].addr == &iflags.sanity_check && !wizard) - continue; - if (allopt[i].addr == &iflags.menu_tab_sep && !wizard) - continue; - next_opt(datawin, allopt[i].name); - } + if ((allopt[i].opttyp != BoolOpt || !allopt[i].addr) + || (allopt[i].setwhere == set_wizonly && !wizard)) + continue; + optname = allopt[i].name; + if ((is_wc_option(optname) && !wc_supported(optname)) + || (is_wc2_option(optname) && !wc2_supported(optname))) + continue; + next_opt(datawin, optname); } next_opt(datawin, ""); /* Compound options */ putstr(datawin, 0, "Compound options:"); for (i = 0; allopt[i].name; i++) { - if (allopt[i].opttyp != CompOpt) /* skip booleans */ + if (allopt[i].opttyp != CompOpt + || (allopt[i].setwhere == set_wizonly && !wizard)) continue; - Sprintf(buf2, "`%s'", allopt[i].name); + optname = allopt[i].name; + if ((is_wc_option(optname) && !wc_supported(optname)) + || (is_wc2_option(optname) && !wc2_supported(optname))) + continue; + Sprintf(buf2, "`%s'", optname); Sprintf(buf, "%-20s - %s%c", buf2, allopt[i].descr, allopt[i + 1].name ? ',' : '.'); putstr(datawin, 0, buf); From 934808be0e28c00e0fcd50a5caf49c5227aea658 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 22 Dec 2020 11:10:32 -0800 Subject: [PATCH 667/708] Qt support for changing 'statuslines' dynamically Turns out it was nearly as simple as I originally thought. I just missed one significant detail the first time around. This leaves DYNAMIC_STATUSLINES as conditionl but now enables it by default. Using 'O' to change 'statuslines' from 2 to 3 or vice versa now works for Qt as well as for curses and tty. --- dat/opthelp | 6 ++---- doc/Guidebook.mn | 8 ++------ doc/Guidebook.tex | 6 +----- win/Qt/qt_bind.cpp | 5 +++-- win/Qt/qt_main.cpp | 8 +++++--- win/Qt/qt_main.h | 7 ++++++- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/dat/opthelp b/dat/opthelp index 5ac1e653e..2d82a4e85 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -246,7 +246,8 @@ statushilites whether to display status highlights (when non-zero) and [0] also how many turns to display temporary highlights (for 'up', 'down', and 'changed' hilite_status rules) statuslines whether to use expanded (3) or condensed (2) status [2] - (for tty and curses; 2 is traditional, 3 is recommended) + (for tty and curses; 2 is traditional, 3 is recommended; + also for Qt, where 3 is traditional and 2 is recommended) suppress_alert disable various version-specific warnings about changes [] in game play or the user interface, such as notification given for the 'Q' command that quitting is now done via #quit @@ -321,9 +322,6 @@ role Your starting role (e.g., role:Barbarian, role:Valk). [random] as possible. You can also still denote your role by appending it to the "name" option (e.g., name:Vic-V), but the "role" option will take precedence. -statuslines whether to use expanded (3) or condensed (2) status [2] - (unlike for tty and curses, for Qt this can only be be set at - startup; also unlike tty and curses, 2 is recommended over 3) windowtype windowing system to be used [depends on operating system and compile-time setup] if more than one choice is available. Some instances of the program support only one window-type; diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index dab9e06da..451376619 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,4 +1,4 @@ -.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.408 $ $NHDT-Date: 1608175317 2020/12/17 03:21:57 $ +.\" $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.410 $ $NHDT-Date: 1608664223 2020/12/22 19:10:23 $ .\" .\" This is an excerpt from the 'roff' man page from the 'groff' package. .\" Guidebook.mn currently does *not* fully adhere to these guidelines. @@ -4387,7 +4387,7 @@ up (default yes). Number of lines for traditional below-the-map status display. Acceptable values are \f(CR2\fP and \f(CR3\fP (default is \f(CR2\fP). .lp "" -For \f(CR3\fP, the \f(CRtty\fP interface moves some fields around and +When set to \f(CR3\fP, the \f(CRtty\fP 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 back and forth during the game with the \(oqO\(cq @@ -4408,10 +4408,6 @@ original format, with the status window spread out vertically. A value of \f(CR2\fP makes status be slightly condensed, moving some fields to different lines to eliminate one whole line, reducing the height needed. -For \f(CRQt\fP, -.op statuslines -can only be set in the configuration file or via NETHACKOPTIONS, not -with the \(oqO\(cq command. .lp "term_cols\ \ \fIand\fP" .lp term_rows Curses interface only. diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index b1606a34c..e55152a06 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -4783,7 +4783,7 @@ Number of lines for traditional below-the-map status display. Acceptable values are {\tt 2} and {\tt 3} (default is {\tt 2}). %.lp "" -For {\tt 3}, the {\tt tty} interface moves some fields around and +When set to {\tt 3}, the {\tt 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 back and forth during the game with the `O' @@ -4806,10 +4806,6 @@ original format, with the status window spread out vertically. A value of {\tt 2} makes status be slightly condensed, moving some fields to different lines to eliminate one whole line, reducing the height needed. -For {\tt Qt}, -{\it statuslines\/} -can only be set in the configuration file or via NETHACKOPTIONS, not -with the `O' command. %.lp \item[\ib{term\verb+_+cols} {\normalfont and}] %.lp diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index f355bcd31..7f4926df5 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -834,10 +834,11 @@ void NetHackQtBind::qt_outrip(winid wid, int how, time_t when) void NetHackQtBind::qt_preference_update(const char *optname) { -#ifdef DYNAMIC_STATUSLINES // leave disabled; redoStatus() doesn't work +#ifdef DYNAMIC_STATUSLINES // defined in qt_main.h if (!strcmp(optname, "statuslines")) { // delete and recreate status window - main->redoStatus(); + // to toggle statuslines from 2 to 3 or vice versa + id_to_window[WIN_STATUS] = main->redoStatus(); } #else nhUse(optname); diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 4a43f0a43..18759e0d8 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -1180,14 +1180,14 @@ void NetHackQtMainWindow::layout() } } -#ifdef DYNAMIC_STATUSLINES // leave disabled; this doesn't work as intended +#ifdef DYNAMIC_STATUSLINES // called when 'statuslines' changes from 2 to 3 or vice versa; simpler to // destroy and recreate the status window than to adjust existing fields -void NetHackQtMainWindow::redoStatus() +NetHackQtWindow *NetHackQtMainWindow::redoStatus() { NetHackQtStatusWindow *oldstatus = this->status; if (!oldstatus) - return; // not ready yet? + return NULL; // not ready yet? this->status = new NetHackQtStatusWindow; if (!qt_compact_mode) @@ -1195,6 +1195,8 @@ void NetHackQtMainWindow::redoStatus() delete oldstatus; ShowIfReady(); + + return (NetHackQtWindow *) this->status; } #endif diff --git a/win/Qt/qt_main.h b/win/Qt/qt_main.h index d01d09558..1b4441ec9 100644 --- a/win/Qt/qt_main.h +++ b/win/Qt/qt_main.h @@ -14,6 +14,11 @@ #include "qt_kde0.h" #endif +// Allow changing 'statuslines:2' to 'statuslines:3' or vice versa +// while the game is running; deletes and re-creates the status window. +// [Used in qt_bind.cpp and qt_main.cpp, but not referenced in qt_stat.cpp.] +#define DYNAMIC_STATUSLINES + namespace nethack_qt_ { class NetHackQtInvUsageWindow; @@ -54,7 +59,7 @@ public: void resizePaperDoll(bool); // ENHANCED_PAPERDOLL #ifdef DYNAMIC_STATUSLINES // called when 'statuslines' option has been changed - void redoStatus(); + NetHackQtWindow *redoStatus(); #endif public slots: From 1b7c372f5d92391d5c43a8ac2cdbffb478b349e2 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 22 Dec 2020 13:48:29 -0800 Subject: [PATCH 668/708] fix #K3231 - objects vs pits and holes This got out of hand pretty quickly. can_reach_floor() had different criteria than trap activation. Objects dropped at a hole locations that don't fall through were treated as if they were at the bottom of an abyss, so couldn't be examined or picked up. This a bunch of changes; it is bound to introduce some new bugs. --- doc/fixes37.0 | 3 ++- src/do.c | 8 +++++--- src/dokick.c | 15 +++++++-------- src/dothrow.c | 31 ++++++++++++++++++++++++++----- src/engrave.c | 19 +++++++++++-------- src/hack.c | 41 ++++++++++++++++++++++++++--------------- src/pickup.c | 11 ++++++----- 7 files changed, 83 insertions(+), 45 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 9c4f6f44a..800e48d28 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.396 $ $NHDT-Date: 1608335163 2020/12/18 23:46:03 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.399 $ $NHDT-Date: 1608673688 2020/12/22 21:48:08 $ General Fixes and Modified Features ----------------------------------- @@ -344,6 +344,7 @@ when protection from shape changers begins, force mimic out of concealment best possible armor class reduced from -127 to -99; worst from +127 to +99; charged or enchanted individual items also capped at +/- 99 (affects wizard mode wishing, negligible effect on normal play) +fix several inconsistencies for objects at hole locations Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/src/do.c b/src/do.c index 7090db33e..4d5057595 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do.c $NHDT-Date: 1601595709 2020/10/01 23:41:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ */ +/* NetHack 3.7 do.c $NHDT-Date: 1608673689 2020/12/22 21:48:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.256 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -254,6 +254,8 @@ deletedwithboulder: pline("%s %s into %s %s.", The(xname(obj)), otense(obj, "tumble"), the_your[t->madeby_u], is_pit(t->ttyp) ? "pit" : "hole"); + if (is_hole(t->ttyp) && ship_object(obj, x, y, FALSE)) + return TRUE; } else if (obj->globby) { /* Globby things like puddings might stick together */ while (obj && (otmp = obj_nexto_xy(obj, x, y, TRUE)) != 0) { @@ -698,8 +700,6 @@ boolean with_impact; if (obj == uswapwep) setuswapwep((struct obj *) 0); - if (!u.uswallow && flooreffects(obj, u.ux, u.uy, "drop")) - return; if (u.uswallow) { /* hero has dropped an item while inside an engulfer */ if (obj != uball) { /* mon doesn't pick up ball */ @@ -711,6 +711,8 @@ boolean with_impact; (void) mpickobj(u.ustuck, obj); } } else { + if (flooreffects(obj, u.ux, u.uy, "drop")) + return; place_object(obj, u.ux, u.uy); if (with_impact) container_impact_dmg(obj, u.ux, u.uy); diff --git a/src/dokick.c b/src/dokick.c index 84d373421..765316522 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dokick.c $NHDT-Date: 1606343576 2020/11/25 22:32:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.160 $ */ +/* NetHack 3.7 dokick.c $NHDT-Date: 1608673689 2020/12/22 21:48:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.162 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1814,23 +1814,22 @@ xchar x, y; g.gate_str = 0; /* this matches the player restriction in goto_level() */ - if (on_level(&u.uz, &qstart_level) && !ok_to_quest()) + if (on_level(&u.uz, &qstart_level) && !ok_to_quest()) { return MIGR_NOWHERE; - + } if (stway && !stway->up && !stway->isladder) { g.gate_str = "down the stairs"; return (stway->tolev.dnum == u.uz.dnum) ? MIGR_STAIRS_UP - : MIGR_SSTAIRS; + : MIGR_SSTAIRS; } if (stway && !stway->up && stway->isladder) { g.gate_str = "down the ladder"; return MIGR_LADDER_UP; } - - if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen) - && is_hole(ttmp->ttyp)) { + /* hole will always be flagged as seen; trap drop might or might not */ + if ((ttmp = t_at(x, y)) != 0 && ttmp->tseen && is_hole(ttmp->ttyp)) { g.gate_str = (ttmp->ttyp == TRAPDOOR) ? "through the trap door" - : "through the hole"; + : "through the hole"; return MIGR_RANDOM; } return MIGR_NOWHERE; diff --git a/src/dothrow.c b/src/dothrow.c index f0ed6546e..c3695658d 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dothrow.c $NHDT-Date: 1607200366 2020/12/05 20:32:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 3.7 dothrow.c $NHDT-Date: 1608673690 2020/12/22 21:48:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -451,11 +451,32 @@ boolean verbosely; /* usually True; False if caller has given drop message */ dropy(obj); return; } - if (IS_ALTAR(levl[u.ux][u.uy].typ)) + if (IS_ALTAR(levl[u.ux][u.uy].typ)) { doaltarobj(obj); - else if (verbosely) - pline("%s %s the %s.", Doname2(obj), otense(obj, "hit"), - surface(u.ux, u.uy)); + } else if (verbosely) { + const char *surf = surface(u.ux, u.uy); + struct trap *t = t_at(u.ux, u.uy); + + /* describe something that might keep the object where it is + or precede next message stating that it falls */ + if (t && t->tseen) { + switch (t->ttyp) { + case TRAPDOOR: + surf = "trap door"; + break; + case HOLE: + surf = "edge of the hole"; + break; + case PIT: + case SPIKED_PIT: + surf = "edge of the pit"; + break; + default: + break; + } + } + pline("%s %s the %s.", Doname2(obj), otense(obj, "hit"), surf); + } if (hero_breaks(obj, u.ux, u.uy, TRUE)) return; diff --git a/src/engrave.c b/src/engrave.c index 09ddfcc48..c35311d23 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 engrave.c $NHDT-Date: 1596498167 2020/08/03 23:42:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ */ +/* NetHack 3.7 engrave.c $NHDT-Date: 1608673691 2020/12/22 21:48:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.99 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -146,20 +146,23 @@ boolean check_pit; { struct trap *t; - if (u.uswallow) + if (u.uswallow || (u.ustuck && !sticks(g.youmonst.data)) + || (Levitation && !(Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)))) return FALSE; /* Restricted/unskilled riders can't reach the floor */ if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) return FALSE; - if (check_pit && !Flying - && (t = t_at(u.ux, u.uy)) != 0 + if (u.uundetected && ceiling_hider(g.youmonst.data)) + return FALSE; + + if (Flying || g.youmonst.data->msize >= MZ_HUGE) + return TRUE; + + if (check_pit && (t = t_at(u.ux, u.uy)) != 0 && (uteetering_at_seen_pit(t) || uescaped_shaft(t))) return FALSE; - return (boolean) ((!Levitation || Is_airlevel(&u.uz) - || Is_waterlevel(&u.uz)) - && (!u.uundetected || !is_hider(g.youmonst.data) - || u.umonnum == PM_TRAPPER)); + return TRUE; } /* give a message after caller has determined that hero can't reach */ diff --git a/src/hack.c b/src/hack.c index 5fbc39741..7d766ec31 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 hack.c $NHDT-Date: 1608335164 2020/12/18 23:46:04 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.273 $ */ +/* NetHack 3.7 hack.c $NHDT-Date: 1608673692 2020/12/22 21:48:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.274 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2692,6 +2692,8 @@ boolean newlev; static int pickup_checks() { + struct trap *traphere; + /* uswallow case added by GAN 01/29/87 */ if (u.uswallow) { if (!u.ustuck->minvent) { @@ -2707,8 +2709,8 @@ pickup_checks() } } if (is_pool(u.ux, u.uy)) { - if (Wwalking || is_floater(g.youmonst.data) || is_clinger(g.youmonst.data) - || (Flying && !Breathless)) { + if (Wwalking || is_floater(g.youmonst.data) + || is_clinger(g.youmonst.data) || (Flying && !Breathless)) { You("cannot dive into the %s to pick things up.", hliquid("water")); return 0; @@ -2718,8 +2720,8 @@ pickup_checks() } } if (is_lava(u.ux, u.uy)) { - if (Wwalking || is_floater(g.youmonst.data) || is_clinger(g.youmonst.data) - || (Flying && !Breathless)) { + if (Wwalking || is_floater(g.youmonst.data) + || is_clinger(g.youmonst.data) || (Flying && !Breathless)) { You_cant("reach the bottom to pick things up."); return 0; } else if (!likes_lava(g.youmonst.data)) { @@ -2749,18 +2751,27 @@ pickup_checks() There("is nothing here to pick up."); return 0; } - if (!can_reach_floor(TRUE)) { - struct trap *traphere = t_at(u.ux, u.uy); - if (traphere - && (uteetering_at_seen_pit(traphere) || uescaped_shaft(traphere))) - You("cannot reach the bottom of the %s.", - is_pit(traphere->ttyp) ? "pit" : "abyss"); - else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) + traphere = t_at(u.ux, u.uy); + if (!can_reach_floor(traphere && is_pit(traphere->ttyp))) { + /* it here's a hole here, any objects here clearly aren't at + the bottom so only check for pits */ + if (traphere && uteetering_at_seen_pit(traphere)) { + You("cannot reach the bottom of the pit."); + } else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) { rider_cant_reach(); - else if (Blind && !can_reach_floor(TRUE)) + } else if (Blind) { You("cannot reach anything here."); - else - You("cannot reach the %s.", surface(u.ux, u.uy)); + } else { + const char *surf = surface(u.ux, u.uy); + + if (traphere) { + if (traphere->ttyp == HOLE) + surf = "edge of the hole"; + else if (traphere->ttyp == TRAPDOOR) + surf = "trap door"; + } + You("cannot reach the %s.", surf); + } return 0; } return -1; /* can do normal pickup */ diff --git a/src/pickup.c b/src/pickup.c index ddabf097c..a8d7f3d88 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pickup.c $NHDT-Date: 1601595711 2020/10/01 23:41:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.272 $ */ +/* NetHack 3.7 pickup.c $NHDT-Date: 1608673693 2020/12/22 21:48:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.273 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -598,11 +598,11 @@ int what; /* should be a long */ return 0; } /* no pickup if levitating & not on air or water level */ - if (!can_reach_floor(TRUE)) { + t = t_at(u.ux, u.uy); + if (!can_reach_floor(t && is_pit(t->ttyp))) { (void) describe_decor(); /* even when !flags.mention_decor */ if ((g.multi && !g.context.run) || (autopickup && !flags.pickup) - || ((t = t_at(u.ux, u.uy)) != 0 - && (uteetering_at_seen_pit(t) || uescaped_shaft(t)))) + || (t && (uteetering_at_seen_pit(t) || uescaped_shaft(t)))) read_engr_at(u.ux, u.uy); return 0; } @@ -1780,8 +1780,9 @@ int x, y; boolean looting; /* loot vs tip */ { const char *verb = looting ? "loot" : "tip"; + struct trap *t = t_at(x, y); - if (!can_reach_floor(TRUE)) { + if (!can_reach_floor(t && is_pit(t->ttyp))) { if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) rider_cant_reach(); /* not skilled enough to reach */ else From 3922bbf6665027d211d915d2443d05f17a9c81fd Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Dec 2020 08:26:54 -0800 Subject: [PATCH 669/708] remove a solved item from Qt-issues.txt --- win/Qt/Qt-issues.txt | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/win/Qt/Qt-issues.txt b/win/Qt/Qt-issues.txt index c38fca661..01f5e6cc5 100644 --- a/win/Qt/Qt-issues.txt +++ b/win/Qt/Qt-issues.txt @@ -2,7 +2,7 @@ Qt-NetHack issues ----- Urgent: if the program crashes on OSX, a dialog box asking the user -whether to [ignore], [report], or [restart] will eventually appear +whether to [ignore], [report...], or [re-open] will eventually appear (it's slow). That should be repressed even if the report choice could be directed at nethack.org. @@ -12,7 +12,7 @@ NetHack has started, and typing ^C was sending the program into an endless loop in qt_nhgetch() with repeated messages to stderr (the terminal) complaining that the event loop is already running. Triggered by yn_function("Really quit?") in the core. That situation -has been reduced to a single event loop complaint, do downgraded from +has been reduced to a single event loop complaint, so downgraded from "Urgent", but the prompt is auto-answered with ESC instead of letting the user respond. @@ -52,13 +52,6 @@ intended to be displayed, is displayed (as blank terrain). 3.6 status conditions (Stone, Slime, Strngl, Deaf, Lev, Fly, Ride) have been implemented but need icon artwork (one 40x40 tile for each). -In a menu window, typing ':' (via shift+something) works to initiate -a search without the need to click on the [Search] button. In a text -window, it does not, despite moving the menu key press interpretation -code into its own routine and calling that for both types of windows. -From the text window code, it sees the initial shift but not the ':' -that should follow. - Clicking on window close button pops up a confirmation dialog with [ Save and exit ] [__Quit_without_saving__] with the second one highlighted. Internally they're specified as From 1971adbe45afc36278b5fff6ba6a78855fbc99e5 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Dec 2020 10:43:58 -0800 Subject: [PATCH 670/708] feedback for monsters' health For farlook description of a monster, and for "killed by monster" when game ends, include an indication of the monster's health: uninjured full health barely wounded 95%+ health slightly wounded 80%+ wounded 20%..80% heavily wounded 20%- nearly deceased 5%-, or 1HP for really weak monsters These descriptions and the criteria for choosing which one will probably need some tuning. Messages referring to the monster, including combat, do not include the extra verbosity. --- doc/fixes37.0 | 5 ++++- include/extern.h | 3 ++- src/do_name.c | 5 +++-- src/end.c | 3 ++- src/pager.c | 40 +++++++++++++++++++++++++++++++++------- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 800e48d28..d4a83e844 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.399 $ $NHDT-Date: 1608673688 2020/12/22 21:48:08 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.400 $ $NHDT-Date: 1608749030 2020/12/23 18:43:50 $ General Fixes and Modified Features ----------------------------------- @@ -686,6 +686,9 @@ assign default key binding for or to execute #terrain assign M-X to #exploremode make #herecmdmenu and #therecmdmenu autocomplete add 'sortdiscoveries' option to control output of '\' and '`' commands +include an indication of monsters' health during farlook feedback (including + /M and autodescribe); also include it in death reason when killed by + a monster: "killed by {an uninjured newt,a heavily injured mumak}" Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index cc7fd8be9..ac8b1e723 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1607945415 2020/12/14 11:30:15 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.932 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1608749030 2020/12/23 18:43:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.934 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1866,6 +1866,7 @@ E void NDECL(msgtype_free); /* ### pager.c ### */ E char *FDECL(self_lookat, (char *)); +E char *FDECL(monhealthdescr, (struct monst *mon, BOOLEAN_P, char *)); E void FDECL(mhidden_description, (struct monst *, BOOLEAN_P, char *)); E boolean FDECL(object_from_map, (int,int,int,struct obj **)); E int FDECL(do_screen_description, (coord, BOOLEAN_P, int, char *, diff --git a/src/do_name.c b/src/do_name.c index 7a053186f..c4c2f654c 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 do_name.c $NHDT-Date: 1608343467 2020/12/19 02:04:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ +/* NetHack 3.7 do_name.c $NHDT-Date: 1608749030 2020/12/23 18:43:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.186 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,7 +6,8 @@ #include "hack.h" static char *NDECL(nextmbuf); -static void FDECL(getpos_help_keyxhelp, (winid, const char *, const char *, int)); +static void FDECL(getpos_help_keyxhelp, (winid, const char *, + const char *, int)); static void FDECL(getpos_help, (BOOLEAN_P, const char *)); static int FDECL(CFDECLSPEC cmp_coord_distu, (const void *, const void *)); static int FDECL(gloc_filter_classify_glyph, (int)); diff --git a/src/end.c b/src/end.c index ba489f9a4..50f593280 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 end.c $NHDT-Date: 1606009001 2020/11/22 01:36:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.215 $ */ +/* NetHack 3.7 end.c $NHDT-Date: 1608749031 2020/12/23 18:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.216 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -419,6 +419,7 @@ int how; Strcat(buf, "the "); g.killer.format = KILLED_BY; } + (void) monhealthdescr(mtmp, TRUE, eos(buf)); if (mtmp->minvis) Strcat(buf, "invisible "); if (distorted) diff --git a/src/pager.c b/src/pager.c index 5d5fdcce4..b573bb4aa 100644 --- a/src/pager.c +++ b/src/pager.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 pager.c $NHDT-Date: 1607735717 2020/12/12 01:15:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 3.7 pager.c $NHDT-Date: 1608749031 2020/12/23 18:43:51 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -12,14 +12,13 @@ static boolean FDECL(is_swallow_sym, (int)); static int FDECL(append_str, (char *, const char *)); static void FDECL(look_at_object, (char *, int, int, int)); -static void FDECL(look_at_monster, (char *, char *, - struct monst *, int, int)); +static void FDECL(look_at_monster, (char *, char *, struct monst *, int, int)); static struct permonst *FDECL(lookat, (int, int, char *, char *)); static void FDECL(checkfile, (char *, struct permonst *, - BOOLEAN_P, BOOLEAN_P, char *)); + BOOLEAN_P, BOOLEAN_P, char *)); static void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P)); static void FDECL(do_supplemental_info, (char *, struct permonst *, - BOOLEAN_P)); + BOOLEAN_P)); static void NDECL(whatdoes_help); static void NDECL(docontact); static void NDECL(dispfile_help); @@ -103,6 +102,32 @@ char *outbuf; return outbuf; } +/* format description of 'mon's health for look_at_monster(), done_in_by() */ +char * +monhealthdescr(mon, addspace, outbuf) +struct monst *mon; +boolean addspace; +char *outbuf; +{ + int mhp_max = max(mon->mhpmax, 1), /* bullet proofing */ + pct = (mon->mhp * 100) / mhp_max; + + if (mon->mhp >= mhp_max) + Strcpy(outbuf, "uninjured"); + else if (mon->mhp <= 1 || pct < 5) + Sprintf(outbuf, "%s%s", (mon->mhp > 0) ? "nearly " : "", + !nonliving(mon->data) ? "deceased" : "defunct"); + else + Sprintf(outbuf, "%swounded", + (pct >= 95) ? "barely " + : (pct >= 80) ? "slightly " + : (pct < 20) ? "heavily " + : ""); + if (addspace) + (void) strkitten(outbuf, ' '); + return outbuf; +} + /* describe a hidden monster; used for look_at during extended monster detection and for probing; also when looking at self */ void @@ -280,16 +305,17 @@ char *buf, *monbuf; /* buf: output, monbuf: optional output */ struct monst *mtmp; int x, y; { - char *name, monnambuf[BUFSZ]; + char *name, monnambuf[BUFSZ], healthbuf[BUFSZ]; boolean accurate = !Hallucination; name = (mtmp->data == &mons[PM_COYOTE] && accurate) ? coyotename(mtmp, monnambuf) : distant_monnam(mtmp, ARTICLE_NONE, monnambuf); - Sprintf(buf, "%s%s%s", + Sprintf(buf, "%s%s%s%s", (mtmp->mx != x || mtmp->my != y) ? ((mtmp->isshk && accurate) ? "tail of " : "tail of a ") : "", + accurate ? monhealthdescr(mtmp, TRUE, healthbuf) : "", (mtmp->mtame && accurate) ? "tame " : (mtmp->mpeaceful && accurate) From f05e87831c7a94064e7458f900731858f0e9fae3 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 23 Dec 2020 15:48:26 -0800 Subject: [PATCH 671/708] data.base: Croesus date --- dat/data.base | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/dat/data.base b/dat/data.base index 117d28fe3..a23ba5449 100644 --- a/dat/data.base +++ b/dat/data.base @@ -1,5 +1,5 @@ # NetHack 3.7 data.base -# $NHDT-Date: 1605726848 2020/11/18 19:14:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.98 $ +# $NHDT-Date: 1608767189 2020/12/23 23:46:29 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.99 $ # Copyright (c) 1994, 1995, 1996 by the NetHack Development Team # Copyright (c) 1994 by Boudewijn Wayers # NetHack may be freely redistributed. See license for details. @@ -1064,13 +1064,14 @@ cream pie And welcomes little fishes in, With gently smiling jaws! [ How Doth The Little Crocodile, by Lewis Carroll ] +# Creosote is the Discworld analogue of Croesus croesus kroisos creosote Croesus (in Greek: Kroisos), the wealthy last king of Lydia; - his empire was destroyed when he attacked Cyrus in 549, after - the Oracle of Delphi (q.v.) had told him: "if you attack the - Persians, you will destroy a mighty empire". Herodotus + his empire was destroyed when he attacked Cyrus in 549 BC, + after the Oracle of Delphi (q.v.) had told him: "if you attack + the Persians, you will destroy a mighty empire". Herodotus relates of his legendary conversation with Solon of Athens, who impressed upon him that being rich does not imply being happy and that no one should be considered fortunate before From fe3eb9241103ff3cce0767eec9a5be06a7180948 Mon Sep 17 00:00:00 2001 From: nhmall Date: Wed, 23 Dec 2020 20:31:54 -0500 Subject: [PATCH 672/708] win32: avoid game exit dialog lacking any explanation --- win/win32/mswproc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index 754071f52..a439deca5 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -2796,6 +2796,8 @@ int NHMessageBox(HWND hWnd, LPCTSTR text, UINT type) { TCHAR title[MAX_LOADSTRING]; + if (g.program_state.exiting && !strcmp(text, "\n")) + text = "Press Enter to exit"; LoadString(GetNHApp()->hApp, IDS_APP_TITLE_SHORT, title, MAX_LOADSTRING); From a4184c86843d90f57a63e1e7e713e769b454824d Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 24 Dec 2020 22:37:58 +0200 Subject: [PATCH 673/708] Prevent monsters from picking up locked containers --- src/muse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/muse.c b/src/muse.c index e30bee61e..a9fadee8b 100644 --- a/src/muse.c +++ b/src/muse.c @@ -2407,7 +2407,8 @@ struct obj *obj; && mon->data != &mons[PM_KI_RIN]); if (typ == FROST_HORN || typ == FIRE_HORN) return (obj->spe > 0 && can_blow(mon)); - if (Is_container(obj) && !(Is_mbag(obj) && obj->cursed)) + if (Is_container(obj) && !(Is_mbag(obj) && obj->cursed) + && !obj->olocked) return TRUE; break; case FOOD_CLASS: From 5552f141ba721cbb5aabd02cea8f1085d43c5080 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 24 Dec 2020 13:41:17 -0800 Subject: [PATCH 674/708] fix github issue #427 - unreadable mail The change to make mail objects and monsters separate from mail delivery (so that toggling the latter wouldn't invalidate save and bones files) made it possible to wish for scrolls of mail, find such in bones left by someone who did, or write such via magic marker. That was probably unintentional but I've left it as-is. The problem was that reading such scrolls issued a warning: "What weird effect is this?" because reading scrolls of mail was only allowed when interacting with MAIL was enabled. The issue suggested replacing #if MAIL with #if MAIL_STRUCTURES in seffects(), and then insert #if MAIL in the part of reading that deals with 'real' (or randomly faked for micros) mail. I've done both of those, and also added a couple of message variations for the unreal cases. Closes #427 --- doc/fixes37.0 | 5 ++++- src/invent.c | 11 ++++++++++- src/read.c | 42 +++++++++++++++++++++++++++++------------- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d4a83e844..6a52bd5fc 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.400 $ $NHDT-Date: 1608749030 2020/12/23 18:43:50 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.401 $ $NHDT-Date: 1608846067 2020/12/24 21:41:07 $ General Fixes and Modified Features ----------------------------------- @@ -445,6 +445,9 @@ a long worm with no visible segments (but one internal segment) might trigger warning: tail 'segement' at <0,some_y>, worm at if teleported adding displacer beast inadvertently introduced a regression in swapping with pets, allowing them to be pulled into water by hero on/over water +splitting #if MAIL into #if MAIL_STRUCTURES and #if MAIL made it possible to + wish for and write scrolls of mail with MAIL disabled, but attempting + to read such a scroll issued impossible "What weird effect is this?" curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/invent.c b/src/invent.c index 63f7904a9..5f14e2f46 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 invent.c $NHDT-Date: 1606765212 2020/11/30 19:40:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.308 $ */ +/* NetHack 3.7 invent.c $NHDT-Date: 1608846067 2020/12/24 21:41:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.310 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3784,6 +3784,15 @@ register struct obj *otmp, *obj; : (!has_omailcmd(otmp) || strcmp(OMAILCMD(obj), OMAILCMD(otmp)) != 0)) return FALSE; +#ifdef MAIL_STRUCTURES + if (obj->otyp == SCR_MAIL + /* wished or bones mail and hand written stamped scrolls + each have two flavors; spe keeps them separate from each + other but we want to keep their flavors separate too */ + && obj->spe > 0 && (obj->o_id % 2) != (otmp->o_id % 2)) + return FALSE; +#endif + /* should be moot since matching artifacts wouldn't be unique */ if (obj->oartifact != otmp->oartifact) return FALSE; diff --git a/src/read.c b/src/read.c index 6f8505dba..30809567e 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1607945439 2020/12/14 11:30:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.205 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1608846072 2020/12/24 21:41:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.207 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -436,7 +436,7 @@ doread() } confused = (Confusion != 0); -#ifdef MAIL +#ifdef MAIL_STRUCTURES if (otyp == SCR_MAIL) { confused = FALSE; /* override */ /* reading mail is a convenience for the player and takes @@ -953,22 +953,38 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */ || objects[otyp].oc_name_known); switch (otyp) { -#ifdef MAIL - case SCR_MAIL: +#ifdef MAIL_STRUCTURES + case SCR_MAIL: { + boolean odd = (sobj->o_id % 2) == 1; + g.known = TRUE; - if (sobj->spe == 2) + switch (sobj->spe) { + case 2: /* "stamped scroll" created via magic marker--without a stamp */ - pline("This scroll is marked \"postage due\"."); - else if (sobj->spe) + pline("This scroll is marked \"%s\".", + odd ? "Postage Due" : "Return to Sender"); + break; + case 1: /* scroll of mail obtained from bones file or from wishing; - * note to the puzzled: the game Larn actually sends you junk - * mail if you win! - */ - pline( - "This seems to be junk mail addressed to the finder of the Eye of Larn."); - else + note to the puzzled: the game Larn actually sends you junk + mail if you win! */ + pline("This seems to be %s.", + odd ? "a chain letter threatening your luck" + : "junk mail addressed to the finder of the Eye of Larn"); + break; + default: +#ifdef MAIL readmail(sobj); +#else + /* unreachable since with MAIL undefined, sobj->spe won't be 0; + as a precaution, be prepared to give arbitrary feedback; + caller has already reported that it disappears upon reading */ + pline("That was a scroll of mail?"); +#endif + break; + } break; + } #endif case SCR_ENCHANT_ARMOR: { register schar s; From 1a2afd21d47eea6fd080bf8d1f7dc7f503149372 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 24 Dec 2020 17:53:57 -0800 Subject: [PATCH 675/708] tty: winch_handler vs NO_SIGNAL While testing something unrelated, I built with NO_SIGNAL defined and winch_handler() caused an unused function warning. --- win/tty/wintty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 05bcfbca4..a0ebef942 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ - /* NetHack 3.7 wintty.c $NHDT-Date: 1606011660 2020/11/22 02:21:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.263 $ */ + /* NetHack 3.7 wintty.c $NHDT-Date: 1608861214 2020/12/25 01:53:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -294,7 +294,7 @@ const char *mesg; /*NOTREACHED*/ } -#if defined(SIGWINCH) && defined(CLIPPING) +#if defined(SIGWINCH) && defined(CLIPPING) && !defined(NO_SIGNAL) static void FDECL(winch_handler, (int)); /* @@ -369,7 +369,7 @@ int sig_unused UNUSED; } } } -#endif +#endif /* SIGWINCH && CLIPPING && !NO_SIGNAL */ /* destroy and recreate status window; extracted from winch_handler() and augmented for use by tty_preference_update() */ From 0ec355bdb4340cf8e055b3be61ce0577a2064ce9 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 25 Dec 2020 13:57:05 -0800 Subject: [PATCH 676/708] fix github issue #426 - binding special commands Binding 'repeat' (DOAGAIN, or redo) to a different key than ^A didn't work as intended because the code that used it was checking for DOAGAIN (a key value from config.h) instead of g.Cmd.spkeys[NHKF_DOAGAIN] (the key currently bound to repeat). Contrary to the github issue, re-bound prefix keys worked ok for me if followed by a direction. However, they behaved strangely if followed by anything else. If the keystroke was stolen from some other command and that command hadn't been bound to another key, following the prefix with a non-direction could end up executing the command that used to own the key. For example, BIND=d:nopickup to use 'd' to move without auto-pickup would work if you used d but if you used d if would execute the drop command. The NHKF_REQMENU prefix could be bound to some key other than 'm' but it only worked as intended if the new key was a movement prefix. This also makes DOAGAIN be unconditional. If it is deleted or commented out in config.h, the default binding will be '\000' so unusable (freeing up ^A for something), but still be available to be bound to some key (perhaps even ^A). This also includes an unrelated change to mdlib.c. The comments added to config.h will force a full rebuild. Changing mdlib.c now rather than separately will avoid forcing that twice. Fixes #426 --- doc/fixes37.0 | 13 ++++++++++++- include/config.h | 9 +++++++-- src/cmd.c | 36 +++++++++++++++++++++++++----------- src/mdlib.c | 15 +++++++++++---- win/Qt/qt_main.cpp | 30 ++++++++++++++++++++---------- 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 6a52bd5fc..f538e48a5 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.401 $ $NHDT-Date: 1608846067 2020/12/24 21:41:07 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.402 $ $NHDT-Date: 1608933417 2020/12/25 21:56:57 $ General Fixes and Modified Features ----------------------------------- @@ -345,6 +345,15 @@ best possible armor class reduced from -127 to -99; worst from +127 to +99; charged or enchanted individual items also capped at +/- 99 (affects wizard mode wishing, negligible effect on normal play) fix several inconsistencies for objects at hole locations +make repeat (^A) work when bound to some other keystroke +if a prefix key was bound to some character which ordinarily ran a regular + command and that command wasn't bound to another key, typing the + prefix followed by a non-movement key behaved strangely: instead + of reporting "invalid direction" it would run the other command + (actually depended upon relative order of prefix's new and old key) +reqmenu (the request-a-menu prefix supported by a handful of non-movement + commands) could be bound to some key other than 'm' but it only + worked if the new key was also a movement prefix Fixes to 3.7.0-x Problems that Were Exposed Via git Repository @@ -692,6 +701,8 @@ add 'sortdiscoveries' option to control output of '\' and '`' commands include an indication of monsters' health during farlook feedback (including /M and autodescribe); also include it in death reason when killed by a monster: "killed by {an uninjured newt,a heavily injured mumak}" +make DOAGAIN (^A) become unconditional; commenting it out in config.h makes + it be bound to NUL, a no-op, but allows BIND=k:repeat to set it to k Platform- and/or Interface-Specific New Features diff --git a/include/config.h b/include/config.h index a94b38267..1d762d99e 100644 --- a/include/config.h +++ b/include/config.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 config.h $NHDT-Date: 1596498529 2020/08/03 23:48:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */ +/* NetHack 3.7 config.h $NHDT-Date: 1608933417 2020/12/25 21:56:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.146 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -482,7 +482,12 @@ typedef unsigned char uchar; #endif #endif -#define DOAGAIN '\001' /* ^A, the "redo" key used in cmd.c and getline.c */ +/* The "repeat" key used in cmd.c as NHKF_DOAGAIN; if commented out or the + * value is changed from C('A') to 0, it won't be bound to any keystroke + * unless you use the run-time configuration file's BIND directive for it. + * [Note: C() macro isn't defined yet but it will be before DOAGAIN is used.] + */ +#define DOAGAIN C('A') /* repeat previous command; default is ^A, '\001' */ /* CONFIG_ERROR_SECURE: If user makes NETHACKOPTIONS point to a file ... * TRUE: Show the first error, nothing else. diff --git a/src/cmd.c b/src/cmd.c index 2192f499c..e40b4eab6 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 cmd.c $NHDT-Date: 1608233885 2020/12/17 19:38:05 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.437 $ */ +/* NetHack 3.7 cmd.c $NHDT-Date: 1608933418 2020/12/25 21:56:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.440 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2875,6 +2875,10 @@ wiz_migrate_mons() } #endif +#ifndef DOAGAIN /* might have gotten undefined in config.h */ +#define DOAGAIN '\0' /* undefined => 0, '\0' => no key to activate redo */ +#endif + static struct { int nhkf; uchar key; @@ -3364,7 +3368,9 @@ register char *cmd; g.context.move = FALSE; return; } - if (*cmd == DOAGAIN && !g.in_doagain && g.saveq[0]) { + /* DOAGAIN might be '\0'; if so, don't execute it even if *cmd is too */ + if ((*cmd && *cmd == g.Cmd.spkeys[NHKF_DOAGAIN]) + && !g.in_doagain && g.saveq[0]) { g.in_doagain = TRUE; g.stail = 0; rhack((char *) 0); /* read and execute command */ @@ -3475,9 +3481,9 @@ register char *cmd; break; } - /* some special prefix handling */ - /* overload 'm' prefix to mean "request a menu" */ - if (prefix_seen && cmd[0] == g.Cmd.spkeys[NHKF_REQMENU]) { + /* after movement--if reqmenu duplicates a prefix, movement takes + precedence; "request a menu" (default 'm') */ + if (cmd[0] == g.Cmd.spkeys[NHKF_REQMENU]) { /* (for func_tab cast, see below) */ const struct ext_func_tab *ft = g.Cmd.commands[cmd[1] & 0xff]; int NDECL((*func)) = ft ? ((struct ext_func_tab *) ft)->ef_funct : 0; @@ -3485,6 +3491,9 @@ register char *cmd; if (func && accept_menu_prefix(func)) { iflags.menu_requested = TRUE; ++cmd; + prefix_seen = FALSE; + } else { + prefix_seen = TRUE; } } @@ -3518,10 +3527,14 @@ register char *cmd; g.context.mv = TRUE; domove(); return; - } else if (prefix_seen && cmd[1] == g.Cmd.spkeys[NHKF_ESC]) { - /* */ - /* don't report "unknown command" for change of heart... */ - bad_command = FALSE; + } else if (prefix_seen) { + if (cmd[1] == g.Cmd.spkeys[NHKF_ESC]) { + /* */ + /* don't report "unknown command" for change of heart... */ + bad_command = FALSE; + } else { /* prefix followed by non-movement command */ + bad_command = TRUE; /* skip cmdlist[] loop */ + } } else if (*cmd == ' ' && !flags.rest_on_space) { bad_command = TRUE; /* skip cmdlist[] loop */ @@ -3641,7 +3654,8 @@ static boolean prefix_cmd(c) char c; { - return (c == g.Cmd.spkeys[NHKF_RUSH] + return (c == g.Cmd.spkeys[NHKF_REQMENU] + || c == g.Cmd.spkeys[NHKF_RUSH] || c == g.Cmd.spkeys[NHKF_RUN] || c == g.Cmd.spkeys[NHKF_NOPICKUP] || c == g.Cmd.spkeys[NHKF_RUN_NOPICKUP] @@ -4448,7 +4462,7 @@ parse() if (foo == g.Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */ clear_nhwindow(WIN_MESSAGE); g.multi = g.last_multi = 0; - } else if (foo == g.Cmd.spkeys[NHKF_DOAGAIN] || g.in_doagain) { + } else if ((foo && foo == g.Cmd.spkeys[NHKF_DOAGAIN]) || g.in_doagain) { g.multi = g.last_multi; } else { g.last_multi = g.multi; diff --git a/src/mdlib.c b/src/mdlib.c index bbd85225b..c1595450f 100644 --- a/src/mdlib.c +++ b/src/mdlib.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mdlib.c $NHDT-Date: 1596567095 2020/08/04 18:51:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.7 mdlib.c $NHDT-Date: 1608933420 2020/12/25 21:57:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.17 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Kenneth Lorber, Kensington, Maryland, 2015. */ /* Copyright (c) M. Stephenson, 1990, 1991. */ @@ -478,6 +478,13 @@ static const char *build_opts[] = { #if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__)) "external program as a message handler", #endif +#if defined(HANGUPHANDLING) && !defined(NO_SIGNAL) +#ifdef SAFERHANGUP + "deferred handling of hangup signal", +#else + "immediate handling of hangup signal", +#endif +#endif #ifdef INSURANCE "insurance files for recovering from crashes", #endif @@ -709,9 +716,9 @@ build_options() continue; #endif #endif /* !MAKEDEFS_C && FOR_RUNTIME */ - opt_out_words(strcat(strcpy(buf, build_opts[i]), - (i < SIZE(build_opts) - 1) ? "," : "."), - &length); + Strcat(strcpy(buf, build_opts[i]), + (i < SIZE(build_opts) - 1) ? "," : "."); + opt_out_words(buf, &length); } opttext[idxopttext] = strdup(optbuf); if (idxopttext < (MAXOPT - 1)) diff --git a/win/Qt/qt_main.cpp b/win/Qt/qt_main.cpp index 18759e0d8..cb2eade3d 100644 --- a/win/Qt/qt_main.cpp +++ b/win/Qt/qt_main.cpp @@ -814,7 +814,8 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : QSignalMapper* sm = new QSignalMapper(this); connect(sm, SIGNAL(mapped(const QString&)), this, SLOT(doKeys(const QString&))); - // 'donull' is a placeholder here; AddToolButton() will fix it up + // 'donull' is a placeholder here; AddToolButton() will fix it up; + // button will be omitted if DOAGAIN is bound to '\0' AddToolButton(toolbar, sm, "Again", donull, QPixmap(again_xpm)); // this used to be called "Get" which is confusing to experienced players AddToolButton(toolbar, sm, "Pick up", dopickup, QPixmap(pickup_xpm)); @@ -888,20 +889,29 @@ NetHackQtMainWindow::NetHackQtMainWindow(NetHackQtKeyBuffer& ks) : } } +// add a toolbar button to invoke command 'name' via function '(*func)()' void NetHackQtMainWindow::AddToolButton(QToolBar *toolbar, QSignalMapper *sm, const char *name, int NDECL((*func)), QPixmap xpm) { - QToolButton *tb = new SmallToolButton(xpm, QString(name), "Action", - sm, SLOT(map()), toolbar); - char actchar[32]; + char actchar[2]; + uchar key; + // the ^A command is just a keystroke, not a full blown command function - if (!strcmp(name, "Again")) - (void) strkitten(actchar, ::g.Cmd.spkeys[NHKF_DOAGAIN]); - else - Sprintf(actchar, "%c", cmd_from_func(func)); - sm->setMapping(tb, actchar); - toolbar->addWidget(tb); + if (!strcmp(name, "Again")) { + key = ::g.Cmd.spkeys[NHKF_DOAGAIN]; + } else + key = (uchar) cmd_from_func(func); + + // if key is valid, add a button for it; otherwise omit the command + // (won't work as intended if a different command is bound to same key) + if (key) { + QToolButton *tb = new SmallToolButton(xpm, QString(name), "Action", + sm, SLOT(map()), toolbar); + actchar[0] = '\0'; + sm->setMapping(tb, strkitten(actchar, (char) key)); + toolbar->addWidget(tb); + } } void NetHackQtMainWindow::zoomMap() From 62e6064a5421bbc779e961397ca5b283a4658dac Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 25 Dec 2020 14:39:13 -0800 Subject: [PATCH 677/708] help: dynamic keylist Make '?i' show special commands (primarily prefixes) without any key assigned (^A and ^C are possible by undefining DOAGAIN and defining NO_SIGNAL, respectively, not sure about any others) or are blocked because another special command earlier in the list is bound to the same key or player has tried to bind one to an active movement command (ie, key used for movement by the current number_pad setting). --- src/cmd.c | 118 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 88 insertions(+), 30 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index e40b4eab6..493a10faa 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -186,6 +186,7 @@ static boolean FDECL(keylist_func_has_key, (const struct ext_func_tab *, static int FDECL(keylist_putcmds, (winid, BOOLEAN_P, int, int, boolean *)); static int FDECL(ch2spkeys, (CHAR_P, int, int)); static boolean FDECL(prefix_cmd, (CHAR_P)); +static const char *FDECL(spkey_name, (int)); static int NDECL((*timed_occ_fn)); static char *FDECL(doc_extcmd_flagstr, (winid, const struct ext_func_tab *)); @@ -2075,13 +2076,13 @@ const char *command; struct ext_func_tab *extcmd; /* special case: "nothing" is reserved for unbinding */ - if (!strcmp(command, "nothing")) { + if (!strcmpi(command, "nothing")) { g.Cmd.commands[key] = (struct ext_func_tab *) 0; return TRUE; } for (extcmd = extcmdlist; extcmd->ef_txt; extcmd++) { - if (strcmp(command, extcmd->ef_txt)) + if (strcmpi(command, extcmd->ef_txt)) continue; g.Cmd.commands[key] = extcmd; #if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */ @@ -2211,12 +2212,6 @@ boolean *keys_used; /* boolean keys_used[256] */ void dokeylist(VOID_ARGS) { - const struct ext_func_tab *extcmd; - char buf[BUFSZ], buf2[BUFSZ]; - uchar key; - boolean keys_used[256]; - winid datawin; - int i; static const char run_desc[] = "Prefix: run until something very interesting is seen", rush_desc[] = "Prefix: rush until something interesting is seen", @@ -2238,17 +2233,26 @@ dokeylist(VOID_ARGS) "Prefix: move without picking up objects or fighting", FALSE }, { NHKF_RUN_NOPICKUP, "Prefix: run without picking up objects or fighting", FALSE }, - { NHKF_DOINV, "view full inventory", TRUE }, - /* NHKF_DOINV2 for num_pad+pcHack_compat isn't implemented */ - /* { NHKF_DOINV2, "view inventory of one class of objects", TRUE }, */ - { NHKF_REQMENU, "Prefix: request a menu", FALSE }, + { NHKF_REQMENU, + "Prefix: request a menu (for some non-movement commands)", FALSE }, { NHKF_COUNT, - "Prefix: for digits when prefixing a command with a count", TRUE }, - { NHKF_DOAGAIN , "re-do: perform the previous command again", FALSE }, + "Prefix: for digits when preceding a command with a count", TRUE }, + { NHKF_DOINV, "numpad: view full inventory", TRUE }, + /* NHKF_DOINV2 for num_pad+pcHack_compat isn't implemented */ + /* { NHKF_DOINV2, "numpad: view inventory of one class of objects", + TRUE }, */ + { NHKF_DOAGAIN , "repeat: perform the previous command again", FALSE }, { 0, (const char *) 0, FALSE } }; + const struct ext_func_tab *extcmd; + winid datawin; + char buf[BUFSZ], buf2[BUFSZ]; + uchar key; + boolean spkey_gap, keys_used[256], mov_seen[256]; + int i, j, pfx_seen[256]; (void) memset((genericptr_t) keys_used, 0, sizeof keys_used); + (void) memset((genericptr_t) pfx_seen, 0, sizeof pfx_seen); keys_used[(uchar) g.Cmd.move_NW] = keys_used[(uchar) g.Cmd.move_N] = keys_used[(uchar) g.Cmd.move_NE] = keys_used[(uchar) g.Cmd.move_W] @@ -2279,25 +2283,38 @@ dokeylist(VOID_ARGS) = keys_used[(uchar) M('6')] = keys_used[(uchar) M('7')] = keys_used[(uchar) M('8')] = keys_used[(uchar) M('9')] = TRUE; } - for (i = 0; misc_keys[i].desc; ++i) { - key = (uchar) g.Cmd.spkeys[misc_keys[i].nhkf]; - if (key && ((misc_keys[i].numpad && iflags.num_pad) - || !misc_keys[i].numpad)) { - keys_used[key] = TRUE; - } - } #ifndef NO_SIGNAL - /* this is actually ambiguous; tty raw mode will override SIGINT */ + /* this is actually ambiguous; tty raw mode will override SIGINT; + when enabled, treat it like a movement command since assigning + other commands to this keystroke would be unwise... */ key = (uchar) C('c'); keys_used[key] = TRUE; #endif + /* movement keys have been flagged in keys_used[]; clone them */ + (void) memcpy((genericptr_t) mov_seen, (genericptr_t) keys_used, + sizeof mov_seen); + + spkey_gap = FALSE; + for (i = 0; misc_keys[i].desc; ++i) { + if (misc_keys[i].numpad && !iflags.num_pad) + continue; + j = misc_keys[i].nhkf; + key = (uchar) g.Cmd.spkeys[j]; + if (key && !mov_seen[key] && (!pfx_seen[key] || j == NHKF_REQMENU)) { + keys_used[key] = TRUE; + if (j != NHKF_REQMENU) + pfx_seen[key] = j; + } else + spkey_gap = TRUE; + } + datawin = create_nhwindow(NHW_TEXT); putstr(datawin, 0, ""); Sprintf(buf, "%7s %s", "", " Full Current Key Bindings List"); putstr(datawin, 0, buf); for (extcmd = extcmdlist; extcmd->ef_txt; ++extcmd) - if (!keylist_func_has_key(extcmd, keys_used)) { + if (spkey_gap || !keylist_func_has_key(extcmd, keys_used)) { Sprintf(buf, "%7s %s", "", "(also commands with no key assignment)"); putstr(datawin, 0, buf); @@ -2330,20 +2347,44 @@ dokeylist(VOID_ARGS) putstr(datawin, 0, ""); putstr(datawin, 0, "Miscellaneous keys:"); for (i = 0; misc_keys[i].desc; ++i) { - key = (uchar) g.Cmd.spkeys[misc_keys[i].nhkf]; - if (key && ((misc_keys[i].numpad && iflags.num_pad) - || !misc_keys[i].numpad)) { + if (misc_keys[i].numpad && !iflags.num_pad) + continue; + j = misc_keys[i].nhkf; + key = (uchar) g.Cmd.spkeys[j]; + if (key && !mov_seen[key] + && (pfx_seen[key] == j || j == NHKF_REQMENU)) { Sprintf(buf, "%-7s %s", key2txt(key, buf2), misc_keys[i].desc); putstr(datawin, 0, buf); } } -#ifndef NO_SIGNAL /* (see above) */ key = (uchar) C('c'); - Sprintf(buf, "%-7s %s", key2txt(key, buf2), - "break out of NetHack (SIGINT)"); - putstr(datawin, 0, buf); +#ifndef NO_SIGNAL + /* last of the special keys */ + Sprintf(buf, "%-7s", key2txt(key, buf2)); +#else + /* first of the keyless commands */ + Sprintf(buf2, "[%s]", key2txt(key, buf)); + Sprintf(buf, "%-21s", buf2); #endif + Strcat(buf, " interrupt: break out of NetHack (SIGINT)"); + putstr(datawin, 0, buf); + /* keyless special key commands, if any */ + if (spkey_gap) { + for (i = 0; misc_keys[i].desc; ++i) { + if (misc_keys[i].numpad && !iflags.num_pad) + continue; + j = misc_keys[i].nhkf; + key = (uchar) g.Cmd.spkeys[j]; + if (!key || (pfx_seen[key] != j && j != NHKF_REQMENU)) { + Sprintf(buf2, "[%s]", spkey_name(j)); + /* lines up with the other unassigned commands which use + "#%-20s ", but not with the other special keys */ + Sprintf(buf, "%-21s %s", buf2, misc_keys[i].desc); + putstr(datawin, 0, buf); + } + } + } putstr(datawin, 0, ""); show_menu_controls(datawin, TRUE); @@ -2935,6 +2976,7 @@ uchar key; const char *command; { int i; + for (i = 0; i < SIZE(spkeys_binds); i++) { if (!spkeys_binds[i].name || strcmp(command, spkeys_binds[i].name)) continue; @@ -2944,6 +2986,22 @@ const char *command; return FALSE; } +static const char * +spkey_name(nhkf) +int nhkf; +{ + const char *name = 0; + int i; + + for (i = 0; i < SIZE(spkeys_binds); i++) { + if (spkeys_binds[i].nhkf == nhkf) { + name = (nhkf == NHKF_ESC) ? "escape" : spkeys_binds[i].name; + break; + } + } + return name; +} + /* returns a one-byte character from the text; may change txt[] */ uchar txt2key(txt) From 0c3b9642e4207ed3c0b756585b83477f59116305 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 26 Dec 2020 11:23:23 -0500 Subject: [PATCH 678/708] pmnames mons gender naming plus a window port interface change add MALE, FEMALE, and gender-neutral names for individual monster species to the mons array. The gender-neutral name (NEUTRAL) is mandatory, the MALE and FEMALE versions are not. replace code uses of the mname field of permonst with one of the three potentially-available gender-specific names. consolidate some separate mons entries that differed only by species into a single mons entry (caveman, cavewoman and priest,priestess etc.) consolidate several "* lord" and "* queen/* king" monst entries into their single species, and allow both genders on some where it makes some sense (there is probably more work and cleanup to come out of this at some point, and the chosen gender-neutral name variations are not cast in stone if someone has better suggestions). related function or macro additions: pmname(pm, gender) to get the gender variation of the permonst name. It guards against monsters that haven't got anything except NEUTRAL naming and falls back to the NEUTRAL version if FEMALE and MALE versions are missing. Ugender to obtain the current hero gender. Mgender(mtmp) to obtain the gender of a monster While the code can safely refer directly to pmnames[NEUTRAL] safely in the code because it always exists, the other two (pmnames[MALE] and pmnames[FEMALE] may not exist so use: pmname(ptr, gidx) where -ptr is a permonst * -gidx is an index into the pmnames array field of the permonst struct pmname() checks for a valid index and checks for null-pointers for pmnames[MALE] and pmnames[FEMALE], and will fall back to pmnames[NEUTRAL] if the pointer requested if the requested variation is unavailable, or if the gidx is out-of-range. Allow code to specify makemon flags to request female or male (via MM_MALE and MM_FEMALE flags respectively)to makedefs, since the species alone doesn't distinguish male/female anymore. Specifying MM_MALE or MM_FEMALE won't override the pm M2_MALE and M2_FEMALE flags on a mons[] entry. male and female tiles have been added to win/share/monsters.txt. The majority are duplicated placeholders except for those that were separate mons entries before. Perhaps someone will contribute artwork in the future to make the male and female variations visually distinguishable. tilemapping via has the MALE tile indexes in the glyph2tile[] array produced at build time. If a window port has information that the FEMALE tile is required, it just has to increment the index returned from the glyph2tile[] array by 1. statues already preserved gender of the monster through STATUE_FEMALE and STATUE_MALE, so ensure that pmnames takes that into consideration. I expect some refinement will be required after broad play-testing puts it to the test. consolidate caveman,cavewoman and priest,priestess monst.c entries etc This commit will require a bump of editlevel in patchlevel.h because it alters the index numbers of the monsters due to the consolidation of some. Those index numbers are saved in some other structures, even though the mons[] array itself is not part of the savefile. Window Port Interface Change Also add a parameter to print_glyph to convey additional information beyond the glyph to the window ports. Every single window port was calling back to mapglyph for the information anyway, so just included it in the interface and produce the information right in the display core. The mapglyph() function uses will be eliminated, although there are still some in the code yet to be dealt with. win32, tty, x11, Qt, msdos window ports have all had adjustments done to utilize the new parameter instead of calling mapglyph, but some of those window ports have not been thoroughly tested since the changes. Interface change additional info: print_glyph(window, x, y, glyph, bkglyph, *glyphmod) -- Print the glyph at (x,y) on the given window. Glyphs are integers at the interface, mapped to whatever the window- port wants (symbol, font, color, attributes, ...there's a 1-1 map between glyphs and distinct things on the map). -- bkglyph is a background glyph for potential use by some graphical or tiled environments to allow the depiction to fall against a background consistent with the grid around x,y. If bkglyph is NO_GLYPH, then the parameter should be ignored (do nothing with it). -- glyphmod provides extended information about the glyph that window ports can use to enhance the display in various ways. unsigned int glyphmod[NUM_GLYPHMOD] where: glyphmod[GM_TTYCHAR] is the text characters associated with the original NetHack display. glyphmod[GM_FLAGS] are the special flags that denote additional information that window ports can use. glyphmod[GM_COLOR] is the text character color associated with the original NetHack display. Support for including the glyphmod info in the display glyph buffer alongside the glyph itself was added and is the default operation. That can be turned off by defining UNBUFFERED_GLYPHMOD at compile time. With UNBUFFERED_GLYPHMOD operation, a call will be placed to map_glyphmod() immediately prior to every print_glyph() call. --- doc/fixes37.0 | 17 +- doc/window.doc | 7 +- include/artilist.h | 4 +- include/decl.h | 3 + include/display.h | 23 + include/extern.h | 13 +- include/hack.h | 27 +- include/mextra.h | 6 +- include/monflag.h | 3 + include/monst.h | 6 +- include/patchlevel.h | 2 +- include/permonst.h | 6 +- include/winX.h | 3 +- include/wincurs.h | 2 +- include/wingem.h | 3 +- include/winprocs.h | 9 +- include/wintty.h | 2 +- include/you.h | 1 + src/apply.c | 18 +- src/attrib.c | 10 +- src/bones.c | 6 +- src/botl.c | 4 +- src/cmd.c | 6 +- src/detect.c | 7 +- src/display.c | 473 ++- src/do_name.c | 114 +- src/do_wear.c | 4 +- src/dog.c | 2 +- src/dogmove.c | 3 +- src/dokick.c | 11 +- src/dothrow.c | 4 +- src/eat.c | 29 +- src/end.c | 21 +- src/exper.c | 2 +- src/explode.c | 2 +- src/files.c | 2 +- src/hack.c | 7 +- src/insight.c | 40 +- src/invent.c | 6 +- src/makemon.c | 31 +- src/mapglyph.c | 30 +- src/mhitu.c | 37 +- src/minion.c | 2 +- src/mkmaze.c | 4 +- src/mkroom.c | 8 +- src/mon.c | 81 +- src/mondata.c | 179 +- src/monst.c | 97 +- src/mplayer.c | 9 +- src/mthrowu.c | 3 +- src/muse.c | 6 +- src/music.c | 2 +- src/nhlobj.c | 3 +- src/objnam.c | 60 +- src/options.c | 4 +- src/pager.c | 22 +- src/pickup.c | 2 +- src/polyself.c | 33 +- src/potion.c | 2 +- src/pray.c | 2 +- src/priest.c | 15 +- src/questpgr.c | 6 +- src/read.c | 32 +- src/restore.c | 6 +- src/role.c | 8 +- src/save.c | 4 +- src/shk.c | 4 +- src/sounds.c | 12 +- src/sp_lev.c | 18 +- src/steal.c | 4 +- src/steed.c | 12 +- src/teleport.c | 3 +- src/timeout.c | 13 +- src/trap.c | 19 +- src/u_init.c | 10 +- src/uhitm.c | 30 +- src/vault.c | 5 +- src/weapon.c | 2 +- src/were.c | 8 +- src/windows.c | 5 +- src/wizard.c | 12 +- src/worn.c | 3 +- src/zap.c | 2 +- sys/msdos/vidvesa.c | 6 +- sys/msdos/vidvga.c | 12 +- util/makedefs.c | 10 +- win/Qt/qt_bind.cpp | 5 +- win/Qt/qt_bind.h | 2 +- win/Qt/qt_glyph.cpp | 22 +- win/Qt/qt_glyph.h | 10 +- win/Qt/qt_map.cpp | 65 +- win/Qt/qt_map.h | 10 +- win/Qt/qt_plsel.cpp | 25 +- win/Qt/qt_stat.cpp | 3 +- win/Qt/qt_win.cpp | 2 +- win/Qt/qt_win.h | 2 +- win/X11/winmap.c | 5 +- win/X11/winstat.c | 12 +- win/chain/wc_chainin.c | 5 +- win/chain/wc_chainout.c | 5 +- win/chain/wc_trace.c | 9 +- win/curses/cursmain.c | 8 +- win/curses/cursstat.c | 2 +- win/share/monsters.txt | 8259 +++++++++++++++++++++++++++++++++++++-- win/share/safeproc.c | 8 +- win/share/tilemap.c | 404 +- win/share/tiletext.c | 65 +- win/shim/winshim.c | 4 +- win/tty/wintty.c | 12 +- win/win32/mhmap.c | 75 +- win/win32/mhmsg.h | 1 + win/win32/mswproc.c | 12 +- win/win32/winMS.h | 2 +- 113 files changed, 9561 insertions(+), 1259 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index f538e48a5..d86b9d5ec 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -703,6 +703,12 @@ include an indication of monsters' health during farlook feedback (including a monster: "killed by {an uninjured newt,a heavily injured mumak}" make DOAGAIN (^A) become unconditional; commenting it out in config.h makes it be bound to NUL, a no-op, but allows BIND=k:repeat to set it to k +add support for a single monster species to have distinct male, female, + and gender-neutral naming terms +add support for a single monster species to have distinct male and female + tiles +consolidate several monsters that differed only by their gender into their + single species Platform- and/or Interface-Specific New Features @@ -730,6 +736,10 @@ Qt: add Filter, Layout, and Reset buttons to the extended command selector; mode only"; Layout redisplays the grid of command buttons, toggling from down columns to across rows or vice versa; Reset puts both back to their default settings and clears any pending typed input +tiles: male and female variations in monsters.txt; tested only with tile2bmp + conversion utility so far; also supported by tilemap utility to + generate tile.c; some window-port modifications still required to + integrate the male and female tile capability into the window port Unix: can define NOSUSPEND in config.h or src/Makefile's CFLAGS to prevent unixconf.h from enabling SUSPEND without need to modify unixconf.h @@ -824,5 +834,8 @@ move 'restoring' to the program_state struct; add corresponding 'saving'; unify special attack damages from separate you-hit-monster, monster-hits-you, and monster-hits-monster into functions by damage type unify trap effects for hero and monster stepping on the trap by trap type - - +replace the single permonst mname field with male, female, and gender-neutral + names pmnames[NUM_MGENDERS] fields +add a new glyphmod parameter to window interface *_print_glyph() to be used + to provide additional details to the window port beyond the glyph; + begin to phase out the mapglyph() calls from within windows ports diff --git a/doc/window.doc b/doc/window.doc index 1f376a5bd..bd55a5ac0 100644 --- a/doc/window.doc +++ b/doc/window.doc @@ -192,7 +192,7 @@ int nh_poskey(int *x, int *y, int *mod) B. High-level routines: -print_glyph(window, x, y, glyph, bkglyph) +print_glyph(window, x, y, glyph, bkglyph, glyphmod[3]) -- Print the glyph at (x,y) on the given window. Glyphs are integers at the interface, mapped to whatever the window- port wants (symbol, font, color, attributes, ...there's @@ -202,7 +202,10 @@ print_glyph(window, x, y, glyph, bkglyph) to fall against a background consistent with the grid around x,y. If bkglyph is NO_GLYPH, then the parameter should be ignored (do nothing with it). - + -- glyphmod (glyphmod[NUM_GLYPHNOD]) provides extended + information about the glyph that window ports can use to + enhance the display in various ways. + char yn_function(const char *ques, const char *choices, char default) -- Print a prompt made up of ques, choices and default. Read a single character response that is contained in diff --git a/include/artilist.h b/include/artilist.h index d3a5e7ab2..c95f41775 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -180,7 +180,7 @@ static NEARDATA struct artifact artilist[] = { A("The Sceptre of Might", MACE, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DALIGN), 0, 0, PHYS(5, 0), - DFNS(AD_MAGM), NO_CARY, CONFLICT, A_LAWFUL, PM_CAVEMAN, NON_PM, 2500L, + DFNS(AD_MAGM), NO_CARY, CONFLICT, A_LAWFUL, PM_CAVE_DWELLER, NON_PM, 2500L, NO_COLOR), #if 0 /* OBSOLETE */ @@ -210,7 +210,7 @@ A("The Palantir of Westernesse", CRYSTAL_BALL, A("The Mitre of Holiness", HELM_OF_BRILLIANCE, (SPFX_NOGEN | SPFX_RESTR | SPFX_DFLAG2 | SPFX_INTEL | SPFX_PROTECT), 0, M2_UNDEAD, NO_ATTK, NO_DFNS, CARY(AD_FIRE), ENERGY_BOOST, A_LAWFUL, - PM_PRIEST, NON_PM, 2000L, NO_COLOR), + PM_CLERIC, NON_PM, 2000L, NO_COLOR), A("The Longbow of Diana", BOW, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_REFLECT), SPFX_ESP, 0, diff --git a/include/decl.h b/include/decl.h index 71147ce18..0a9b61ba9 100644 --- a/include/decl.h +++ b/include/decl.h @@ -524,6 +524,9 @@ struct trapinfo { typedef struct { xchar gnew; /* perhaps move this bit into the rm structure. */ int glyph; +#ifndef UNBUFFERED_GLYPHMOD + unsigned glyphmod[NUM_GLYPHMOD]; +#endif } gbuf_entry; enum vanq_order_modes { diff --git a/include/display.h b/include/display.h index 28c02becd..1c944c276 100644 --- a/include/display.h +++ b/include/display.h @@ -475,4 +475,27 @@ enum explosion_types { #define glyph_is_unexplored(glyph) ((glyph) == GLYPH_UNEXPLORED) #define glyph_is_nothing(glyph) ((glyph) == GLYPH_NOTHING) +/* flags for map_glyphmod */ + +/* mgflags for altering map_glyphmod() internal behaviour */ +#define MG_FLAG_NORMAL 0x00 +#define MG_FLAG_NOOVERRIDE 0x01 +#define MG_FLAG_RETURNIDX 0x02 + +/* Special mapped glyph flags encoded in glyphmod[GM_FLAGS] by map_glyphmod() */ +#define MG_CORPSE 0x0001 +#define MG_INVIS 0x0002 +#define MG_DETECT 0x0004 +#define MG_PET 0x0008 +#define MG_RIDDEN 0x0010 +#define MG_STATUE 0x0020 +#define MG_OBJPILE 0x0040 /* more than one stack of objects */ +#define MG_BW_LAVA 0x0080 /* 'black & white lava': highlight lava if it + can't be distringuished from water by color */ +#define MG_BW_ICE 0x0100 /* similar for ice vs floor */ +#define MG_NOTHING 0x0200 /* char represents GLYPH_NOTHING */ +#define MG_UNEXPL 0x0400 /* char represents GLYPH_UNEXPLORED */ +#define MG_FEMALE 0x0800 /* represents a female mon,detected mon,pet,ridden */ +#define MG_BADXY 0x1000 /* bad coordinates were passed */ + #endif /* DISPLAY_H */ diff --git a/include/extern.h b/include/extern.h index ac8b1e723..cf66dd4ff 100644 --- a/include/extern.h +++ b/include/extern.h @@ -374,6 +374,7 @@ E void NDECL(reglyph_darkroom); E void NDECL(set_wall_state); E void FDECL(unset_seenv, (struct rm *, int, int, int, int)); E int FDECL(warning_of, (struct monst *)); +E void FDECL(map_glyphmod, (XCHAR_P, XCHAR_P, int, unsigned, unsigned *)); /* ### do.c ### */ @@ -415,8 +416,8 @@ E char *FDECL(coord_desc, (int, int, char *, CHAR_P)); E boolean FDECL(getpos_menu, (coord *, int)); E int FDECL(getpos, (coord *, BOOLEAN_P, const char *)); E void FDECL(getpos_sethilite, (void (*f)(int), boolean (*d)(int,int))); -E void FDECL(new_mname, (struct monst *, int)); -E void FDECL(free_mname, (struct monst *)); +E void FDECL(new_mgivenname, (struct monst *, int)); +E void FDECL(free_mgivenname, (struct monst *)); E void FDECL(new_oname, (struct obj *, int)); E void FDECL(free_oname, (struct obj *)); E const char *FDECL(safe_oname, (struct obj *)); @@ -457,6 +458,10 @@ E struct monst *FDECL(christen_orc, (struct monst *, const char *, const char *)); E const char *FDECL(noveltitle, (int *)); E const char *FDECL(lookup_novel, (const char *, int *)); +#ifndef PMNAME_MACROS +E int FDECL(Mgender, (struct monst *)); +E const char *FDECL(pmname, (struct permonst *, int)); +#endif /* PMNAME_MACROS */ /* ### do_wear.c ### */ @@ -1516,8 +1521,8 @@ E boolean FDECL(dmgtype, (struct permonst *, int)); E int FDECL(max_passive_dmg, (struct monst *, struct monst *)); E boolean FDECL(same_race, (struct permonst *, struct permonst *)); E int FDECL(monsndx, (struct permonst *)); -E int FDECL(name_to_mon, (const char *)); -E int FDECL(name_to_monplus, (const char *, const char **)); +E int FDECL(name_to_mon, (const char *, int *)); +E int FDECL(name_to_monplus, (const char *, const char **, int *)); E int FDECL(name_to_monclass, (const char *, int *)); E int FDECL(gender, (struct monst *)); E int FDECL(pronoun_gender, (struct monst *, unsigned)); diff --git a/include/hack.h b/include/hack.h index 0917b93c4..aa9b57106 100644 --- a/include/hack.h +++ b/include/hack.h @@ -79,24 +79,6 @@ enum dismount_types { DISMOUNT_BYCHOICE = 6 }; -/* mgflags for mapglyph() */ -#define MG_FLAG_NORMAL 0x00 -#define MG_FLAG_NOOVERRIDE 0x01 - -/* Special returns from mapglyph() */ -#define MG_CORPSE 0x0001 -#define MG_INVIS 0x0002 -#define MG_DETECT 0x0004 -#define MG_PET 0x0008 -#define MG_RIDDEN 0x0010 -#define MG_STATUE 0x0020 -#define MG_OBJPILE 0x0040 /* more than one stack of objects */ -#define MG_BW_LAVA 0x0080 /* 'black & white lava': highlight lava if it - can't be distringuished from water by color */ -#define MG_BW_ICE 0x0100 /* similar for ice vs floor */ -#define MG_NOTHING 0x0200 /* char represents GLYPH_NOTHING */ -#define MG_UNEXPL 0x0400 /* char represents GLYPH_UNEXPLORED */ - /* sellobj_state() states */ #define SELL_NORMAL (0) #define SELL_DELIBERATE (1) @@ -216,6 +198,9 @@ typedef struct { #define SYM_OFF_X (SYM_OFF_W + WARNCOUNT) #define SYM_MAX (SYM_OFF_X + MAXOTHER) +/* glyphmod entries */ +enum { GM_FLAGS, GM_TTYCHAR, GM_COLOR, NUM_GLYPHMOD }; + #include "rect.h" #include "region.h" #include "decl.h" @@ -293,10 +278,12 @@ typedef struct sortloot_item Loot; #define MM_ASLEEP 0x002000L /* monsters should be generated asleep */ #define MM_NOGRP 0x004000L /* suppress creation of monster groups */ #define MM_NOTAIL 0x008000L /* if a long worm, don't give it a tail */ +#define MM_MALE 0x010000L /* male variation */ +#define MM_FEMALE 0x020000L /* female variation */ /* if more MM_ flag masks are added, skip or renumber the GP_ one(s) */ -#define GP_ALLOW_XY 0x010000L /* [actually used by enexto() to decide whether +#define GP_ALLOW_XY 0x040000L /* [actually used by enexto() to decide whether * to make an extra call to goodpos()] */ -#define GP_ALLOW_U 0x020000L /* don't reject hero's location */ +#define GP_ALLOW_U 0x080000L /* don't reject hero's location */ /* flags for make_corpse() and mkcorpstat() */ #define CORPSTAT_NONE 0x00 diff --git a/include/mextra.h b/include/mextra.h index 0ade0adf7..cc4d715ae 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -175,7 +175,7 @@ struct edog { ** mextra.h -- collection of all monster extensions */ struct mextra { - char *mname; + char *mgivenname; struct egd *egd; struct epri *epri; struct eshk *eshk; @@ -186,7 +186,7 @@ struct mextra { * or an alignment mask for one posing as an altar */ }; -#define MNAME(mon) ((mon)->mextra->mname) +#define MGIVENNAME(mon) ((mon)->mextra->mgivenname) #define EGD(mon) ((mon)->mextra->egd) #define EPRI(mon) ((mon)->mextra->epri) #define ESHK(mon) ((mon)->mextra->eshk) @@ -194,7 +194,7 @@ struct mextra { #define EDOG(mon) ((mon)->mextra->edog) #define MCORPSENM(mon) ((mon)->mextra->mcorpsenm) -#define has_mname(mon) ((mon)->mextra && MNAME(mon)) +#define has_mgivenname(mon) ((mon)->mextra && MGIVENNAME(mon)) #define has_egd(mon) ((mon)->mextra && EGD(mon)) #define has_epri(mon) ((mon)->mextra && EPRI(mon)) #define has_eshk(mon) ((mon)->mextra && ESHK(mon)) diff --git a/include/monflag.h b/include/monflag.h index a243dc8a4..d7a1a88f5 100644 --- a/include/monflag.h +++ b/include/monflag.h @@ -205,6 +205,9 @@ enum ms_sounds { #define G_GONE (G_GENOD | G_EXTINCT) #define MV_KNOWS_EGG 0x08 /* player recognizes egg of this monster type */ +enum mgender { MALE, FEMALE, NEUTRAL, + NUM_MGENDERS }; + /* *INDENT-ON* */ /* clang-format on */ #endif /* MONFLAG_H */ diff --git a/include/monst.h b/include/monst.h index 6842162ca..66f51f469 100644 --- a/include/monst.h +++ b/include/monst.h @@ -184,7 +184,7 @@ struct monst { #define DEADMONSTER(mon) ((mon)->mhp < 1) #define is_starting_pet(mon) ((mon)->m_id == g.context.startingpet_mid) #define is_vampshifter(mon) \ - ((mon)->cham == PM_VAMPIRE || (mon)->cham == PM_VAMPIRE_LORD \ + ((mon)->cham == PM_VAMPIRE || (mon)->cham == PM_VAMPIRE_LEADER \ || (mon)->cham == PM_VLAD_THE_IMPALER) #define vampshifted(mon) (is_vampshifter((mon)) && !is_vampire((mon)->data)) @@ -220,4 +220,8 @@ struct monst { #define montoostrong(monindx, lev) (mons[monindx].difficulty > lev) #define montooweak(monindx, lev) (mons[monindx].difficulty < lev) +#ifdef PMNAME_MACROS +#define Mgender(mon) ((mon)->female ? FEMALE : MALE) +#endif + #endif /* MONST_H */ diff --git a/include/patchlevel.h b/include/patchlevel.h index d6969198b..a7b4c2da8 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 29 +#define EDITLEVEL 30 /* * Development status possibilities. diff --git a/include/permonst.h b/include/permonst.h index 5125f1339..0a017c68a 100644 --- a/include/permonst.h +++ b/include/permonst.h @@ -40,7 +40,7 @@ struct attack { #include "monflag.h" struct permonst { - const char *mname; /* full name */ + const char *pmnames[NUM_MGENDERS]; char mlet; /* symbol */ schar mlevel, /* base monster level */ mmove, /* move speed */ @@ -78,4 +78,8 @@ extern NEARDATA struct permonst mons[]; /* the master list of monster types */ /* mons[SPECIAL_PM] through mons[NUMMONS-1], inclusive, are never generated randomly and cannot be polymorphed into */ +#ifdef PMNAME_MACROS +#define pmname(pm,g) ((((g) == MALE || (g) == FEMALE) && (pm)->pmnames[g]) \ + ? (pm)->pmnames[g] : (pm)->pmnames[NEUTRAL]) +#endif #endif /* PERMONST_H */ diff --git a/include/winX.h b/include/winX.h index 7cf1c2885..3f29dce75 100644 --- a/include/winX.h +++ b/include/winX.h @@ -453,7 +453,8 @@ E void NDECL(X11_wait_synch); #ifdef CLIPPING E void FDECL(X11_cliparound, (int, int)); #endif -E void FDECL(X11_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); +E void FDECL(X11_print_glyph, (winid, XCHAR_P, XCHAR_P, + int, int, unsigned *)); E void FDECL(X11_raw_print, (const char *)); E void FDECL(X11_raw_print_bold, (const char *)); E int NDECL(X11_nhgetch); diff --git a/include/wincurs.h b/include/wincurs.h index 4e5ce4e78..001c813e6 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -90,7 +90,7 @@ extern void curses_mark_synch(void); extern void curses_wait_synch(void); extern void curses_cliparound(int x, int y); extern void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, - int glyph, int bkglyph); + int glyph, int bkglyph, unsigned *glyphmod); extern void curses_raw_print(const char *str); extern void curses_raw_print_bold(const char *str); extern int curses_nhgetch(void); diff --git a/include/wingem.h b/include/wingem.h index 6a0a517f7..f433e1cc6 100644 --- a/include/wingem.h +++ b/include/wingem.h @@ -84,7 +84,8 @@ E void FDECL(Gem_cliparound, (int, int)); #ifdef POSITIONBAR E void FDECL(Gem_update_positionbar, (char *)); #endif -E void FDECL(Gem_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); +E void FDECL(Gem_print_glyph, (winid, XCHAR_P, XCHAR_P, + int, int, unsigned *)); E void FDECL(Gem_raw_print, (const char *)); E void FDECL(Gem_raw_print_bold, (const char *)); E int NDECL(Gem_nhgetch); diff --git a/include/winprocs.h b/include/winprocs.h index fa6652c05..728e35067 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -45,7 +45,8 @@ struct window_procs { #ifdef POSITIONBAR void FDECL((*win_update_positionbar), (char *)); #endif - void FDECL((*win_print_glyph), (winid, XCHAR_P, XCHAR_P, int, int)); + void FDECL((*win_print_glyph), (winid, XCHAR_P, XCHAR_P, + int, int, unsigned *)); void FDECL((*win_raw_print), (const char *)); void FDECL((*win_raw_print_bold), (const char *)); int NDECL((*win_nhgetch)); @@ -345,7 +346,8 @@ struct chain_procs { #ifdef POSITIONBAR void FDECL((*win_update_positionbar), (CARGS, char *)); #endif - void FDECL((*win_print_glyph), (CARGS, winid, XCHAR_P, XCHAR_P, int, int)); + void FDECL((*win_print_glyph), (CARGS, winid, XCHAR_P, XCHAR_P, + int, int, unsigned *)); void FDECL((*win_raw_print), (CARGS, const char *)); void FDECL((*win_raw_print_bold), (CARGS, const char *)); int FDECL((*win_nhgetch), (CARGS)); @@ -420,7 +422,8 @@ extern void FDECL(safe_cliparound, (int, int)); #ifdef POSITIONBAR extern void FDECL(safe_update_positionbar, (char *)); #endif -extern void FDECL(safe_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); +extern void FDECL(safe_print_glyph, (winid, XCHAR_P, XCHAR_P, + int, int, unsigned *)); extern void FDECL(safe_raw_print, (const char *)); extern void FDECL(safe_raw_print_bold, (const char *)); extern int NDECL(safe_nhgetch); diff --git a/include/wintty.h b/include/wintty.h index 2d0b05fd2..5d1d444d0 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -211,7 +211,7 @@ E void FDECL(tty_cliparound, (int, int)); #ifdef POSITIONBAR E void FDECL(tty_update_positionbar, (char *)); #endif -E void FDECL(tty_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); +E void FDECL(tty_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int, unsigned *)); E void FDECL(tty_raw_print, (const char *)); E void FDECL(tty_raw_print_bold, (const char *)); E int NDECL(tty_nhgetch); diff --git a/include/you.h b/include/you.h index 0d9686f88..79d3737ff 100644 --- a/include/you.h +++ b/include/you.h @@ -479,5 +479,6 @@ struct you { }; /* end of `struct you' */ #define Upolyd (u.umonnum != u.umonster) +#define Ugender ((Upolyd ? u.mfemale : flags.female) ? 1 : 0) #endif /* YOU_H */ diff --git a/src/apply.c b/src/apply.c index daa2b9c4b..737836f15 100644 --- a/src/apply.c +++ b/src/apply.c @@ -272,7 +272,7 @@ int rx, ry, *resp; humanoid(mptr) ? "person" : "creature"); what = buf; } else { - what = mptr->mname; + what = pmname(mptr, NEUTRAL); if (!type_is_pname(mptr)) what = The(what); } @@ -408,7 +408,7 @@ register struct obj *obj; || odummy->otyp == LENSES); break; case M_AP_MONSTER: /* ignore Hallucination here */ - what = mons[mtmp->mappearance].mname; + what = pmname(&mons[mtmp->mappearance], Mgender(mtmp)); break; case M_AP_FURNITURE: what = defsyms[mtmp->mappearance].explanation; @@ -904,7 +904,7 @@ struct obj *obj; } else if (u.uhs >= WEAK) { You(look_str, "undernourished"); } else if (Upolyd) { - You("look like %s.", an(mons[u.umonnum].mname)); + You("look like %s.", an(pmname(&mons[u.umonnum], Ugender))); } else { You("look as %s as ever.", uvisage); } @@ -985,8 +985,8 @@ struct obj *obj; if (vis) pline("%s confuses itself!", Monnam(mtmp)); mtmp->mconf = 1; - } else if (monable && (mlet == S_NYMPH || mtmp->data == &mons[PM_SUCCUBUS] - || mtmp->data == &mons[PM_INCUBUS])) { + } else if (monable && + (mlet == S_NYMPH || mtmp->data == &mons[PM_AMOROUS_DEMON])) { if (vis) { char buf[BUFSZ]; /* "She" or "He" */ @@ -1951,12 +1951,12 @@ struct obj *obj; if (poly_when_stoned(g.youmonst.data)) You("tin %s without wearing gloves.", - an(mons[corpse->corpsenm].mname)); + an(mons[corpse->corpsenm].pmnames[NEUTRAL])); else { pline("Tinning %s without wearing gloves is a fatal mistake...", - an(mons[corpse->corpsenm].mname)); + an(mons[corpse->corpsenm].pmnames[NEUTRAL])); Sprintf(kbuf, "trying to tin %s without gloves", - an(mons[corpse->corpsenm].mname)); + an(mons[corpse->corpsenm].pmnames[NEUTRAL])); } instapetrify(kbuf); } @@ -2895,7 +2895,7 @@ struct obj *obj; char kbuf[BUFSZ]; Sprintf(kbuf, "%s corpse", - an(mons[otmp->corpsenm].mname)); + an(mons[otmp->corpsenm].pmnames[NEUTRAL])); pline("Snatching %s is a fatal mistake.", kbuf); instapetrify(kbuf); } diff --git a/src/attrib.c b/src/attrib.c index 551992bf7..759296702 100644 --- a/src/attrib.c +++ b/src/attrib.c @@ -298,7 +298,7 @@ boolean thrown_weapon; /* thrown weapons are less deadly */ } /* suppress killer prefix if it already has one */ - i = name_to_mon(pkiller); + i = name_to_mon(pkiller, (int *) 0); if (i >= LOW_PM && (mons[i].geno & G_UNIQ)) { kprefix = KILLED_BY; if (!type_is_pname(&mons[i])) @@ -709,11 +709,11 @@ int r; } roleabils[] = { { PM_ARCHEOLOGIST, arc_abil }, { PM_BARBARIAN, bar_abil }, - { PM_CAVEMAN, cav_abil }, + { PM_CAVE_DWELLER, cav_abil }, { PM_HEALER, hea_abil }, { PM_KNIGHT, kni_abil }, { PM_MONK, mon_abil }, - { PM_PRIEST, pri_abil }, + { PM_CLERIC, pri_abil }, { PM_RANGER, ran_abil }, { PM_ROGUE, rog_abil }, { PM_SAMURAI, sam_abil }, @@ -1054,8 +1054,8 @@ int x; #endif } else if (x == A_CHA) { if (tmp < 18 - && (g.youmonst.data->mlet == S_NYMPH || u.umonnum == PM_SUCCUBUS - || u.umonnum == PM_INCUBUS)) + && (g.youmonst.data->mlet == S_NYMPH + || u.umonnum == PM_AMOROUS_DEMON)) return (schar) 18; } else if (x == A_CON) { if (uwep && uwep->oartifact == ART_OGRESMASHER) diff --git a/src/bones.c b/src/bones.c index ca5a818cc..93c23b962 100644 --- a/src/bones.c +++ b/src/bones.c @@ -617,12 +617,12 @@ getbones() * set to the magic DEFUNCT_MONSTER cookie value. */ for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { - if (has_mname(mtmp)) - sanitize_name(MNAME(mtmp)); + if (has_mgivenname(mtmp)) + sanitize_name(MGIVENNAME(mtmp)); if (mtmp->mhpmax == DEFUNCT_MONSTER) { if (wizard) { debugpline1("Removing defunct monster %s from bones.", - mtmp->data->mname); + mtmp->data->pmnames[NEUTRAL]); } mongone(mtmp); } else diff --git a/src/botl.c b/src/botl.c index 23dd6906c..ab225740c 100644 --- a/src/botl.c +++ b/src/botl.c @@ -67,7 +67,7 @@ do_statusline1() char mbot[BUFSZ]; int k = 0; - Strcpy(mbot, mons[u.umonnum].mname); + Strcpy(mbot, pmname(&mons[u.umonnum], Ugender)); while (mbot[k] != 0) { if ((k == 0 || (k > 0 && mbot[k - 1] == ' ')) && 'a' <= mbot[k] && mbot[k] <= 'z') @@ -719,7 +719,7 @@ bot_via_windowport() */ Strcpy(nb = buf, g.plname); nb[0] = highc(nb[0]); - titl = !Upolyd ? rank() : mons[u.umonnum].mname; + titl = !Upolyd ? rank() : pmname(&mons[u.umonnum], Ugender); i = (int) (strlen(buf) + sizeof " the " + strlen(titl) - sizeof ""); /* if "Name the Rank/monster" is too long, we truncate the name but always keep at least 10 characters of it; when hitpintbar is diff --git a/src/cmd.c b/src/cmd.c index 493a10faa..0ae12b0db 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2623,8 +2623,8 @@ boolean incl_wsegs; if (mtmp->mextra) { sz += (int) sizeof (struct mextra); - if (MNAME(mtmp)) - sz += (int) strlen(MNAME(mtmp)) + 1; + if (MGIVENNAME(mtmp)) + sz += (int) strlen(MGIVENNAME(mtmp)) + 1; if (EGD(mtmp)) sz += (int) sizeof (struct egd); if (EPRI(mtmp)) @@ -4241,7 +4241,7 @@ boolean doit; #if 0 if (Upolyd) { /* before objects */ Sprintf(buf, "Use %s special ability", - s_suffix(mons[u.umonnum].mname)); + s_suffix(pmname(&mons[u.umonnum], Ugender))); add_herecmd_menuitem(win, domonability, buf); } #endif diff --git a/src/detect.c b/src/detect.c index ddf52e59f..db5e84895 100644 --- a/src/detect.c +++ b/src/detect.c @@ -2005,12 +2005,13 @@ dump_map() blankrow = TRUE; /* assume blank until we discover otherwise */ lastnonblank = -1; /* buf[] index rather than map's x */ for (x = 1; x < COLNO; x++) { - int ch, color; - unsigned special; + int ch; + unsigned glyphmod[NUM_GLYPHMOD]; glyph = reveal_terrain_getglyph(x, y, FALSE, u.uswallow, default_glyph, subset); - (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); + map_glyphmod(x, y, glyph, 0, glyphmod); + ch = (int) glyphmod[GM_TTYCHAR]; buf[x - 1] = ch; if (ch != ' ') { blankrow = FALSE; diff --git a/src/display.c b/src/display.c index 1e0ac89e7..8a98c8f55 100644 --- a/src/display.c +++ b/src/display.c @@ -132,6 +132,9 @@ static void FDECL(display_warning, (struct monst *)); static int FDECL(check_pos, (int, int, int)); static int FDECL(get_bk_glyph, (XCHAR_P, XCHAR_P)); static int FDECL(tether_glyph, (int, int)); +#ifdef UNBUFFERED_GLYPHMOD +static unsigned *FDECL(glyphmod_at, (XCHAR_P, XCHAR_P, int)); +#endif /*#define WA_VERBOSE*/ /* give (x,y) locations for all "bad" spots */ #ifdef WA_VERBOSE @@ -1367,6 +1370,17 @@ see_traps() } } +static unsigned no_gm[NUM_GLYPHMOD] = + {MG_BADXY, (unsigned) ' ', (unsigned) NO_COLOR}; +#ifndef UNBUFFERED_GLYPHMOD +#define Glyphmod_at(x,y,glyph) ( \ + ((x) < 0 || (y) < 0 || (x) >= COLNO || (y) >= ROWNO) \ + ? &no_gm[0] : &g.gbuf[(y)][(x)].glyphmod[0]) +#else +static unsigned gm[NUM_GLYPHMOD]; +#define Glyphmod_at(x,y,glyph) glyphmod_at(x, y, glyph) +#endif + /* * Put the cursor on the hero. Flush all accumulated glyphs before doing it. */ @@ -1462,7 +1476,8 @@ redraw_map() for (y = 0; y < ROWNO; ++y) for (x = 1; x < COLNO; ++x) { glyph = glyph_at(x, y); /* not levl[x][y].glyph */ - print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y)); + print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y), + Glyphmod_at(x, y, glyph)); } flush_screen(1); } @@ -1524,6 +1539,10 @@ void show_glyph(x, y, glyph) int x, y, glyph; { +#ifndef UNBUFFERED_GLYPHMOD + unsigned glyphmod[NUM_GLYPHMOD]; +#endif + /* * Check for bad positions and glyphs. */ @@ -1578,7 +1597,6 @@ int x, y, glyph; text = "monster"; offset = glyph; } - impossible("show_glyph: bad pos %d %d with glyph %d [%s %d].", x, y, glyph, text, offset); return; @@ -1589,10 +1607,27 @@ int x, y, glyph; MAX_GLYPH, x, y); return; } +#ifndef UNBUFFERED_GLYPHMOD + /* without UNBUFFERED_GLYPHMOD defined the glyphmod values are buffered + alongside the glyphs themselves for better performance, increased + buffer size */ + map_glyphmod(x, y, glyph, 0, glyphmod); +#endif - if (g.gbuf[y][x].glyph != glyph || iflags.use_background_glyph) { + if (g.gbuf[y][x].glyph != glyph +#ifndef UNBUFFERED_GLYPHMOD + /* I don't think we have to test for changes in TTYCHAR or COLOR + because they typically only change if the glyph changed */ + || g.gbuf[y][x].glyphmod[GM_FLAGS] != glyphmod[GM_FLAGS] +#endif + || iflags.use_background_glyph ) { g.gbuf[y][x].glyph = glyph; g.gbuf[y][x].gnew = 1; +#ifndef UNBUFFERED_GLYPHMOD + g.gbuf[y][x].glyphmod[GM_FLAGS] = glyphmod[GM_FLAGS]; + g.gbuf[y][x].glyphmod[GM_TTYCHAR] = glyphmod[GM_TTYCHAR]; + g.gbuf[y][x].glyphmod[GM_COLOR] = glyphmod[GM_COLOR]; +#endif if (g.gbuf_start[y] > x) g.gbuf_start[y] = x; if (g.gbuf_stop[y] < x) @@ -1614,6 +1649,14 @@ int x, y, glyph; } \ } +static gbuf_entry nul_gbuf = { + 0, /* gnew */ + GLYPH_UNEXPLORED, /* glyph */ +#ifndef UNBUFFERED_GLYPHMOD + {(unsigned) ' ', (unsigned) NO_COLOR, MG_UNEXPL}, +#endif +}; + /* * Turn the 3rd screen into UNEXPLORED that needs to be refreshed. */ @@ -1621,15 +1664,25 @@ void clear_glyph_buffer() { register int x, y; - register gbuf_entry *gptr, nul_gbuf; - int ch = ' ', color = NO_COLOR; - unsigned special = 0; - - (void) mapglyph(GLYPH_UNEXPLORED, &ch, &color, &special, 0, 0, 0); - nul_gbuf.gnew = (ch != ' ' || color != NO_COLOR - || (special & ~MG_UNEXPL) != 0) ? 1 : 0; - nul_gbuf.glyph = GLYPH_UNEXPLORED; + gbuf_entry *gptr = &g.gbuf[0][0]; + unsigned *gmptr = +#ifndef UNBUFFERED_GLYPHMOD + &gptr->glyphmod[0]; +#else + &gm[0]; + map_glyphmod(0, 0, GLYPH_UNEXPLORED, 0, gmptr); +#endif +#ifndef UNBUFFERED_GLYPHMOD + nul_gbuf.gnew = (gmptr[GM_TTYCHAR] != nul_gbuf.glyphmod[GM_TTYCHAR] + || gmptr[GM_COLOR] != nul_gbuf.glyphmod[GM_COLOR] + || gmptr[GM_FLAGS] != nul_gbuf.glyphmod[GM_FLAGS]) +#else + nul_gbuf.gnew = (gmptr[GM_TTYCHAR] != ' ' + || gmptr[GM_COLOR] != NO_COLOR + || (gmptr[GM_FLAGS] & ~MG_UNEXPL) != 0) +#endif + ? 1 : 0; for (y = 0; y < ROWNO; y++) { gptr = &g.gbuf[y][0]; for (x = COLNO; x; x--) { @@ -1648,16 +1701,31 @@ int start, stop, y; { register int x, glyph; register boolean force; - int ch = ' ', color = NO_COLOR; - unsigned special = 0; - - (void) mapglyph(GLYPH_UNEXPLORED, &ch, &color, &special, 0, 0, 0); - force = (ch != ' ' || color != NO_COLOR || (special & ~MG_UNEXPL) != 0); + gbuf_entry *gptr = &g.gbuf[0][0]; + unsigned *gmptr = +#ifndef UNBUFFERED_GLYPHMOD + &gptr->glyphmod[0]; +#else + &gm[0]; + map_glyphmod(0, 0, GLYPH_UNEXPLORED, 0, gmptr); +#endif +#ifndef UNBUFFERED_GLYPHMOD + force = (gmptr[GM_TTYCHAR] != nul_gbuf.glyphmod[GM_TTYCHAR] + || gmptr[GM_COLOR] != nul_gbuf.glyphmod[GM_COLOR] + || gmptr[GM_FLAGS] != nul_gbuf.glyphmod[GM_FLAGS]) +#else + force = (gmptr[GM_TTYCHAR] != ' ' + || gmptr[GM_COLOR] != NO_COLOR + || (gmptr[GM_FLAGS] & ~MG_UNEXPL) != 0) +#endif + ? 1 : 0; for (x = start; x <= stop; x++) { - glyph = g.gbuf[y][x].glyph; + gptr = &g.gbuf[y][x]; + glyph = gptr->glyph; if (force || glyph != GLYPH_UNEXPLORED) - print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y)); + print_glyph(WIN_MAP, x, y, glyph, + get_bk_glyph(x, y), Glyphmod_at(x, y, glyph)); } } @@ -1712,7 +1780,8 @@ int cursor_on_u; for (; x <= g.gbuf_stop[y]; gptr++, x++) if (gptr->gnew) { - print_glyph(WIN_MAP, x, y, gptr->glyph, get_bk_glyph(x, y)); + print_glyph(WIN_MAP, x, y, gptr->glyph, + get_bk_glyph(x, y), Glyphmod_at(x, y, gptr->glyph)); gptr->gnew = 0; } } @@ -1930,6 +1999,17 @@ xchar x, y; return g.gbuf[y][x].glyph; } +#ifdef UNBUFFERED_GLYPHMOD +unsigned * +glyphmod_at(x, y, glyph) +xchar x, y; +int glyph; +{ + map_glyphmod(x, y, glyph, 0, gm); + return &gm[0]; +} +#endif + /* * This will be used to get the glyph for the background so that * it can potentially be merged into graphical window ports to @@ -2002,6 +2082,361 @@ xchar x, y; return bkglyph; } +#define HI_DOMESTIC CLR_WHITE /* monst.c */ +#ifdef TEXTCOLOR +static const int explcolors[] = { + CLR_BLACK, /* dark */ + CLR_GREEN, /* noxious */ + CLR_BROWN, /* muddy */ + CLR_BLUE, /* wet */ + CLR_MAGENTA, /* magical */ + CLR_ORANGE, /* fiery */ + CLR_WHITE, /* frosty */ +}; + +#define zap_color(n) color = iflags.use_color ? zapcolors[n] : NO_COLOR +#define cmap_color(n) color = iflags.use_color ? defsyms[n].color : NO_COLOR +#define obj_color(n) color = iflags.use_color ? objects[n].oc_color : NO_COLOR +#define mon_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR +#define invis_color(n) color = NO_COLOR +#define pet_color(n) color = iflags.use_color ? mons[n].mcolor : NO_COLOR +#define warn_color(n) \ + color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR +#define explode_color(n) color = iflags.use_color ? explcolors[n] : NO_COLOR + +#else /* no text color */ + +#define zap_color(n) +#define cmap_color(n) +#define obj_color(n) +#define mon_color(n) +#define invis_color(n) +#define pet_color(c) +#define warn_color(n) +#define explode_color(n) +#endif + +#if defined(USE_TILES) && defined(MSDOS) +#define HAS_ROGUE_IBM_GRAPHICS \ + (g.currentgraphics == ROGUESET && SYMHANDLING(H_IBM) && !iflags.grmode) +#else +#define HAS_ROGUE_IBM_GRAPHICS \ + (g.currentgraphics == ROGUESET && SYMHANDLING(H_IBM)) +#endif + +#define is_objpile(x,y) (!Hallucination && g.level.objects[(x)][(y)] \ + && g.level.objects[(x)][(y)]->nexthere) + +#define GMAP_SET 0x00000001 +#define GMAP_ROGUELEVEL 0x00000002 +#define GMAP_ALTARCOLOR 0x00000004 + +void +map_glyphmod(x, y, glyph, mgflags, glyphmod) +xchar x, y; +int glyph; +unsigned mgflags, *glyphmod; +{ + register int offset, idx; + int color = NO_COLOR; + unsigned special = 0; + struct obj *obj; /* only used for STATUE */ + + /* condense multiple tests in macro version down to single */ + boolean has_rogue_ibm_graphics = HAS_ROGUE_IBM_GRAPHICS, + is_you = (x == u.ux && y == u.uy), + has_rogue_color = (has_rogue_ibm_graphics + && g.symset[g.currentgraphics].nocolor == 0), + do_mon_checks = FALSE; + + if (x < 0 || y < 0 || x >= COLNO || y >= ROWNO) { + glyphmod[GM_FLAGS] = MG_BADXY; + glyphmod[GM_COLOR] = NO_COLOR; + glyphmod[GM_TTYCHAR] = ' '; + return; + } + + if (!g.glyphmap_perlevel_flags) { + /* + * GMAP_SET 0x00000001 + * GMAP_ROGUELEVEL 0x00000002 + * GMAP_ALTARCOLOR 0x00000004 + */ + g.glyphmap_perlevel_flags |= GMAP_SET; + + if (Is_rogue_level(&u.uz)) { + g.glyphmap_perlevel_flags |= GMAP_ROGUELEVEL; + } else if ((Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) { + g.glyphmap_perlevel_flags |= GMAP_ALTARCOLOR; + } + } + + /* + * Map the glyph to a character and color. + * + * Warning: For speed, this makes an assumption on the order of + * offsets. The order is set in display.h. + */ + if ((offset = (glyph - GLYPH_NOTHING_OFF)) >= 0) { + idx = SYM_NOTHING + SYM_OFF_X; + color = NO_COLOR; + special |= MG_NOTHING; + } else if ((offset = (glyph - GLYPH_UNEXPLORED_OFF)) >= 0) { + idx = SYM_UNEXPLORED + SYM_OFF_X; + color = NO_COLOR; + special |= MG_UNEXPL; + } else if ((offset = (glyph - GLYPH_STATUE_OFF)) >= 0) { /* a statue */ + idx = mons[offset].mlet + SYM_OFF_M; + if (has_rogue_color) + color = CLR_RED; + else + obj_color(STATUE); + special |= MG_STATUE; + if (is_objpile(x,y)) + special |= MG_OBJPILE; + if ((obj = sobj_at(STATUE, x, y)) && (obj->spe & STATUE_FEMALE)) + special |= MG_FEMALE; + } else if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { /* warn flash */ + idx = offset + SYM_OFF_W; + if (has_rogue_color) + color = NO_COLOR; + else + warn_color(offset); + } else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) { /* swallow */ + /* see swallow_to_glyph() in display.c */ + idx = (S_sw_tl + (offset & 0x7)) + SYM_OFF_P; + if (has_rogue_color && iflags.use_color) + color = NO_COLOR; + else + mon_color(offset >> 3); + } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) { /* zap beam */ + /* see zapdir_to_glyph() in display.c */ + idx = (S_vbeam + (offset & 0x3)) + SYM_OFF_P; + if (has_rogue_color && iflags.use_color) + color = NO_COLOR; + else + zap_color((offset >> 2)); + } else if ((offset = (glyph - GLYPH_EXPLODE_OFF)) >= 0) { /* explosion */ + idx = ((offset % MAXEXPCHARS) + S_explode1) + SYM_OFF_P; + explode_color(offset / MAXEXPCHARS); + } else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) { /* cmap */ + idx = offset + SYM_OFF_P; + if (has_rogue_color && iflags.use_color) { + if (offset >= S_vwall && offset <= S_hcdoor) + color = CLR_BROWN; + else if (offset >= S_arrow_trap && offset <= S_polymorph_trap) + color = CLR_MAGENTA; + else if (offset == S_corr || offset == S_litcorr) + color = CLR_GRAY; + else if (offset >= S_room && offset <= S_water + && offset != S_darkroom) + color = CLR_GREEN; + else + color = NO_COLOR; +#ifdef TEXTCOLOR + /* provide a visible difference if normal and lit corridor + use the same symbol */ + } else if (iflags.use_color && offset == S_litcorr + && g.showsyms[idx] == g.showsyms[S_corr + SYM_OFF_P]) { + color = CLR_WHITE; +#endif + /* try to provide a visible difference between water and lava + if they use the same symbol and color is disabled */ + } else if (!iflags.use_color && offset == S_lava + && (g.showsyms[idx] == g.showsyms[S_pool + SYM_OFF_P] + || g.showsyms[idx] + == g.showsyms[S_water + SYM_OFF_P])) { + special |= MG_BW_LAVA; + /* similar for floor [what about empty doorway?] and ice */ + } else if (!iflags.use_color && offset == S_ice + && (g.showsyms[idx] == g.showsyms[S_room + SYM_OFF_P] + || g.showsyms[idx] + == g.showsyms[S_darkroom + SYM_OFF_P])) { + special |= MG_BW_ICE; + } else if (offset == S_altar && iflags.use_color) { + int amsk = altarmask_at(x, y); /* might be a mimic */ + + if ((g.glyphmap_perlevel_flags & GMAP_ALTARCOLOR) + && (amsk & AM_SHRINE) != 0) { + /* high altar */ + color = CLR_BRIGHT_MAGENTA; + } else { + switch (amsk & AM_MASK) { +#if 0 /* + * On OSX with TERM=xterm-color256 these render as + * white -> tty: gray, curses: ok + * gray -> both tty and curses: black + * black -> both tty and curses: blue + * red -> both tty and curses: ok. + * Since the colors have specific associations (with the + * unicorns matched with each alignment), we shouldn't use + * scrambled colors and we don't have sufficient information + * to handle platform-specific color variations. + */ + case AM_LAWFUL: /* 4 */ + color = CLR_WHITE; + break; + case AM_NEUTRAL: /* 2 */ + color = CLR_GRAY; + break; + case AM_CHAOTIC: /* 1 */ + color = CLR_BLACK; + break; +#else /* !0: TEMP? */ + case AM_LAWFUL: /* 4 */ + case AM_NEUTRAL: /* 2 */ + case AM_CHAOTIC: /* 1 */ + cmap_color(S_altar); /* gray */ + break; +#endif /* 0 */ + case AM_NONE: /* 0 */ + color = CLR_RED; + break; + default: /* 3, 5..7 -- shouldn't happen but 3 was possible + * prior to 3.6.3 (due to faulty sink polymorph) */ + color = NO_COLOR; + break; + } + } + } else { + cmap_color(offset); + } + } else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) { /* object */ + idx = objects[offset].oc_class + SYM_OFF_O; + if (offset == BOULDER) + idx = SYM_BOULDER + SYM_OFF_X; + if (has_rogue_color && iflags.use_color) { + switch (objects[offset].oc_class) { + case COIN_CLASS: + color = CLR_YELLOW; + break; + case FOOD_CLASS: + color = CLR_RED; + break; + default: + color = CLR_BRIGHT_BLUE; + break; + } + } else + obj_color(offset); + if (offset != BOULDER && is_objpile(x,y)) + special |= MG_OBJPILE; + } else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */ + idx = mons[offset].mlet + SYM_OFF_M; + if (has_rogue_color) + /* This currently implies that the hero is here -- monsters */ + /* don't ride (yet...). Should we set it to yellow like in */ + /* the monster case below? There is no equivalent in rogue. */ + color = NO_COLOR; /* no need to check iflags.use_color */ + else + mon_color(offset); + special |= MG_RIDDEN; + do_mon_checks = TRUE; + } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ + idx = objects[CORPSE].oc_class + SYM_OFF_O; + if (has_rogue_color && iflags.use_color) + color = CLR_RED; + else + mon_color(offset); + special |= MG_CORPSE; + if (is_objpile(x,y)) + special |= MG_OBJPILE; + } else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */ + idx = mons[offset].mlet + SYM_OFF_M; + if (has_rogue_color) + color = NO_COLOR; /* no need to check iflags.use_color */ + else + mon_color(offset); + /* Disabled for now; anyone want to get reverse video to work? */ + /* is_reverse = TRUE; */ + special |= MG_DETECT; + do_mon_checks = TRUE; + } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */ + idx = SYM_INVISIBLE + SYM_OFF_X; + if (has_rogue_color) + color = NO_COLOR; /* no need to check iflags.use_color */ + else + invis_color(offset); + special |= MG_INVIS; + } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) { /* a pet */ + idx = mons[offset].mlet + SYM_OFF_M; + if (has_rogue_color) + color = NO_COLOR; /* no need to check iflags.use_color */ + else + pet_color(offset); + special |= MG_PET; + do_mon_checks = TRUE; + } else { /* a monster */ + idx = mons[glyph].mlet + SYM_OFF_M; + if (has_rogue_color && iflags.use_color) { + if (is_you) + /* actually player should be yellow-on-gray if in corridor */ + color = CLR_YELLOW; + else + color = NO_COLOR; + } else { + mon_color(glyph); +#ifdef TEXTCOLOR + /* special case the hero for `showrace' option */ + if (iflags.use_color && is_you && flags.showrace && !Upolyd) + color = HI_DOMESTIC; +#endif + } + do_mon_checks = TRUE; + } + + if (do_mon_checks) { + struct monst *m; + + if (is_you) { + if (Ugender == FEMALE) + special |= MG_FEMALE; + } else { + /* when hero is riding, steed will be shown at hero's location + but has not been placed on the map so m_at() won't find it */ + m = (x == u.ux && y == u.uy && u.usteed) ? u.usteed : m_at(x, y); + if (m) { + if (!Hallucination) { + if (m->female) + special |= MG_FEMALE; + } else if (rn2_on_display_rng(2)) { + special |= MG_FEMALE; + } + } + } + } + /* These were requested by a blind player to enhance screen reader use */ + if (sysopt.accessibility == 1 && !(mgflags & MG_FLAG_NOOVERRIDE)) { + int ovidx; + + if ((special & MG_PET) != 0) { + ovidx = SYM_PET_OVERRIDE + SYM_OFF_X; + if ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL) + ? g.ov_rogue_syms[ovidx] + : g.ov_primary_syms[ovidx]) + idx = ovidx; + } + if (is_you) { + ovidx = SYM_HERO_OVERRIDE + SYM_OFF_X; + if ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL) + ? g.ov_rogue_syms[ovidx] + : g.ov_primary_syms[ovidx]) + idx = ovidx; + } + } + + glyphmod[GM_TTYCHAR] = ((mgflags & MG_FLAG_RETURNIDX) != 0) ? idx : g.showsyms[idx]; + +#ifdef TEXTCOLOR + /* Turn off color if no color defined, or rogue level w/o PC graphics. */ + if (!has_color(color) + || ((g.glyphmap_perlevel_flags & GMAP_ROGUELEVEL) && !has_rogue_color)) +#endif + color = NO_COLOR; + glyphmod[GM_COLOR] = color; + glyphmod[GM_FLAGS] = special; +} + /* ------------------------------------------------------------------------ */ /* Wall Angle ------------------------------------------------------------- */ diff --git a/src/do_name.c b/src/do_name.c index c4c2f654c..8a757fb7e 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -18,7 +18,7 @@ static void NDECL(gloc_filter_done); static boolean FDECL(gather_locs_interesting, (int, int, int)); static void FDECL(gather_locs, (coord **, int *, int)); static void FDECL(auto_describe, (int, int)); -static void NDECL(do_mname); +static void NDECL(do_mgivenname); static boolean FDECL(alreadynamed, (struct monst *, char *, char *)); static void FDECL(do_oname, (struct obj *)); static char *FDECL(docall_xname, (struct obj *)); @@ -996,7 +996,7 @@ const char *goal; /* allocate space for a monster's name; removes old name if there is one */ void -new_mname(mon, lth) +new_mgivenname(mon, lth) struct monst *mon; int lth; /* desired length (caller handles adding 1 for terminator) */ { @@ -1005,23 +1005,23 @@ int lth; /* desired length (caller handles adding 1 for terminator) */ if (!mon->mextra) mon->mextra = newmextra(); else - free_mname(mon); /* already has mextra, might also have name */ - MNAME(mon) = (char *) alloc((unsigned) lth); + free_mgivenname(mon); /* already has mextra, might also have name */ + MGIVENNAME(mon) = (char *) alloc((unsigned) lth); } else { /* zero length: the new name is empty; get rid of the old name */ - if (has_mname(mon)) - free_mname(mon); + if (has_mgivenname(mon)) + free_mgivenname(mon); } } /* release a monster's name; retains mextra even if all fields are now null */ void -free_mname(mon) +free_mgivenname(mon) struct monst *mon; { - if (has_mname(mon)) { - free((genericptr_t) MNAME(mon)); - MNAME(mon) = (char *) 0; + if (has_mgivenname(mon)) { + free((genericptr_t) MGIVENNAME(mon)); + MGIVENNAME(mon) = (char *) 0; } } @@ -1087,14 +1087,14 @@ const char *name; name = strncpy(buf, name, PL_PSIZ - 1); buf[PL_PSIZ - 1] = '\0'; } - new_mname(mtmp, lth); /* removes old name if one is present */ + new_mgivenname(mtmp, lth); /* removes old name if one is present */ if (lth) - Strcpy(MNAME(mtmp), name); + Strcpy(MGIVENNAME(mtmp), name); return mtmp; } /* check whether user-supplied name matches or nearly matches an unnameable - monster's name; if so, give an alternate reject message for do_mname() */ + monster's name; if so, give an alternate reject message for do_mgivenname() */ static boolean alreadynamed(mtmp, monnambuf, usrbuf) struct monst *mtmp; @@ -1126,7 +1126,7 @@ char *monnambuf, *usrbuf; /* allow player to assign a name to some chosen monster */ static void -do_mname() +do_mgivenname() { char buf[BUFSZ], monnambuf[BUFSZ], qbuf[QBUFSZ]; coord cc; @@ -1170,8 +1170,8 @@ do_mname() buf[0] = '\0'; #ifdef EDIT_GETLIN /* if there's an existing name, make it be the default answer */ - if (has_mname(mtmp)) - Strcpy(buf, MNAME(mtmp)); + if (has_mgivenname(mtmp)) + Strcpy(buf, MGIVENNAME(mtmp)); #endif getlin(qbuf, buf); if (!*buf || *buf == '\033') @@ -1398,7 +1398,7 @@ docallcmd() case 'q': break; case 'm': /* name a visible monster */ - do_mname(); + do_mgivenname(); break; case 'i': /* name an individual object in inventory */ allowall[0] = ALL_CLASSES; @@ -1661,7 +1661,7 @@ boolean called; { char *buf = nextmbuf(); struct permonst *mdat = mtmp->data; - const char *pm_name = mdat->mname; + const char *pm_name = pmname(mdat, Mgender(mtmp)); boolean do_hallu, do_invis, do_it, do_saddle, do_name; boolean name_at_start, has_adjectives; char *bp; @@ -1706,12 +1706,14 @@ boolean called; name += 4; return strcpy(buf, name); } +#if 0 /* an "aligned priest" not flagged as a priest or minion should be "priest" or "priestess" (normally handled by priestname()) */ - if (mdat == &mons[PM_ALIGNED_PRIEST]) + if (mdat == &mons[PM_ALIGNED_CLERIC]) pm_name = mtmp->female ? "priestess" : "priest"; - else if (mdat == &mons[PM_HIGH_PRIEST] && mtmp->female) + else if (mdat == &mons[PM_HIGH_CLERIC] && mtmp->female) pm_name = "high priestess"; +#endif /* Shopkeepers: use shopkeeper name. For normal shopkeepers, just * "Asidonhopo"; for unusual ones, "Asidonhopo the invisible @@ -1755,8 +1757,8 @@ boolean called; Strcat(buf, rname); name_at_start = bogon_is_pname(rnamecode); - } else if (do_name && has_mname(mtmp)) { - char *name = MNAME(mtmp); + } else if (do_name && has_mgivenname(mtmp)) { + char *name = MGIVENNAME(mtmp); if (mdat == &mons[PM_GHOST]) { Sprintf(eos(buf), "%s ghost", s_suffix(name)); @@ -1829,7 +1831,7 @@ l_monnam(mtmp) struct monst *mtmp; { return x_monnam(mtmp, ARTICLE_NONE, (char *) 0, - (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE); + (has_mgivenname(mtmp)) ? SUPPRESS_SADDLE : 0, TRUE); } char * @@ -1837,7 +1839,7 @@ mon_nam(mtmp) struct monst *mtmp; { return x_monnam(mtmp, ARTICLE_THE, (char *) 0, - (has_mname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE); + (has_mgivenname(mtmp)) ? SUPPRESS_SADDLE : 0, FALSE); } /* print the name as if mon_nam() was called, but assume that the player @@ -1849,7 +1851,7 @@ noit_mon_nam(mtmp) struct monst *mtmp; { return x_monnam(mtmp, ARTICLE_THE, (char *) 0, - (has_mname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT) + (has_mgivenname(mtmp)) ? (SUPPRESS_SADDLE | SUPPRESS_IT) : SUPPRESS_IT, FALSE); } @@ -1900,7 +1902,7 @@ struct monst *mtmp; int prefix, suppression_flag; prefix = mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE; - suppression_flag = (has_mname(mtmp) + suppression_flag = (has_mgivenname(mtmp) /* "saddled" is redundant when mounted */ || mtmp == u.usteed) ? SUPPRESS_SADDLE @@ -1915,7 +1917,7 @@ struct monst *mtmp; const char *adj; { char *bp = x_monnam(mtmp, ARTICLE_THE, adj, - has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE); + has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE); *bp = highc(*bp); return bp; @@ -1926,7 +1928,7 @@ a_monnam(mtmp) struct monst *mtmp; { return x_monnam(mtmp, ARTICLE_A, (char *) 0, - has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE); + has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE); } char * @@ -1950,7 +1952,7 @@ char *outbuf; /* high priest(ess)'s identity is concealed on the Astral Plane, unless you're adjacent (overridden for hallucination which does its own obfuscation) */ - if (mon->data == &mons[PM_HIGH_PRIEST] && !Hallucination + if (mon->data == &mons[PM_HIGH_CLERIC] && !Hallucination && Is_astralevel(&u.uz) && distu(mon->mx, mon->my) > 2) { Strcpy(outbuf, article == ARTICLE_THE ? "the " : ""); Strcat(outbuf, mon->female ? "high priestess" : "high priest"); @@ -2048,37 +2050,65 @@ boolean ckloc; } else if (ckloc && ptr == &mons[PM_LONG_WORM] && g.level.monsters[mon->mx][mon->my] != mon) { Sprintf(outbuf, "%s <%d,%d>", - mons[PM_LONG_WORM_TAIL].mname, mon->mx, mon->my); + pmname(&mons[PM_LONG_WORM_TAIL], Mgender(mon)), mon->mx, mon->my); } else { Sprintf(outbuf, "%s%s <%d,%d>", mon->mtame ? "tame " : mon->mpeaceful ? "peaceful " : "", - mon->data->mname, mon->mx, mon->my); + pmname(mon->data, Mgender(mon)), mon->mx, mon->my); if (mon->cham != NON_PM) - Sprintf(eos(outbuf), "{%s}", mons[mon->cham].mname); + Sprintf(eos(outbuf), "{%s}", pmname(&mons[mon->cham], Mgender(mon))); } return outbuf; } +#ifndef PMNAME_MACROS +int +Mgender(mtmp) +struct monst *mtmp; +{ + int mgender = MALE; + + if (mtmp == &g.youmonst) { + if (Upolyd ? u.mfemale : flags.female) + mgender = FEMALE; + } else if (mtmp->female) { + mgender = FEMALE; + } + return mgender; +} + +const char * +pmname(pm, mgender) +struct permonst *pm; +int mgender; +{ + if ((mgender >= MALE && mgender < NUM_MGENDERS) && pm->pmnames[mgender]) + return pm->pmnames[mgender]; + else + return pm->pmnames[NEUTRAL]; +} +#endif /* PMNAME_MACROS */ + /* fake monsters used to be in a hard-coded array, now in a data file */ char * bogusmon(buf, code) char *buf, *code; { static const char bogon_codes[] = "-_+|="; /* see dat/bonusmon.txt */ - char *mname = buf; + char *mnam = buf; if (code) *code = '\0'; /* might fail (return empty buf[]) if the file isn't available */ get_rnd_text(BOGUSMONFILE, buf, rn2_on_display_rng); - if (!*mname) { + if (!*mnam) { Strcpy(buf, "bogon"); - } else if (index(bogon_codes, *mname)) { /* strip prefix if present */ + } else if (index(bogon_codes, *mnam)) { /* strip prefix if present */ if (code) - *code = *mname; - ++mname; + *code = *mnam; + ++mnam; } - return mname; + return mnam; } /* return a random monster name, for hallucination */ @@ -2087,7 +2117,7 @@ rndmonnam(code) char *code; { static char buf[BUFSZ]; - char *mname; + char *mnam; int name; #define BOGUSMONSIZE 100 /* arbitrary */ @@ -2100,11 +2130,11 @@ char *code; && (type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN))); if (name >= SPECIAL_PM) { - mname = bogusmon(buf, code); + mnam = bogusmon(buf, code); } else { - mname = strcpy(buf, mons[name].mname); + mnam = strcpy(buf, pmname(&mons[name], rn2_on_display_rng(2))); } - return mname; + return mnam; #undef BOGUSMONSIZE } diff --git a/src/do_wear.c b/src/do_wear.c index 670fc6aa8..044b363d6 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -428,7 +428,7 @@ Helmet_on(VOID_ARGS) inventory; do so now [set_bknown() calls update_inventory()] */ if (Blind) set_bknown(uarmh, 0); /* lose bknown if previously set */ - else if (Role_if(PM_PRIEST)) + else if (Role_if(PM_CLERIC)) set_bknown(uarmh, 1); /* (bknown should already be set) */ else if (uarmh->bknown) update_inventory(); /* keep bknown as-is; display the curse */ @@ -766,6 +766,8 @@ Amulet_on() You("are suddenly very %s!", flags.female ? "feminine" : "masculine"); g.context.botl = 1; + newsym(u.ux, u.uy); /* glyphmon flag and tile may have gone + from male to female or vice versa */ } else /* already polymorphed into single-gender monster; only changed the character's base sex */ diff --git a/src/dog.c b/src/dog.c index 450996168..50ffd00c9 100644 --- a/src/dog.c +++ b/src/dog.c @@ -170,7 +170,7 @@ makedog() /* default pet names */ if (!*petname && pettype == PM_LITTLE_DOG) { /* All of these names were for dogs. */ - if (Role_if(PM_CAVEMAN)) + if (Role_if(PM_CAVE_DWELLER)) petname = "Slasher"; /* The Warrior */ if (Role_if(PM_SAMURAI)) petname = "Hachi"; /* Shibuya Station */ diff --git a/src/dogmove.c b/src/dogmove.c index 363bbcd5c..8d255ec3e 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1429,7 +1429,8 @@ struct monst *mtmp; && OBJ_NAME(objects[mtmp->mappearance])) ? an(OBJ_NAME(objects[mtmp->mappearance])) : (M_AP_TYPE(mtmp) == M_AP_MONSTER) - ? an(mons[mtmp->mappearance].mname) + ? an(pmname(&mons[mtmp->mappearance], + Mgender(mtmp))) : something, cansee(mtmp->mx, mtmp->my) ? "" : "has ", cansee(mtmp->mx, mtmp->my) ? "" : "ed", diff --git a/src/dokick.c b/src/dokick.c index 765316522..c685fa201 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1159,9 +1159,6 @@ dokick() } if (IS_SINK(g.maploc->typ)) { int gend = poly_gender(); - short washerndx = (gend == 1 || (gend == 2 && rn2(2))) - ? PM_INCUBUS - : PM_SUCCUBUS; if (Levitation) goto dumb; @@ -1185,10 +1182,12 @@ dokick() g.maploc->looted |= S_LPUDDING; return 1; } else if (!(g.maploc->looted & S_LDWASHER) && !rn2(3) - && !(g.mvitals[washerndx].mvflags & G_GONE)) { + && !(g.mvitals[PM_AMOROUS_DEMON].mvflags & G_GONE)) { /* can't resist... */ pline("%s returns!", (Blind ? Something : "The dish washer")); - if (makemon(&mons[washerndx], x, y, NO_MM_FLAGS)) + if (makemon(&mons[PM_AMOROUS_DEMON], x, y, + (gend == 1 || (gend == 2 && rn2(2))) + ? MM_FEMALE : MM_MALE)) newsym(x, y); g.maploc->looted |= S_LDWASHER; exercise(A_DEX, TRUE); @@ -1746,7 +1745,7 @@ unsigned long deliverflags; /* special treatment for orcs and their kind */ if ((otmp->corpsenm & M2_ORC) != 0 && has_oname(otmp)) { - if (!has_mname(mtmp)) { + if (!has_mgivenname(mtmp)) { if (at_crime_scene || !rn2(2)) mtmp = christen_orc(mtmp, at_crime_scene ? ONAME(otmp) diff --git a/src/dothrow.c b/src/dothrow.c index c3695658d..8318bafb3 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -39,7 +39,7 @@ struct obj *launcher; /* can be NULL */ schar skill = objects[ammo->otyp].oc_skill; switch (pm) { - case PM_CAVEMAN: + case PM_CAVE_DWELLER: /* give bonus for low-tech gear */ if (skill == -P_SLING || skill == P_SPEAR) multishot++; @@ -158,7 +158,7 @@ int shotlimit; : obj->oclass == WEAPON_CLASS) && !(Confusion || Stunned)) { /* some roles don't get a volley bonus until becoming expert */ - weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_PRIEST) + weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_CLERIC) || (Role_if(PM_HEALER) && skill != P_KNIFE) || (Role_if(PM_TOURIST) && skill != -P_DART) /* poor dexterity also inhibits multishot */ diff --git a/src/eat.c b/src/eat.c index f73c4d1d5..13628642b 100644 --- a/src/eat.c +++ b/src/eat.c @@ -40,7 +40,7 @@ static int FDECL(tin_variety, (struct obj *, BOOLEAN_P)); static boolean FDECL(maybe_cannibal, (int, BOOLEAN_P)); /* also used to see if you're allowed to eat cats and dogs */ -#define CANNIBAL_ALLOWED() (Role_if(PM_CAVEMAN) || Race_if(PM_ORC)) +#define CANNIBAL_ALLOWED() (Role_if(PM_CAVE_DWELLER) || Race_if(PM_ORC)) /* monster types that cause hero to be turned into stone if eaten */ #define flesh_petrifies(pm) (touch_petrifies(pm) || (pm) == &mons[PM_MEDUSA]) @@ -516,7 +516,8 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */ tentacle-touch should have been caught before reaching this far) */ if (magr == &g.youmonst) { if (!Stone_resistance && !Stoned) - make_stoned(5L, (char *) 0, KILLED_BY_AN, pd->mname); + make_stoned(5L, (char *) 0, KILLED_BY_AN, + pmname(pd, Mgender(mdef))); } else { /* no need to check for poly_when_stoned or Stone_resistance; mind flayers don't have those capabilities */ @@ -546,7 +547,8 @@ int *dmg_p; /* for dishing out extra damage in lieu of Int loss */ return MM_MISS; } else if (is_rider(pd)) { pline("Ingesting that is fatal."); - Sprintf(g.killer.name, "unwisely ate the brain of %s", pd->mname); + Sprintf(g.killer.name, "unwisely ate the brain of %s", + pmname(pd, Mgender(mdef))); g.killer.format = NO_KILLER_PREFIX; done(DIED); /* life-saving needed to reach here */ @@ -676,7 +678,8 @@ register int pm; if (!Stone_resistance && !(poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM))) { - Sprintf(g.killer.name, "tasting %s meat", mons[pm].mname); + Sprintf(g.killer.name, "tasting %s meat", + mons[pm].pmnames[NEUTRAL]); g.killer.format = KILLED_BY; You("turn to stone."); done(STONING); @@ -695,7 +698,8 @@ register int pm; case PM_LARGE_CAT: /* cannibals are allowed to eat domestic animals without penalty */ if (!CANNIBAL_ALLOWED()) { - You_feel("that eating the %s was a bad idea.", mons[pm].mname); + You_feel("that eating the %s was a bad idea.", + mons[pm].pmnames[NEUTRAL]); HAggravate_monster |= FROMOUTSIDE; } break; @@ -707,7 +711,8 @@ register int pm; case PM_PESTILENCE: case PM_FAMINE: { pline("Eating that is instantly fatal."); - Sprintf(g.killer.name, "unwisely ate the body of %s", mons[pm].mname); + Sprintf(g.killer.name, "unwisely ate the body of %s", + mons[pm].pmnames[NEUTRAL]); g.killer.format = NO_KILLER_PREFIX; done(DIED); /* life-saving needed to reach here */ @@ -1033,7 +1038,7 @@ int pm; Hallucination ? "You suddenly dread being peeled and mimic %s again!" : "You now prefer mimicking %s again.", - an(Upolyd ? g.youmonst.data->mname : g.urace.noun)); + an(Upolyd ? pmname(g.youmonst.data, Ugender) : g.urace.noun)); g.eatmbuf = dupstr(buf); g.nomovemsg = g.eatmbuf; g.afternmv = eatmdone; @@ -1247,9 +1252,9 @@ char *buf; Strcpy(eos(buf), " of "); } if (vegetarian(&mons[mnum])) - Sprintf(eos(buf), "%s", mons[mnum].mname); + Sprintf(eos(buf), "%s", mons[mnum].pmnames[NEUTRAL]); else - Sprintf(eos(buf), "%s meat", mons[mnum].mname); + Sprintf(eos(buf), "%s meat", mons[mnum].pmnames[NEUTRAL]); } } } @@ -1343,7 +1348,7 @@ const char *mesg; } else if (Hallucination) { what = rndmonnam(NULL); } else { - what = mons[mnum].mname; + what = mons[mnum].pmnames[NEUTRAL]; if (the_unique_pm(&mons[mnum])) which = 2; else if (type_is_pname(&mons[mnum])) @@ -1370,7 +1375,7 @@ const char *mesg; g.context.victual.fullwarn = g.context.victual.eating = g.context.victual.doreset = FALSE; - You("consume %s %s.", tintxts[r].txt, mons[mnum].mname); + You("consume %s %s.", tintxts[r].txt, mons[mnum].pmnames[NEUTRAL]); eating_conducts(&mons[mnum]); @@ -2254,7 +2259,7 @@ struct obj *otmp; && polymon(PM_STONE_GOLEM))) { if (!Stoned) { Sprintf(g.killer.name, "%s egg", - mons[otmp->corpsenm].mname); + mons[otmp->corpsenm].pmnames[NEUTRAL]); make_stoned(5L, (char *) 0, KILLED_BY_AN, g.killer.name); } } diff --git a/src/end.c b/src/end.c index 50f593280..f362a07c6 100644 --- a/src/end.c +++ b/src/end.c @@ -409,13 +409,13 @@ int how; /* "killed by the high priest of Crom" is okay, "killed by the high priest" alone isn't */ if ((mptr->geno & G_UNIQ) != 0 && !(imitator && !mimicker) - && !(mptr == &mons[PM_HIGH_PRIEST] && !mtmp->ispriest)) { + && !(mptr == &mons[PM_HIGH_CLERIC] && !mtmp->ispriest)) { if (!type_is_pname(mptr)) Strcat(buf, "the "); g.killer.format = KILLED_BY; } /* _the_ ghost of Dudley */ - if (mptr == &mons[PM_GHOST] && has_mname(mtmp)) { + if (mptr == &mons[PM_GHOST] && has_mgivenname(mtmp)) { Strcat(buf, "the "); g.killer.format = KILLED_BY; } @@ -427,14 +427,15 @@ int how; if (imitator) { char shape[BUFSZ]; - const char *realnm = champtr->mname, *fakenm = mptr->mname; + const char *realnm = pmname(champtr, Mgender(mtmp)), + *fakenm = pmname(mptr, Mgender(mtmp)); boolean alt = is_vampshifter(mtmp); if (mimicker) { /* realnm is already correct because champtr==mptr; set up fake mptr for type_is_pname/the_unique_pm */ mptr = &mons[mtmp->mappearance]; - fakenm = mptr->mname; + fakenm = pmname(mptr, Mgender(mtmp)); } else if (alt && strstri(realnm, "vampire") && !strcmp(fakenm, "vampire bat")) { /* special case: use "vampire in bat form" in preference @@ -459,8 +460,8 @@ int how; mptr = mtmp->data; /* reset for mimicker case */ } else if (mptr == &mons[PM_GHOST]) { Strcat(buf, "ghost"); - if (has_mname(mtmp)) - Sprintf(eos(buf), " of %s", MNAME(mtmp)); + if (has_mgivenname(mtmp)) + Sprintf(eos(buf), " of %s", MGIVENNAME(mtmp)); } else if (mtmp->isshk) { const char *shknm = shkname(mtmp), *honorific = shkname_is_pname(mtmp) ? "" @@ -473,9 +474,9 @@ int how; it overrides the effect of Hallucination on priestname() */ Strcat(buf, m_monnam(mtmp)); } else { - Strcat(buf, mptr->mname); - if (has_mname(mtmp)) - Sprintf(eos(buf), " called %s", MNAME(mtmp)); + Strcat(buf, pmname(mptr, Mgender(mtmp))); + if (has_mgivenname(mtmp)) + Sprintf(eos(buf), " called %s", MGIVENNAME(mtmp)); } Strcpy(g.killer.name, buf); @@ -1414,7 +1415,7 @@ int how; (u.ugrave_arise != PM_GREEN_SLIME) ? "body rises from the dead" : "revenant persists", - an(mons[u.ugrave_arise].mname)); + an(pmname(&mons[u.ugrave_arise], Ugender))); display_nhwindow(WIN_MESSAGE, FALSE); } diff --git a/src/exper.c b/src/exper.c index de4404ab4..ea2dcc6bb 100644 --- a/src/exper.c +++ b/src/exper.c @@ -28,7 +28,7 @@ enermod(en) int en; { switch (Role_switch) { - case PM_PRIEST: + case PM_CLERIC: case PM_WIZARD: return (2 * en); case PM_HEALER: diff --git a/src/explode.c b/src/explode.c index 8abe642fd..30dc6b92c 100644 --- a/src/explode.c +++ b/src/explode.c @@ -66,7 +66,7 @@ int expltype; type = 0; } switch (Role_switch) { - case PM_PRIEST: + case PM_CLERIC: case PM_MONK: case PM_WIZARD: damu /= 5; diff --git a/src/files.c b/src/files.c index dd7245861..f995f8d1a 100644 --- a/src/files.c +++ b/src/files.c @@ -3089,7 +3089,7 @@ struct obj *obj; /* subset of starting inventory pre-ID */ obj->dknown = 1; - if (Role_if(PM_PRIEST)) + if (Role_if(PM_CLERIC)) obj->bknown = 1; /* ok to bypass set_bknown() */ /* same criteria as lift_object()'s check for available inventory slot */ if (obj->oclass != COIN_CLASS && inv_cnt(FALSE) >= 52 diff --git a/src/hack.c b/src/hack.c index 7d766ec31..30ea83a96 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1913,10 +1913,10 @@ domove_core() You("%s %s.", mtmp->mpeaceful ? "swap places with" : "frighten", x_monnam(mtmp, mtmp->mtame ? ARTICLE_YOUR - : (!has_mname(mtmp) && !type_is_pname(mtmp->data)) + : (!has_mgivenname(mtmp) && !type_is_pname(mtmp->data)) ? ARTICLE_THE : ARTICLE_NONE, (mtmp->mpeaceful && !mtmp->mtame) ? "peaceful" : 0, - has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE)); + has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE)); /* check for displacing it into pools and traps */ switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) { @@ -3071,7 +3071,8 @@ const char *msg_override; if life-saved while poly'd and Unchanging (explore or wizard mode declining to die since can't be both Unchanging and Lifesaved) */ if (Upolyd && !strncmpi(g.nomovemsg, "You survived that ", 18)) - You("are %s.", an(mons[u.umonnum].mname)); /* (ignore Hallu) */ + You("are %s.", + an(pmname(&mons[u.umonnum], Ugender))); /* (ignore Hallu) */ } g.nomovemsg = 0; u.usleep = 0; diff --git a/src/insight.c b/src/insight.c index 57cd5596e..fd5bbfd3e 100644 --- a/src/insight.c +++ b/src/insight.c @@ -327,10 +327,12 @@ int final; if (!is_male(uasmon) && !is_female(uasmon) && !is_neuter(uasmon)) Sprintf(tmpbuf, "%s ", genders[flags.female ? 1 : 0].adj); if (altphrasing) - Sprintf(eos(tmpbuf), "%s in ", mons[g.youmonst.cham].mname); + Sprintf(eos(tmpbuf), "%s in ", + pmname(&mons[g.youmonst.cham], + flags.female ? FEMALE : MALE)); Sprintf(buf, "%s%s%s%s form", !final ? "currently " : "", altphrasing ? just_an(anbuf, tmpbuf) : "in ", - tmpbuf, uasmon->mname); + tmpbuf, pmname(uasmon, flags.female ? FEMALE : MALE)); you_are(buf, ""); } @@ -1367,7 +1369,7 @@ int final; } if (Warn_of_mon && g.context.warntype.speciesidx >= LOW_PM) { Sprintf(buf, "aware of the presence of %s", - makeplural(mons[g.context.warntype.speciesidx].mname)); + makeplural(mons[g.context.warntype.speciesidx].pmnames[NEUTRAL])); you_are(buf, from_what(WARN_OF_MON)); } if (Undead_warning) @@ -1574,10 +1576,14 @@ int final; && u.umonnum == PM_GREEN_SLIME && !Unchanging)) { /* foreign shape (except were-form which is handled below) */ if (!vampshifted(&g.youmonst)) - Sprintf(buf, "polymorphed into %s", an(g.youmonst.data->mname)); + Sprintf(buf, "polymorphed into %s", + an(pmname(g.youmonst.data, + flags.female ? FEMALE : MALE))); else Sprintf(buf, "polymorphed into %s in %s form", - an(mons[g.youmonst.cham].mname), g.youmonst.data->mname); + an(pmname(&mons[g.youmonst.cham], + flags.female ? FEMALE : MALE)), + pmname(g.youmonst.data, flags.female ? FEMALE : MALE)); if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); you_are(buf, ""); @@ -1586,7 +1592,8 @@ int final; you_can("lay eggs", ""); if (u.ulycn >= LOW_PM) { /* "you are a werecreature [in beast form]" */ - Strcpy(buf, an(mons[u.ulycn].mname)); + Strcpy(buf, an(pmname(&mons[u.ulycn], + flags.female ? FEMALE : MALE))); if (u.umonnum == u.ulycn) { Strcat(buf, " in beast form"); if (wizard) @@ -2226,15 +2233,16 @@ const genericptr vptr2; res = mstr2 - mstr1; /* monstr high to low */ break; case VANQ_ALPHA_SEP: - uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_PRIEST); - uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_PRIEST); + uniq1 = ((mons[indx1].geno & G_UNIQ) && indx1 != PM_HIGH_CLERIC); + uniq2 = ((mons[indx2].geno & G_UNIQ) && indx2 != PM_HIGH_CLERIC); if (uniq1 ^ uniq2) { /* one or other uniq, but not both */ res = uniq2 - uniq1; break; } /* else both unique or neither unique */ /*FALLTHRU*/ case VANQ_ALPHA_MIX: - name1 = mons[indx1].mname, name2 = mons[indx2].mname; + name1 = mons[indx1].pmnames[NEUTRAL], + name2 = mons[indx2].pmnames[NEUTRAL]; res = strcmpi(name1, name2); /* caseblind alhpa, low to high */ break; case VANQ_MCLS_HTOL: @@ -2344,7 +2352,7 @@ doborn() g.mvitals[i].died, g.mvitals[i].born, ((g.mvitals[i].mvflags & G_GONE) == G_EXTINCT) ? 'E' : ((g.mvitals[i].mvflags & G_GONE) == G_GENOD) ? 'G' : ' ', - mons[i].mname); + mons[i].pmnames[NEUTRAL]); putstr(datawin, 0, buf); nborn += g.mvitals[i].born; ndied += g.mvitals[i].died; @@ -2361,7 +2369,7 @@ doborn() /* high priests aren't unique but are flagged as such to simplify something */ #define UniqCritterIndx(mndx) ((mons[mndx].geno & G_UNIQ) \ - && mndx != PM_HIGH_PRIEST) + && mndx != PM_HIGH_CLERIC) #define done_stopprint g.program_state.stopprint @@ -2435,7 +2443,7 @@ boolean ask; if (UniqCritterIndx(i)) { Sprintf(buf, "%s%s", !type_is_pname(&mons[i]) ? "the " : "", - mons[i].mname); + mons[i].pmnames[NEUTRAL]); if (nkilled > 1) { switch (nkilled) { case 2: @@ -2458,10 +2466,10 @@ boolean ask; /* trolls or undead might have come back, but we don't keep track of that */ if (nkilled == 1) - Strcpy(buf, an(mons[i].mname)); + Strcpy(buf, an(mons[i].pmnames[NEUTRAL])); else Sprintf(buf, "%3d %s", nkilled, - makeplural(mons[i].mname)); + makeplural(mons[i].pmnames[NEUTRAL])); } /* number of leading spaces to match 3 digit prefix */ pfx = !strncmpi(buf, "the ", 3) ? 0 @@ -2507,7 +2515,7 @@ num_genocides() ++n; if (UniqCritterIndx(i)) impossible("unique creature '%d: %s' genocided?", - i, mons[i].mname); + i, mons[i].pmnames[NEUTRAL]); } } return n; @@ -2570,7 +2578,7 @@ boolean ask; if (UniqCritterIndx(i)) continue; if (g.mvitals[i].mvflags & G_GONE) { - Sprintf(buf, " %s", makeplural(mons[i].mname)); + Sprintf(buf, " %s", makeplural(mons[i].pmnames[NEUTRAL])); /* * "Extinct" is unfortunate terminology. A species * is marked extinct when its birth limit is reached, diff --git a/src/invent.c b/src/invent.c index 5f14e2f46..8b1a96287 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2980,7 +2980,7 @@ boolean FDECL((*filterfunc), (OBJ_P)); for (; list; list = list->nobj) { /* priests always know bless/curse state */ - if (Role_if(PM_PRIEST)) + if (Role_if(PM_CLERIC)) list->bknown = (list->oclass != COIN_CLASS); /* some actions exclude some or most items */ if (filterfunc && !(*filterfunc)(list)) @@ -3020,7 +3020,7 @@ int *bcp, *ucp, *ccp, *xcp, *ocp; *bcp = *ucp = *ccp = *xcp = *ocp = 0; for ( ; list; list = (by_nexthere ? list->nexthere : list->nobj)) { /* priests always know bless/curse state */ - if (Role_if(PM_PRIEST)) + if (Role_if(PM_CLERIC)) list->bknown = (list->oclass != COIN_CLASS); /* coins are either uncursed or unknown based upon option setting */ if (list->oclass == COIN_CLASS) { @@ -3731,7 +3731,7 @@ register struct obj *otmp, *obj; return FALSE; if (obj->dknown != otmp->dknown - || (obj->bknown != otmp->bknown && !Role_if(PM_PRIEST)) + || (obj->bknown != otmp->bknown && !Role_if(PM_CLERIC)) || obj->oeroded != otmp->oeroded || obj->oeroded2 != otmp->oeroded2 || obj->greased != otmp->greased) return FALSE; diff --git a/src/makemon.c b/src/makemon.c index b9bb36d5f..27f9ad049 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -247,14 +247,14 @@ register struct monst *mtmp; } break; } - if (mm == PM_ELVENKING) { + if (mm == PM_ELVENMONARCH) { if (rn2(3) || (g.in_mklev && Is_earthlevel(&u.uz))) (void) mongets(mtmp, PICK_AXE); if (!rn2(50)) (void) mongets(mtmp, CRYSTAL_BALL); } } else if (ptr->msound == MS_PRIEST - || quest_mon_represents_role(ptr, PM_PRIEST)) { + || quest_mon_represents_role(ptr, PM_CLERIC)) { otmp = mksobj(MACE, FALSE, FALSE); otmp->spe = rnd(3); if (!rn2(2)) @@ -428,7 +428,7 @@ register struct monst *mtmp; } break; case S_OGRE: - if (!rn2(mm == PM_OGRE_KING ? 3 : mm == PM_OGRE_LORD ? 6 : 12)) + if (!rn2(mm == PM_OGRE_TYRANT ? 3 : mm == PM_OGRE_LEADER ? 6 : 12)) (void) mongets(mtmp, BATTLE_AXE); else (void) mongets(mtmp, CLUB); @@ -700,7 +700,7 @@ register struct monst *mtmp; (void) mongets(mtmp, WAN_STRIKING); } } else if (ptr->msound == MS_PRIEST - || quest_mon_represents_role(ptr, PM_PRIEST)) { + || quest_mon_represents_role(ptr, PM_CLERIC)) { (void) mongets(mtmp, rn2(7) ? ROBE : rn2(3) ? CLOAK_OF_PROTECTION : CLOAK_OF_MAGIC_RESISTANCE); @@ -882,8 +882,8 @@ xchar x, y; /* clone's preferred location or 0 (near mon) */ new_light_source(m2->mx, m2->my, emits_light(m2->data), LS_MONSTER, monst_to_any(m2)); /* if 'parent' is named, give the clone the same name */ - if (has_mname(mon)) { - m2 = christen_monst(m2, MNAME(mon)); + if (has_mgivenname(mon)) { + m2 = christen_monst(m2, MGIVENNAME(mon)); } else if (mon->isshk) { m2 = christen_monst(m2, shkname(mon)); } @@ -946,7 +946,7 @@ boolean ghostly; result = ((int) g.mvitals[mndx].born < lim && !gone) ? TRUE : FALSE; /* if it's unique, don't ever make it again */ - if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_PRIEST) + if ((mons[mndx].geno & G_UNIQ) != 0 && mndx != PM_HIGH_CLERIC) g.mvitals[mndx].mvflags |= G_EXTINCT; if (g.mvitals[mndx].born < 255 && tally && (!ghostly || result)) @@ -956,7 +956,7 @@ boolean ghostly; && !(g.mvitals[mndx].mvflags & G_EXTINCT)) { if (wizard) { debugpline1("Automatically extinguished %s.", - makeplural(mons[mndx].mname)); + makeplural(mons[mndx].pmnames[NEUTRAL])); } g.mvitals[mndx].mvflags |= G_EXTINCT; } @@ -1184,7 +1184,7 @@ long mmflags; return (struct monst *) 0; if (wizard && (g.mvitals[mndx].mvflags & G_EXTINCT)) { debugpline1("Explicitly creating extinct monster %s.", - mons[mndx].mname); + mons[mndx].pmnames[NEUTRAL]); } } else { /* make a random (common) monster that can survive here. @@ -1236,9 +1236,9 @@ long mmflags; /* set up level and hit points */ newmonhp(mtmp, mndx); - if (is_female(ptr)) + if (is_female(ptr) || ((mmflags & MM_FEMALE) && !is_male(ptr))) mtmp->female = TRUE; - else if (is_male(ptr)) + else if (is_male(ptr) || ((mmflags & MM_MALE) && !is_female(ptr))) mtmp->female = FALSE; /* leader and nemesis gender is usually hardcoded in mons[], but for ones which can be random, it has already been chosen @@ -1369,7 +1369,7 @@ long mmflags; types; make sure their extended data is initialized to something sensible if caller hasn't specified MM_EPRI|MM_EMIN (when they're specified, caller intends to handle this itself) */ - if ((mndx == PM_ALIGNED_PRIEST || mndx == PM_HIGH_PRIEST) + if ((mndx == PM_ALIGNED_CLERIC || mndx == PM_HIGH_CLERIC) ? !(mmflags & (MM_EPRI | MM_EMIN)) : (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) { struct emin *eminp; @@ -1857,8 +1857,11 @@ struct monst *mtmp, *victim; oldtype = monsndx(ptr); newtype = (oldtype == PM_KILLER_BEE && !victim) ? PM_QUEEN_BEE : little_to_big(oldtype); +#if 0 + /* gender-neutral PM_CLERIC now */ if (newtype == PM_PRIEST && mtmp->female) newtype = PM_PRIESTESS; +#endif /* growth limits differ depending on method of advancement */ if (victim) { /* killed a monster */ @@ -1914,7 +1917,7 @@ struct monst *mtmp, *victim; if (g.mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */ if (canspotmon(mtmp)) pline("As %s grows up into %s, %s %s!", mon_nam(mtmp), - an(ptr->mname), mhe(mtmp), + an(pmname(ptr, Mgender(mtmp))), mhe(mtmp), nonliving(ptr) ? "expires" : "dies"); set_mon_data(mtmp, ptr); /* keep g.mvitals[] accurate */ mondied(mtmp); @@ -1932,7 +1935,7 @@ struct monst *mtmp, *victim; (can't happen with 3.6.0 mons[], but perhaps slightly less sexist if prepared for it...) */ : (fem && !mtmp->female) ? "female " : "", - ptr->mname); + pmname(ptr, fem)); pline("%s %s %s.", upstart(y_monnam(mtmp)), (fem != mtmp->female) ? "changes into" : humanoid(ptr) ? "becomes" diff --git a/src/mapglyph.c b/src/mapglyph.c index 291a11f36..a28c94670 100644 --- a/src/mapglyph.c +++ b/src/mapglyph.c @@ -77,9 +77,10 @@ unsigned mgflags; unsigned special = 0; /* condense multiple tests in macro version down to single */ boolean has_rogue_ibm_graphics = HAS_ROGUE_IBM_GRAPHICS, - is_you = (x == u.ux && y == u.uy), + is_you = (x == u.ux && y == u.uy && !u.usteed), has_rogue_color = (has_rogue_ibm_graphics - && g.symset[g.currentgraphics].nocolor == 0); + && g.symset[g.currentgraphics].nocolor == 0), + do_mon_checks = FALSE; if (!g.glyphmap_perlevel_flags) { /* @@ -254,6 +255,7 @@ unsigned mgflags; else mon_color(offset); special |= MG_RIDDEN; + do_mon_checks = TRUE; } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) { /* a corpse */ idx = objects[CORPSE].oc_class + SYM_OFF_O; if (has_rogue_color && iflags.use_color) @@ -272,6 +274,7 @@ unsigned mgflags; /* Disabled for now; anyone want to get reverse video to work? */ /* is_reverse = TRUE; */ special |= MG_DETECT; + do_mon_checks = TRUE; } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) { /* invisible */ idx = SYM_INVISIBLE + SYM_OFF_X; if (has_rogue_color) @@ -286,6 +289,7 @@ unsigned mgflags; else pet_color(offset); special |= MG_PET; + do_mon_checks = TRUE; } else { /* a monster */ idx = mons[glyph].mlet + SYM_OFF_M; if (has_rogue_color && iflags.use_color) { @@ -302,6 +306,21 @@ unsigned mgflags; color = HI_DOMESTIC; #endif } + do_mon_checks = TRUE; + } + if (do_mon_checks) { + struct monst *m; + + if (is_you) { + if (Ugender == FEMALE) + special |= MG_FEMALE; + } else { + /* when hero is riding, steed will be shown at hero's location + but has not been placed on the map so m_at() won't find it */ + m = (x == u.ux && y == u.uy && u.usteed) ? u.usteed : m_at(x, y); + if (m && m->female) + special |= MG_FEMALE; + } } /* These were requested by a blind player to enhance screen reader use */ @@ -354,14 +373,14 @@ const char *str; { static const char hex[] = "00112233445566778899aAbBcCdDeEfF"; char *put = buf; + unsigned glyphmod[NUM_GLYPHMOD]; if (!str) return strcpy(buf, ""); while (*str) { if (*str == '\\') { - int rndchk, dcount, so, gv, ch = 0, oc = 0; - unsigned os = 0; + int rndchk, dcount, so, gv; const char *dp, *save_str; save_str = str++; @@ -380,7 +399,8 @@ const char *str; gv = (gv * 16) + ((int) (dp - hex) / 2); else break; - so = mapglyph(gv, &ch, &oc, &os, 0, 0, 0); + map_glyphmod(0, 0, gv, MG_FLAG_RETURNIDX, glyphmod); + so = glyphmod[GM_TTYCHAR]; *put++ = g.showsyms[so]; /* 'str' is ready for the next loop iteration and '*str' should not be copied at the end of this iteration */ diff --git a/src/mhitu.c b/src/mhitu.c index 89d77dd2d..f4260cbc1 100644 --- a/src/mhitu.c +++ b/src/mhitu.c @@ -510,12 +510,12 @@ register struct monst *mtmp; pline( "Wait, %s! There's a hidden %s named %s there!", m_monnam(mtmp), - g.youmonst.data->mname, g.plname); + pmname(g.youmonst.data, Ugender), g.plname); else pline( "Wait, %s! There's a %s named %s hiding under %s!", - m_monnam(mtmp), g.youmonst.data->mname, g.plname, - doname(g.level.objects[u.ux][u.uy])); + m_monnam(mtmp), pmname(g.youmonst.data, Ugender), + g.plname, doname(g.level.objects[u.ux][u.uy])); if (obj) obj->spe = save_spe; } else @@ -537,7 +537,7 @@ register 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), - g.youmonst.data->mname, g.plname); + pmname(g.youmonst.data, Ugender), g.plname); if (sticky) set_ustuck(mtmp); g.youmonst.m_ap_type = M_AP_NOTHING; @@ -557,13 +557,14 @@ register struct monst *mtmp; : "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(&g.youmonst), an(mons[u.umonnum].mname), - g.plname); + mimic_obj_name(&g.youmonst), + an(pmname(&mons[u.umonnum], Ugender)), g.plname); if (g.multi < 0) { /* this should always be the case */ char buf[BUFSZ]; Sprintf(buf, "You appear to be %s again.", - Upolyd ? (const char *) an(g.youmonst.data->mname) + Upolyd ? (const char *) an(pmname(g.youmonst.data, + flags.female)) : (const char *) "yourself"); unmul(buf); /* immediately stop mimicking */ } @@ -793,8 +794,7 @@ boolean youseeit; */ if (is_demon(mdat)) { - if (mdat != &mons[PM_BALROG] - && mdat != &mons[PM_SUCCUBUS] && mdat != &mons[PM_INCUBUS]) { + if (mdat != &mons[PM_BALROG] && mdat != &mons[PM_AMOROUS_DEMON]) { if (!rn2(13)) (void) msummon(mtmp); } @@ -861,7 +861,7 @@ struct permonst *mdat; return FALSE; } else { make_sick(Sick ? Sick / 3L + 1L : (long) rn1(ACURR(A_CON), 20), - mdat->mname, TRUE, SICK_NONVOMITABLE); + mdat->pmnames[NEUTRAL], TRUE, SICK_NONVOMITABLE); return TRUE; } } @@ -915,7 +915,7 @@ struct monst *mon; via_amul = FALSE, gotprot = is_you ? (EProtection != 0L) /* high priests have innate protection */ - : (mon->data == &mons[PM_HIGH_PRIEST]); + : (mon->data == &mons[PM_HIGH_CLERIC]); for (o = is_you ? g.invent : mon->minvent; o; o = o->nobj) { /* a_can field is only applicable for armor (which must be worn) */ @@ -948,7 +948,7 @@ struct monst *mon; protection is too easy); it confers minimum mc 1 instead of 0 */ if ((is_you && ((HProtection && u.ublessed > 0) || u.uspellprot)) /* aligned priests and angels have innate intrinsic Protection */ - || (mon->data == &mons[PM_ALIGNED_PRIEST] || is_minion(mon->data))) + || (mon->data == &mons[PM_ALIGNED_CLERIC] || is_minion(mon->data))) mc = 1; } return mc; @@ -1034,7 +1034,7 @@ register struct attack *mattk; if (mhm.damage) { if (Half_physical_damage /* Mitre of Holiness */ - || (Role_if(PM_PRIEST) && uarmh && is_quest_artifact(uarmh) + || (Role_if(PM_CLERIC) && uarmh && is_quest_artifact(uarmh) && (is_undead(mtmp->data) || is_demon(mtmp->data) || is_vampshifter(mtmp)))) mhm.damage = (mhm.damage + 1) / 2; @@ -1543,7 +1543,7 @@ struct attack *mattk; break; You("turn to stone..."); g.killer.format = KILLED_BY; - Strcpy(g.killer.name, mtmp->data->mname); + Strcpy(g.killer.name, pmname(mtmp->data, Mgender(mtmp))); done(STONING); } break; @@ -1751,8 +1751,7 @@ struct attack *mattk; /* non-Null: current attack; Null: general capability */ for seduction, both pass the could_seduce() test; incubi/succubi have three attacks, their claw attacks for damage don't pass the test */ - if ((pagr->mlet != S_NYMPH - && pagr != &mons[PM_INCUBUS] && pagr != &mons[PM_SUCCUBUS]) + if ((pagr->mlet != S_NYMPH && pagr != &mons[PM_AMOROUS_DEMON]) || (adtyp != AD_SEDU && adtyp != AD_SSEX && adtyp != AD_SITM)) return 0; @@ -1765,7 +1764,8 @@ doseduce(mon) struct monst *mon; { struct obj *ring, *nring; - boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ + boolean fem = (mon->data == &mons[PM_AMOROUS_DEMON] + && Mgender(mon) == FEMALE); /* otherwise incubus */ boolean seewho, naked; /* True iff no armor */ int attr_tot, tried_gloves = 0; char qbuf[QBUFSZ], Who[QBUFSZ]; @@ -2232,7 +2232,8 @@ struct attack *mattk; && (perceives(mtmp->data) || !Invis)) { if (Blind) pline("As a blind %s, you cannot defend yourself.", - g.youmonst.data->mname); + pmname(g.youmonst.data, + flags.female ? FEMALE : MALE)); else { if (mon_reflects(mtmp, "Your gaze is reflected by %s %s.")) diff --git a/src/minion.c b/src/minion.c index 03f0b27c0..c6a7dec58 100644 --- a/src/minion.c +++ b/src/minion.c @@ -196,7 +196,7 @@ boolean talk; EMIN(mon)->renegade = FALSE; } } else if (mnum != PM_SHOPKEEPER && mnum != PM_GUARD - && mnum != PM_ALIGNED_PRIEST && mnum != PM_HIGH_PRIEST) { + && mnum != PM_ALIGNED_CLERIC && mnum != PM_HIGH_CLERIC) { /* This was mons[mnum].pxlth == 0 but is this restriction appropriate or necessary now that the structures are separate? */ mon = makemon(&mons[mnum], u.ux, u.uy, MM_EMIN); diff --git a/src/mkmaze.c b/src/mkmaze.c index 4b3e7c588..c79068bf1 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -569,7 +569,7 @@ fixup_special() set_corpsenm(otmp, rndmonnum()); } } - } else if (Role_if(PM_PRIEST) && In_quest(&u.uz)) { + } else if (Role_if(PM_CLERIC) && In_quest(&u.uz)) { /* less chance for undead corpses (lured from lower morgues) */ g.level.flags.graveyard = 1; } else if (Is_stronghold(&u.uz)) { @@ -742,7 +742,7 @@ stolen_booty(VOID_ARGS) if (DEADMONSTER(mtmp)) continue; - if (is_orc(mtmp->data) && !has_mname(mtmp) && rn2(10)) { + if (is_orc(mtmp->data) && !has_mgivenname(mtmp) && rn2(10)) { /* * We'll consider the orc captain from the level * description to be the captain of a rival orc horde diff --git a/src/mkroom.c b/src/mkroom.c index d1e7c7cbb..405efb312 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -250,10 +250,10 @@ mk_zoo_thronemon(x,y) int x,y; { int i = rnd(level_difficulty()); - int pm = (i > 9) ? PM_OGRE_KING - : (i > 5) ? PM_ELVENKING - : (i > 2) ? PM_DWARF_KING - : PM_GNOME_KING; + int pm = (i > 9) ? PM_OGRE_TYRANT + : (i > 5) ? PM_ELVENMONARCH + : (i > 2) ? PM_DWARF_RULER + : PM_GNOME_RULER; struct monst *mon = makemon(&mons[pm], x, y, NO_MM_FLAGS); if (mon) { diff --git a/src/mon.c b/src/mon.c index 1676dc072..c6136e779 100644 --- a/src/mon.c +++ b/src/mon.c @@ -84,14 +84,17 @@ const char *msg; /* bad if not fmons list or if not vault guard */ if (strcmp(msg, "fmon") || !mtmp->isgd) impossible("dead monster on %s; %s at <%d,%d>", - msg, mons[mndx].mname, mx, my); + msg, mons[mndx].pmnames[NEUTRAL], + mx, my); #endif return; } if (chk_geno && (g.mvitals[mndx].mvflags & G_GENOD) != 0) - impossible("genocided %s in play (%s)", mons[mndx].mname, msg); + impossible("genocided %s in play (%s)", + pmname(&mons[mndx], Mgender(mtmp)), msg); if (mtmp->mtame && !mtmp->mpeaceful) - impossible("tame %s is not peaceful (%s)", mons[mndx].mname, msg); + impossible("tame %s is not peaceful (%s)", + pmname(&mons[mndx], Mgender(mtmp)), msg); } if (mtmp->isshk && !has_eshk(mtmp)) impossible("shk without eshk (%s)", msg); @@ -151,7 +154,7 @@ const char *msg; but only until the pet finishes eating a mimic corpse */ if (!(is_mimic || mtmp->meating)) impossible("non-mimic (%s) posing as %s (%s)", - mptr->mname, what, msg); + mptr->pmnames[NEUTRAL], what, msg); if (!(accessible(mx, my) || passes_walls(mptr))) { char buf[BUFSZ]; const char *typnam = levltyp_to_name(levl[mx][my].typ); @@ -337,7 +340,7 @@ int mndx; mndx = PM_ELF; break; case PM_VAMPIRE: - case PM_VAMPIRE_LORD: + case PM_VAMPIRE_LEADER: #if 0 /* DEFERRED */ case PM_VAMPIRE_MAGE: #endif @@ -378,7 +381,7 @@ int mndx, mode; mndx = mode ? PM_BARBARIAN : PM_HUMAN; break; case PM_NEANDERTHAL: - mndx = mode ? PM_CAVEMAN : PM_HUMAN; + mndx = mode ? PM_CAVE_DWELLER : PM_HUMAN; break; case PM_ATTENDANT: mndx = mode ? PM_HEALER : PM_HUMAN; @@ -390,7 +393,7 @@ int mndx, mode; mndx = mode ? PM_MONK : PM_HUMAN; break; case PM_ACOLYTE: - mndx = mode ? PM_PRIEST : PM_HUMAN; + mndx = mode ? PM_CLERIC : PM_HUMAN; break; case PM_HUNTER: mndx = mode ? PM_RANGER : PM_HUMAN; @@ -514,7 +517,7 @@ unsigned corpseflags; (void) mksobj_at(WORM_TOOTH, x, y, TRUE, FALSE); goto default_1; case PM_VAMPIRE: - case PM_VAMPIRE_LORD: + case PM_VAMPIRE_LEADER: /* include mtmp in the mkcorpstat() call */ num = undead_to_corpse(mndx); corpstatflags |= CORPSTAT_INIT; @@ -546,19 +549,19 @@ unsigned corpseflags; num = d(2, 6); while (num--) obj = mksobj_at(IRON_CHAIN, x, y, TRUE, FALSE); - free_mname(mtmp); /* don't christen obj */ + free_mgivenname(mtmp); /* don't christen obj */ break; case PM_GLASS_GOLEM: num = d(2, 4); /* very low chance of creating all glass gems */ while (num--) obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE, FALSE); - free_mname(mtmp); + free_mgivenname(mtmp); break; case PM_CLAY_GOLEM: obj = mksobj_at(ROCK, x, y, FALSE, FALSE); obj->quan = (long) (rn2(20) + 50); obj->owt = weight(obj); - free_mname(mtmp); + free_mgivenname(mtmp); break; case PM_STONE_GOLEM: corpstatflags &= ~CORPSTAT_INIT; @@ -570,24 +573,24 @@ unsigned corpseflags; while (num--) { obj = mksobj_at(QUARTERSTAFF, x, y, TRUE, FALSE); } - free_mname(mtmp); + free_mgivenname(mtmp); break; case PM_LEATHER_GOLEM: num = d(2, 4); while (num--) obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE, FALSE); - free_mname(mtmp); + free_mgivenname(mtmp); break; case PM_GOLD_GOLEM: /* Good luck gives more coins */ obj = mkgold((long) (200 - rnl(101)), x, y); - free_mname(mtmp); + free_mgivenname(mtmp); break; case PM_PAPER_GOLEM: num = rnd(4); while (num--) obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE, FALSE); - free_mname(mtmp); + free_mgivenname(mtmp); break; /* expired puddings will congeal into a large blob; like dragons, relies on the order remaining consistent */ @@ -604,7 +607,7 @@ unsigned corpseflags; pudding_merge_message(obj, otmp); obj = obj_meld(&obj, &otmp); } - free_mname(mtmp); + free_mgivenname(mtmp); return obj; default: default_1: @@ -635,8 +638,8 @@ unsigned corpseflags; if (g.context.bypasses) bypass_obj(obj); - if (has_mname(mtmp)) - obj = oname(obj, MNAME(mtmp)); + if (has_mgivenname(mtmp)) + obj = oname(obj, MGIVENNAME(mtmp)); /* Avoid "It was hidden under a green mold corpse!" * during Blind combat. An unseen monster referred to as "it" @@ -2118,9 +2121,9 @@ struct monst *mtmp2, *mtmp1; if (!mtmp2->mextra) mtmp2->mextra = newmextra(); - if (MNAME(mtmp1)) { - new_mname(mtmp2, (int) strlen(MNAME(mtmp1)) + 1); - Strcpy(MNAME(mtmp2), MNAME(mtmp1)); + if (MGIVENNAME(mtmp1)) { + new_mgivenname(mtmp2, (int) strlen(MGIVENNAME(mtmp1)) + 1); + Strcpy(MGIVENNAME(mtmp2), MGIVENNAME(mtmp1)); } if (EGD(mtmp1)) { if (!EGD(mtmp2)) @@ -2158,8 +2161,8 @@ struct monst *m; struct mextra *x = m->mextra; if (x) { - if (x->mname) - free((genericptr_t) x->mname); + if (x->mgivenname) + free((genericptr_t) x->mgivenname); if (x->egd) free((genericptr_t) x->egd); if (x->epri) @@ -2514,7 +2517,7 @@ boolean was_swallowed; /* digestion */ if (magr == &g.youmonst) { There("is an explosion in your %s!", body_part(STOMACH)); Sprintf(g.killer.name, "%s explosion", - s_suffix(mdat->mname)); + s_suffix(pmname(mdat, Mgender(mon)))); losehp(Maybe_Half_Phys(tmp), g.killer.name, KILLED_BY_AN); } else { You_hear("an explosion."); @@ -2531,7 +2534,8 @@ boolean was_swallowed; /* digestion */ return FALSE; } - Sprintf(g.killer.name, "%s explosion", s_suffix(mdat->mname)); + Sprintf(g.killer.name, "%s explosion", + s_suffix(pmname(mdat, Mgender(mon)))); g.killer.format = KILLED_BY_AN; explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE, EXPL_NOXIOUS); g.killer.name[0] = '\0'; @@ -2649,8 +2653,8 @@ struct monst *mdef; so that saved monster traits won't retain any stale item-conferred attributes */ otmp = mkcorpstat(STATUE, mdef, mdef->data, x, y, CORPSTAT_NONE); - if (has_mname(mdef)) - otmp = oname(otmp, MNAME(mdef)); + if (has_mgivenname(mdef)) + otmp = oname(otmp, MGIVENNAME(mdef)); while ((obj = oldminvent) != 0) { oldminvent = obj->nobj; obj->nobj = 0; /* avoid merged-> obfree-> dealloc_obj-> panic */ @@ -2798,7 +2802,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */ u.uconduct.killer++; if (!nomsg) { - boolean namedpet = has_mname(mtmp) && !Hallucination; + boolean namedpet = has_mgivenname(mtmp) && !Hallucination; You("%s %s!", nonliving(mtmp->data) ? "destroy" : "kill", @@ -2987,7 +2991,7 @@ struct monst *mtmp; pline("%s solidifies...", Monnam(mtmp)); if (newcham(mtmp, &mons[PM_STONE_GOLEM], FALSE, FALSE)) { if (canseemon(mtmp)) - pline("Now it's %s.", an(mtmp->data->mname)); + pline("Now it's %s.", an(pmname(mtmp->data, Mgender(mtmp)))); } else { if (canseemon(mtmp)) pline("... and returns to normal."); @@ -3415,7 +3419,7 @@ boolean via_attack; } } if (got_mad && !Hallucination) { - const char *who = q_guardian->mname; + const char *who = q_guardian->pmnames[NEUTRAL]; if (got_mad > 1) who = makeplural(who); @@ -3888,7 +3892,7 @@ struct monst *mon; break; /* leave mndx as is */ wolfchance = 3; /*FALLTHRU*/ - case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */ + case PM_VAMPIRE_LEADER: /* vampire lord or Vlad can become wolf */ if (!rn2(wolfchance) && !uppercase_only) { mndx = PM_WOLF; break; @@ -4039,7 +4043,7 @@ struct monst *mon; mndx = pick_animal(); break; case PM_VLAD_THE_IMPALER: - case PM_VAMPIRE_LORD: + case PM_VAMPIRE_LEADER: case PM_VAMPIRE: mndx = pickvampshape(mon); break; @@ -4097,7 +4101,7 @@ struct monst *mon; mndx = NON_PM; break; } - mndx = name_to_mon(buf); + mndx = name_to_mon(buf, (int *) 0); if (mndx == NON_PM) { /* didn't get a type, so check whether it's a class (single letter or text match with def_monsyms[]) */ @@ -4222,7 +4226,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */ } /* we need this one whether msg is true or not */ Strcpy(l_oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0, - has_mname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE)); + has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE)); /* mdat = 0 -> caller wants a random monster shape */ if (mdat == 0) { @@ -4255,7 +4259,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */ * polymorphed, so dropping rank for mplayers seems reasonable. */ if (In_endgame(&u.uz) && is_mplayer(olddata) - && has_mname(mtmp) && (p = strstr(MNAME(mtmp), " the ")) != 0) + && has_mgivenname(mtmp) && (p = strstr(MGIVENNAME(mtmp), " the ")) != 0) *p = '\0'; if (mtmp->wormno) { /* throw tail away */ @@ -4646,9 +4650,9 @@ char *str; for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (DEADMONSTER(mtmp) - || mtmp->data != &mons[PM_GHOST] || !has_mname(mtmp)) + || mtmp->data != &mons[PM_GHOST] || !has_mgivenname(mtmp)) continue; - if (!strcmpi(MNAME(mtmp), str)) + if (!strcmpi(MGIVENNAME(mtmp), str)) return mtmp; } return (struct monst *) 0; @@ -4694,8 +4698,7 @@ struct permonst *mdat; You("notice a bovine smell."); msg_given = TRUE; break; - case PM_CAVEMAN: - case PM_CAVEWOMAN: + case PM_CAVE_DWELLER: case PM_BARBARIAN: case PM_NEANDERTHAL: You("smell body odor."); diff --git a/src/mondata.c b/src/mondata.c index e15fef59a..e78806dbe 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -681,15 +681,17 @@ struct permonst *ptr; struct alt_spl { const char *name; short pm_val; + int genderhint; }; /* figure out what type of monster a user-supplied string is specifying; ingore anything past the monster name */ int -name_to_mon(in_str) +name_to_mon(in_str, gender_name_var) const char *in_str; +int *gender_name_var; { - return name_to_monplus(in_str, (const char **) 0); + return name_to_monplus(in_str, (const char **) 0, gender_name_var); } /* figure out what type of monster a user-supplied string is specifying; @@ -697,9 +699,10 @@ const char *in_str; caller wants to strip off the name and it matches one of the alternate names rather the canonical mons[].mname */ int -name_to_monplus(in_str, remainder_p) +name_to_monplus(in_str, remainder_p, gender_name_var) const char *in_str; const char **remainder_p; +int *gender_name_var; { /* Be careful. We must check the entire string in case it was * something such as "ettin zombie corpse". The calling routine @@ -717,7 +720,8 @@ const char **remainder_p; register int mntmp = NON_PM; register char *s, *str, *term; char buf[BUFSZ]; - int len, slen; + int len, slen, mgend; + boolean exact_match = FALSE; if (remainder_p) *remainder_p = (const char *) 0; @@ -749,70 +753,72 @@ const char **remainder_p; { static const struct alt_spl names[] = { /* Alternate spellings */ - { "grey dragon", PM_GRAY_DRAGON }, - { "baby grey dragon", PM_BABY_GRAY_DRAGON }, - { "grey unicorn", PM_GRAY_UNICORN }, - { "grey ooze", PM_GRAY_OOZE }, - { "gray-elf", PM_GREY_ELF }, - { "mindflayer", PM_MIND_FLAYER }, - { "master mindflayer", PM_MASTER_MIND_FLAYER }, + { "grey dragon", PM_GRAY_DRAGON, NEUTRAL }, + { "baby grey dragon", PM_BABY_GRAY_DRAGON, NEUTRAL }, + { "grey unicorn", PM_GRAY_UNICORN, NEUTRAL }, + { "grey ooze", PM_GRAY_OOZE, NEUTRAL }, + { "gray-elf", PM_GREY_ELF, NEUTRAL }, + { "mindflayer", PM_MIND_FLAYER, NEUTRAL }, + { "master mindflayer", PM_MASTER_MIND_FLAYER, NEUTRAL }, /* More alternates; priest and priestess are separate monster types but that isn't the case for {aligned,high} priests */ - { "aligned priestess", PM_ALIGNED_PRIEST }, - { "high priestess", PM_HIGH_PRIEST }, + { "aligned priestess", PM_ALIGNED_CLERIC, NEUTRAL }, + { "high priestess", PM_HIGH_CLERIC, NEUTRAL }, /* Inappropriate singularization by -ves check above */ - { "master of thief", PM_MASTER_OF_THIEVES }, + { "master of thief", PM_MASTER_OF_THIEVES, NEUTRAL }, /* Potential misspellings where we want to avoid falling back to the rank title prefix (input has been singularized) */ - { "master thief", PM_MASTER_OF_THIEVES }, - { "master of assassin", PM_MASTER_ASSASSIN }, + { "master thief", PM_MASTER_OF_THIEVES, NEUTRAL }, + { "master of assassin", PM_MASTER_ASSASSIN, NEUTRAL }, /* Outdated names */ - { "invisible stalker", PM_STALKER }, - { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */ + { "invisible stalker", PM_STALKER, NEUTRAL }, + { "high-elf", PM_ELVENMONARCH, NEUTRAL }, /* PM_HIGH_ELF is obsolete */ /* other misspellings or incorrect words */ - { "wood-elf", PM_WOODLAND_ELF }, - { "wood elf", PM_WOODLAND_ELF }, - { "woodland nymph", PM_WOOD_NYMPH }, - { "halfling", PM_HOBBIT }, /* potential guess for polyself */ - { "genie", PM_DJINNI }, /* potential guess for ^G/#wizgenesis */ + { "wood-elf", PM_WOODLAND_ELF, NEUTRAL }, + { "wood elf", PM_WOODLAND_ELF, NEUTRAL }, + { "woodland nymph", PM_WOOD_NYMPH, NEUTRAL }, + { "halfling", PM_HOBBIT, NEUTRAL }, /* potential guess for polyself */ + { "genie", PM_DJINNI, NEUTRAL }, /* potential guess for ^G/#wizgenesis */ /* prefix used to workaround duplicate monster names for monsters with alternate forms */ - { "human wererat", PM_HUMAN_WERERAT }, - { "human werejackal", PM_HUMAN_WEREJACKAL }, - { "human werewolf", PM_HUMAN_WEREWOLF }, + { "human wererat", PM_HUMAN_WERERAT, NEUTRAL }, + { "human werejackal", PM_HUMAN_WEREJACKAL, NEUTRAL }, + { "human werewolf", PM_HUMAN_WEREWOLF, NEUTRAL }, /* for completeness */ - { "rat wererat", PM_WERERAT }, - { "jackal werejackal", PM_WEREJACKAL }, - { "wolf werewolf", PM_WEREWOLF }, + { "rat wererat", PM_WERERAT, NEUTRAL }, + { "jackal werejackal", PM_WEREJACKAL, NEUTRAL }, + { "wolf werewolf", PM_WEREWOLF, NEUTRAL }, /* Hyphenated names -- it would be nice to handle these via fuzzymatch() but it isn't able to ignore trailing stuff */ - { "ki rin", PM_KI_RIN }, - { "kirin", PM_KI_RIN }, - { "uruk hai", PM_URUK_HAI }, - { "orc captain", PM_ORC_CAPTAIN }, - { "woodland elf", PM_WOODLAND_ELF }, - { "green elf", PM_GREEN_ELF }, - { "grey elf", PM_GREY_ELF }, - { "gray elf", PM_GREY_ELF }, - { "elf lord", PM_ELF_LORD }, - { "olog hai", PM_OLOG_HAI }, - { "arch lich", PM_ARCH_LICH }, - { "archlich", PM_ARCH_LICH }, + { "ki rin", PM_KI_RIN, NEUTRAL }, + { "kirin", PM_KI_RIN, NEUTRAL }, + { "uruk hai", PM_URUK_HAI, NEUTRAL }, + { "orc captain", PM_ORC_CAPTAIN, NEUTRAL }, + { "woodland elf", PM_WOODLAND_ELF, NEUTRAL }, + { "green elf", PM_GREEN_ELF, NEUTRAL }, + { "grey elf", PM_GREY_ELF, NEUTRAL }, + { "gray elf", PM_GREY_ELF, NEUTRAL }, + { "elf lady", PM_ELF_NOBLE, FEMALE }, + { "elf lord", PM_ELF_NOBLE, MALE }, + { "elf noble", PM_ELF_NOBLE, NEUTRAL }, + { "olog hai", PM_OLOG_HAI, NEUTRAL }, + { "arch lich", PM_ARCH_LICH, NEUTRAL }, + { "archlich", PM_ARCH_LICH, NEUTRAL }, /* Some irregular plurals */ - { "incubi", PM_INCUBUS }, - { "succubi", PM_SUCCUBUS }, - { "violet fungi", PM_VIOLET_FUNGUS }, - { "homunculi", PM_HOMUNCULUS }, - { "baluchitheria", PM_BALUCHITHERIUM }, - { "lurkers above", PM_LURKER_ABOVE }, - { "cavemen", PM_CAVEMAN }, - { "cavewomen", PM_CAVEWOMAN }, - { "watchmen", PM_WATCHMAN }, - { "djinn", PM_DJINNI }, - { "mumakil", PM_MUMAK }, - { "erinyes", PM_ERINYS }, + { "incubi", PM_AMOROUS_DEMON, MALE }, + { "succubi", PM_AMOROUS_DEMON, FEMALE }, + { "violet fungi", PM_VIOLET_FUNGUS, NEUTRAL }, + { "homunculi", PM_HOMUNCULUS, NEUTRAL }, + { "baluchitheria", PM_BALUCHITHERIUM, NEUTRAL }, + { "lurkers above", PM_LURKER_ABOVE, NEUTRAL }, + { "cavemen", PM_CAVE_DWELLER, MALE }, + { "cavewomen", PM_CAVE_DWELLER, FEMALE }, + { "watchmen", PM_WATCHMAN, NEUTRAL }, + { "djinn", PM_DJINNI, NEUTRAL }, + { "mumakil", PM_MUMAK, NEUTRAL }, + { "erinyes", PM_ERINYS, NEUTRAL }, /* end of list */ - { 0, NON_PM } + { 0, NON_PM, NEUTRAL } }; register const struct alt_spl *namep; @@ -823,18 +829,28 @@ const char **remainder_p; && (!str[len] || str[len] == ' ' || str[len] == '\'')) { if (remainder_p) *remainder_p = in_str + (&str[len] - buf); + if (gender_name_var != (int *) 0) + *gender_name_var = namep->genderhint; return namep->pm_val; } } } for (len = 0, i = LOW_PM; i < NUMMONS; i++) { - register int m_i_len = (int) strlen(mons[i].mname); + for (mgend = MALE; mgend < NUM_MGENDERS; mgend++) { + int m_i_len; - if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) { + if (!mons[i].pmnames[mgend]) + continue; + + m_i_len = (int) strlen(mons[i].pmnames[mgend]); + if (m_i_len > len && !strncmpi(mons[i].pmnames[mgend], str, m_i_len)) { if (m_i_len == slen) { mntmp = i; len = m_i_len; + if (gender_name_var != (int *) 0) + *gender_name_var = mgend; + exact_match = TRUE; break; /* exact match */ } else if (slen > m_i_len && (str[m_i_len] == ' ' @@ -850,6 +866,9 @@ const char **remainder_p; len = m_i_len; } } + } + if (exact_match) + break; } if (mntmp == NON_PM) mntmp = title_to_mon(str, (int *) 0, &len); @@ -868,8 +887,8 @@ int *mndx_p; /* Single letters are matched against def_monsyms[].sym; words or phrases are first matched against def_monsyms[].explain to check class description; if not found there, then against - mons[].mname to test individual monster types. Input can be a - substring of the full description or mname, but to be accepted, + mons[].pmnames[] to test individual monster types. Input can be a + substring of the full description or pmname, but to be accepted, such partial matches must start at beginning of a word. Some class descriptions include "foo or bar" and "foo or other foo" so we don't want to accept "or", "other", "or other" there. */ @@ -881,16 +900,16 @@ int *mndx_p; static NEARDATA const struct alt_spl truematch[] = { /* "long worm" won't match "worm" class but would accidentally match "long worm tail" class before the comparison with monster types */ - { "long worm", PM_LONG_WORM }, + { "long worm", PM_LONG_WORM, NEUTRAL }, /* matches wrong--or at least suboptimal--class */ - { "demon", -S_DEMON }, /* hits "imp or minor demon" */ + { "demon", -S_DEMON, NEUTRAL }, /* hits "imp or minor demon" */ /* matches specific monster (overly restrictive) */ - { "devil", -S_DEMON }, /* always "horned devil" */ + { "devil", -S_DEMON, NEUTRAL }, /* always "horned devil" */ /* some plausible guesses which need help */ - { "bug", -S_XAN }, /* would match bugbear... */ - { "fish", -S_EEL }, /* wouldn't match anything */ + { "bug", -S_XAN, NEUTRAL }, /* would match bugbear... */ + { "fish", -S_EEL, NEUTRAL }, /* wouldn't match anything */ /* end of list */ - { 0, NON_PM } + { 0, NON_PM, NEUTRAL} }; const char *p, *x; int i, len; @@ -941,7 +960,7 @@ int *mndx_p; return i; } /* check individual species names */ - i = name_to_mon(in_str); + i = name_to_mon(in_str, (int *) 0); if (i != NON_PM) { if (mndx_p) *mndx_p = i; @@ -1014,11 +1033,11 @@ static const short grownups[][2] = { { PM_PONY, PM_HORSE }, { PM_HORSE, PM_WARHORSE }, { PM_KOBOLD, PM_LARGE_KOBOLD }, - { PM_LARGE_KOBOLD, PM_KOBOLD_LORD }, - { PM_GNOME, PM_GNOME_LORD }, - { PM_GNOME_LORD, PM_GNOME_KING }, - { PM_DWARF, PM_DWARF_LORD }, - { PM_DWARF_LORD, PM_DWARF_KING }, + { PM_LARGE_KOBOLD, PM_KOBOLD_LEADER }, + { PM_GNOME, PM_GNOME_LEADER }, + { PM_GNOME_LEADER, PM_GNOME_RULER }, + { PM_DWARF, PM_DWARF_LEADER }, + { PM_DWARF_LEADER, PM_DWARF_RULER }, { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER }, { PM_ORC, PM_ORC_CAPTAIN }, { PM_HILL_ORC, PM_ORC_CAPTAIN }, @@ -1026,17 +1045,17 @@ static const short grownups[][2] = { { PM_URUK_HAI, PM_ORC_CAPTAIN }, { PM_SEWER_RAT, PM_GIANT_RAT }, { PM_CAVE_SPIDER, PM_GIANT_SPIDER }, - { PM_OGRE, PM_OGRE_LORD }, - { PM_OGRE_LORD, PM_OGRE_KING }, - { PM_ELF, PM_ELF_LORD }, - { PM_WOODLAND_ELF, PM_ELF_LORD }, - { PM_GREEN_ELF, PM_ELF_LORD }, - { PM_GREY_ELF, PM_ELF_LORD }, - { PM_ELF_LORD, PM_ELVENKING }, + { PM_OGRE, PM_OGRE_LEADER }, + { PM_OGRE_LEADER, PM_OGRE_TYRANT }, + { PM_ELF, PM_ELF_NOBLE }, + { PM_WOODLAND_ELF, PM_ELF_NOBLE }, + { PM_GREEN_ELF, PM_ELF_NOBLE }, + { PM_GREY_ELF, PM_ELF_NOBLE }, + { PM_ELF_NOBLE, PM_ELVENMONARCH }, { PM_LICH, PM_DEMILICH }, { PM_DEMILICH, PM_MASTER_LICH }, { PM_MASTER_LICH, PM_ARCH_LICH }, - { PM_VAMPIRE, PM_VAMPIRE_LORD }, + { PM_VAMPIRE, PM_VAMPIRE_LEADER }, { PM_BAT, PM_GIANT_BAT }, { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON }, { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON }, @@ -1063,11 +1082,11 @@ static const short grownups[][2] = { { PM_SERGEANT, PM_LIEUTENANT }, { PM_LIEUTENANT, PM_CAPTAIN }, { PM_WATCHMAN, PM_WATCH_CAPTAIN }, - { PM_ALIGNED_PRIEST, PM_HIGH_PRIEST }, + { PM_ALIGNED_CLERIC, PM_HIGH_CLERIC }, { PM_STUDENT, PM_ARCHEOLOGIST }, { PM_ATTENDANT, PM_HEALER }, { PM_PAGE, PM_KNIGHT }, - { PM_ACOLYTE, PM_PRIEST }, + { PM_ACOLYTE, PM_CLERIC }, { PM_APPRENTICE, PM_WIZARD }, { PM_MANES, PM_LEMURE }, { PM_KEYSTONE_KOP, PM_KOP_SERGEANT }, diff --git a/src/monst.c b/src/monst.c index 1955f37a0..2e44b5413 100644 --- a/src/monst.c +++ b/src/monst.c @@ -45,7 +45,13 @@ */ #define MON(nam, sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, col) \ { \ - nam, sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, C(col) \ + {(const char *) 0, (const char *) 0, nam}, \ + sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, C(col) \ + } +#define MON3(namm, namf, namn, sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, col) \ + { \ + {namm, namf, namn}, \ + sym, lvl, gen, atk, siz, mr1, mr2, flg1, flg2, flg3, d, C(col) \ } /* LVL() and SIZ() collect several fields to cut down on number of args * for MON() @@ -436,7 +442,8 @@ NEARDATA struct permonst mons_init[] = { NO_ATTK), SIZ(1250, 250, MS_GROWL, MZ_LARGE), 0, 0, M1_HUMANOID | M1_OMNIVORE, M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 5, CLR_BROWN), - MON("dwarf lord", S_HUMANOID, LVL(4, 6, 10, 10, 5), (G_GENO | 2), + MON3("dwarf lord", "dwarf lady", "dwarf leader", + S_HUMANOID, LVL(4, 6, 10, 10, 5), (G_GENO | 2), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0, @@ -444,12 +451,13 @@ NEARDATA struct permonst mons_init[] = { M2_DWARF | M2_STRONG | M2_LORD | M2_MALE | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 6, CLR_BLUE), - MON("dwarf king", S_HUMANOID, LVL(6, 6, 10, 20, 6), (G_GENO | 1), + MON3("dwarf king", "dwarf queen", "dwarf ruler", + S_HUMANOID, LVL(6, 6, 10, 20, 6), (G_GENO | 1), A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0, M1_TUNNEL | M1_NEEDPICK | M1_HUMANOID | M1_OMNIVORE, - M2_DWARF | M2_STRONG | M2_PRINCE | M2_MALE | M2_GREEDY | M2_JEWELS + M2_DWARF | M2_STRONG | M2_PRINCE | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 8, HI_LORD), MON("mind flayer", S_HUMANOID, LVL(9, 12, 5, 90, -8), (G_GENO | 1), @@ -547,12 +555,13 @@ NEARDATA struct permonst mons_init[] = { SIZ(450, 150, MS_ORC, MZ_SMALL), MR_POISON, 0, M1_HUMANOID | M1_POIS | M1_OMNIVORE, M2_HOSTILE | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 2, CLR_RED), - MON("kobold lord", S_KOBOLD, LVL(2, 6, 10, 0, -4), (G_GENO | 1), + MON3("kobold lord", "kobold lady", "kobold leader", + S_KOBOLD, LVL(2, 6, 10, 0, -4), (G_GENO | 1), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(500, 200, MS_ORC, MZ_SMALL), MR_POISON, 0, M1_HUMANOID | M1_POIS | M1_OMNIVORE, - M2_HOSTILE | M2_LORD | M2_MALE | M2_COLLECT, + M2_HOSTILE | M2_LORD | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 3, HI_LORD), MON("kobold shaman", S_KOBOLD, LVL(2, 6, 6, 10, -4), (G_GENO | 1), A(ATTK(AT_MAGC, AD_SPEL, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, @@ -1359,22 +1368,24 @@ NEARDATA struct permonst mons_init[] = { SIZ(650, 100, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, M2_NOPOLY | M2_GNOME | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 3, CLR_BROWN), - MON("gnome lord", S_GNOME, LVL(3, 8, 10, 4, 0), (G_GENO | 2), + MON3("gnome lord", "gnome lady", "gnome leader", + S_GNOME, LVL(3, 8, 10, 4, 0), (G_GENO | 2), A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, - M2_GNOME | M2_LORD | M2_MALE | M2_COLLECT, + M2_GNOME | M2_LORD | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 4, CLR_BLUE), MON("gnomish wizard", S_GNOME, LVL(3, 10, 4, 10, 0), (G_GENO | 1), A(ATTK(AT_MAGC, AD_SPEL, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(700, 120, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, M2_GNOME | M2_MAGIC, M3_INFRAVISIBLE | M3_INFRAVISION, 5, HI_ZAP), - MON("gnome king", S_GNOME, LVL(5, 10, 10, 20, 0), (G_GENO | 1), + MON3("gnome king", "gnome queen", "gnome ruler", + S_GNOME, LVL(5, 10, 10, 20, 0), (G_GENO | 1), A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(750, 150, MS_ORC, MZ_SMALL), 0, 0, M1_HUMANOID | M1_OMNIVORE, - M2_GNOME | M2_PRINCE | M2_MALE | M2_COLLECT, + M2_GNOME | M2_PRINCE | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 6, HI_LORD), #ifdef SPLITMON_1 }; @@ -1681,17 +1692,19 @@ struct permonst _mons2[] = { SIZ(1600, 500, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, M2_STRONG | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 7, CLR_BROWN), - MON("ogre lord", S_OGRE, LVL(7, 12, 3, 30, -5), (G_GENO | 2), + MON3("ogre lord", "ogre conqueress", "ogre leader", + S_OGRE, LVL(7, 12, 3, 30, -5), (G_GENO | 2), A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(1700, 700, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, - M2_STRONG | M2_LORD | M2_MALE | M2_GREEDY | M2_JEWELS | M2_COLLECT, + M2_STRONG | M2_LORD | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 9, CLR_RED), - MON("ogre king", S_OGRE, LVL(9, 14, 4, 60, -7), (G_GENO | 2), + MON3("ogre king", "ogre queen", "ogre tyrant", + S_OGRE, LVL(9, 14, 4, 60, -7), (G_GENO | 2), A(ATTK(AT_WEAP, AD_PHYS, 3, 5), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(1700, 750, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, - M2_STRONG | M2_PRINCE | M2_MALE | M2_GREEDY | M2_JEWELS | M2_COLLECT, + M2_STRONG | M2_PRINCE | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 11, HI_LORD), /* * Puddings @@ -1871,14 +1884,15 @@ struct permonst _mons2[] = { M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY | M2_SHAPESHIFTER, M3_INFRAVISIBLE, 12, CLR_RED), - MON("vampire lord", S_VAMPIRE, LVL(12, 14, 0, 50, -9), + MON3("vampire lord", "vampire lady", "vampire leader", + S_VAMPIRE, LVL(12, 14, 0, 50, -9), (G_GENO | G_NOCORPSE | 1), A(ATTK(AT_CLAW, AD_PHYS, 1, 8), ATTK(AT_BITE, AD_DRLI, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0, M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN, M2_UNDEAD | M2_STALK | M2_HOSTILE | M2_STRONG | M2_NASTY | M2_LORD - | M2_MALE | M2_SHAPESHIFTER, + | M2_SHAPESHIFTER, M3_INFRAVISIBLE, 14, CLR_BLUE), #if 0 /* DEFERRED */ MON("vampire mage", S_VAMPIRE, @@ -2187,19 +2201,21 @@ struct permonst _mons2[] = { SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP, M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, M2_ELF | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY), - MON("elf-lord", S_HUMAN, LVL(8, 12, 10, 20, -9), (G_GENO | G_SGROUP | 2), + MON3("elf-lord", "elf-queen", "elf-noble", + S_HUMAN, LVL(8, 12, 10, 20, -9), (G_GENO | G_SGROUP | 2), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP, M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, - M2_ELF | M2_STRONG | M2_LORD | M2_MALE | M2_COLLECT, + M2_ELF | M2_STRONG | M2_LORD | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 11, CLR_BRIGHT_BLUE), - MON("Elvenking", S_HUMAN, LVL(9, 12, 10, 25, -10), (G_GENO | 1), + MON3("Elvenking", "Elvenqueen", "Elvenmonarch", + S_HUMAN, LVL(9, 12, 10, 25, -10), (G_GENO | 1), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_ELF, 350, MS_HUMANOID, MZ_HUMAN), MR_SLEEP, MR_SLEEP, M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, - M2_ELF | M2_STRONG | M2_PRINCE | M2_MALE | M2_COLLECT, + M2_ELF | M2_STRONG | M2_PRINCE | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 11, HI_LORD), MON("doppelganger", S_HUMAN, LVL(9, 12, 5, 20, 0), (G_GENO | 1), A(ATTK(AT_WEAP, AD_PHYS, 1, 12), @@ -2242,7 +2258,8 @@ struct permonst _mons2[] = { /* aligned priests always have the epri extension attached; individual instantiations should always have either ispriest or isminion set */ - MON("aligned priest", S_HUMAN, LVL(12, 12, 10, 50, 0), G_NOGEN, + MON3("priest", "priestess", "aligned cleric", + S_HUMAN, LVL(12, 12, 10, 50, 0), G_NOGEN, A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_KICK, AD_PHYS, 1, 4), ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_HUMAN, 400, MS_PRIEST, MZ_HUMAN), MR_ELEC, 0, @@ -2250,7 +2267,8 @@ struct permonst _mons2[] = { M2_NOPOLY | M2_HUMAN | M2_LORD | M2_PEACEFUL | M2_COLLECT, M3_INFRAVISIBLE, 15, CLR_WHITE), /* high priests always have epri and always have ispriest set */ - MON("high priest", S_HUMAN, LVL(25, 15, 7, 70, 0), (G_NOGEN | G_UNIQ), + MON3("high priest", "high priestess", "high cleric", + S_HUMAN, LVL(25, 15, 7, 70, 0), (G_NOGEN | G_UNIQ), A(ATTK(AT_WEAP, AD_PHYS, 4, 10), ATTK(AT_KICK, AD_PHYS, 2, 8), ATTK(AT_MAGC, AD_CLRC, 2, 8), ATTK(AT_MAGC, AD_CLRC, 2, 8), NO_ATTK, NO_ATTK), @@ -2392,10 +2410,12 @@ struct permonst _mons2[] = { #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) - MON("succubus", S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1), + /* incubus and succubus */ + MON3("incubus", "succubus", "Amorous Demon", + S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1), SEDUCTION_ATTACKS_YES, SIZ(WT_HUMAN, 400, MS_SEDUCE, MZ_HUMAN), MR_FIRE | MR_POISON, 0, M1_HUMANOID | M1_FLY | M1_POIS, - M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY | M2_FEMALE, + M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY, M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY), MON("horned devil", S_DEMON, LVL(6, 9, -5, 50, 11), (G_HELL | G_NOCORPSE | 2), @@ -2405,11 +2425,6 @@ struct permonst _mons2[] = { SIZ(WT_HUMAN, 400, MS_SILENT, MZ_HUMAN), MR_FIRE | MR_POISON, 0, M1_POIS | M1_THICK_HIDE, M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY, M3_INFRAVISIBLE | M3_INFRAVISION, 9, CLR_BROWN), - MON("incubus", S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1), - SEDUCTION_ATTACKS_YES, SIZ(WT_HUMAN, 400, MS_SEDUCE, MZ_HUMAN), - MR_FIRE | MR_POISON, 0, M1_HUMANOID | M1_FLY | M1_POIS, - M2_DEMON | M2_STALK | M2_HOSTILE | M2_NASTY | M2_MALE, - M3_INFRAVISIBLE | M3_INFRAVISION, 8, CLR_GRAY), /* Used by AD&D for a type of demon, originally one of the Furies and spelled this way */ MON("erinys", S_DEMON, LVL(7, 12, 2, 30, 10), @@ -2757,19 +2772,13 @@ struct permonst _mons2[] = { M1_HUMANOID | M1_OMNIVORE, M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE, 12, HI_DOMESTIC), - MON("caveman", S_HUMAN, LVL(10, 12, 10, 0, 1), G_NOGEN, + MON3("caveman", "cavewoman", "cave dweller", + S_HUMAN, LVL(10, 12, 10, 0, 1), G_NOGEN, A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0, M1_HUMANOID | M1_OMNIVORE, - M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_MALE | M2_COLLECT, - M3_INFRAVISIBLE, 12, HI_DOMESTIC), - MON("cavewoman", S_HUMAN, LVL(10, 12, 10, 0, 1), G_NOGEN, - A(ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, - NO_ATTK), - SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0, - M1_HUMANOID | M1_OMNIVORE, - M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_FEMALE | M2_COLLECT, + M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE, 12, HI_DOMESTIC), MON("healer", S_HUMAN, LVL(10, 12, 10, 1, 0), G_NOGEN, A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, @@ -2792,19 +2801,13 @@ struct permonst _mons2[] = { M1_HUMANOID | M1_HERBIVORE, M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT | M2_MALE, M3_INFRAVISIBLE, 11, HI_DOMESTIC), - MON("priest", S_HUMAN, LVL(10, 12, 10, 2, 0), G_NOGEN, + MON3("priest", "priestess", "cleric", + S_HUMAN, LVL(10, 12, 10, 2, 0), G_NOGEN, A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0, M1_HUMANOID | M1_OMNIVORE, - M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_MALE | M2_COLLECT, - M3_INFRAVISIBLE, 12, HI_DOMESTIC), - MON("priestess", S_HUMAN, LVL(10, 12, 10, 2, 0), G_NOGEN, - A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, - NO_ATTK), - SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0, - M1_HUMANOID | M1_OMNIVORE, - M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_FEMALE | M2_COLLECT, + M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE, 12, HI_DOMESTIC), MON("ranger", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN, A(ATTK(AT_WEAP, AD_PHYS, 1, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, diff --git a/src/mplayer.c b/src/mplayer.c index 80b995b5d..78f8f84f3 100644 --- a/src/mplayer.c +++ b/src/mplayer.c @@ -53,7 +53,8 @@ dev_name() for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { if (!is_mplayer(mtmp->data)) continue; - if (!strncmp(developers[i], (has_mname(mtmp)) ? MNAME(mtmp) : "", + if (!strncmp(developers[i], + (has_mgivenname(mtmp)) ? MGIVENNAME(mtmp) : "", strlen(developers[i]))) { match = TRUE; break; @@ -176,8 +177,7 @@ register boolean special; if (helm == HELM_OF_BRILLIANCE) helm = STRANGE_OBJECT; break; - case PM_CAVEMAN: - case PM_CAVEWOMAN: + case PM_CAVE_DWELLER: if (rn2(4)) weapon = MACE; else if (rn2(2)) @@ -208,8 +208,7 @@ register boolean special; if (rn2(2)) shield = STRANGE_OBJECT; break; - case PM_PRIEST: - case PM_PRIESTESS: + case PM_CLERIC: if (rn2(2)) weapon = MACE; if (rn2(2)) diff --git a/src/mthrowu.c b/src/mthrowu.c index c5064e37d..bba8fd939 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -345,7 +345,8 @@ boolean verbose; /* give message(s) even when you can't see what happened */ if (vis) { if (otmp->otyp == EGG) pline("Splat! %s is hit with %s egg!", Monnam(mtmp), - otmp->known ? an(mons[otmp->corpsenm].mname) : "an"); + otmp->known ? an(mons[otmp->corpsenm].pmnames[NEUTRAL]) + : "an"); else hit(distant_name(otmp, mshot_xname), mtmp, exclam(damage)); } else if (verbose && !g.mtarget) diff --git a/src/muse.c b/src/muse.c index a9fadee8b..91aaa9c8e 100644 --- a/src/muse.c +++ b/src/muse.c @@ -241,7 +241,7 @@ struct obj *otmp; saverole = Role_switch; if (!vismon) { otmp->bknown = 0; - if (Role_if(PM_PRIEST)) + if (Role_if(PM_CLERIC)) Role_switch = 0; } Strcpy(onambuf, singular(otmp, doname)); @@ -2889,7 +2889,9 @@ struct monst *mon; return (ptr->mcolor == CLR_GREEN || ptr->mcolor == CLR_BRIGHT_GREEN); #endif /* approximation */ - if (strstri(ptr->mname, "green")) + if (strstri(ptr->pmnames[NEUTRAL], "green") + || (ptr->pmnames[MALE] && strstri(ptr->pmnames[MALE], "green")) + || (ptr->pmnames[FEMALE] && strstri(ptr->pmnames[FEMALE], "green"))) return TRUE; switch (monsndx(ptr)) { case PM_FOREST_CENTAUR: diff --git a/src/music.c b/src/music.c index dd84b98c6..3dc60efc3 100644 --- a/src/music.c +++ b/src/music.c @@ -387,7 +387,7 @@ int force; You("destroy %s!", mtmp->mtame ? x_monnam(mtmp, ARTICLE_THE, "poor", - has_mname(mtmp) + has_mgivenname(mtmp) ? SUPPRESS_SADDLE : 0, FALSE) : mon_nam(mtmp)); diff --git a/src/nhlobj.c b/src/nhlobj.c index ca9567d8d..03e07401d 100644 --- a/src/nhlobj.c +++ b/src/nhlobj.c @@ -318,7 +318,8 @@ lua_State *L; if (obj->corpsenm != NON_PM && (obj->otyp == TIN || obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == FIGURINE || obj->otyp == STATUE)) - nhl_add_table_entry_str(L, "corpsenm_name", mons[obj->corpsenm].mname); + nhl_add_table_entry_str(L, "corpsenm_name", + mons[obj->corpsenm].pmnames[NEUTRAL]); /* TODO: leashmon, fromsink, novelidx, record_achieve_special */ nhl_add_table_entry_int(L, "usecount", obj->usecount); /* TODO: spestudied */ diff --git a/src/objnam.c b/src/objnam.c index a99523ef5..2330fa4dc 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -24,7 +24,7 @@ struct _readobjnam_data { int eroded, eroded2, erodeproof, locked, unlocked, broken, real, fake; int halfeaten, mntmp, contents; int islit, unlabeled, ishistoric, isdiluted, trapped; - int tmp, tinv, tvariety; + int tmp, tinv, tvariety, mgend; int wetness, gsize; int ftype; struct obj *otmp; @@ -471,7 +471,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ obj->known = 0; if (!Blind && !g.distantname) obj->dknown = 1; - if (Role_if(PM_PRIEST)) + if (Role_if(PM_CLERIC)) obj->bknown = 1; /* actively avoid set_bknown(); * we mustn't call update_inventory() now because * it would call xname() (via doname()) recursively @@ -528,8 +528,8 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ char anbuf[10]; /* [4] would be enough: 'a','n',' ','\0' */ Sprintf(eos(buf), " of %s%s", - just_an(anbuf, mons[omndx].mname), - mons[omndx].mname); + just_an(anbuf, mons[omndx].pmnames[NEUTRAL]), + mons[omndx].pmnames[NEUTRAL]); } else if (is_wet_towel(obj)) { if (wizard) Sprintf(eos(buf), " (%d)", obj->spe); @@ -617,6 +617,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ case ROCK_CLASS: if (typ == STATUE && omndx != NON_PM) { char anbuf[10]; + int mgend = (obj->spe & STATUE_FEMALE) ? FEMALE : MALE; Sprintf(buf, "%s%s of %s%s", (Role_if(PM_ARCHEOLOGIST) && (obj->spe & STATUE_HISTORIC)) @@ -627,8 +628,8 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ ? "" : the_unique_pm(&mons[omndx]) ? "the " - : just_an(anbuf, mons[omndx].mname), - mons[omndx].mname); + : just_an(anbuf, pmname(&mons[omndx], mgend)), + pmname(&mons[omndx], mgend)); } else Strcpy(buf, actualn); break; @@ -822,7 +823,7 @@ struct obj *obj; bufp = distant_name(&bareobj, xname); /* xname(&bareobj) */ if (!strncmp(bufp, "uncursed ", 9)) - bufp += 9; /* Role_if(PM_PRIEST) */ + bufp += 9; /* Role_if(PM_CLERIC) */ objects[otyp].oc_uname = saveobcls.oc_uname; objects[otyp].oc_name_known = saveobcls.oc_name_known; @@ -878,7 +879,7 @@ struct permonst *ptr; /* high priest is unique if it includes "of ", otherwise not (caller needs to handle the 1st possibility; we assume the 2nd); worm tail should be irrelevant but is included for completeness */ - if (ptr == &mons[PM_HIGH_PRIEST] || ptr == &mons[PM_LONG_WORM_TAIL]) + if (ptr == &mons[PM_HIGH_CLERIC] || ptr == &mons[PM_LONG_WORM_TAIL]) uniq = FALSE; /* Wizard no longer needs this; he's flagged as unique these days */ if (ptr == &mons[PM_WIZARD_OF_YENDOR]) @@ -1062,7 +1063,7 @@ unsigned doname_flags; #endif && obj->otyp != FAKE_AMULET_OF_YENDOR && obj->otyp != AMULET_OF_YENDOR - && !Role_if(PM_PRIEST))) + && !Role_if(PM_CLERIC))) Strcat(prefix, "uncursed "); } @@ -1200,7 +1201,7 @@ unsigned doname_flags; #endif if (omndx >= LOW_PM && (known || (g.mvitals[omndx].mvflags & MV_KNOWS_EGG))) { - Strcat(prefix, mons[omndx].mname); + Strcat(prefix, mons[omndx].pmnames[NEUTRAL]); Strcat(prefix, " "); if (obj->spe == 1) Strcat(bp, " (laid by you)"); @@ -1433,21 +1434,21 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0, possessive = FALSE, glob = (otmp->otyp != CORPSE && otmp->globby); - const char *mname; + const char *mnam; if (glob) { - mname = OBJ_NAME(objects[otmp->otyp]); /* "glob of " */ + mnam = OBJ_NAME(objects[otmp->otyp]); /* "glob of " */ } else if (omndx == NON_PM) { /* paranoia */ - mname = "thing"; + mnam = "thing"; /* [Possible enhancement: check whether corpse has monster traits attached in order to use priestname() for priests and minions.] */ - } else if (omndx == PM_ALIGNED_PRIEST) { + } else if (omndx == PM_ALIGNED_CLERIC) { /* avoid "aligned priest"; it just exposes internal details */ - mname = "priest"; + mnam = "priest"; } else { - mname = mons[omndx].mname; + mnam = mons[omndx].pmnames[NEUTRAL]; if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) { - mname = s_suffix(mname); + mnam = s_suffix(mnam); possessive = TRUE; /* don't precede personal name like "Medusa" with an article */ if (type_is_pname(&mons[omndx])) @@ -1473,13 +1474,13 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ if (!adjective || !*adjective) { /* normal case: newt corpse */ - Strcat(nambuf, mname); + 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", mname, adjective); + Sprintf(eos(nambuf), "%s %s", mnam, adjective); else /* cursed partly eaten troll corpse */ - Sprintf(eos(nambuf), "%s %s", adjective, mname); + Sprintf(eos(nambuf), "%s %s", adjective, mnam); /* in case adjective has a trailing space, squeeze it out */ mungspaces(nambuf); /* doname() might include a count in the adjective argument; @@ -3270,6 +3271,7 @@ struct _readobjnam_data *d; = d->ishistoric = d->isdiluted = d->trapped = d->locked = d->unlocked = d->broken = d->real = d->fake = 0; d->tvariety = RANDOM_TIN; + d->mgend = MALE; d->mntmp = NON_PM; d->contents = UNDEFINED; d->oclass = 0; @@ -3597,7 +3599,8 @@ struct _readobjnam_data *d; || !strcmpi(d->bp, "globs") || !BSTRCMPI(d->bp, d->bp + i - 6, " globs") || (d->p = strstri(d->bp, "glob of ")) != 0 || (d->p = strstri(d->bp, "globs of ")) != 0) { - d->mntmp = name_to_mon(!d->p ? d->bp : (strstri(d->p, " of ") + 4)); + d->mntmp = name_to_mon(!d->p ? d->bp + : (strstri(d->p, " of ") + 4), (int *) 0); /* if we didn't recognize monster type, pick a valid one at random */ if (d->mntmp == NON_PM) d->mntmp = rn1(PM_BLACK_PUDDING - PM_GRAY_OOZE, PM_GRAY_OOZE); @@ -3605,7 +3608,7 @@ struct _readobjnam_data *d; variant (grey ooze) or player used inverted syntax ( glob); if player has given a valid monster type but not valid glob type, object name lookup won't find it and wish attempt will fail */ - Sprintf(d->globbuf, "glob of %s", mons[d->mntmp].mname); + Sprintf(d->globbuf, "glob of %s", mons[d->mntmp].pmnames[NEUTRAL]); d->bp = d->globbuf; d->mntmp = NON_PM; /* not useful for "glob of " object lookup */ d->cnt = 0; /* globs don't stack */ @@ -3631,12 +3634,13 @@ struct _readobjnam_data *d; } else { d->tmp = tin_variety_txt(d->p + 7, &d->tinv); d->tvariety = d->tinv; - d->mntmp = name_to_mon(d->p + 7 + d->tmp); + d->mntmp = name_to_mon(d->p + 7 + d->tmp, &d->mgend); } d->typ = TIN; return 2; /*goto typfnd;*/ } else if ((d->p = strstri(d->bp, " of ")) != 0 - && (d->mntmp = name_to_mon(d->p + 4)) >= LOW_PM) + && (d->mntmp = name_to_mon(d->p + 4, + &d->mgend)) >= LOW_PM) *d->p = 0; } } @@ -3649,7 +3653,8 @@ struct _readobjnam_data *d; const char *rest = 0; if (d->mntmp < LOW_PM && strlen(d->bp) > 2 - && (d->mntmp = name_to_monplus(d->bp, &rest)) >= LOW_PM) { + && (d->mntmp = name_to_monplus(d->bp, &rest, + &d->mgend)) >= LOW_PM) { char *obp = d->bp; /* 'rest' is a pointer past the matching portion; if that was @@ -4280,8 +4285,11 @@ struct obj *no_wish; case LARGE_BOX: case HEAVY_IRON_BALL: case IRON_CHAIN: + break; case STATUE: /* otmp->cobj already done in mksobj() */ + if (d.mgend) + d.otmp->spe |= STATUE_FEMALE; break; #ifdef MAIL_STRUCTURES /* scroll of mail: 0: delivered in-game via external event (or randomly @@ -4355,7 +4363,7 @@ struct obj *no_wish; d.otmp->corpsenm = d.mntmp; if (Has_contents(d.otmp) && verysmall(&mons[d.mntmp])) delete_contents(d.otmp); /* no spellbook */ - d.otmp->spe = d.ishistoric ? STATUE_HISTORIC : 0; + d.otmp->spe |= d.ishistoric ? STATUE_HISTORIC : 0; break; case SCALE_MAIL: /* Dragon mail - depends on the order of objects & dragons. */ diff --git a/src/options.c b/src/options.c index ed0101c4b..d58c4e1f0 100644 --- a/src/options.c +++ b/src/options.c @@ -7376,13 +7376,13 @@ struct fruit *replace_fruit; || !strncmp(g.pl_fruit, "partly eaten ", 13) || (!strncmp(g.pl_fruit, "tin of ", 7) && (!strcmp(g.pl_fruit + 7, "spinach") - || name_to_mon(g.pl_fruit + 7) >= LOW_PM)) + || name_to_mon(g.pl_fruit + 7, (int *) 0) >= LOW_PM)) || !strcmp(g.pl_fruit, "empty tin") || (!strcmp(g.pl_fruit, "glob") || (globpfx > 0 && !strcmp("glob", &g.pl_fruit[globpfx]))) || ((str_end_is(g.pl_fruit, " corpse") || str_end_is(g.pl_fruit, " egg")) - && name_to_mon(g.pl_fruit) >= LOW_PM)) { + && name_to_mon(g.pl_fruit, (int *) 0) >= LOW_PM)) { Strcpy(buf, g.pl_fruit); Strcpy(g.pl_fruit, "candied "); nmcpy(g.pl_fruit + 8, buf, PL_FSIZ - 8); diff --git a/src/pager.c b/src/pager.c index b573bb4aa..197cd4b3c 100644 --- a/src/pager.c +++ b/src/pager.c @@ -89,7 +89,7 @@ char *outbuf; Sprintf(outbuf, "%s%s%s called %s", /* being blinded may hide invisibility from self */ (Invis && (senseself() || !Blind)) ? "invisible " : "", race, - mons[u.umonnum].mname, g.plname); + pmname(&mons[u.umonnum], Ugender), g.plname); if (u.usteed) Sprintf(eos(outbuf), ", mounted on %s", y_monnam(u.usteed)); if (u.uundetected || (Upolyd && U_AP_TYPE)) @@ -167,7 +167,7 @@ char *outbuf; } else if (M_AP_TYPE(mon) == M_AP_MONSTER) { if (altmon) Sprintf(outbuf, ", masquerading as %s", - an(mons[mon->mappearance].mname)); + an(pmname(&mons[mon->mappearance], Mgender(mon)))); } else if (isyou ? u.uundetected : mon->mundetected) { Strcpy(outbuf, ", hiding"); if (hides_under(mon->data)) { @@ -403,7 +403,7 @@ int x, y; : (mW & M2_ELF & m2) ? "elf" : (mW & M2_ORC & m2) ? "orc" : (mW & M2_DEMON & m2) ? "demon" - : mtmp->data->mname); + : pmname(mtmp->data, Mgender(mtmp))); Sprintf(eos(monbuf), "warned of %s", makeplural(whom)); } @@ -616,7 +616,7 @@ char *supplemental_name; * user_typed_name and picked name. */ if (pm != (struct permonst *) 0 && !user_typed_name) - dbase_str = strcpy(newstr, pm->mname); + dbase_str = strcpy(newstr, pm->pmnames[NEUTRAL]); else dbase_str = strcpy(newstr, inp); (void) lcase(dbase_str); @@ -893,15 +893,14 @@ struct permonst **for_supplement; hallucinate = (Hallucination && !g.program_state.gameover); const char *x_str; nhsym tmpsym; + unsigned glyphmod[NUM_GLYPHMOD]; gobbledygook[0] = '\0'; /* no hallucinatory liquid (yet) */ if (looked) { - int oc; - unsigned os; - glyph = glyph_at(cc.x, cc.y); /* Convert glyph at selected position to a symbol for use below. */ - (void) mapglyph(glyph, &sym, &oc, &os, cc.x, cc.y, 0); + map_glyphmod(cc.x, cc.y, glyph, 0, glyphmod); + sym = glyphmod[GM_TTYCHAR]; Sprintf(prefix, "%s ", encglyph(glyph)); } else @@ -1154,12 +1153,9 @@ struct permonst **for_supplement; break; case SYM_PET_OVERRIDE + SYM_OFF_X: if (looked) { - int oc = 0; - unsigned os = 0; - /* convert to symbol without override in effect */ - (void) mapglyph(glyph, &sym, &oc, &os, - cc.x, cc.y, MG_FLAG_NOOVERRIDE); + map_glyphmod(cc.x, cc.y, glyph, MG_FLAG_NOOVERRIDE, glyphmod); + sym = (int) glyphmod[GM_TTYCHAR]; goto check_monsters; } break; diff --git a/src/pickup.c b/src/pickup.c index a8d7f3d88..f271d4c17 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -484,7 +484,7 @@ struct obj *obj; ? TRUE : FALSE) : TRUE; /* catchall: no filters specified, so accept */ - if (Role_if(PM_PRIEST) && !obj->bknown) + if (Role_if(PM_CLERIC) && !obj->bknown) set_bknown(obj, 1); /* diff --git a/src/polyself.c b/src/polyself.c index ccc076076..3d898ec66 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -263,10 +263,13 @@ change_sex() : g.urole.malenum; if (!already_polyd) { u.umonnum = u.umonster; - } else if (u.umonnum == PM_SUCCUBUS || u.umonnum == PM_INCUBUS) { + } else if (u.umonnum == PM_AMOROUS_DEMON) { flags.female = !flags.female; - /* change monster type to match new sex */ +#if 0 + /* change monster type to match new sex; disabled with PM_AMOROUS_DEMON */ + u.umonnum = (u.umonnum == PM_SUCCUBUS) ? PM_INCUBUS : PM_SUCCUBUS; +#endif set_uasmon(); } } @@ -394,7 +397,7 @@ polyself(psflags) int psflags; { char buf[BUFSZ] = DUMMY; - int old_light, new_light, mntmp, class, tryct; + int old_light, new_light, mntmp, class, tryct, gvariant = NEUTRAL; boolean forcecontrol = (psflags == 1), monsterpoly = (psflags == 2), formrevert = (psflags == 3), @@ -449,7 +452,7 @@ int psflags; continue; /* end do-while(--tryct > 0) loop */ } class = 0; - mntmp = name_to_mon(buf); + mntmp = name_to_mon(buf, &gvariant); if (mntmp < LOW_PM) { by_class: class = name_to_monclass(buf, &mntmp); @@ -489,7 +492,7 @@ int psflags; 0 and trigger thats_enough_tries message */ ++tryct; } - pm_name = mons[mntmp].mname; + pm_name = pmname(&mons[mntmp], flags.female ? FEMALE : MALE); if (the_unique_pm(&mons[mntmp])) pm_name = the(pm_name); else if (!type_is_pname(&mons[mntmp])) @@ -552,7 +555,7 @@ int psflags; } else if (isvamp) { do_vampyr: if (mntmp < LOW_PM || (mons[mntmp].geno & G_UNIQ)) { - mntmp = (g.youmonst.data == &mons[PM_VAMPIRE_LORD] && !rn2(10)) + mntmp = (g.youmonst.data == &mons[PM_VAMPIRE_LEADER] && !rn2(10)) ? PM_WOLF : !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; if (g.youmonst.cham >= LOW_PM @@ -560,7 +563,8 @@ int psflags; mntmp = g.youmonst.cham; } if (controllable_poly) { - Sprintf(buf, "Become %s?", an(mons[mntmp].mname)); + Sprintf(buf, "Become %s?", + an(pmname(&mons[mntmp], gvariant))); if (yn(buf) != 'y') return; } @@ -622,7 +626,8 @@ int mntmp; int mlvl; if (g.mvitals[mntmp].mvflags & G_GENOD) { /* allow G_EXTINCT */ - You_feel("rather %s-ish.", mons[mntmp].mname); + You_feel("rather %s-ish.", + pmname(&mons[mntmp], flags.female ? FEMALE : MALE)); exercise(A_WIS, TRUE); return 0; } @@ -676,7 +681,7 @@ int mntmp; Strcat(buf, (is_male(&mons[mntmp]) || is_female(&mons[mntmp])) ? "" : flags.female ? "female " : "male "); } - Strcat(buf, mons[mntmp].mname); + Strcat(buf, pmname(&mons[mntmp], flags.female ? FEMALE : MALE)); You("%s %s!", (u.umonnum != mntmp) ? "turn into" : "feel like", an(buf)); if (Stoned && poly_when_stoned(&mons[mntmp])) { @@ -774,7 +779,8 @@ int mntmp; if (touch_petrifies(u.usteed->data) && !Stone_resistance && rnl(3)) { pline("%s touch %s.", no_longer_petrify_resistant, mon_nam(u.usteed)); - Sprintf(buf, "riding %s", an(u.usteed->data->mname)); + Sprintf(buf, "riding %s", + an(pmname(u.usteed->data, Mgender(u.usteed)))); instapetrify(buf); } if (!can_ride(u.usteed)) @@ -1576,7 +1582,8 @@ dopoly() if (is_vampire(g.youmonst.data) || is_vampshifter(&g.youmonst)) { polyself(2); if (savedat != g.youmonst.data) { - You("transform into %s.", an(g.youmonst.data->mname)); + You("transform into %s.", + an(pmname(g.youmonst.data, Ugender))); newsym(u.ux, u.uy); } } @@ -1764,7 +1771,7 @@ int part; if ((part == HAND || part == HANDED) && (humanoid(mptr) && attacktype(mptr, AT_CLAW) && !index(not_claws, mptr->mlet) && mptr != &mons[PM_STONE_GOLEM] - && mptr != &mons[PM_INCUBUS] && mptr != &mons[PM_SUCCUBUS])) + && mptr != &mons[PM_AMOROUS_DEMON])) return (part == HAND) ? "claw" : "clawed"; if ((mptr == &mons[PM_MUMAK] || mptr == &mons[PM_MASTODON]) && part == NOSE) @@ -1926,7 +1933,7 @@ polysense() warnidx = PM_SHRIEKER; break; case PM_VAMPIRE: - case PM_VAMPIRE_LORD: + case PM_VAMPIRE_LEADER: g.context.warntype.polyd = M2_HUMAN | M2_ELF; HWarn_of_mon |= FROMRACE; return; diff --git a/src/potion.c b/src/potion.c index bf2f2becd..4d3265c0d 100644 --- a/src/potion.c +++ b/src/potion.c @@ -660,7 +660,7 @@ register struct obj *otmp; exercise(A_CON, FALSE); if (u.ulycn >= LOW_PM) { Your("affinity to %s disappears!", - makeplural(mons[u.ulycn].mname)); + makeplural(mons[u.ulycn].pmnames[NEUTRAL])); if (g.youmonst.data == &mons[u.ulycn]) you_unwere(FALSE); set_ulycn(NON_PM); /* cure lycanthropy */ diff --git a/src/pray.c b/src/pray.c index f6ce19b1a..fa95503ae 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1979,7 +1979,7 @@ doturn() const char *Gname; int once, range, xlev; - if (!Role_if(PM_PRIEST) && !Role_if(PM_KNIGHT)) { + if (!Role_if(PM_CLERIC) && !Role_if(PM_KNIGHT)) { /* Try to use the "turn undead" spell. * * This used to be based on whether hero knows the name of the diff --git a/src/priest.c b/src/priest.c index 3b0c6c1e5..354cbc5a4 100644 --- a/src/priest.c +++ b/src/priest.c @@ -233,7 +233,7 @@ boolean sanctum; /* is it the seat of the high priest? */ struct obj *otmp; int cnt; int px = 0, py = 0, i, si = rn2(8); - struct permonst *prim = &mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST]; + struct permonst *prim = &mons[sanctum ? PM_HIGH_CLERIC : PM_ALIGNED_CLERIC]; for (i = 0; i < 8; i++) { px = sx + xdir[(i+si) % 8]; @@ -310,10 +310,11 @@ register struct monst *mon; char *pname; /* caller-supplied output buffer */ { boolean do_hallu = Hallucination, - aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST], - high_priest = mon->data == &mons[PM_HIGH_PRIEST]; + aligned_priest = mon->data == &mons[PM_ALIGNED_CLERIC], + high_priest = mon->data == &mons[PM_HIGH_CLERIC]; char whatcode = '\0'; - const char *what = do_hallu ? rndmonnam(&whatcode) : mon->data->mname; + const char *what = do_hallu ? rndmonnam(&whatcode) + : pmname(mon->data, Mgender(mon)); if (!mon->ispriest && !mon->isminion) /* should never happen... */ return strcpy(pname, what); /* caller must be confused */ @@ -416,7 +417,7 @@ int roomno; epri_p = EPRI(priest); shrined = has_shrine(priest); - sanctum = (priest->data == &mons[PM_HIGH_PRIEST] + sanctum = (priest->data == &mons[PM_HIGH_CLERIC] && (Is_sanctum(&u.uz) || In_endgame(&u.uz))); can_speak = (priest->mcanmove && !priest->msleeping); if (can_speak && !Deaf && g.moves >= epri_p->intone_time) { @@ -668,7 +669,7 @@ boolean peaceful; register boolean coaligned = (u.ualign.type == alignment); #if 0 /* this was due to permonst's pxlth field which is now gone */ - if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL]) + if (ptr != &mons[PM_ALIGNED_CLERIC] && ptr != &mons[PM_ANGEL]) return (struct monst *) 0; #endif @@ -697,7 +698,7 @@ register struct monst *roamer; { if (!roamer->isminion) return; - if (roamer->data != &mons[PM_ALIGNED_PRIEST] + if (roamer->data != &mons[PM_ALIGNED_CLERIC] && roamer->data != &mons[PM_ANGEL]) return; diff --git a/src/questpgr.c b/src/questpgr.c index bfae12d0c..2a52de0f1 100644 --- a/src/questpgr.c +++ b/src/questpgr.c @@ -52,7 +52,7 @@ ldrname() int i = g.urole.ldrnum; Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ", - mons[i].mname); + mons[i].pmnames[NEUTRAL]); return g.nambuf; } @@ -129,7 +129,7 @@ neminame() int i = g.urole.neminum; Sprintf(g.nambuf, "%s%s", type_is_pname(&mons[i]) ? "" : "the ", - mons[i].mname); + mons[i].pmnames[NEUTRAL]); return g.nambuf; } @@ -138,7 +138,7 @@ guardname() /* return your role leader's guard monster name */ { int i = g.urole.guardnum; - return mons[i].mname; + return mons[i].pmnames[NEUTRAL]; } static const char * diff --git a/src/read.c b/src/read.c index 30809567e..e32dcdfbc 100644 --- a/src/read.c +++ b/src/read.c @@ -2059,7 +2059,7 @@ do_class_genocide() return; class = name_to_monclass(buf, (int *) 0); - if (class == 0 && (i = name_to_mon(buf)) != NON_PM) + if (class == 0 && (i = name_to_mon(buf, (int *) 0)) != NON_PM) class = mons[i].mlet; immunecnt = gonecnt = goodcnt = 0; for (i = LOW_PM; i < NUMMONS; i++) { @@ -2101,7 +2101,7 @@ do_class_genocide() if (mons[i].mlet == class) { char nam[BUFSZ]; - Strcpy(nam, makeplural(mons[i].mname)); + Strcpy(nam, makeplural(mons[i].pmnames[NEUTRAL])); /* Although "genus" is Latin for race, the hero benefits * from both race and role; thus genocide affects either. */ @@ -2165,12 +2165,12 @@ do_class_genocide() named = type_is_pname(&mons[i]) ? TRUE : FALSE; uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE; /* one special case */ - if (i == PM_HIGH_PRIEST) + if (i == PM_HIGH_CLERIC) uniq = FALSE; You("aren't permitted to genocide %s%s.", (uniq && !named) ? "the " : "", - (uniq || named) ? mons[i].mname : nam); + (uniq || named) ? mons[i].pmnames[NEUTRAL] : nam); } } } @@ -2205,7 +2205,7 @@ int how; if (how & PLAYER) { mndx = u.umonster; /* non-polymorphed mon num */ ptr = &mons[mndx]; - Strcpy(buf, ptr->mname); + Strcpy(buf, pmname(ptr, Ugender)); killplayer++; } else { for (i = 0;; i++) { @@ -2230,7 +2230,7 @@ int how; return; } - mndx = name_to_mon(buf); + mndx = name_to_mon(buf, (int *) 0); if (mndx == NON_PM || (g.mvitals[mndx].mvflags & G_GENOD)) { pline("Such creatures %s exist in this world.", (mndx == NON_PM) ? "do not" : "no longer"); @@ -2276,15 +2276,15 @@ int how; which = "all "; if (Hallucination) { if (Upolyd) - Strcpy(buf, g.youmonst.data->mname); + Strcpy(buf, pmname(g.youmonst.data, flags.female ? FEMALE : MALE)); else { Strcpy(buf, (flags.female && g.urole.name.f) ? g.urole.name.f : g.urole.name.m); buf[0] = lowc(buf[0]); } } else { - Strcpy(buf, ptr->mname); /* make sure we have standard singular */ - if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST]) + Strcpy(buf, ptr->pmnames[NEUTRAL]); /* make sure we have standard singular */ + if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_CLERIC]) which = !type_is_pname(ptr) ? "the " : ""; } if (how & REALLY) { @@ -2425,7 +2425,7 @@ struct obj *from_obj; { /* SHOPKEEPERS can be revived now */ if (*mtype == PM_GUARD || (*mtype == PM_SHOPKEEPER && !revival) - || *mtype == PM_HIGH_PRIEST || *mtype == PM_ALIGNED_PRIEST + || *mtype == PM_HIGH_CLERIC || *mtype == PM_ALIGNED_CLERIC || *mtype == PM_ANGEL) { *mtype = PM_HUMAN_ZOMBIE; return TRUE; @@ -2447,6 +2447,7 @@ create_particular_parse(str, d) char *str; struct _create_particular_data *d; { + int gender_name_var = NEUTRAL; char *bufp = str; char *tmpp; @@ -2516,7 +2517,13 @@ struct _create_particular_data *d; d->randmonst = TRUE; return TRUE; } - d->which = name_to_mon(bufp); + d->which = name_to_mon(bufp, &gender_name_var); + /* + * With the introduction of male and female monster names + * in 3.7, preserve that detail. + */ + if (gender_name_var != NEUTRAL) + d->fem = gender_name_var; if (d->which >= LOW_PM) return TRUE; /* got one */ d->monclass = name_to_monclass(bufp, &d->which); @@ -2556,7 +2563,8 @@ struct _create_particular_data *d; char buf[BUFSZ]; Sprintf(buf, "Creating %s instead; force %s?", - mons[d->which].mname, mons[firstchoice].mname); + mons[d->which].pmnames[NEUTRAL], + mons[firstchoice].pmnames[NEUTRAL]); if (yn(buf) == 'y') d->which = firstchoice; } diff --git a/src/restore.c b/src/restore.c index 528d76a04..935c54630 100644 --- a/src/restore.c +++ b/src/restore.c @@ -333,13 +333,13 @@ struct monst *mtmp; if (mtmp->mextra) { mtmp->mextra = newmextra(); - /* mname - monster's name */ + /* mgivenname - monster's name */ if (nhfp->structlevel) mread(nhfp->fd, (genericptr_t) &buflen, sizeof(buflen)); if (buflen > 0) { /* includes terminating '\0' */ - new_mname(mtmp, buflen); + new_mgivenname(mtmp, buflen); if (nhfp->structlevel) - mread(nhfp->fd, (genericptr_t) MNAME(mtmp), buflen); + mread(nhfp->fd, (genericptr_t) MGIVENNAME(mtmp), buflen); } /* egd - vault guard */ if (nhfp->structlevel) diff --git a/src/role.c b/src/role.c index 98854f3dc..fe30684a1 100644 --- a/src/role.c +++ b/src/role.c @@ -123,8 +123,8 @@ const struct Role roles[NUM_ROLES+1] = { "Cav", "the Caves of the Ancestors", "the Dragon's Lair", - PM_CAVEMAN, - PM_CAVEWOMAN, + PM_CAVE_DWELLER, + NON_PM, PM_LITTLE_DOG, PM_SHAMAN_KARNOV, PM_NEANDERTHAL, @@ -289,8 +289,8 @@ const struct Role roles[NUM_ROLES+1] = { "Pri", "the Great Temple", "the Temple of Nalzok", - PM_PRIEST, - PM_PRIESTESS, + PM_CLERIC, + NON_PM, NON_PM, PM_ARCH_PRIEST, PM_ACOLYTE, diff --git a/src/save.c b/src/save.c index f463e8939..fe6001bbf 100644 --- a/src/save.c +++ b/src/save.c @@ -814,12 +814,12 @@ struct monst *mtmp; bwrite(nhfp->fd, (genericptr_t) mtmp, buflen); } if (mtmp->mextra) { - buflen = MNAME(mtmp) ? (int) strlen(MNAME(mtmp)) + 1 : 0; + buflen = MGIVENNAME(mtmp) ? (int) strlen(MGIVENNAME(mtmp)) + 1 : 0; if (nhfp->structlevel) bwrite(nhfp->fd, (genericptr_t) &buflen, sizeof buflen); if (buflen > 0) { if (nhfp->structlevel) - bwrite(nhfp->fd, (genericptr_t) MNAME(mtmp), buflen); + bwrite(nhfp->fd, (genericptr_t) MGIVENNAME(mtmp), buflen); } buflen = EGD(mtmp) ? (int) sizeof (struct egd) : 0; if (nhfp->structlevel) diff --git a/src/shk.c b/src/shk.c index 2d1eb5b36..e12937de2 100644 --- a/src/shk.c +++ b/src/shk.c @@ -839,8 +839,8 @@ char rmno; (int) rmno, (int) g.rooms[rmno - ROOMOFFSET].rtype, shkp->mnum, - /* [real shopkeeper name is kept in ESHK, not MNAME] */ - has_mname(shkp) ? MNAME(shkp) : "anonymous"); + /* [real shopkeeper name is kept in ESHK, not MGIVENNAME] */ + has_mgivenname(shkp) ? MGIVENNAME(shkp) : "anonymous"); /* not sure if this is appropriate, because it does nothing to correct the underlying g.rooms[].resident issue but... */ return (struct monst *) 0; diff --git a/src/sounds.c b/src/sounds.c index 75b0de790..6a4409b21 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -184,8 +184,8 @@ dosounds() continue; if (is_mercenary(mtmp->data) #if 0 /* don't bother excluding these */ - && !strstri(mtmp->data->mname, "watch") - && !strstri(mtmp->data->mname, "guard") + && !strstri(mtmp->data->pmnames[NEUTRAL], "watch") + && !strstri(mtmp->data->pmnames[NEUTRAL], "guard") #endif && mon_in_room(mtmp, BARRACKS) /* sleeping implies not-yet-disturbed (usually) */ @@ -634,7 +634,7 @@ register struct monst *mtmp; * night */ boolean isnight = night(); boolean kindred = (Upolyd && (u.umonnum == PM_VAMPIRE - || u.umonnum == PM_VAMPIRE_LORD)); + || u.umonnum == PM_VAMPIRE_LEADER)); boolean nightchild = (Upolyd && (u.umonnum == PM_WOLF || u.umonnum == PM_WINTER_WOLF || u.umonnum == PM_WINTER_WOLF_CUB)); @@ -696,7 +696,8 @@ register struct monst *mtmp; verbl_msg = verbuf; } else if (vampindex == 1) { Sprintf(verbuf, vampmsg[vampindex], - Upolyd ? an(mons[u.umonnum].mname) + Upolyd ? an(pmname(&mons[u.umonnum], + flags.female ? FEMALE : MALE)) : an(racenoun)); verbl_msg = verbuf; } else @@ -1086,7 +1087,8 @@ dochat() struct obj *otmp; if (is_silent(g.youmonst.data)) { - pline("As %s, you cannot speak.", an(g.youmonst.data->mname)); + pline("As %s, you cannot speak.", + an(pmname(g.youmonst.data, flags.female ? FEMALE : MALE))); return 0; } if (Strangled) { diff --git a/src/sp_lev.c b/src/sp_lev.c index 6d64c182c..859945bbc 100755 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -1965,12 +1965,12 @@ struct mkroom *croom; break; case M_AP_MONSTER: { - int mndx; + int mndx, gender_name_var = NEUTRAL; if (!strcmpi(m->appear_as.str, "random")) mndx = select_newcham_form(mtmp); else - mndx = name_to_mon(m->appear_as.str); + mndx = name_to_mon(m->appear_as.str, &gender_name_var); if (mndx == NON_PM || (is_vampshifter(mtmp) && !validvamp(mtmp, &mndx, S_HUMAN))) { @@ -1998,6 +1998,8 @@ struct mkroom *croom; struct permonst *olddata = mtmp->data; mgender_from_permonst(mtmp, mdat); + if (gender_name_var != NEUTRAL) + mtmp->female = gender_name_var; set_mon_data(mtmp, mdat); if (emits_light(olddata) != emits_light(mtmp->data)) { /* used to give light, now doesn't, or vice versa, @@ -3016,7 +3018,11 @@ const char *s; int i; for (i = LOW_PM; i < NUMMONS; i++) - if (!strcmpi(mons[i].mname, s)) + if (!strcmpi(mons[i].pmnames[NEUTRAL], s) + || (mons[i].pmnames[MALE] != 0 + && !strcmpi(mons[i].pmnames[MALE], s)) + || (mons[i].pmnames[FEMALE] != 0 + && !strcmpi(mons[i].pmnames[FEMALE], s))) return i; return NON_PM; } @@ -3428,7 +3434,11 @@ lua_State *L; pm = mkclass(def_char_to_monclass(*montype), G_NOGEN|G_IGNORE); } else { for (i = LOW_PM; i < NUMMONS; i++) - if (!strcmpi(mons[i].mname, montype)) { + 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))) { pm = &mons[i]; break; } diff --git a/src/steal.c b/src/steal.c index 7ce86a9ce..790a08128 100644 --- a/src/steal.c +++ b/src/steal.c @@ -508,11 +508,11 @@ register struct obj *otmp; if (!otmp) { impossible("monster (%s) taking or picking up nothing?", - mtmp->data->mname); + pmname(mtmp->data, Mgender(mtmp))); return 1; } else if (otmp == uball || otmp == uchain) { impossible("monster (%s) taking or picking up attached %s (%s)?", - mtmp->data->mname, + pmname(mtmp->data, Mgender(mtmp)), (otmp == uchain) ? "chain" : "ball", simpleonames(otmp)); return 0; } diff --git a/src/steed.c b/src/steed.c index e380a4c5c..44dd33e9f 100644 --- a/src/steed.c +++ b/src/steed.c @@ -70,11 +70,12 @@ struct obj *otmp; You("touch %s.", mon_nam(mtmp)); if (!(poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM))) { - Sprintf(kbuf, "attempting to saddle %s", an(mtmp->data->mname)); + Sprintf(kbuf, "attempting to saddle %s", + an(pmname(mtmp->data, Mgender(mtmp)))); instapetrify(kbuf); } } - if (ptr == &mons[PM_INCUBUS] || ptr == &mons[PM_SUCCUBUS]) { + if (ptr == &mons[PM_AMOROUS_DEMON]) { pline("Shame on you!"); exercise(A_WIS, FALSE); return 1; @@ -275,7 +276,8 @@ boolean force; /* Quietly force this animal */ char kbuf[BUFSZ]; You("touch %s.", mon_nam(mtmp)); - Sprintf(kbuf, "attempting to ride %s", an(mtmp->data->mname)); + Sprintf(kbuf, "attempting to ride %s", + an(pmname(mtmp->data, Mgender(mtmp)))); instapetrify(kbuf); } if (!mtmp->mtame || mtmp->isminion) { @@ -535,9 +537,9 @@ int reason; /* Player was thrown off etc. */ You("can't. There isn't anywhere for you to stand."); return; } - if (!has_mname(mtmp)) { + if (!has_mgivenname(mtmp)) { pline("You've been through the dungeon on %s with no name.", - an(mtmp->data->mname)); + an(pmname(mtmp->data, Mgender(mtmp)))); if (Hallucination) pline("It felt good to get out of the rain."); } else diff --git a/src/teleport.c b/src/teleport.c index 7af0b7b15..88bd395f7 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -225,7 +225,8 @@ long entflags; if (allow_xx_yy && goodpos(xx, yy, &fakemon, entflags)) { return TRUE; /* 'cc' is set */ } else { - debugpline3("enexto(\"%s\",%d,%d) failed", mdat->mname, xx, yy); + debugpline3("enexto(\"%s\",%d,%d) failed", + mdat->pmnames[NEUTRAL], xx, yy); return FALSE; } } diff --git a/src/timeout.c b/src/timeout.c index 66e56d295..9f57fbf51 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -602,7 +602,8 @@ nh_timeout() } dealloc_killer(kptr); - if ((m_idx = name_to_mon(g.killer.name)) >= LOW_PM) { + if ((m_idx = name_to_mon(g.killer.name, + (int *) 0)) >= LOW_PM) { if (type_is_pname(&mons[m_idx])) { g.killer.format = KILLED_BY; } else if (mons[m_idx].geno & G_UNIQ) { @@ -706,7 +707,7 @@ nh_timeout() g.context.warntype.speciesidx = NON_PM; if (g.context.warntype.species) { You("are no longer warned about %s.", - makeplural(g.context.warntype.species->mname)); + makeplural(g.context.warntype.species->pmnames[NEUTRAL])); g.context.warntype.species = (struct permonst *) 0; } } @@ -1075,15 +1076,15 @@ slip_or_trip() if (!uarmf && otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && !Stone_resistance) { Sprintf(g.killer.name, "tripping over %s corpse", - an(mons[otmp->corpsenm].mname)); + an(mons[otmp->corpsenm].pmnames[NEUTRAL])); instapetrify(g.killer.name); } } else if (rn2(3) && is_ice(u.ux, u.uy)) { pline("%s %s%s on the ice.", u.usteed ? upstart(x_monnam(u.usteed, - (has_mname(u.usteed)) ? ARTICLE_NONE - : ARTICLE_THE, - (char *) 0, SUPPRESS_SADDLE, FALSE)) + (has_mgivenname(u.usteed)) ? ARTICLE_NONE + : ARTICLE_THE, + (char *) 0, SUPPRESS_SADDLE, FALSE)) : "You", rn2(2) ? "slip" : "slide", on_foot ? "" : "s"); } else { diff --git a/src/trap.c b/src/trap.c index 60bd409f8..6b20f2596 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2427,7 +2427,7 @@ unsigned trflags; u.usteed->mtrapseen |= (1 << (ttype - 1)); /* suppress article in various steed messages when using its name (which won't occur when hallucinating) */ - if (has_mname(u.usteed) && !Hallucination) + if (has_mgivenname(u.usteed) && !Hallucination) steed_article = ARTICLE_NONE; } @@ -3133,8 +3133,10 @@ const char *arg; if (uwep && uwep->otyp == CORPSE && touch_petrifies(&mons[uwep->corpsenm]) && !Stone_resistance) { - pline("%s touch the %s corpse.", arg, mons[uwep->corpsenm].mname); - Sprintf(kbuf, "%s corpse", an(mons[uwep->corpsenm].mname)); + pline("%s touch the %s corpse.", arg, + mons[uwep->corpsenm].pmnames[NEUTRAL]); + Sprintf(kbuf, "%s corpse", + an(mons[uwep->corpsenm].pmnames[NEUTRAL])); instapetrify(kbuf); /* life-saved; unwield the corpse if we can't handle it */ if (!uarmg && !Stone_resistance) @@ -3144,8 +3146,10 @@ const char *arg; allow two-weapon combat when either weapon is a corpse] */ if (u.twoweap && uswapwep && uswapwep->otyp == CORPSE && touch_petrifies(&mons[uswapwep->corpsenm]) && !Stone_resistance) { - pline("%s touch the %s corpse.", arg, mons[uswapwep->corpsenm].mname); - Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname)); + pline("%s touch the %s corpse.", arg, + mons[uswapwep->corpsenm].pmnames[NEUTRAL]); + Sprintf(kbuf, "%s corpse", + an(mons[uswapwep->corpsenm].pmnames[NEUTRAL])); instapetrify(kbuf); /* life-saved; unwield the corpse */ if (!uarmg && !Stone_resistance) @@ -4672,7 +4676,8 @@ struct trap *ttmp; /* is it a cockatrice?... */ if (touch_petrifies(mtmp->data) && !uarmg && !Stone_resistance) { - You("grab the trapped %s using your bare %s.", mtmp->data->mname, + You("grab the trapped %s using your bare %s.", + pmname(mtmp->data, Mgender(mtmp)), makeplural(body_part(HAND))); if (poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM)) { @@ -4681,7 +4686,7 @@ struct trap *ttmp; char kbuf[BUFSZ]; Sprintf(kbuf, "trying to help %s out of a pit", - an(mtmp->data->mname)); + an(pmname(mtmp->data, Mgender(mtmp)))); instapetrify(kbuf); return 1; } diff --git a/src/u_init.c b/src/u_init.c index 81927ed9f..99be2a44d 100644 --- a/src/u_init.c +++ b/src/u_init.c @@ -688,7 +688,7 @@ u_init() knows_class(ARMOR_CLASS); skill_init(Skill_B); break; - case PM_CAVEMAN: + case PM_CAVE_DWELLER: Cave_man[C_AMMO].trquan = rn1(11, 10); /* 10..20 */ ini_inv(Cave_man); skill_init(Skill_C); @@ -724,7 +724,7 @@ u_init() skill_init(Skill_Mon); break; } - case PM_PRIEST: + case PM_CLERIC: ini_inv(Priest); if (!rn2(10)) ini_inv(Magicmarker); @@ -811,7 +811,7 @@ u_init() * Non-warriors get an instrument. We use a kludge to * get only non-magic instruments. */ - if (Role_if(PM_PRIEST) || Role_if(PM_WIZARD)) { + if (Role_if(PM_CLERIC) || Role_if(PM_WIZARD)) { static int trotyp[] = { WOODEN_FLUTE, TOOLED_HORN, WOODEN_HARP, BELL, BUGLE, LEATHER_DRUM }; Instrument[0].trotyp = trotyp[rn2(SIZE(trotyp))]; @@ -921,7 +921,7 @@ int otyp; case PM_BARBARIAN: skills = Skill_B; break; - case PM_CAVEMAN: + case PM_CAVE_DWELLER: skills = Skill_C; break; case PM_HEALER: @@ -933,7 +933,7 @@ int otyp; case PM_MONK: skills = Skill_Mon; break; - case PM_PRIEST: + case PM_CLERIC: skills = Skill_P; break; case PM_RANGER: diff --git a/src/uhitm.c b/src/uhitm.c index 5855962da..34896bdd0 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -958,7 +958,7 @@ int dieroll; pline("Splat! You hit %s with %s %s egg%s!", mon_nam(mon), obj->known ? "the" : cnt > 1L ? "some" : "a", - obj->known ? mons[obj->corpsenm].mname + obj->known ? mons[obj->corpsenm].pmnames[NEUTRAL] : "petrifying", plur(cnt)); obj->known = 1; /* (not much point...) */ @@ -971,8 +971,8 @@ int dieroll; } else { /* ordinary egg(s) */ const char *eggp = (obj->corpsenm != NON_PM && obj->known) - ? the(mons[obj->corpsenm].mname) - : (cnt > 1L) ? "some" : "an"; + ? the(mons[obj->corpsenm].pmnames[NEUTRAL]) + : (cnt > 1L) ? "some" : "an"; You("hit %s with %s egg%s.", mon_nam(mon), eggp, plur(cnt)); @@ -2593,7 +2593,7 @@ struct mhitm_data *mhm; if (uncancelled && !rn2(8)) { Sprintf(buf, "%s %s", s_suffix(Monnam(magr)), mpoisons_subj(magr, mattk)); - poisoned(buf, ptmp, pa->mname, 30, FALSE); + poisoned(buf, ptmp, pmname(pa, Mgender(magr)), 30, FALSE); } } else { /* mhitm */ @@ -2814,7 +2814,7 @@ struct mhitm_data *mhm; g.killer.format = KILLED_BY_AN; Sprintf(g.killer.name, "%s by %s", moat ? "moat" : "pool of water", - an(magr->data->mname)); + an(pmname(magr->data, Mgender(magr)))); done(DROWNING); } else if (mattk->aatyp == AT_HUGS) { You("are being crushed."); @@ -2992,7 +2992,8 @@ struct mhitm_data *mhm; } else if (!Slimed) { You("don't feel very well."); make_slimed(10L, (char *) 0); - delayed_killer(SLIMED, KILLED_BY_AN, magr->data->mname); + delayed_killer(SLIMED, KILLED_BY_AN, + pmname(magr->data, Mgender(magr))); } else pline("Yuck!"); } else { @@ -3326,7 +3327,7 @@ struct monst *mtmp; && !(poly_when_stoned(g.youmonst.data) && polymon(PM_STONE_GOLEM))) { int kformat = KILLED_BY_AN; - const char *kname = mtmp->data->mname; + const char *kname = pmname(mtmp->data, Mgender(mtmp)); if (mtmp->data->geno & G_UNIQ) { if (!type_is_pname(mtmp->data)) @@ -3446,7 +3447,7 @@ struct mhitm_data *mhm; && touch_petrifies(&mons[otmp->corpsenm])) { mhm->damage = 1; pline("%s hits you with the %s corpse.", Monnam(magr), - mons[otmp->corpsenm].mname); + mons[otmp->corpsenm].pmnames[NEUTRAL]); if (!Stoned) { if (do_stone_u(magr)) { mhm->hitflags = MM_HIT; @@ -4200,8 +4201,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */ negated = !(rn2(10) >= 3 * armpro); if (is_demon(g.youmonst.data) && !rn2(13) && !uwep - && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS - && u.umonnum != PM_BALROG) { + && u.umonnum != PM_AMOROUS_DEMON && u.umonnum != PM_BALROG) { demonpet(); return MM_MISS; } @@ -4358,12 +4358,12 @@ register struct attack *mattk; if (fatal_gulp && !is_rider(pd)) { /* petrification */ char kbuf[BUFSZ]; - const char *mname = pd->mname; + const char *mnam = pmname(pd, Mgender(mdef)); if (!type_is_pname(pd)) - mname = an(mname); + mnam = an(mnam); You("englut %s.", mon_nam(mdef)); - Sprintf(kbuf, "swallowing %s whole", mname); + Sprintf(kbuf, "swallowing %s whole", mnam); instapetrify(kbuf); } else { start_engulf(mdef); @@ -4374,7 +4374,7 @@ register struct attack *mattk; pline("Unfortunately, digesting any of it is fatal."); end_engulf(); Sprintf(g.killer.name, "unwisely tried to eat %s", - pd->mname); + pmname(pd, Mgender(mdef))); g.killer.format = NO_KILLER_PREFIX; done(DIED); return MM_MISS; /* lifesaved */ @@ -4425,7 +4425,7 @@ register struct attack *mattk; pline1(msgbuf); if (pd == &mons[PM_GREEN_SLIME]) { Sprintf(msgbuf, "%s isn't sitting well with you.", - The(pd->mname)); + The(pmname(pd, Mgender(mdef)))); if (!Unchanging) { make_slimed(5L, (char *) 0); } diff --git a/src/vault.c b/src/vault.c index c59ffd433..8fb059a9e 100644 --- a/src/vault.c +++ b/src/vault.c @@ -397,7 +397,7 @@ invault() gsensed = !canspotmon(guard); if (!gsensed) pline("Suddenly one of the Vault's %s enters!", - makeplural(guard->data->mname)); + makeplural(pmname(guard->data, Mgender(guard)))); else pline("Someone else has entered the Vault."); newsym(guard->mx, guard->my); @@ -1091,7 +1091,8 @@ boolean silently; gx = g.rooms[EGD(grd)->vroom].lx + rn2(2); gy = g.rooms[EGD(grd)->vroom].ly + rn2(2); Sprintf(buf, "To Croesus: here's the gold recovered from %s the %s.", - g.plname, mons[u.umonster].mname); + g.plname, + pmname(&mons[u.umonster], flags.female ? FEMALE : MALE)); make_grave(gx, gy, buf); } for (coins = g.invent; coins; coins = nextcoins) { diff --git a/src/weapon.c b/src/weapon.c index 7abfcdbad..0ccefdf8c 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -1672,7 +1672,7 @@ const struct def_skill *class_skill; /* set skills for magic */ if (Role_if(PM_HEALER) || Role_if(PM_MONK)) { P_SKILL(P_HEALING_SPELL) = P_BASIC; - } else if (Role_if(PM_PRIEST)) { + } else if (Role_if(PM_CLERIC)) { P_SKILL(P_CLERIC_SPELL) = P_BASIC; } else if (Role_if(PM_WIZARD)) { P_SKILL(P_ATTACK_SPELL) = P_BASIC; diff --git a/src/were.c b/src/were.c index c441ad6d1..e0e208151 100644 --- a/src/were.c +++ b/src/were.c @@ -99,13 +99,15 @@ register struct monst *mon; pm = counter_were(monsndx(mon->data)); if (pm < LOW_PM) { - impossible("unknown lycanthrope %s.", mon->data->mname); + impossible("unknown lycanthrope %s.", + mon->data->pmnames[NEUTRAL]); return; } if (canseemon(mon) && !Hallucination) pline("%s changes into a %s.", Monnam(mon), - is_human(&mons[pm]) ? "human" : mons[pm].mname + 4); + is_human(&mons[pm]) ? "human" + : pmname(&mons[pm], Mgender(mon)) + 4); set_mon_data(mon, &mons[pm]); if (mon->msleeping || !mon->mcanmove) { @@ -183,7 +185,7 @@ you_were() if (controllable_poly) { /* `+4' => skip "were" prefix to get name of beast */ Sprintf(qbuf, "Do you want to change into %s?", - an(mons[u.ulycn].mname + 4)); + an(mons[u.ulycn].pmnames[NEUTRAL] + 4)); if (!paranoid_query(ParanoidWerechange, qbuf)) return; } diff --git a/src/windows.c b/src/windows.c index f3af21f49..1b95009cf 100644 --- a/src/windows.c +++ b/src/windows.c @@ -520,7 +520,7 @@ static void FDECL(hup_add_menu, (winid, int, const anything *, CHAR_P, CHAR_P, int, const char *, unsigned int)); static void FDECL(hup_end_menu, (winid, const char *)); static void FDECL(hup_putstr, (winid, int, const char *)); -static void FDECL(hup_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int)); +static void FDECL(hup_print_glyph, (winid, XCHAR_P, XCHAR_P, int, int, unsigned *)); static void FDECL(hup_outrip, (winid, int, time_t)); static void FDECL(hup_curs, (winid, int, int)); static void FDECL(hup_display_nhwindow, (winid, BOOLEAN_P)); @@ -736,11 +736,12 @@ const char *text UNUSED; /*ARGSUSED*/ static void -hup_print_glyph(window, x, y, glyph, bkglyph) +hup_print_glyph(window, x, y, glyph, bkglyph, glyphmod) winid window UNUSED; xchar x UNUSED, y UNUSED; int glyph UNUSED; int bkglyph UNUSED; +unsigned *glyphmod UNUSED; { return; } diff --git a/src/wizard.c b/src/wizard.c index 0c6462888..a4e9d07f1 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -35,10 +35,10 @@ static NEARDATA const int nasties[] = { PM_IRON_GOLEM, PM_OCHRE_JELLY, PM_GREEN_SLIME, PM_DISPLACER_BEAST, PM_GENETIC_ENGINEER, /* chaotic */ - PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LORD, + PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LEADER, PM_MASTER_MIND_FLAYER, PM_DISENCHANTER, PM_WINGED_GARGOYLE, - PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_LORD, PM_ELVENKING, - PM_OGRE_KING, PM_CAPTAIN, PM_GREMLIN, + PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_NOBLE, PM_ELVENMONARCH, + PM_OGRE_TYRANT, PM_CAPTAIN, PM_GREMLIN, /* lawful */ PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON, PM_YELLOW_DRAGON, PM_GUARDIAN_NAGA, PM_FIRE_GIANT, @@ -543,11 +543,11 @@ int difcap; /* if non-zero, try to make difficulty be lower than this */ || (mons[res].geno & (Inhell ? G_NOHELL : G_HELL)) != 0) alt = big_to_little(res); if (alt != res && (g.mvitals[alt].mvflags & G_GENOD) == 0) { - const char *mname = mons[alt].mname, - *lastspace = rindex(mname, ' '); + const char *mnam = mons[alt].pmnames[NEUTRAL], + *lastspace = rindex(mnam, ' '); /* only non-juveniles can become alternate choice */ - if (strncmp(mname, "baby ", 5) + if (strncmp(mnam, "baby ", 5) && (!lastspace || (strcmp(lastspace, " hatchling") && strcmp(lastspace, " pup") diff --git a/src/worn.c b/src/worn.c index 82abcf26c..7da309a02 100644 --- a/src/worn.c +++ b/src/worn.c @@ -1019,7 +1019,8 @@ boolean polyspot; char buf[BUFSZ]; You("touch %s.", mon_nam(u.usteed)); - Sprintf(buf, "falling off %s", an(u.usteed->data->mname)); + Sprintf(buf, "falling off %s", + an(pmname(u.usteed->data, Mgender(u.usteed)))); instapetrify(buf); } dismount_steed(DISMOUNT_FELL); diff --git a/src/zap.c b/src/zap.c index 0b4f7f4bd..04ebb8181 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1022,7 +1022,7 @@ struct monst *mon; pline("%s%s suddenly %s%s%s!", owner, corpse, nonliving(mtmp2->data) ? "reanimates" : "comes alive", different_type ? " as " : "", - different_type ? an(mtmp2->data->mname) : ""); + different_type ? an(pmname(mtmp2->data, Mgender(mtmp2))) : ""); else if (canseemon(mtmp2)) pline("%s suddenly appears!", Amonnam(mtmp2)); } diff --git a/sys/msdos/vidvesa.c b/sys/msdos/vidvesa.c index 747dd0ac0..125cf712d 100644 --- a/sys/msdos/vidvesa.c +++ b/sys/msdos/vidvesa.c @@ -700,6 +700,7 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden - int col, row; int attr; int ry; + int tilenum = 0; row = currow; col = curcol; @@ -721,7 +722,10 @@ unsigned special; /* special feature: corpse, invis, detected, pet, ridden - if (!iflags.over_view && map[ry][col].special) decal_packed(packcell, special); #endif - vesa_DisplayCell(glyph2tile[glyphnum], col - clipx, ry - clipy); + tilenum = glyph2tile[glyphnum]; + if (map[ry][col].special & MG_FEMALE) + tilenum++; + vesa_DisplayCell(tilenum, col - clipx, ry - clipy); } } if (col < (CO - 1)) diff --git a/sys/msdos/vidvga.c b/sys/msdos/vidvga.c index badff0432..621cf1d9a 100644 --- a/sys/msdos/vidvga.c +++ b/sys/msdos/vidvga.c @@ -688,6 +688,7 @@ unsigned char (*indexes)[TILE_X]; { const struct TileImage *tile; unsigned x, y; + int row, col, ry, tilenum = 0; /* We don't have enough colors to show the statues */ if (glyph >= GLYPH_STATUE_OFF) { @@ -695,7 +696,16 @@ unsigned char (*indexes)[TILE_X]; } /* Get the tile from the image */ - tile = get_tile(glyph2tile[glyph]); + tilenum = glyph2tile[glyph]; + row = currow; + col = curcol; + if ((col < 0 || col >= COLNO) + || (row < TOP_MAP_ROW || row >= (ROWNO + TOP_MAP_ROW))) + return; + ry = row - TOP_MAP_ROW; + if (map[ry][col].special & MG_FEMALE) + tilenum++; + tile = get_tile(tilenum); /* Map to a 16 bit palette; assume colors laid out as in default tileset */ memset(indexes, 0, sizeof(indexes)); diff --git a/util/makedefs.c b/util/makedefs.c index 3d81f4ab8..65d7f4878 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1888,14 +1888,14 @@ struct permonst *ptr; if ((tmp2 == AD_DRLI) || (tmp2 == AD_STON) || (tmp2 == AD_DRST) || (tmp2 == AD_DRDX) || (tmp2 == AD_DRCO) || (tmp2 == AD_WERE)) n += 2; - else if (strcmp(ptr->mname, "grid bug")) + else if (strcmp(ptr->pmnames[NEUTRAL], "grid bug")) n += (tmp2 != AD_PHYS); n += ((int) (ptr->mattk[i].damd * ptr->mattk[i].damn) > 23); } /* Leprechauns are special cases. They have many hit dice so they can hit and are hard to kill, but they don't really do much damage. */ - if (!strcmp(ptr->mname, "leprechaun")) + if (!strcmp(ptr->pmnames[NEUTRAL], "leprechaun")) n -= 2; /* Finally, adjust the monster level 0 <= n <= 24 (approx.) */ @@ -1973,7 +1973,7 @@ do_monstr() Fprintf(ofp, "\n\n/*\n * default mons[].difficulty values\n *\n"); for (ptr = &mons[0]; ptr->mlet; ptr++) { i = mstrength(ptr); - Fprintf(ofp, "%-24s %2u\n", ptr->mname, (unsigned int) (uchar) i); + Fprintf(ofp, "%-24s %2u\n", ptr->pmnames[NEUTRAL], (unsigned int) (uchar) i); } Fprintf(ofp, " *\n */\n\n"); @@ -2021,9 +2021,9 @@ do_permonst() Fprintf(ofp, "\n PM_"); else Fprintf(ofp, "\n#define\tPM_"); - if (mons[i].mlet == S_HUMAN && !strncmp(mons[i].mname, "were", 4)) + if (mons[i].mlet == S_HUMAN && !strncmp(mons[i].pmnames[NEUTRAL], "were", 4)) Fprintf(ofp, "HUMAN_"); - for (nam = c = tmpdup(mons[i].mname); *c; c++) + for (nam = c = tmpdup(mons[i].pmnames[NEUTRAL]); *c; c++) if (*c >= 'a' && *c <= 'z') *c -= (char) ('a' - 'A'); else if (*c < 'A' || *c > 'Z') diff --git a/win/Qt/qt_bind.cpp b/win/Qt/qt_bind.cpp index 7f4926df5..ba4c21567 100644 --- a/win/Qt/qt_bind.cpp +++ b/win/Qt/qt_bind.cpp @@ -474,11 +474,12 @@ void NetHackQtBind::qt_cliparound_window(winid wid, int x, int y) NetHackQtWindow* window=id_to_window[(int)wid]; window->ClipAround(x,y); } -void NetHackQtBind::qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph,int bkglyph UNUSED) +void NetHackQtBind::qt_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph, + int bkglyph UNUSED, unsigned *glyphmod) { /* TODO: bkglyph */ NetHackQtWindow* window=id_to_window[(int)wid]; - window->PrintGlyph(x,y,glyph); + window->PrintGlyph(x,y,glyph,glyphmod); } //void NetHackQtBind::qt_print_glyph_compose(winid wid,xchar x,xchar y,int glyph1, int glyph2) //{ diff --git a/win/Qt/qt_bind.h b/win/Qt/qt_bind.h index bc3f2d647..73f4d4fa8 100644 --- a/win/Qt/qt_bind.h +++ b/win/Qt/qt_bind.h @@ -64,7 +64,7 @@ public: 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, XCHAR_P x, XCHAR_P y, - int glyph, int bkglyph); + int glyph, int bkglyph, unsigned int *); static void qt_raw_print(const char *str); static void qt_raw_print_bold(const char *str); static int qt_nhgetch(); diff --git a/win/Qt/qt_glyph.cpp b/win/Qt/qt_glyph.cpp index bed3bd5a3..f807282f3 100644 --- a/win/Qt/qt_glyph.cpp +++ b/win/Qt/qt_glyph.cpp @@ -82,30 +82,32 @@ NetHackQtGlyphs::NetHackQtGlyphs() } void NetHackQtGlyphs::drawGlyph(QPainter& painter, int glyph, int x, int y, - bool reversed) + bool fem, bool reversed) { if (!reversed) { int tile = glyph2tile[glyph]; + if (fem) + ++tile; int px = (tile % tiles_per_row) * width(); int py = tile / tiles_per_row * height(); painter.drawPixmap(x, y, pm, px, py, width(), height()); } else { // for paper doll; mirrored image for left side of two-handed weapon - painter.drawPixmap(x, y, reversed_pixmap(glyph), + painter.drawPixmap(x, y, reversed_pixmap(glyph, fem), 0, 0, width(), height()); } } void NetHackQtGlyphs::drawCell(QPainter& painter, int glyph, - int cellx, int celly) + int cellx, int celly, bool fem) { - drawGlyph(painter, glyph, cellx * width(), celly * height(), false); + drawGlyph(painter, glyph, cellx * width(), celly * height(), fem, false); } void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, int cellx, int celly, int border, - bool reversed) + bool reversed, bool fem) { int wd = width(), ht = height(), @@ -113,7 +115,7 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, lox = cellx * (wd + 2), loy = celly * (ht + 2) + yoffset; - drawGlyph(painter, glyph, lox + 1, loy + 1, reversed); + drawGlyph(painter, glyph, lox + 1, loy + 1, fem, reversed); #ifdef TEXTCOLOR if (border != NO_BORDER) { @@ -164,9 +166,11 @@ void NetHackQtGlyphs::drawBorderedCell(QPainter& painter, int glyph, } // mis-named routine to get the pixmap for a particular glyph -QPixmap NetHackQtGlyphs::glyph(int glyphindx) +QPixmap NetHackQtGlyphs::glyph(int glyphindx, bool fem) { int tile = glyph2tile[glyphindx]; + if (fem) + ++tile; int px = (tile % tiles_per_row) * tilefile_tile_W; int py = tile / tiles_per_row * tilefile_tile_H; @@ -175,9 +179,9 @@ QPixmap NetHackQtGlyphs::glyph(int glyphindx) } // transpose a glyph's tile horizontally, scaled for use in paper doll -QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx) +QPixmap NetHackQtGlyphs::reversed_pixmap(int glyphindx, bool fem) { - QPixmap pxmp = glyph(glyphindx); + QPixmap pxmp = glyph(glyphindx, fem); #ifdef ENHANCED_PAPERDOLL qreal wid = (qreal) pxmp.width(), //hgt = (qreal) pxmp.height(), diff --git a/win/Qt/qt_glyph.h b/win/Qt/qt_glyph.h index 39b0e3914..afc2b92ca 100644 --- a/win/Qt/qt_glyph.h +++ b/win/Qt/qt_glyph.h @@ -24,13 +24,13 @@ public: void setSize(int w, int h); void drawGlyph(QPainter &, int glyph, int pixelx, int pixely, - bool reversed = false); - void drawCell(QPainter &, int glyph, int cellx, int celly); + bool fem, bool reversed = false); + void drawCell(QPainter &, int glyph, int cellx, int celly, bool fem); void drawBorderedCell(QPainter &, int glyph, int cellx, int celly, int bordercode, - bool reversed); - QPixmap glyph(int glyphindx); - QPixmap reversed_pixmap(int glyphindx); + bool reversed, bool fem = false); + QPixmap glyph(int glyphindx, bool fem = false); + QPixmap reversed_pixmap(int glyphindx, bool fem = false); private: QImage img; diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index f55e023c8..b3681b155 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -176,14 +176,19 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) for (int j=garea.top(); j<=garea.bottom(); j++) { for (int i=garea.left(); i<=garea.right(); i++) { +#if 0 unsigned short g=Glyph(i,j); int color; int ch; unsigned special; - +#else + int color = Glyphcolor(i,j); + int ch = Glyphttychar(i,j); + unsigned special = Glyphflags(i,j); +#endif painter.setPen( Qt::green ); /* map glyph to character and color */ - mapglyph(g, &ch, &color, &special, i, j, 0); +// mapglyph(g, &ch, &color, &special, i, j, 0); ch = cp437(ch); #ifdef TEXTCOLOR painter.setPen( nhcolor_to_pen(color) ); @@ -220,15 +225,20 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) } painter.setFont(font()); - } else { + } else { // tiles for (int j=garea.top(); j<=garea.bottom(); j++) { for (int i=garea.left(); i<=garea.right(); i++) { unsigned short g=Glyph(i,j); +#if 0 int color; int ch; unsigned special; mapglyph(g, &ch, &color, &special, i, j, 0); - qt_settings->glyphs().drawCell(painter, g, i, j); +#else + unsigned special = Glyphflags(i, j); +#endif + bool femflag = (special & MG_FEMALE) ? true : false; + qt_settings->glyphs().drawCell(painter, g, i, j, femflag); #ifdef TEXTCOLOR if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), @@ -559,8 +569,14 @@ void NetHackQtMapViewport::Clear() // FIXME: map column 0 should be surpressed from being displayed // Glyph(0, j) = GLYPH_NOTHING; + Glyphttychar(0, j) = ' '; + Glyphcolor(0, j) = NO_COLOR; + Glyphflags(0, j) = 0; for (int i = 1; i < COLNO; ++i) Glyph(i, j) = GLYPH_UNEXPLORED; + Glyphttychar(0, j) = ' '; + Glyphcolor(0, j) = NO_COLOR; + Glyphflags(0, j) = 0; } change.clear(); @@ -594,9 +610,12 @@ void NetHackQtMapViewport::CursorTo(int x,int y) Changed(cursor.x(),cursor.y()); } -void NetHackQtMapViewport::PrintGlyph(int x,int y,int theglyph) +void NetHackQtMapViewport::PrintGlyph(int x,int y,int theglyph,unsigned *glyphmod) { Glyph(x,y)=theglyph; + Glyphttychar(x,y)=glyphmod[GM_TTYCHAR]; + Glyphcolor(x,y)=glyphmod[GM_COLOR]; + Glyphflags(x,y)=glyphmod[GM_FLAGS]; Changed(x,y); } @@ -701,9 +720,9 @@ void NetHackQtMapWindow2::ClipAround(int x,int y) ensureVisible(x,y,width()*0.45,height()*0.45); } -void NetHackQtMapWindow2::PrintGlyph(int x,int y,int glyph) +void NetHackQtMapWindow2::PrintGlyph(int x,int y,int glyph, unsigned *glyphmod) { - m_viewport->PrintGlyph(x, y, glyph); + m_viewport->PrintGlyph(x, y, glyph, glyphmod); } #if 0 //RLC @@ -825,8 +844,15 @@ void NetHackQtMapWindow::Clear() { for (int j = 0; j < ROWNO; ++j) { Glyph(0, j) = GLYPH_NOTHING; - for (int i = 1; i < COLNO; ++i) + Glyphcolor(0, j) = NO_COLOR; + Glyphttychar(0, j) = ' '; + Glyphflags(0, j) = 0; + for (int i = 1; i < COLNO; ++i) { Glyph(i, j) = GLYPH_UNEXPLORED; + Glyphcolor(i, j) = NO_COLOR; + Glyphttychar(i, j) = ' '; + Glyphflags(i, j) = 0; + } } change.clear(); @@ -897,13 +923,18 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) for (int j=garea.top(); j<=garea.bottom(); j++) { for (int i=garea.left(); i<=garea.right(); i++) { unsigned short g=Glyph(i,j); +#if 0 int color; char32_t ch; unsigned special; - +#else + int color = Glyphcolor(i,j); + char32_t ch = Glyphttychar(i,j); + unsigned special = Glyphflags(i,j); +#endif painter.setPen( Qt::green ); /* map glyph to character and color */ - mapglyph(g, &ch, &color, &special, i, j, 0); +// mapglyph(g, &ch, &color, &special, i, j, 0); #ifdef TEXTCOLOR painter.setPen( nhcolor_to_pen(color) ); #endif @@ -935,11 +966,18 @@ void NetHackQtMapWindow::paintEvent(QPaintEvent* event) for (int j=garea.top(); j<=garea.bottom(); j++) { for (int i=garea.left(); i<=garea.right(); i++) { unsigned short g=Glyph(i,j); +#if 0 int color; int ch; unsigned special; mapglyph(g, &ch, &color, &special, i, j, 0); - qt_settings->glyphs().drawCell(painter, g, i, j); +#else + int color = Glyphcolor(i,j); + int ch = Glyphttychar(i,j); + unsigned special = Glyphflags(i,j); +#endif + bool femflag = (special & MG_FEMALE) ? true : false; + qt_settings->glyphs().drawCell(painter, g, i, j, femflag); #ifdef TEXTCOLOR if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), @@ -1048,9 +1086,12 @@ void NetHackQtMapWindow::ClipAround(int x,int y) viewport.center(x,y,0.45,0.45); } -void NetHackQtMapWindow::PrintGlyph(int x,int y,int glyph) +void NetHackQtMapWindow::PrintGlyph(int x,int y,int glyph, unsigned *glyphmod) { Glyph(x,y)=glyph; + Glyphttychar(x,y)=glyphmod[GM_TTYCHAR]; + Glyphcolor(x,y)=glyphmod[GM_COLOR]; + Glyphflags(x,y)=glyphmod[GM_FLAGS]; Changed(x,y); } diff --git a/win/Qt/qt_map.h b/win/Qt/qt_map.h index bf8afceb4..6200e0412 100644 --- a/win/Qt/qt_map.h +++ b/win/Qt/qt_map.h @@ -32,6 +32,12 @@ private: QFont *rogue_font; unsigned short glyph[ROWNO][COLNO]; unsigned short& Glyph(int x, int y) { return glyph[y][x]; } + unsigned int glyphttychar[ROWNO][COLNO]; + unsigned int& Glyphttychar(int x, int y) { return glyphttychar[y][x]; } + unsigned int glyphcolor[ROWNO][COLNO]; + unsigned int& Glyphcolor(int x, int y) { return glyphcolor[y][x]; } + unsigned int glyphflags[ROWNO][COLNO]; + unsigned int& Glyphflags(int x, int y) { return glyphflags[y][x]; } QPoint cursor; QPixmap pet_annotation; QPixmap pile_annotation; @@ -42,7 +48,7 @@ private: void Clear(); void Display(bool block); void CursorTo(int x,int y); - void PrintGlyph(int x,int y,int glyph); + void PrintGlyph(int x,int y,int glyph,unsigned *glyphmod); void Changed(int x, int y); void updateTiles(); @@ -64,7 +70,7 @@ public: virtual void CursorTo(int x,int y); virtual void PutStr(int attr, const QString& text); virtual void ClipAround(int x,int y); - virtual void PrintGlyph(int x,int y,int glyph); + virtual void PrintGlyph(int x,int y,int glyph,unsigned *glyphmod); signals: void resized(); diff --git a/win/Qt/qt_plsel.cpp b/win/Qt/qt_plsel.cpp index bbc3132fa..e20735b56 100644 --- a/win/Qt/qt_plsel.cpp +++ b/win/Qt/qt_plsel.cpp @@ -82,14 +82,14 @@ public: { } - void setGlyph(int g) + void setGlyph(int g, bool fem) { NetHackQtGlyphs& glyphs = qt_settings->glyphs(); int gw = glyphs.width(); int gh = glyphs.height(); QPixmap pm(gw,gh); QPainter p(&pm); - glyphs.drawGlyph(p, g, 0, 0); + glyphs.drawGlyph(p, g, 0, 0, fem); p.end(); setIcon(QIcon(pm)); //RLC setHeight(std::max(pm.height()+1,height())); @@ -124,7 +124,7 @@ public: #endif ) { - setGlyph(monnum_to_glyph(roles[id].malenum)); + setGlyph(monnum_to_glyph(roles[id].malenum), false); } }; @@ -139,7 +139,7 @@ public: #endif ) { - setGlyph(monnum_to_glyph(races[id].malenum)); + setGlyph(monnum_to_glyph(races[id].malenum), false); } }; @@ -257,6 +257,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) chosen_gend = flags.initgend; chosen_align = flags.initalign; + bool fem = (chosen_gend > ROLE_NONE); // XXX QListView unsorted goes in rev. for (nrole=0; roles[nrole].name.m; nrole++) @@ -264,8 +265,8 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) role->setRowCount(nrole); for (i=0; roles[i].name.m; i++) { QTableWidgetItem *item = new QTableWidgetItem( - QIcon(qt_settings->glyphs().glyph(roles[i].malenum)), - roles[i].name.m); + QIcon(qt_settings->glyphs().glyph(roles[i].malenum, fem)), + roles[i].name.m); item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); role->setItem(i, 0, item); } @@ -280,7 +281,7 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) race->setRowCount(nrace); for (i=0; races[i].noun; i++) { QTableWidgetItem *item = new QTableWidgetItem( - QIcon(qt_settings->glyphs().glyph(races[i].malenum)), + QIcon(qt_settings->glyphs().glyph(races[i].malenum, fem)), races[i].noun); item->setFlags(Qt::ItemIsEnabled|Qt::ItemIsSelectable); race->setItem(i, 0, item); @@ -290,9 +291,13 @@ NetHackQtPlayerSelector::NetHackQtPlayerSelector(NetHackQtKeyBuffer& ks UNUSED) race->setHorizontalHeaderLabels(QStringList("Race")); race->resizeColumnToContents(0); - // TODO: render the alignment and gender labels smaller to match the - // horizontal header labels for role and race; getting the font from - // race table above and setting it for labels below made no difference + // TODO: + // Render the alignment and gender labels smaller to match the + // horizontal header labels for role and race; getting the font from + // race table above and setting it for labels below made no difference. + // + // Maybe, if the order of choosing becomes more dynamic: + // Replace the role and race glyphs when gender gets set. QLabel *gendlabel = new QLabel("Gender"); genderbox->layout()->addWidget(gendlabel); diff --git a/win/Qt/qt_stat.cpp b/win/Qt/qt_stat.cpp index 88a6cfa8c..3fca92c89 100644 --- a/win/Qt/qt_stat.cpp +++ b/win/Qt/qt_stat.cpp @@ -788,7 +788,8 @@ void NetHackQtStatusWindow::updateStats() if (u.usteed) ++k, ride.show(); else ride.hide(); if (Upolyd) { - buf = nh_capitalize_words(mons[u.umonnum].mname); + buf = nh_capitalize_words(pmname(&mons[u.umonnum], + ::flags.female ? FEMALE : MALE)); } else { buf = rank_of(u.ulevel, g.pl_character[0], ::flags.female); } diff --git a/win/Qt/qt_win.cpp b/win/Qt/qt_win.cpp index 3fd51edf9..670ae8da8 100644 --- a/win/Qt/qt_win.cpp +++ b/win/Qt/qt_win.cpp @@ -109,7 +109,7 @@ void NetHackQtWindow::EndMenu(const QString& prompt UNUSED) { puts("unexpected E int NetHackQtWindow::SelectMenu(int how UNUSED, MENU_ITEM_P **menu_list UNUSED) { puts("unexpected SelectMenu"); return 0; } void NetHackQtWindow::ClipAround(int x UNUSED,int y UNUSED) { puts("unexpected ClipAround"); } -void NetHackQtWindow::PrintGlyph(int x UNUSED,int y UNUSED,int glyph UNUSED) { puts("unexpected PrintGlyph"); } +void NetHackQtWindow::PrintGlyph(int x UNUSED,int y UNUSED,int glyph UNUSED, unsigned *glyphmod UNUSED) { puts("unexpected PrintGlyph"); } //void NetHackQtWindow::PrintGlyphCompose(int x,int y,int,int) { puts("unexpected PrintGlyphCompose"); } void NetHackQtWindow::UseRIP(int how UNUSED, time_t when UNUSED) { puts("unexpected UseRIP"); } diff --git a/win/Qt/qt_win.h b/win/Qt/qt_win.h index daa6e0d1d..681b06be1 100644 --- a/win/Qt/qt_win.h +++ b/win/Qt/qt_win.h @@ -40,7 +40,7 @@ public: virtual void EndMenu(const QString& prompt); virtual int SelectMenu(int how, MENU_ITEM_P **menu_list); virtual void ClipAround(int x, int y); - virtual void PrintGlyph(int x, int y, int glyph); + virtual void PrintGlyph(int x, int y, int glyph, unsigned *glyphmod); virtual void UseRIP(int how, time_t when); int nhid; diff --git a/win/X11/winmap.c b/win/X11/winmap.c index 6e2d2aa7c..19cbe0400 100644 --- a/win/X11/winmap.c +++ b/win/X11/winmap.c @@ -73,11 +73,12 @@ static void FDECL(display_cursor, (struct xwindow *)); /* Global functions ======================================================= */ void -X11_print_glyph(window, x, y, glyph, bkglyph) +X11_print_glyph(window, x, y, glyph, bkglyph, glyphmod) winid window; xchar x, y; int glyph; int bkglyph UNUSED; +unsigned *glyphmod UNUSED; { struct map_info_t *map_info; boolean update_bbox = FALSE; @@ -1295,6 +1296,8 @@ boolean inverted; int dest_x = (cur_col - COL0_OFFSET) * tile_map->square_width; int dest_y = row * tile_map->square_height; + if ((tile_map->glyphs[row][cur_col].special & MG_FEMALE)) + tile++; /* advance to the female tile variation */ src_x = (tile % TILES_PER_ROW) * tile_width; src_y = (tile / TILES_PER_ROW) * tile_height; XCopyArea(dpy, tile_pixmap, XtWindow(wp->w), diff --git a/win/X11/winstat.c b/win/X11/winstat.c index a30ed01e7..cbc0ce078 100644 --- a/win/X11/winstat.c +++ b/win/X11/winstat.c @@ -1453,15 +1453,15 @@ long new_value; buf[0] = highc(buf[0]); Strcat(buf, " the "); if (Upolyd) { - char mname[BUFSZ]; + char mnam[BUFSZ]; int k; - Strcpy(mname, mons[u.umonnum].mname); - for (k = 0; mname[k] != '\0'; k++) { - if (k == 0 || mname[k - 1] == ' ') - mname[k] = highc(mname[k]); + Strcpy(mnam, pmname(&mons[u.umonnum], Ugender)); + for (k = 0; mnam[k] != '\0'; k++) { + if (k == 0 || mnam[k - 1] == ' ') + mnam[k] = highc(mnam[k]); } - Strcat(buf, mname); + Strcat(buf, mnam); } else Strcat(buf, rank_of(u.ulevel, g.pl_character[0], flags.female)); diff --git a/win/chain/wc_chainin.c b/win/chain/wc_chainin.c index b6825632f..fb84ab32a 100644 --- a/win/chain/wc_chainin.c +++ b/win/chain/wc_chainin.c @@ -272,12 +272,13 @@ char *posbar; /* XXX can we decode the glyph in a meaningful way? */ void -chainin_print_glyph(window, x, y, glyph, bkglyph) +chainin_print_glyph(window, x, y, glyph, bkglyph, glyphmod) winid window; xchar x, y; int glyph, bkglyph; +int glyphmod[NUM_GLYPHMOD]; { - (*cibase->nprocs->win_print_glyph)(cibase->ndata, window, x, y, glyph, bkglyph); + (*cibase->nprocs->win_print_glyph)(cibase->ndata, window, x, y, glyph, bkglyph, glyphmod); } void diff --git a/win/chain/wc_chainout.c b/win/chain/wc_chainout.c index a4401a1eb..3ad84aa45 100644 --- a/win/chain/wc_chainout.c +++ b/win/chain/wc_chainout.c @@ -336,15 +336,16 @@ char *posbar; #endif void -chainout_print_glyph(vp, window, x, y, glyph, bkglyph) +chainout_print_glyph(vp, window, x, y, glyph, bkglyph, glyphmod) void *vp; winid window; xchar x, y; int glyph, bkglyph; +int glyphmod[NUM_GLYPHMOD]; { struct chainout_data *tdp = vp; - (*tdp->nprocs->win_print_glyph)(window, x, y, glyph, bkglyph); + (*tdp->nprocs->win_print_glyph)(window, x, y, glyph, bkglyph, glyphmod); } void diff --git a/win/chain/wc_trace.c b/win/chain/wc_trace.c index e2939549e..b6519e443 100644 --- a/win/chain/wc_trace.c +++ b/win/chain/wc_trace.c @@ -578,19 +578,20 @@ char *posbar; /* XXX can we decode the glyph in a meaningful way? see mapglyph()? genl_putmixed? */ void -trace_print_glyph(vp, window, x, y, glyph, bkglyph) +trace_print_glyph(vp, window, x, y, glyph, bkglyph, glyphmod) void *vp; winid window; xchar x, y; int glyph, bkglyph; +int glyphmod[NUM_GLYPHMOD]; { struct trace_data *tdp = vp; - fprintf(wc_tracelogf, "%sprint_glyph(%d, %d, %d, %d, %d)\n", INDENT, window, - x, y, glyph, bkglyph); + fprintf(wc_tracelogf, "%sprint_glyph(%d, %d, %d, %d, %d, %lu)\n", INDENT, window, + x, y, glyph, bkglyph, glyphmod); PRE; - (*tdp->nprocs->win_print_glyph)(tdp->ndata, window, x, y, glyph, bkglyph); + (*tdp->nprocs->win_print_glyph)(tdp->ndata, window, x, y, glyph, bkglyph, glyphmod); POST; } diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index 4035b3c9f..baceb8901 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -646,17 +646,21 @@ curses_cliparound(int x, int y) } /* -print_glyph(window, x, y, glyph, bkglyph) +print_glyph(window, x, y, glyph, bkglyph, glyphmod) -- Print the glyph at (x,y) on the given window. Glyphs are integers at the interface, mapped to whatever the window- port wants (symbol, font, color, attributes, ...there's a 1-1 map between glyphs and distinct things on the map). bkglyph is to render the background behind the glyph. It's not used here. + -- glyphmod (glyphmod[NUM_GLYPHNOD]) provides extended + information about the glyph that window ports can use to + enhance the display in various ways. + */ void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, - int bkglyph UNUSED) + int bkglyph UNUSED, unsigned *glyphmod) { int ch; int color; diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index 6a3a5d833..63c188886 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -1468,7 +1468,7 @@ get_playerrank(char *rank) if (Upolyd) { int k = 0; - Strcpy(buf, mons[u.umonnum].mname); + Strcpy(buf, pmname(&mons[u.umonnum], flags.female ? FEMALE : MALE)); while(buf[k] != 0) { if ((k == 0 || (k > 0 && buf[k-1] == ' ')) && 'a' <= buf[k] && buf[k] <= 'z') diff --git a/win/share/monsters.txt b/win/share/monsters.txt index 6a69c8de6..e14f4611f 100644 --- a/win/share/monsters.txt +++ b/win/share/monsters.txt @@ -27,7 +27,7 @@ Y = (149, 149, 149) Z = (195, 195, 195) 0 = (100, 100, 100) 1 = (72, 108, 108) -# tile 0 (giant ant) +# tile 0 (giant ant,male) { ................ ................ @@ -46,7 +46,26 @@ Z = (195, 195, 195) ......JA.JA..... ................ } -# tile 1 (killer bee) +# tile 1 (giant ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......JAJKKA... + .....JAAAKJJJA.. + .....AKJJAJJAA.. + ...KKAJJJAAA.... + ..BJJAAAAAJJA... + ..JBJAJAJAA..... + .....AJA.JA..... + ......JA.JA..... + ................ +} +# tile 2 (killer bee,male) { ................ ................ @@ -65,7 +84,26 @@ Z = (195, 195, 195) .....AAAAAA..... ................ } -# tile 2 (soldier ant) +# tile 3 (killer bee,female) +{ + ................ + ................ + .PPP.....PP..... + PPPPP...PBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAA.. + ABJBBJJJJAHAHH.. + .JJABJAJ.J.HH... + .......J.J...... + ................ + ...AAAAAAAAAAA.. + .....AAAAAA..... + ................ +} +# tile 4 (soldier ant,male) { ................ ................ @@ -84,7 +122,26 @@ Z = (195, 195, 195) ..JJAAJA.JA..... ................ } -# tile 3 (fire ant) +# tile 5 (soldier ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......JAJKKA... + .....JAAAKJJJA.. + .....AKJJAJJAA.. + .JJKKAJJJAAA.... + JBJJJAAAAAJJA... + JJJBJAJAJAA..... + JAAJJAJA.JA..... + ..JJAAJA.JA..... + ................ +} +# tile 6 (fire ant,male) { ................ ................ @@ -103,7 +160,26 @@ Z = (195, 195, 195) ......DA.DA..... ................ } -# tile 4 (giant beetle) +# tile 7 (fire ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......DACCCA... + .....DAAACDDDA.. + .....ACDDADDAA.. + ...CCADDDAAA.... + ..GDDAAAAADDA... + ..DGDADADAA..... + .....ADA.DA..... + ......DA.DA..... + ................ +} +# tile 8 (giant beetle,male) { ................ ................ @@ -122,7 +198,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 5 (queen bee) +# tile 9 (giant beetle,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......KKDKK..... + ....KACLCJJD.... + ...KCLCJJDDDK... + ...DCCJDADDAD... + ...ADJDDDDDDD... + ...BAKDDAADKAA.. + ...ABAKDDK...... + ......AA.AA..... + ................ + ................ +} +# tile 10 (queen bee,male) { ................ .PPP.....PP..... @@ -141,7 +236,26 @@ Z = (195, 195, 195) .....AAAAAA..... ................ } -# tile 6 (acid blob) +# tile 11 (queen bee,female) +{ + ................ + .PPP.....PP..... + PPPPP...PPPP.... + PPPPP..PPBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAAH. + ABJBBJJJJAHAHHH. + .JJABJAJ.JHHHAA. + ...J...J.JAAAHH. + ..JJ..JJ.J.HHAH. + ..JAAAJAAJ..HH.. + .....AAAAAA..... + ................ +} +# tile 12 (acid blob,male) { ................ ................ @@ -160,7 +274,26 @@ Z = (195, 195, 195) ..IA............ ................ } -# tile 7 (quivering blob) +# tile 13 (acid blob,female) +{ + ................ + ................ + ................ + .....KDDA....... + ...DDKDDKA...... + .DDDIIIDJDA..... + D.IIOOIIDAIA.... + .DKNNNODIDA..IA. + IDJNANOJDDJA.... + ADIDNOIDIDDDA... + ...JDIKIADKIA... + .IA.IDID.JDA.... + ...I.DDA....DA.. + .........IA..... + ..IA............ + ................ +} +# tile 14 (quivering blob,male) { ................ ................ @@ -179,7 +312,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 8 (gelatinous cube) +# tile 15 (quivering blob,female) +{ + ................ + ................ + .....PPPP....... + .........P...... + .P.OOOPPE..AAA.. + P.OPBBBPOEAEAA.. + P.PBNNNP.OEAAEA. + P.PNNNNNPOEEAEA. + POPNAANNEO.OAEA. + .OPNAANNE..OAAA. + .OPBNNNEPP.OEAA. + BPOPEEEBBPO.EEA. + BBBPBBBBBBPPPPA. + ..BBBBBBBBBBPA.. + ................ + ................ +} +# tile 16 (gelatinous cube,male) { ................ ................ @@ -198,7 +350,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 9 (chickatrice) +# tile 17 (gelatinous cube,female) +{ + ................ + ................ + ................ + ................ + ................ + .......LLL...... + .....LLLLLLLL... + ...LLLLLLLLLD... + ...CLLLLLLLDDA.. + ...CGGCLLLDDDAA. + ...CAGCGGDDDDAAA + ...CCCCAGDDDAAAA + .....CCCCDDAAAA. + .......CCDAAA... + ................ + ................ +} +# tile 18 (chickatrice,male) { ................ ................ @@ -217,7 +388,26 @@ Z = (195, 195, 195) ........AA...... ................ } -# tile 10 (cockatrice) +# tile 19 (chickatrice,female) +{ + ................ + ................ + ................ + ................ + .......OO....... + ......HAOO...... + .....HHOOH.HHA.. + ........OOHOA... + ........OOFA.... + ........FGGFA... + ........AGFGAA.. + ...........GA... + .......F..FFA... + .......AFFAA.... + ........AA...... + ................ +} +# tile 20 (cockatrice,male) { ................ ...D.DD......... @@ -236,7 +426,26 @@ Z = (195, 195, 195) .....FFFFA...... ................ } -# tile 11 (pyrolisk) +# tile 21 (cockatrice,female) +{ + ................ + ...D.DD......... + ....DD.......... + ....NL..AA...... + ..HHAN.AAA...... + .HH.NO..AAAA.... + ...AOOLFFFAA.... + ...OOLKGGFFAA... + ...AOAGGFGFFAA.. + .......GFFGFAA.. + .........FGGAA.. + .....FA...FFA... + ....FA....FFA... + ....FA..FFFA.... + .....FFFFA...... + ................ +} +# tile 22 (pyrolisk,male) { ................ ...D.DD......... @@ -255,7 +464,26 @@ Z = (195, 195, 195) .....JKKKA...... ................ } -# tile 12 (jackal) +# tile 23 (pyrolisk,female) +{ + ................ + ...D.DD......... + ....DD.......... + ....NB..AA...... + ..HHAN.AAA...... + .HH.NB..AAAA.... + ...APBBJJJAA.... + ...PPPKDDKJAA... + ...APADDKDKJAA.. + .......DJKDJAA.. + .........JDDAA.. + .....JA...JJA... + ....JA....JJA... + ....KA..KKKA.... + .....JKKKA...... + ................ +} +# tile 24 (jackal,male) { ................ ................ @@ -274,7 +502,26 @@ Z = (195, 195, 195) .....OO..OOA.... ................ } -# tile 13 (fox) +# tile 25 (jackal,female) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOAOOOOOOOAA.. + ..AAOOOOOOOOAA.. + ....OJOOOOOLAA.. + ....OJOLKALKAA.. + ...OOAOAAAOAA... + .....OO..OOA.... + ................ +} +# tile 26 (fox,male) { ................ ................ @@ -293,7 +540,26 @@ Z = (195, 195, 195) ...AC.ACA....... ................ } -# tile 14 (coyote) +# tile 27 (fox,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....C........... + ....C........... + ..CCAC...CCC.... + ..ACCCCCCACCC... + ...AACCCC.ACC... + ....ACAAC..AA... + ...AC.ACA....... + ................ +} +# tile 28 (coyote,male) { ................ ................ @@ -312,7 +578,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 15 (werejackal) +# tile 29 (coyote,female) +{ + ................ + ................ + ................ + ...K..K......... + ...K.KK......KKK + ..KKKK......KKKA + ..NCNK.KKKKKAAA. + .KCCKKKKKKKKK... + KKCKAKKKKKKKK... + DKKKAKAKKKKAK... + ..AAKAAKAAAAK... + ....AKAKAAAAK... + ...AKKAKA.AKK... + .....AKK........ + ................ + ................ +} +# tile 30 (werejackal,male) { ................ ................ @@ -331,7 +616,26 @@ Z = (195, 195, 195) ...L.LL..OOA.... ......L......... } -# tile 16 (little dog) +# tile 31 (werejackal,female) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOALLOOOOOAA.. + ..AALLLLOOOOAA.. + ....LJLLLOOLAA.. + ....LJLLKALKAA.. + ..LLLALAAAOAA... + ...L.LL..OOA.... + ......L......... +} +# tile 32 (little dog,male) { ................ ................ @@ -350,7 +654,26 @@ Z = (195, 195, 195) .....KK...KA.... ................ } -# tile 17 (dingo) +# tile 33 (little dog,female) +{ + ................ + ................ + ................ + ................ + ...J..J......... + ...J.JJ...K..... + ..JJJJ.....K.... + ..NJNKK....K.A.. + .JJJCKK....K.A.. + .PJJAKCKKCKKAA.. + .DDAACKKCKKKAA.. + ....KJKJCJKJAA.. + ....KJKJJAJJAA.. + ...KKAKAAAKAA... + .....KK...KA.... + ................ +} +# tile 34 (dingo,male) { ................ ................ @@ -369,7 +692,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 18 (dog) +# tile 35 (dingo,female) +{ + ................ + ................ + ................ + .............C.. + ...C..C.......C. + ...C.CC.......CA + ..CCCCK.......CA + ..ACACCKCCCCCCAA + ..LLCCCKCCCLCCCA + .KCCACKCLLLLACCA + ..AACAACLLAAACCA + ....ACACAAAAAACA + ....CCACAAA..CCA + .....ACCA....... + ................ + ................ +} +# tile 36 (dog,male) { ................ ................ @@ -388,7 +730,26 @@ Z = (195, 195, 195) .....KKAA...KA.. ................ } -# tile 19 (large dog) +# tile 37 (dog,female) +{ + ................ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKK......K.A + .JJJCKKKK....K.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ....KJKKJJJAJJAA + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 38 (large dog,male) { ................ ................ @@ -407,7 +768,26 @@ Z = (195, 195, 195) .....KKAA...KA.. ................ } -# tile 20 (wolf) +# tile 39 (large dog,female) +{ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKKK.....K.A + .JJJCKKKKK..JK.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ...JKJKKJJJAJJAA + ....KAKJAAAAKJA. + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 40 (wolf,male) { ................ ................ @@ -426,7 +806,26 @@ Z = (195, 195, 195) .....PPAA..PPA.. ................ } -# tile 21 (werewolf) +# tile 41 (wolf,female) +{ + ................ + ................ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPAPPPPPPPPPAA + ..AAP.PP..P.P.AA + ....P.PP...A.PAA + ....PAP.AAAAP.A. + ...PPAPAAAAAPAA. + .....PPAA..PPA.. + ................ +} +# tile 42 (werewolf,male) { ................ ................ @@ -445,7 +844,26 @@ Z = (195, 195, 195) ...L.LLAA..PP... .....LL......... } -# tile 22 (winter wolf cub) +# tile 43 (werewolf,female) +{ + ................ + ................ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPALPPPPPPPPAA + ..AALLPL..P.P.AA + ....L.LL...A.PAA + ....LAL.AAAAP.A. + ..LLLALAAAAAPPA. + ...L.LLAA..PP... + .....LL......... +} +# tile 44 (winter wolf cub,male) { ................ ................ @@ -464,7 +882,26 @@ Z = (195, 195, 195) .....NB..NBA.... ................ } -# tile 23 (warg) +# tile 45 (winter wolf cub,female) +{ + ................ + ................ + ................ + ................ + ...N..N......... + ...N.NB...N..... + ..NNNN.....N.... + ..DNDNB....N.A.. + ..NNNNB....N.A.. + .NNNNNNNNNNNAA.. + .DNBBNNNNNNBAA.. + ....NNNNNNNBAA.. + ....NNNBBANBAA.. + ...NBANAAANAA... + .....NB..NBA.... + ................ +} +# tile 46 (warg,male) { ................ ...P..P....PP... @@ -483,7 +920,26 @@ Z = (195, 195, 195) ....PPPAA.PPPA.. ................ } -# tile 24 (winter wolf) +# tile 47 (warg,female) +{ + ................ + ...P..P....PP... + ...P.PP......P.. + ..PPPP.......P.A + ..N.NPP......P.A + .P..PPPPP....P.A + PPPPDPPPPPPPPPAA + DPPNDPPPPPPPPPAA + ..DDDPPPPPPPPPAA + PNDNP.PPPPPPPPAA + .PPPPAPPPPAPP.A. + ...PAAPPAAAAPPAA + ...PAAP.AAAAP.A. + .PPPAAPAAAAAPAA. + ....PPPAA.PPPA.. + ................ +} +# tile 48 (winter wolf,male) { ................ ................ @@ -502,7 +958,26 @@ Z = (195, 195, 195) .....NNAA..NNA.. ................ } -# tile 25 (hell hound pup) +# tile 49 (winter wolf,female) +{ + ................ + ................ + ................ + ...N..N.....N... + ...N.NN......N.. + ..NNNN.......N.. + ..DODNN......N.A + .NOONNNNN....N.A + NNONANNNNNNNNNAA + DNNBANNNNNNNNNAA + ..AANNNNNNNBNNAA + ....NBNNNBBANNAA + ....NANBAAAANBA. + ...NNANAAAAANAA. + .....NNAA..NNA.. + ................ +} +# tile 50 (hell hound pup,male) { ................ ................ @@ -521,7 +996,26 @@ Z = (195, 195, 195) .....CC...CA.... ................ } -# tile 26 (hell hound) +# tile 51 (hell hound pup,female) +{ + ................ + ................ + ................ + ................ + ...C..C......... + ...C.CC...C..... + ..CCCC.....C.... + ..DCDCC....C.A.. + .CCCCCC....C.A.. + .PCCACCCCCCCAA.. + .CHAACCCCCCCAA.. + CHC.CCCCCCCCAA.. + .D..CCCCCACCAA.. + ...CCACAAACAA... + .....CC...CA.... + ................ +} +# tile 52 (hell hound,male) { ................ ...C..C....CC... @@ -540,7 +1034,26 @@ Z = (195, 195, 195) ....CCCAA.CCCA.. ................ } -# tile 27 (Cerberus) +# tile 53 (hell hound,female) +{ + ................ + ...C..C....CC... + ...C.CC......C.. + ..CCCC.......C.A + ..DJDCC......C.A + .CCCCCCCC....C.A + CCCCDCCCCCCCCCAA + .CHC.CCCCCCCCCAA + CHC..CCCCCCCCCAA + .D..CCCCCCCCCCAA + ...CCACCCCACC.A. + ...CAACCAAAACCAA + ...CAAC.AAAAC.A. + .CCCAACAAAAACAA. + ....CCCAA.CCCA.. + ................ +} +# tile 54 (Cerberus,male) { ................ ..J..J.......... @@ -559,7 +1072,26 @@ Z = (195, 195, 195) .....JJAA...JA.. ................ } -# tile 28 (gas spore) +# tile 55 (Cerberus,female) +{ + ................ + ..J..J.......... + ..JJJJ.J..J..... + .NJNJ..J.JJ..... + JJJJKAJJJJ....J. + PJJJJANJNKK...J. + DJKJAJJJKJJK..J. + ..AAJPJKAJKJKJJ. + ..JJJDDAJKJJJJJA + ..JJJAAJJJJJJJJA + .JKKKJJJKJJKJJAA + .JJAAKJJKJJJKJAA + JJAAAAJJAAAAJJA. + JAAAAAJAAAAAJAA. + .....JJAA...JA.. + ................ +} +# tile 56 (gas spore,male) { ................ ................ @@ -578,7 +1110,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 29 (floating eye) +# tile 57 (gas spore,female) +{ + ................ + ................ + ................ + .....PFGGFP..... + ....PGFFFFFP.... + ...PFFFFFGGFP... + ...FFGGFFGGFF... + ...GFGGFFFFFG... + ...GFFFFFFFFG... + ...FFFFGGFFFF... + ...PGGFGGFGGP... + ....PGFFFFGP.... + .....PFGGFP..... + ................ + ................ + ................ +} +# tile 58 (floating eye,male) { ................ ................ @@ -597,7 +1148,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 30 (freezing sphere) +# tile 59 (floating eye,female) +{ + ................ + ................ + ......ONNNO..... + ....PNNNNNNNP... + ....NNNNNNNNN... + ...ONNBBBBNNNO.. + ...NNBBEEBBNNN.. + ...NNBEAAEBNNN.. + ...ONBEAAEBNNO.. + ....NBBEEBBNN... + ....PNBBBBNNPAA. + ......ONNNOAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 60 (freezing sphere,male) { ................ ................ @@ -616,7 +1186,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 31 (flaming sphere) +# tile 61 (freezing sphere,female) +{ + ................ + ................ + ......PBBBP..... + ....PBBBBBBBP... + ....BBBBBBBBB... + ...PBPPPBBBBBP.. + ...BBNNBBPPPBB.. + ...BBANPBNNBBB.. + ...PBBPPBANPBP.. + ....BBBBBBPPB... + ....PBBBBBBBPAA. + ......PBBBPAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 62 (flaming sphere,male) { ................ ....C...H....... @@ -635,7 +1224,26 @@ Z = (195, 195, 195) ......JJJJJ..... ................ } -# tile 32 (shocking sphere) +# tile 63 (flaming sphere,female) +{ + ................ + ....C...H....... + ....C....O...C.. + ...C..H.CC...C.. + ...C..C.CC..CC.. + ...DCA.DDC.ACC.. + .AHCDCADDCAADC.. + .AACDCDDDDDADD.. + ..ACDDDJJJDDDD.. + ..ADDCAKDDACDD.. + ...ADAKDDCDAD... + ...ADADHCHCAD... + ....DADDDCDAD... + .....DADDDAD.... + ......JJJJJ..... + ................ +} +# tile 64 (shocking sphere,male) { ................ .....PPPPPP..... @@ -654,7 +1262,26 @@ Z = (195, 195, 195) ......PPPPP..... ................ } -# tile 33 (beholder) +# tile 65 (shocking sphere,female) +{ + ................ + .....PPPPPP..... + ...PPIAAADAPP... + ..PAAAIAAADDAP.. + ..PHAAAPBOAAAP.. + .PAHHAPBBBOAAAP. + .PHAAAPBBBBAHHP. + .PAAAAPPBBBAAAP. + .PAAAIAPPPAAAIP. + .PIIIAAAAAAIIAP. + ..PIAANAAPAAAIP. + ..PIAANAAAPAAP.. + ...PANANAPAPAP.. + ....PPAIAPAPP... + ......PPPPP..... + ................ +} +# tile 66 (beholder,male) { ....OA..OA...... ..OA.DADA.OA.OA. @@ -673,7 +1300,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 34 (kitten) +# tile 67 (beholder,female) +{ + ....OA..OA...... + ..OA.DADA.OA.OA. + ...DA.DADADADD.. + ..OADDOOOODDADO. + ...DDHOAAOHDDA.. + ...JDHOAAOHDDJ.. + ...DDDOOOODDDD.. + ...DDDDDDDDDDD.. + ...JDAOAAAOADJ.. + ....DDAAOAADD... + ....PDDDDDDDPAA. + ......JDDDJAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 68 (kitten,male) { ................ ................ @@ -692,7 +1338,26 @@ Z = (195, 195, 195) ......CCA..CA... ................ } -# tile 35 (housecat) +# tile 69 (kitten,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ...........K.... + ............C... + ....C.C.....L.A. + ...CCCCJ....C.A. + ...NCNCJCCLCL.A. + ...CCCCJCCLCCAA. + ....IACCLLCCCAA. + .....CACCJCCJA.. + ......CCA..CA... + ................ +} +# tile 70 (housecat,male) { ................ ................ @@ -711,7 +1376,26 @@ Z = (195, 195, 195) .....CCA...CA... ................ } -# tile 36 (jaguar) +# tile 71 (housecat,female) +{ + ................ + ................ + ................ + ................ + ................ + ...........K.... + ............C... + ...C.C......L.A. + ..CCCCJ.....C.A. + .CNCNCJCLCLCL.A. + .CCCCCJCLCLCCAA. + ..CICJCCLCLCLAA. + ...AACCLCLCCCAA. + ...CCACCJJCCJA.. + .....CCA...CA... + ................ +} +# tile 72 (jaguar,male) { ................ ................ @@ -730,7 +1414,26 @@ Z = (195, 195, 195) .....CCAA...CA.. ................ } -# tile 37 (lynx) +# tile 73 (jaguar,female) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + ..CC.CJ......C.A + .CCCCCJ......C.A + .GCGCCJCAACCJC.A + .CCCCCJCCCCCCCAA + .CDDDJCAACCAJCAA + ..CCACCAJCCAACAA + ....CACCJJJCCJA. + ....CACAAAAACJA. + ...CKACAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 74 (lynx,male) { ................ ................ @@ -749,7 +1452,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 38 (panther) +# tile 75 (lynx,female) +{ + ................ + ................ + ................ + ................ + O....O.......... + AC.CCA.......... + .CCCA........CA. + .GCGCOAKKKKK.LA. + .CKCCAJCCCCCKA.. + LLDDLLACLLLCCAA. + ..CC.AACLLLCCAA. + .......CAAAACAA. + ....CACAAAACCA.. + ................ + ................ + ................ +} +# tile 76 (panther,male) { ................ ................ @@ -768,7 +1490,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 39 (large cat) +# tile 77 (panther,female) +{ + ................ + ................ + ............AA.. + ..............A. + ..............A. + .A...A........A. + .EA.AE........A. + .AAAAAEAAAAAAA.. + .AAAAAEAAAAAAA.. + .HAHAA.AAAAAAAA. + .AAAA.AAAAAEAAA. + .AAA..AAAAAEAAA. + .....AA....AAA.. + ..AAAA..AAAA.... + ................ + ................ +} +# tile 78 (large cat,male) { ................ ................ @@ -787,7 +1528,26 @@ Z = (195, 195, 195) .....CCAA...CA.. ................ } -# tile 40 (tiger) +# tile 79 (large cat,female) +{ + ................ + ................ + ................ + ................ + ............K... + .............C.. + ...C.C.......L.A + ..CCCCJ......C.A + .CNCNCJCLCCLCL.A + .CCCCCJCLCCLCCAA + ..CDCJCCLCCLCLAA + ...AACCLCCLCCCAA + ....CACCJJJCCJA. + ...CKALAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 80 (tiger,male) { ................ ................ @@ -806,7 +1566,26 @@ Z = (195, 195, 195) .....CCAA..CCA.. ................ } -# tile 41 (displacer beast) +# tile 81 (tiger,female) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + .CCJCC.......C.A + .CAACCJ......A.A + .GAGCCJACACAJC.A + .CCCCCACACACACAA + .ODOCACCACACACAA + .OCOACCJACACACAA + ....CACJAJAJCAA. + ....AACAAAAAAJA. + ...CKACAAAAACAA. + .....CCAA..CCA.. + ................ +} +# tile 82 (displacer beast,male) { ................ ........E....... @@ -825,7 +1604,26 @@ Z = (195, 195, 195) ...AE.AE.EA.EA.. ................ } -# tile 42 (gremlin) +# tile 83 (displacer beast,female) +{ + ................ + ........E....... + .......E.E..AA.. + DEEEA..A.E....A. + ....EA.E.D....A. + .A...A.E......A. + .EA.AEAAA.....A. + .AAAAAAAAAA..A.. + .AAAAEAAAAAAAA.. + .HAHAEAAAAAAAAA. + .AAAAEAAAAAAAAA. + .AAA.AAAAAAAAAA. + .....AE.AEEA.EA. + ....AE.AE.EA.EA. + ...AE.AE.EA.EA.. + ................ +} +# tile 84 (gremlin,male) { ................ ................ @@ -844,7 +1642,26 @@ Z = (195, 195, 195) ...GFA.FGA...... ................ } -# tile 43 (gargoyle) +# tile 85 (gremlin,female) +{ + ................ + ................ + ................ + GGGA....AGGG.... + .GGGFAAAGGG..... + ..FFFFFFFF...... + ...NDFFDNA...... + ...GNFFNGA...... + ...GFFFFGA..AA.. + ...AGFFFAFAAAAA. + ..GFAGFAFFFAAAA. + .GFGFAAFFAFAAAA. + .GF.GFAGAAFAAAA. + ....FFAGFAA.AA.. + ...GFA.FGA...... + ................ +} +# tile 86 (gargoyle,male) { ................ ................ @@ -863,7 +1680,26 @@ Z = (195, 195, 195) ....PFA.FPA..... ................ } -# tile 44 (winged gargoyle) +# tile 87 (gargoyle,female) +{ + ................ + ................ + ...PAPPPPAP..... + ..PA......AP.... + ..P.DD..DDAP.... + ....PD..DPA..... + ....P....PA..AA. + ....AP...A.AAAAA + ...P.AP.A...AAAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 88 (winged gargoyle,male) { ...K......K..... ...KJ....KJ..... @@ -882,7 +1718,26 @@ Z = (195, 195, 195) ....PFA.FPA..... ................ } -# tile 45 (hobbit) +# tile 89 (winged gargoyle,female) +{ + ...K......K..... + ...KJ....KJ..... + ..KJAPPPPAJJ.... + ..KJ......AJ.... + ..KJDD..DDAJ.... + .KJAPD..DPAJJ... + .KJAP....PAAJAA. + KJA.AP...A.AJJAA + J..P.AP.A...AJAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 90 (hobbit,male) { ................ ................ @@ -901,7 +1756,26 @@ Z = (195, 195, 195) ....LLL.LLL..... ................ } -# tile 46 (dwarf) +# tile 91 (hobbit,female) +{ + ................ + ................ + ................ + ................ + ......JJA....... + .....JJJJA...... + ....JLFLFJ...... + ....JLLLLJ...... + ....JKLLKJJ.AA.. + ...CLLLLLLCAAA.. + ..CLALLLLALCA... + ..LLAJJKJALLA... + ...L.LKJLALAA... + .....LLALLA.A... + ....LLL.LLL..... + ................ +} +# tile 92 (dwarf,male) { ................ ................ @@ -920,7 +1794,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 47 (bugbear) +# tile 93 (dwarf,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BLLLE....... + .....OLO...AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 94 (bugbear,male) { ................ ................ @@ -939,7 +1832,26 @@ Z = (195, 195, 195) ........CCA..... ................ } -# tile 48 (dwarf lord) +# tile 95 (bugbear,female) +{ + ................ + ................ + ......K......... + .K..KKK......... + .KKKKKK......... + KADKADKKK....... + KKKKKKKJKK...... + KAPAPAKJJKJ..... + KAAAAAKKJKJJ.... + .KKKKKJKAKKJ.... + ..KAJJCAKKKJ.AA. + ..KK.KKKKKJJAA.. + ...C..KJAKJAA... + .....CCAAKJA.... + ........CCA..... + ................ +} +# tile 96 (dwarf leader,male) { ................ ................ @@ -958,7 +1870,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 49 (dwarf king) +# tile 97 (dwarf leader,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....HHHHH....... + ....BLLLE....... + ....BOLOE..AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 98 (dwarf ruler,male) { ................ ................ @@ -977,7 +1908,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 50 (mind flayer) +# tile 99 (dwarf ruler,female) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....BLLLE...A... + .....OLO...AAAA. + ...EBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 100 (mind flayer,male) { ................ .......IIIIC.... @@ -996,7 +1946,26 @@ Z = (195, 195, 195) ......CFFCAA.... ....IIC.IIA..... } -# tile 51 (master mind flayer) +# tile 101 (mind flayer,female) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + ....IIIIIC...... + ....IAIAIF...... + ....IAIAIF...... + ....IAIAIFI..... + .....FIFIFIC.AA. + ....CBIBBF.CAAA. + ...IIIBBFFACAAA. + ......BBFCAAAA.. + ......CFFCAA.... + ....IIC.IIA..... +} +# tile 102 (master mind flayer,male) { ................ .......IIIIC.... @@ -1015,7 +1984,26 @@ Z = (195, 195, 195) ...EEECEEEAA.... ....IIC.IIA..... } -# tile 52 (manes) +# tile 103 (master mind flayer,female) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + .EEEIIIIICEEEE.. + ..EEIAIAIEEEE... + ...EIAIAIEEE.... + ....IAIAIEEE.... + ....EFIFIEEE.AA. + ....CBIBBEEEAAA. + ...IIIBBEEEEAAA. + ....EEBEEEEAAA.. + ...EEECEEEAA.... + ....IIC.IIA..... +} +# tile 104 (manes,male) { ................ ................ @@ -1034,7 +2022,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 53 (homunculus) +# tile 105 (manes,female) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP......... + ..PPPPP.PPP.P... + ..P..PPPP....... + ..P..PPPPP...P.. + ..PPPPP.PPP..... + ..P.P.P.PP.P.... + .P...P.PPPP..... + .P....PPP.PP.... + ..P....P.P.P.P.. + ........P....... + ................ + ................ +} +# tile 106 (homunculus,male) { ................ ................ @@ -1053,7 +2060,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 54 (imp) +# tile 107 (homunculus,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJJ....... + ......LLC....... + ......LLC....... + .....BBPPPAA.... + ....L.BPPACAA... + ......BAPAAAA... + .....LLALCA..... + ................ + ................ +} +# tile 108 (imp,male) { ................ ................ @@ -1072,7 +2098,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 55 (lemure) +# tile 109 (imp,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDO...... + ......CDD....... + .....GGFFFAA.... + ....C.GFFADAA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 110 (lemure,male) { ................ ................ @@ -1091,7 +2136,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 56 (quasit) +# tile 111 (lemure,female) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP....P.... + ..PPPPP..PP.P... + ..P..PPPPPPPP... + ..P..PPPPPPP.... + ..PPPPPPPPP..... + ....PPPPPPPP.... + ..PPPPPPPPPP.... + ...PPPPPPPPPP... + ..P.P..PPPP.PP.. + ........P.PP.... + ................ + ................ +} +# tile 112 (quasit,male) { ................ ................ @@ -1110,7 +2174,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 57 (tengu) +# tile 113 (quasit,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDOD..... + ......CDD.D..... + .....GGFFFAA.... + ....C.GFFAAADA.. + ....C.GFFJJDA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 114 (tengu,male) { ................ .......PP....... @@ -1129,7 +2212,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 58 (blue jelly) +# tile 115 (tengu,female) +{ + ................ + .......PP....... + ......PPPP...... + .....DPPNP...... + ....DDDPPP...... + ....DDPPPP...... + ....D..PPA...... + .....PIAAIP.AAA. + ....PPPIIPPPAAA. + ....PAPPPPAPAAA. + ....PAHHHHAPAAA. + ....LAPPPPALAAA. + ......PPPPAAAA.. + ......PPPPAA.A.. + .....LLA.LLA.... + ................ +} +# tile 116 (blue jelly,male) { ................ ................ @@ -1148,7 +2250,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 59 (spotted jelly) +# tile 117 (blue jelly,female) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OBEBOE.... + ..OBEOBBEOBBE... + ..OBEOBBEOBBE... + ..BBBGGBGGBEEE.. + ..BBBAGBAGEEEEA. + ..BBBBBBEBEEEEAA + ...BBBBBBBEEEAAA + ....BBBBBEEEAAA. + ......BBBEEAA... + ................ + ................ +} +# tile 118 (spotted jelly,male) { ................ ................ @@ -1167,7 +2288,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 60 (ochre jelly) +# tile 119 (spotted jelly,female) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OCEBOE.... + ..OCEOCCEOBCE... + ..OCEOBCEOCBD... + ..BBBHHBHHBEDD.. + ..CCBAHBAHEEEEA. + ..BBCBBBEBEEDEAA + ...BBBCBBBEEDAAA + ....BCCCBEEDAAA. + ......CCBEEAA... + ................ + ................ +} +# tile 120 (ochre jelly,male) { ................ ................ @@ -1186,7 +2326,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 61 (kobold) +# tile 121 (ochre jelly,female) +{ + ................ + ................ + ................ + .......D........ + ......LCD....... + ...CD.LCDCLD.... + ..LCDLCCDLCCD... + ..LCDLCCDLCCD... + ..CCCGGCGGCDDD.. + ..CCCAGCAGDDDDA. + ..CCCCCCDCDDDDAA + ...CCCCCCCDDDAAA + ....CCCCCDDDAAA. + ......CCCDDAA... + ................ + ................ +} +# tile 122 (kobold,male) { ................ ................ @@ -1205,7 +2364,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 62 (large kobold) +# tile 123 (kobold,female) +{ + ................ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.A.. + ..BPBBBBPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 124 (large kobold,male) { ................ ................ @@ -1224,7 +2402,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 63 (kobold lord) +# tile 125 (large kobold,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.... + ..BPBBBBPAAA.A.. + ..BAPBPAPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 126 (kobold leader,male) { ................ ................ @@ -1243,7 +2440,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 64 (kobold shaman) +# tile 127 (kobold leader,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NCCCN........ + ...CABAC........ + ...CBBPC..A..... + ..CCBABCC.AA.... + ..CCBBBCCAAA.A.. + ..BCCBCCPAAAAA.. + ..BACBCAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 128 (kobold shaman,male) { ................ ................ @@ -1262,7 +2478,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 65 (leprechaun) +# tile 129 (kobold shaman,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NHHHN........ + ...HABAH........ + ...HBBPH..A..... + ..HHBABHH.AA.... + .HHHBBBHHHAA.A.. + .HBHHBHHPHAAAA.. + ..BAHBHAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 130 (leprechaun,male) { ................ ................ @@ -1281,7 +2516,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 66 (small mimic) +# tile 131 (leprechaun,female) +{ + ................ + ................ + ................ + ................ + ......G......... + ......F....K.... + .....GFF..KLK... + ....GFFFF..K.... + .....KLKA.GLAA.. + ...FGFJFFFAKA.A. + ...GAGFFAAAK.AA. + ....LKHKKJAKAA.. + ....GFAGKJAKA... + ...GFAA.GFAK.... + ................ + ................ +} +# tile 132 (small mimic,male) { ................ ................ @@ -1300,7 +2554,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 67 (large mimic) +# tile 133 (small mimic,female) +{ + ................ + ................ + ................ + ................ + ......POP....... + ......NNO....... + ......NNO....... + .......OA....... + .....NNNNN..AA.. + ....OONNNOO.AA.. + ....NANOOANAAA.. + ......NAOAAAA... + ......NAOAA.A... + .....NN.OOA..... + ................ + ................ +} +# tile 134 (large mimic,male) { ................ ................ @@ -1319,7 +2592,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 68 (giant mimic) +# tile 135 (large mimic,female) +{ + ................ + ................ + ................ + ......LLOA...... + ......NNOA...... + ......NNOA...... + ......ONOA...... + .....NNNNO..AAA. + ....OONNNOO.AAA. + ...NOANNNAOOAAA. + ...NAONONOANAAA. + .....NO.NOAAAA.. + .....NO.NOAA.A.. + ....NNO.NOOA.... + ................ + ................ +} +# tile 136 (giant mimic,male) { ................ ......NNO....... @@ -1338,7 +2630,26 @@ Z = (195, 195, 195) ...NNNO.NNOOA... ................ } -# tile 69 (wood nymph) +# tile 137 (giant mimic,female) +{ + ................ + ......NNO....... + .....NNNNOA..... + .....NNNNOA..... + .....NNNNOA..... + .....ONNNOA..... + ..PONNOOONOOPAAA + .PONONNNNOONOPAA + .ONOANNNNOAONOAA + .NNOANNNNOAOOOAA + ...AANNONNAAAAAA + ....PNO.NNPAAAAA + ....ONO.NNOAA..A + ....NNO.NNOAA..A + ...NNNO.NNOOA... + ................ +} +# tile 138 (wood nymph,male) { ................ ................ @@ -1357,7 +2668,26 @@ Z = (195, 195, 195) ....KJKJKJKJ.... ................ } -# tile 70 (water nymph) +# tile 139 (wood nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLFKKKKLA.... + .HKFLFKKKKA..... + OHKJFKKJJK.A.... + HKKLJJGKAAAAAAA. + .JJAJGDKJAAAAA.. + ..JA.KKJJAAAA... + ...J.KKKKJAA.... + ....JKKKKKJA.... + ....KJKJKJKJ.... + ................ +} +# tile 140 (water nymph,male) { ................ ................ @@ -1376,7 +2706,26 @@ Z = (195, 195, 195) ....BPBPBPBP.... ................ } -# tile 71 (mountain nymph) +# tile 141 (water nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLJBBBBLA.... + .HBJLJBBBBA..... + OHBPJBBPPB.A.... + HBBLPPNBAAAAAAA. + .PPAPNDB.AAAAA.. + ..PA.BBPPAAAA... + ...P.BBBBPAA.... + ....PBBBBBPA.... + ....BPBPBPBP.... + ................ +} +# tile 142 (mountain nymph,male) { ................ ................ @@ -1395,7 +2744,26 @@ Z = (195, 195, 195) ....OLOLOLOL.... ................ } -# tile 72 (goblin) +# tile 143 (mountain nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLCOOOOLA.... + .HOCLCOOOOA..... + OHOLCOOLLO.A.... + HOOKLLIOAAAAAAA. + .LLALIBOKAAAAA.. + ..LA.OOLLAAAA... + ...L.OOOOLAA.... + ....LOOOOOLA.... + ....OLOLOLOL.... + ................ +} +# tile 144 (goblin,male) { ................ ................ @@ -1414,7 +2782,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 73 (hobgoblin) +# tile 145 (goblin,female) +{ + ................ + ................ + ................ + ....LK.......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IGIGIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICJAAAAA... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 146 (hobgoblin,male) { ................ .....LK......... @@ -1433,7 +2820,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 74 (orc) +# tile 147 (hobgoblin,female) +{ + ................ + .....LK......... + ....CKA......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IHIHIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICCAAAAA... + ....IIIIJA...... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 148 (orc,male) { ................ ................ @@ -1452,7 +2858,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 75 (hill orc) +# tile 149 (orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KCCAKKKA.AA... + ..BPCKJ.P.AAA... + ..BAGGFAAPNO.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BJACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 150 (hill orc,male) { ................ ................ @@ -1471,7 +2896,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 76 (Mordor orc) +# tile 151 (hill orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LKLA........ + .....K.A........ + ..KGGAFFKA.AA... + ..JKGFF.K.AAA... + ..JAHHFAAKNO.... + ..JAGFFNOAAA.... + ....GNNFAAAAAA.. + ...GGAGFAAAA.... + ..KJJAKJJA...... + ................ + ................ +} +# tile 152 (Mordor orc,male) { ................ ................ @@ -1490,7 +2934,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 77 (Uruk-hai) +# tile 153 (Mordor orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KIIAIIKA.AA... + ..BPIDD.P.AAA... + ..BAGGFAAP.O.... + ..BAIDDNOAAA.... + ....BNOJAAAAAA.. + ...BIAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 154 (Uruk-hai,male) { ................ ................ @@ -1509,7 +2972,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 78 (orc shaman) +# tile 155 (Uruk-hai,female) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..IIIAIIIA...... + ..BPIKI.BAAAA... + ..BIG.PPPPAAA... + .NBAD.PDDPAA.... + ..BNNJPDDPAA.... + ....INPPPPAAAA.. + ...BIAK.AAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 156 (orc shaman,male) { ................ ................ @@ -1528,7 +3010,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 79 (orc-captain) +# tile 157 (orc shaman,female) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..CCCACCCA...... + ..BPCKC.BAAAA... + ..BCGGFJBAAAA... + ..BAJJCJBAAA.... + ..BAJJCJBAAA.... + ....CACJAAAAAA.. + ...BCACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 158 (orc-captain,male) { ................ ................ @@ -1547,7 +3048,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 80 (rock piercer) +# tile 159 (orc-captain,female) +{ + ................ + ................ + .....OA......... + ...NNOOPA....... + ....LPLA........ + ...IPPPA........ + ..DIIPADDA.AA... + ..BPIAD.P.AAA... + ..BAGGFAAP.O.... + ..BAGGFAAP.O.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BDAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 160 (rock piercer,male) { .JKKKKKKKKJAAA.. ..JJGKGKJJAAAA.. @@ -1566,7 +3086,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 81 (iron piercer) +# tile 161 (rock piercer,female) +{ + .JKKKKKKKKJAAA.. + ..JJGKGKJJAAAA.. + ...JKKKJJAAAA... + ...JJKKJJAAAA... + ....JKKJAAAA.... + ....JJKJ.AAA.... + ....JJKJ.AAA.... + ....JJJJ..A..... + .....JJ...A..... + .....JJ...A..... + .....JJ......... + .....JJ......... + .....J.......... + .....J.......... + ................ + ................ +} +# tile 162 (iron piercer,male) { .BPPPPPPPP.AAA.. ..BBDPDP..AAAA.. @@ -1585,7 +3124,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 82 (glass piercer) +# tile 163 (iron piercer,female) +{ + .BPPPPPPPP.AAA.. + ..BBDPDP..AAAA.. + ...BPPP..AAAA... + ...PBPP..AAAA... + ....BPP.AAAA.... + ....BBP.AAAA.... + ....PBP.AAAA.... + ....PBP...A..... + .....BP...A..... + .....BP...A..... + .....BP......... + .....BP......... + .....B.......... + .....P.......... + ................ + ................ +} +# tile 164 (glass piercer,male) { .NBBBBBBBBPAAA.. ..NNDBDBPPAAAA.. @@ -1604,7 +3162,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 83 (rothe) +# tile 165 (glass piercer,female) +{ + .NBBBBBBBBPAAA.. + ..NNDBDBPPAAAA.. + ...NBBBPPAAAA... + ...PNBBPPAAAA... + ....NBBPAAAA.... + ....NNBPAAAA.... + ....PNBPAAAA.... + ....PNBP..A..... + .....NB...A..... + .....NB...A..... + .....NB......... + .....NB......... + .....N.......... + .....P.......... + ................ + ................ +} +# tile 166 (rothe,male) { ................ ...........K.... @@ -1623,7 +3200,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 84 (mumak) +# tile 167 (rothe,female) +{ + ................ + ...........K.... + ............K... + ............K... + .......JJJKKJ... + .....JKKKKKKK... + ..AAAKKKKKKKK... + .AAAAAKKKKKKKA.. + AAKKAAKKKKKAKA.. + .KEKKAKKKJAAKA.. + .KKKJAKKAJAAK... + ..KJAAAKAAA..... + ..AAKA.KA....... + ..A..A.K........ + ................ + ................ +} +# tile 168 (mumak,male) { ................ ...........P.... @@ -1642,7 +3238,26 @@ Z = (195, 195, 195) PPPA............ .AA............. } -# tile 85 (leocrotta) +# tile 169 (mumak,female) +{ + ................ + ...........P.... + .PP.........P... + PPP...PPPPP.P... + PPPPPPPPP.PP.... + PPPPBPPBBP.PP... + PPPBPPPPPP.PP... + .PDPPDDPP.PPP... + ..BPPDDP.PPPPA.. + ..PPPPPPPPPPPA.. + ..PPPPO..PAPPA.. + .OOPPOOAPPAPPA.. + OOPPOOAAPPA..... + .PPPAPA.PP...... + PPPA............ + .AA............. +} +# tile 170 (leocrotta,male) { ................ ..A..A.......... @@ -1661,7 +3276,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 86 (wumpus) +# tile 171 (leocrotta,female) +{ + ................ + ..A..A.......... + ..AOOA....J..... + ..AOOAA....J.... + .APOAFA....J.... + .APOAAA.JJJJ.... + .AOPAAJKKKKKJ... + .AOAAKJJKKJKJA.. + ...JKKKKKJAKKA.. + ...JKJKKJAAKKA.. + ..JKJAKKAAPAPA.. + ..KKAAKKAAPAPA.. + .PAPAAPAPA...... + .PAPA.PAPA...... + ................ + ................ +} +# tile 172 (wumpus,male) { ................ ............B... @@ -1680,7 +3314,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 87 (titanothere) +# tile 173 (wumpus,female) +{ + ................ + ............B... + .............B.. + .......BBBBB.B.. + ....BBBPPBBBB... + ...BOOBBBPBBBB.. + ...OOBBBBBPBBB.. + ..DABBAABBPBBBA. + .BOOBBDABEBBEBAA + .BOBBBBBBEBEBBAA + .BBBBBBBEBBABBAA + .EBBBBBEABBABBAA + ..EEEEEAABBA.... + .....BBA.BB..... + ................ + ................ +} +# tile 174 (titanothere,male) { ................ ................ @@ -1699,7 +3352,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 88 (baluchitherium) +# tile 175 (titanothere,female) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + .PPPPP.PPPPPPP.. + .PPEPP.PPPP.PPA. + PBPPP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 176 (baluchitherium,male) { ................ ................ @@ -1718,7 +3390,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 89 (mastodon) +# tile 177 (baluchitherium,female) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + BPPPPP.PPPPPPP.. + B.PEPP.PPPP.PPA. + PB.PP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 178 (mastodon,male) { ................ ................ @@ -1737,7 +3428,26 @@ Z = (195, 195, 195) .......PPA...... ................ } -# tile 90 (sewer rat) +# tile 179 (mastodon,female) +{ + ................ + ................ + ................ + ................ + ................ + ..O...O......... + .N..POP.P....... + N..PNPPPPP...... + O.PNPPPPPP.PP... + O.POPEPPP.PPPPP. + .OPOPOP..PPPPPAP + ..PPOPP.PPPPPPAA + ..PPAAAPPPPAPPA. + ..P...APPAAAPPA. + .......PPA...... + ................ +} +# tile 180 (sewer rat,male) { ................ ................ @@ -1756,7 +3466,26 @@ Z = (195, 195, 195) .........JJA.... ................ } -# tile 91 (giant rat) +# tile 181 (sewer rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKK.... + ..KKKKJKKJKKK... + ..JAKAKJJJKKKJ.. + ..GKGKJKAKKAKKA. + .KKJJJJKAKAAKKA. + .PJJAAKKAJAJKA.. + ..AA.KKA..JKA... + .........JJA.... + ................ +} +# tile 182 (giant rat,male) { ................ ................ @@ -1775,7 +3504,26 @@ Z = (195, 195, 195) ..........JJA... ................ } -# tile 92 (rabid rat) +# tile 183 (giant rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 184 (rabid rat,male) { ................ ................ @@ -1794,7 +3542,26 @@ Z = (195, 195, 195) .OOOOOOOO.JJA... ................ } -# tile 93 (wererat) +# tile 185 (rabid rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJOOOKAJKAAKKA + .PJOOAKKAJJAJKA. + ..AOOOKAA..JKA.. + .OOOOOOOO.JJA... + ................ +} +# tile 186 (wererat,male) { ................ ................ @@ -1813,7 +3580,26 @@ Z = (195, 195, 195) ..........JJA... ................ } -# tile 94 (rock mole) +# tile 187 (wererat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..LLLLKJKJJKKKJ. + ..FLFLLJKJJKKKK. + ..LLLLJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 188 (rock mole,male) { ................ ................ @@ -1832,7 +3618,26 @@ Z = (195, 195, 195) AN.NAA.AA...AA.. .AAAA........... } -# tile 95 (woodchuck) +# tile 189 (rock mole,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......AAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + ..JAJAAAAAAAAAA. + .AAAAAAAAAAAAAA. + AN.NAAAAAAAAAAA. + A...AAAA...AAA.. + AN.NAA.AA...AA.. + .AAAA........... +} +# tile 190 (woodchuck,male) { ................ ................ @@ -1851,7 +3656,26 @@ Z = (195, 195, 195) .....JJAAJJAA... ................ } -# tile 96 (cave spider) +# tile 191 (woodchuck,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .......KJA...... + ......NKKNA..... + ......KNOJA..... + ......KNOJA..... + .....KKKKKJA.... + ....JJKLLJJJAA.. + ......KLLJAAAAA. + ......KJJJAAAA.. + .....JJAAJJAA... + ................ +} +# tile 192 (cave spider,male) { ................ ................ @@ -1870,7 +3694,26 @@ Z = (195, 195, 195) .....PAA.APA.... ................ } -# tile 97 (centipede) +# tile 193 (cave spider,female) +{ + ................ + ................ + ................ + ................ + ................ + ........PA...... + .......PA....... + ......PAPBBA.... + ...PA.APBPPPA... + ...ABBPPAPPAA.PA + ...GPPPPAAAPPPAA + ...PPGPAAPPAAAA. + ..D.PAPAPAAPPA.. + ....D.PAAPA.APA. + .....PAA.APA.... + ................ +} +# tile 194 (centipede,male) { ................ ................ @@ -1889,7 +3732,26 @@ Z = (195, 195, 195) ...B............ ................ } -# tile 98 (giant spider) +# tile 195 (centipede,female) +{ + ................ + ................ + ......PBPP...... + ....BBPAAA...... + ..PPBAAA........ + .PAPBBBPPPP..... + ..PAAPPBBBA..... + ....PAAPAPBPP... + ......AABBPP.... + ......BB.PPAP... + ....PBBPPAP.A... + ...GPPPAP.AP.... + ...PPGPAAP...... + ..B.PAA......... + ...B............ + ................ +} +# tile 196 (giant spider,male) { ................ ................ @@ -1908,7 +3770,26 @@ Z = (195, 195, 195) .....JAA.AJA.... ................ } -# tile 99 (scorpion) +# tile 197 (giant spider,female) +{ + ................ + ................ + ................ + ................ + ................ + ........JA...... + .......JA....... + ......JAJKKA.... + ...JA.AJKJJJA... + ...AKKJJAJJAA.JA + ...GJJJJAAAJJJAA + ...JJGJAAJJAAAA. + ..D.JAJAJAAJJA.. + ....D.JAAJA.AJA. + .....JAA.AJA.... + ................ +} +# tile 198 (scorpion,male) { ................ ................ @@ -1927,7 +3808,26 @@ Z = (195, 195, 195) .......JAAJA.... ................ } -# tile 100 (lurker above) +# tile 199 (scorpion,female) +{ + ................ + ................ + .......JKJKJAA.. + ......JA.JKJKKA. + .......KA...JJJA + ......JA....KKJA + ...........JJJKA + .......AJKKAJJA. + .....AAJKJJJAA.. + ...AKKJJAJJAA... + ...GJJJJAAAJJJA. + ...JJGJAAJJAAAJ. + ..D.JAJAJAAJJA.. + ....D.JAAJA.JAA. + .......JAAJA.... + ................ +} +# tile 200 (lurker above,male) { .AAAAAAAAAAAAAAA ...AAGFAAGFAAA.. @@ -1946,7 +3846,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 101 (trapper) +# tile 201 (lurker above,female) +{ + .AAAAAAAAAAAAAAA + ...AAGFAAGFAAA.. + ...AAAAAAAAAAA.. + ....AODODODOA... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 202 (trapper,male) { ................ ................ @@ -1965,7 +3884,26 @@ Z = (195, 195, 195) ...AAGFAAGFAAA.. .AAAAAAAAAAAAAAA } -# tile 102 (pony) +# tile 203 (trapper,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....AODODODOA... + ...AAAAAAAAAAA.. + ...AAGFAAGFAAA.. + .AAAAAAAAAAAAAAA +} +# tile 204 (pony,male) { ................ ................ @@ -1984,7 +3922,26 @@ Z = (195, 195, 195) .....LA...L..... ................ } -# tile 103 (white unicorn) +# tile 205 (pony,female) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ...KKEKJ........ + ..KKJKKJ........ + ..JJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKJ..... + ...KKKKKKKJJAAA. + ...KJKJJJJJAJA.. + ...JAJAAAAJAA... + ...JAJAAJAJA.... + ...L.JAALAJ..... + .....LA...L..... + ................ +} +# tile 206 (white unicorn,male) { ................ ..HP............ @@ -2003,7 +3960,26 @@ Z = (195, 195, 195) .....LA...L..... ................ } -# tile 104 (gray unicorn) +# tile 207 (white unicorn,female) +{ + ................ + ..HP............ + ..PHO.NN........ + ...PHNNB........ + ...ONENB........ + ..ONNNNB........ + ..NOANNBAA...... + ...AONNBA....... + ...ONNNONNN..... + ..NONNNNONNOAAA. + ..N.ONONNONAOA.. + ..OAANAAAAOAA... + ...LAOAAOAOA.... + .....OAALAO..... + .....LA...L..... + ................ +} +# tile 208 (gray unicorn,male) { ................ ..HP............ @@ -2022,7 +3998,26 @@ Z = (195, 195, 195) .....LA...L..... ................ } -# tile 105 (black unicorn) +# tile 209 (gray unicorn,female) +{ + ................ + ..HP............ + ..PHO.PP........ + ...PHPPN........ + ....PGPN........ + ...PPPPN........ + ..PPAPPNAA...... + ...APPPNA....... + ....PPP.PPP..... + ..P.PPPP.PP.AAA. + ..P..P.PP.PA.A.. + ..PAAPAAAA.AA... + ...LA.AA.A.A.... + ......AALA...... + .....LA...L..... + ................ +} +# tile 210 (black unicorn,male) { ................ ..HP............ @@ -2041,7 +4036,26 @@ Z = (195, 195, 195) .....LP...L..... ................ } -# tile 106 (horse) +# tile 211 (black unicorn,female) +{ + ................ + ..HP............ + ..PHO.AA........ + ...PHAAJ........ + ...AADAJ........ + ..AAAAAJ........ + ..AAPAAJPP...... + ...PAAAJP....... + ...AAAAAAAA..... + ..AAAAAAAAAAPPP. + ..A.AAAAAAAPAP.. + ..APPAPPAPAPP... + ...LPAPPAPAP.... + .....APPLPA..... + .....LP...L..... + ................ +} +# tile 212 (horse,male) { ................ ................ @@ -2060,7 +4074,26 @@ Z = (195, 195, 195) .....LA....L.... ................ } -# tile 107 (warhorse) +# tile 213 (horse,female) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ..KKKEKJ........ + .KKKJKKJAA...... + .JJJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKKJA... + ..KKKKKKKKKKJA.. + ..KJJKJJJJJKAJA. + ..JAAJAAAAAJAJA. + ..JAAJAAAJAJAA.. + ..LA.JAA.L.JA... + .....LA....L.... + ................ +} +# tile 214 (warhorse,male) { ................ .....JJJ........ @@ -2079,7 +4112,26 @@ Z = (195, 195, 195) .....LC....LC... ................ } -# tile 108 (fog cloud) +# tile 215 (warhorse,female) +{ + ................ + .....JJJ........ + ...KKKKJJ....... + .KKKKEKJJ....... + KKKKKKKJJAA..... + JKKKJKKJJAA..... + .JJJAKKJJAA..... + ...AKKKJJA...... + ...KKKKKKKKKJA.. + ..KKKKKKKKKKKJA. + ..KKJKKJKKJKKJJA + ..KJAKJAKJAKJAJA + ..KJAKJAKJAKJA.. + ..LC.KJALC.KJ... + .....LC....LC... + ................ +} +# tile 216 (fog cloud,male) { .......P........ ....P..P........ @@ -2098,7 +4150,26 @@ Z = (195, 195, 195) ..P..P.P..P..... ................ } -# tile 109 (dust vortex) +# tile 217 (fog cloud,female) +{ + .......P........ + ....P..P........ + .....P.P...P.... + ...P.......P.... + ..P..P.P.P...... + ....PP.PP.P.P... + .P..APAPPP..P... + ...P.PPPP.PP.... + ......PPPPP.P.P. + ...P.PPPPP..P... + ....P..P.PP.P... + .P...P.P...PPP.. + ..P.P....PP..... + .......P....P... + ..P..P.P..P..... + ................ +} +# tile 218 (dust vortex,male) { ................ ................ @@ -2117,7 +4188,26 @@ Z = (195, 195, 195) ....KKKK..K..... ................ } -# tile 110 (ice vortex) +# tile 219 (dust vortex,female) +{ + ................ + ................ + ....K..KKKK..... + ...K..KKJJJK.... + ..K..KJJJJ..K... + .KJ.KJJ.JKK..K.. + .KJJKJ.JJJJK.... + .KJJJJ....JJK... + .KKJ.J...J.JKK.. + ..KJJ....JJJJK.. + ...KJJJJ.JKJJK.. + .K..KKJ.JJK.JK.. + ..K..JJJJK..K... + ...KJJJKK..K.... + ....KKKK..K..... + ................ +} +# tile 220 (ice vortex,male) { ................ ................ @@ -2136,7 +4226,26 @@ Z = (195, 195, 195) ....NNNN..N..... ................ } -# tile 111 (energy vortex) +# tile 221 (ice vortex,female) +{ + ................ + ................ + ....N..NNNN..... + ...N..NNOOON.... + ..N..NOOOO..N... + .NO.NOO.ONN..N.. + .NOONO.OOOON.... + .NOOOO....OON... + .NNO.O...O.ONN.. + ..NOO....OOOON.. + ...NOOOO.ONOON.. + .N..NNO.OON.ON.. + ..N..OOOON..N... + ...NOOONN..N.... + ....NNNN..N..... + ................ +} +# tile 222 (energy vortex,male) { ................ ................ @@ -2155,7 +4264,26 @@ Z = (195, 195, 195) ....EEEE..E..... ................ } -# tile 112 (steam vortex) +# tile 223 (energy vortex,female) +{ + ................ + ................ + ....E..EEEE..... + ...E..EEAAAE.... + ..E..EAAAA..E... + .EA.EAAAAIE..E.. + .EAAIAAAAAAE.... + .EAAAAAAAAAAE... + .EEAAAAAAAAAEE.. + ..EAAAAAAAAAAE.. + ...EAAAAAAIAAE.. + .E..EIAAAAE.AE.. + ..E..AAAAE..E... + ...EAAAEE..E.... + ....EEEE..E..... + ................ +} +# tile 224 (steam vortex,male) { ................ ................ @@ -2174,7 +4302,26 @@ Z = (195, 195, 195) ....PPPP..P..... ................ } -# tile 113 (fire vortex) +# tile 225 (steam vortex,female) +{ + ................ + ................ + ....P..PPPP..... + ...P..PPBBBP.... + ..P..PBBBB..P... + .PB.PBBPBPP..P.. + .PBBPBPBBBBP.... + .PBBBBP.PPBBP... + .PPBPB...BPBPP.. + ..PBBPP.PBBBBP.. + ...PBBBBPBPBBP.. + .P..PPBPBBP.BP.. + ..P..BBBBP..P... + ...PBBBPP..P.... + ....PPPP..P..... + ................ +} +# tile 226 (fire vortex,male) { ................ ................ @@ -2193,7 +4340,26 @@ Z = (195, 195, 195) ....DDDD..D..... ................ } -# tile 114 (baby long worm) +# tile 227 (fire vortex,female) +{ + ................ + ................ + ....D..DDDD..... + ...D..DDCCCD.... + ..D..DCCCC..D... + .DC.DCCHCDD..D.. + .DCCDCHCCCCD.... + .DCCCCHHHHCCD... + .DDCHCHHHCHCDD.. + ..DCCHHHHCCCCD.. + ...DCCCCHCDCCD.. + .D..DDCHCCD.CD.. + ..D..CCCCD..D... + ...DCCCDD..D.... + ....DDDD..D..... + ................ +} +# tile 228 (baby long worm,male) { ................ ................ @@ -2212,7 +4378,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 115 (baby purple worm) +# tile 229 (baby long worm,female) +{ + ................ + ................ + ................ + ................ + ......CLC....... + ......LLL....... + .....GGAGG.A.... + .....GGAGGAAA... + ......LLLAAA.C.. + ......LLLAA.CC.. + ......CLLCCCCA.. + .......LLLCCA... + ........CLL..... + ................ + ................ + ................ +} +# tile 230 (baby purple worm,male) { ................ ................ @@ -2231,7 +4416,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 116 (long worm) +# tile 231 (baby purple worm,female) +{ + ................ + ................ + ................ + .......I........ + ......III....... + ......III....... + .....GGAGG.A.... + .....GGAGGAAA... + ......IIIAAA.D.. + ......IIIAA.DD.. + ......IIIDDDDA.. + .......IIIDDA... + ........III..... + ................ + ................ + ................ +} +# tile 232 (long worm,male) { ................ ................ @@ -2250,7 +4454,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 117 (purple worm) +# tile 233 (long worm,female) +{ + ................ + ................ + .....CLC........ + ....CLLLC....... + ....LLLLL....... + ...GGGLGGGAA.... + ...GAGLGAGAAA... + ...GGGLGGGAAA... + ....LLLLLAAACC.. + ....LLLLLAACCC.. + ....CLLLLCCCCA.. + .....LLLLLCCA... + ......CLLLL..... + ................ + ................ + ................ +} +# tile 234 (purple worm,male) { ................ ................ @@ -2269,7 +4492,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 118 (grid bug) +# tile 235 (purple worm,female) +{ + ................ + ................ + .....DID........ + ....DIIID....... + ....IIIII....... + ...GGGIGGGAA.... + ...GAGIGAGAAA... + ...GGGIGGGAAA... + ....IIIIIAAADD.. + ....IIIIIAADDD.. + ....DIIIIDDDDA.. + .....IIIIIDDA... + ......DIIII..... + ................ + ................ + ................ +} +# tile 236 (grid bug,male) { ................ ................ @@ -2288,7 +4530,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 119 (xan) +# tile 237 (grid bug,female) +{ + ................ + ................ + ................ + ................ + ..D....NHCN..D.. + .D.D..NHDNCNDED. + D.D.D.NNHCND.DED + .D...D.NNHDND... + .DDD..ENNG.D.DE. + ..DDDDEEEEGD..DE + D.....DEHEE.D... + .D.......H...... + ................ + ................ + ................ + ................ +} +# tile 238 (xan,male) { ................ ................ @@ -2307,7 +4568,26 @@ Z = (195, 195, 195) ..G..AAAAAA..... ......AA.AA..... } -# tile 120 (yellow light) +# tile 239 (xan,female) +{ + ................ + ................ + ..........GG.... + ...HHH...GOGG... + .....HH..GGGG... + ...HHHHH.GGG.... + .......GG...AAA. + .....GOGGHHAAAA. + ....GOGG..HHAAA. + NNNGOGG.AAHHHA.. + NANGGGG.AAHAH... + NNNGGNNNAAAAAA.. + ..GGGNANAA.AAA.. + .GGGANNNAA.A.A.. + ..G..AAAAAA..... + ......AA.AA..... +} +# tile 240 (yellow light,male) { ................ ......NA........ @@ -2326,7 +4606,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 121 (black light) +# tile 241 (yellow light,female) +{ + ................ + ......NA........ + ......HA........ + ..NA.NHNA.NA.... + ...LALHLALA..... + ....NHHHNA...... + ..NLHHHHHLNA.... + NHHHHHHHHHHHNA.. + ..NLHHHHHLNA.... + ....NHHHNA...... + ...LALHLALA..... + ..NA.NNNA.NA.... + ......HA........ + ......NA........ + ................ + ................ +} +# tile 242 (black light,male) { ................ ......AA........ @@ -2345,7 +4644,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 122 (zruty) +# tile 243 (black light,female) +{ + ................ + ......AA........ + ......AA........ + ..AA.AAAA.AA.... + ...AAAAAAAA..... + ....AAAAAA...... + ..AAAAAAAAAA.... + AAAAAAAAAAAAAA.. + ..AAAAAAAAAA.... + ....AAAAAA...... + ...AAAAAAAA..... + ..AA.AAAA.AA.... + ......AA........ + ......AA........ + ................ + ................ +} +# tile 244 (zruty,male) { ................ ......FFGF...... @@ -2364,7 +4682,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 123 (couatl) +# tile 245 (zruty,female) +{ + ................ + ......FFGF...... + ....OOFGFFFF.... + ...AOFGFOOKFF... + ...FFGFAOAJKKF.. + ..FFFFFFJAAJKK.. + ..ODOFFJAJJKKJA. + ..DDDDJAJJKJJAA. + ..JODOAJJJAJJAAA + .KKJAJJJKJAJJAAA + .KKAAJKKKKJAAAAA + ...AJJKKKKJJAAAA + ...KJJAAAAKJAAA. + ..JKJJJAAJJJJ... + ................ + ................ +} +# tile 246 (couatl,male) { ................ ................ @@ -2383,7 +4720,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 124 (Aleax) +# tile 247 (couatl,female) +{ + ................ + ................ + ........I....I.. + ....KKAIII..III. + ...NAOJAKI.IIIII + ...KKJAJJKKK..II + ...KKAAIJJJJJ..I + ...FAA.I...KJ..I + ..FAFA..AAAKJAA. + .......AAAJJAAA. + ......AKKJJAAA.. + ......KJAAAAAJA. + .....JJAA...JA.. + ......JJJJJJA... + ................ + ................ +} +# tile 248 (Aleax,male) { ................ ......BBBB..I... @@ -2402,7 +4758,26 @@ Z = (195, 195, 195) ..BF.LLAALLAFB.. ................ } -# tile 125 (Angel) +# tile 249 (Aleax,female) +{ + ................ + ......BBBB..I... + ..I..BF...B..... + ....BF.HHA.B.... + ...BF.HHHHA.B.I. + ...BF.LFLFA.FB.. + .I.BF.LLLLA.FB.. + ...BF.ALLA.FB... + ..BF.LLAALL.ABA. + .BF.LLLLLLLLAFB. + .BF.LALLLLALAFB. + .BF.LAJJKJALAFB. + ..BF..LJJLAAABA. + ...BF.LLALAABA.. + ..BF.LLAALLAFB.. + ................ +} +# tile 250 (Angel,male) { ................ ................ @@ -2421,7 +4796,26 @@ Z = (195, 195, 195) ....BNNNNNNP.... ................ } -# tile 126 (ki-rin) +# tile 251 (Angel,female) +{ + ................ + ................ + ......HHHH...... + ................ + .......CC....... + ......CLLC..AA.. + ......PLLP....A. + ......NPPPA.A... + .....BBLLPPAAA.. + .....NNLLPPAAA.. + ......BNNPAAAA.. + ......BNNPAAAA.. + .....BNNNPAA.A.. + .....BNNNNPA.... + ....BNNNNNNP.... + ................ +} +# tile 252 (ki-rin,male) { ................ ................ @@ -2440,7 +4834,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 127 (Archon) +# tile 253 (ki-rin,female) +{ + ................ + ................ + ..LP............ + ..PLO.C.C....... + ...PLCCD........ + ...KCIKD........ + ..KCCCCD........ + ..CKACCDA....... + ...ACCCCCC...A.. + ...KCCCKCCKAA... + ..CAKCKCKCAKA... + ..CAAKAKAKA..... + ...L.KALAK...... + .....LA..L...... + ................ + ................ +} +# tile 254 (Archon,male) { ................ ......OOOO...... @@ -2459,7 +4872,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 128 (bat) +# tile 255 (Archon,female) +{ + ................ + ......OOOO...... + .....OOOOOO..... + .....OJLLJO..... + .....OLLLLO..... + ....OOJLLJOO.... + ......AJJA...... + .....AAAAAAA.... + ....AAAAAAAAA... + ...OAAOAAAJLJ... + ..OOAOAAAACJC... + ....LAAAACCJCC.. + .....AAAAAJJJ... + ....AAAAAAAA.... + ................ + ................ +} +# tile 256 (bat,male) { ................ ................ @@ -2478,7 +4910,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 129 (giant bat) +# tile 257 (bat,female) +{ + ................ + ................ + ................ + ................ + ...JJJCACJJJ.... + ..JJAAHJHAAJJ... + ..JA...JA..AJ... + ................ + ................ + ......AAAA...... + ....AAAAAAAA.... + ...AAA.AA.AAA... + .......AA....... + ................ + ................ + ................ +} +# tile 258 (giant bat,male) { ................ ................ @@ -2497,7 +4948,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 130 (raven) +# tile 259 (giant bat,female) +{ + ................ + ................ + ................ + ...JK.J.J.JK.... + ..KJJJCACJJKJ... + .JJJAAHJHAAJJK.. + .KJA...JA..AJJ.. + ..JA.......AJ... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 260 (raven,male) { ..AAAA...AAA.... .AAAAAA.AAA..... @@ -2516,7 +4986,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 131 (vampire bat) +# tile 261 (raven,female) +{ + ..AAAA...AAA.... + .AAAAAA.AAA..... + AAAAAAAAAAA.AA.. + A...AAAAAAAAAAA. + ......AAAAAAAAA. + .....AAAA.....AA + .....ADA.......A + .....PA......... + .....P.......... + .........P.P.P.. + ........P.P.P.P. + .......P.P.P.... + ........P.P.P... + ...........P.... + ................ + ................ +} +# tile 262 (vampire bat,male) { ................ ................ @@ -2535,7 +5024,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 132 (plains centaur) +# tile 263 (vampire bat,female) +{ + ................ + ................ + ................ + ...AA.A.A.AA.... + ..AAAAAAAAAAA... + .AAAA.DAD.AAAA.. + .AAA...A...AAA.. + ..A.........A... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 264 (plains centaur,male) { ................ ...KKA.......... @@ -2554,7 +5062,26 @@ Z = (195, 195, 195) ....CA...C...... ................ } -# tile 133 (forest centaur) +# tile 265 (plains centaur,female) +{ + ................ + ...KKA.......... + ...LLAA......... + .AAKKAA......... + .LLAALLA........ + LALLLLALA....... + LALLLKALA.A..... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 266 (forest centaur,male) { ................ ................ @@ -2573,7 +5100,26 @@ Z = (195, 195, 195) ....CA...C...... ................ } -# tile 134 (mountain centaur) +# tile 267 (forest centaur,female) +{ + ................ + ................ + ................ + ...KKA.......... + LA.LLAALA....... + LAALLAALA....... + .LLAALLA........ + ..LLLLA.A....... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKA.A.. + .KAKJJJJKJAAAA.. + .KAAKAAJAKA..... + ..C.KAAKAK...... + ....CA...C...... + ................ +} +# tile 268 (mountain centaur,male) { ................ ................ @@ -2592,7 +5138,26 @@ Z = (195, 195, 195) ....CA...C...... ................ } -# tile 135 (baby gray dragon) +# tile 269 (mountain centaur,female) +{ + ................ + ................ + ...KKA.......... + ...LLAA......... + ..AKKAA......... + .LJJJJLA........ + LAJKKJALA.A..... + LAKKKKALAAA..... + ..JJJJKJJKAA.... + .KJJJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 270 (baby gray dragon,male) { ................ ................ @@ -2611,7 +5176,26 @@ Z = (195, 195, 195) .....BPAA..PPAA. ...........PAA.. } -# tile 136 (baby silver dragon) +# tile 271 (baby gray dragon,female) +{ + ................ + ................ + ................ + .....BBBA....... + ....NPNPPA...... + ...BPPPPPA...... + ..CHHPABPA.AAA.. + .CHCDA.BPAAAAAA. + ..D..BPPAAAAAAA. + ....BBPPPPPAAAA. + ...BOOPPPPPPAAA. + ..BPOBPPPPPPPAA. + ..BPPBPPOBPAPPA. + ..BPABP.ABPAPPA. + .....BPAA..PPAA. + ...........PAA.. +} +# tile 272 (baby silver dragon,male) { ................ ................ @@ -2630,7 +5214,26 @@ Z = (195, 195, 195) .....PBAA..BBAA. ...........BAA.. } -# tile 137 (baby shimmering dragon) +# tile 273 (baby silver dragon,female) +{ + ................ + ................ + ................ + .....PPPA....... + ....OBOBBA...... + ...PBBBBBA...... + ..CHHBAPBA.AAA.. + .CHCDA.PBAAAAAA. + ..D..PBBAAAAAAA. + ....PPBBBBBAAAA. + ...PNNBBBBBBAAA. + ..PBNPBBBBBBBAA. + ..PBBPBBNPBABBA. + ..PBAPB.APBABBA. + .....PBAA..BBAA. + ...........BAA.. +} +# tile 274 (baby shimmering dragon,male) { .I.............. ...BBBBBBB.I.... @@ -2649,7 +5252,26 @@ Z = (195, 195, 195) B....BPAA..PPAAB .B.........PAAB. } -# tile 138 (baby red dragon) +# tile 275 (baby shimmering dragon,female) +{ + .I.............. + ...BBBBBBB.I.... + ..BF.FFF.FB...I. + .BF..BBBA.FB.... + BF..NPNPPAFB.I.. + BF.BPPPPPA.B.... + B.CHHPABPAFBAAI. + BCHCDA.BPAAFBAA. + B.D..BPPAAAAFBA. + B...BBPPPPPAAFB. + BF.BOOPPPPPPAAAB + BFBPOBPPPPPPPAFB + BFBPPBPPOBPAPPFB + B.BPABP.ABPAPPFB + B....BPAA..PPAAB + .B.........PAAB. +} +# tile 276 (baby red dragon,male) { ................ ................ @@ -2668,7 +5290,26 @@ Z = (195, 195, 195) .....IDAA..DDAA. ...........DAA.. } -# tile 139 (baby white dragon) +# tile 277 (baby red dragon,female) +{ + ................ + ................ + ................ + .....IIIA....... + ....NDNDDA...... + ...IDDDDDA...... + ..CHHDAIDA.AAA.. + .CHCDA.IDAAAAAA. + ..D..IDDAAAAAAA. + ....IIDDDDDAAAA. + ...IHHDDDDDDAAA. + ..IDHIDDDDDDDAA. + ..IDDIDDHIDADDA. + ..IDAID.AIDADDA. + .....IDAA..DDAA. + ...........DAA.. +} +# tile 278 (baby white dragon,male) { ................ ................ @@ -2687,7 +5328,26 @@ Z = (195, 195, 195) .....NOAA..OOAA. ...........OAA.. } -# tile 140 (baby orange dragon) +# tile 279 (baby white dragon,female) +{ + ................ + ................ + ................ + .....NNNA....... + ....IOIOOA...... + ...NOOOOOA...... + ..CHHOANOA.AAA.. + .CHCDA.NOAAAAAA. + ..D..NOOAAAAAAA. + ....NNOOOOOAAAA. + ...NOOOOOOOOAAA. + ..NOONOOOOOOOAA. + ..NOONOOONOAOOA. + ..NOANO.ANOAOOA. + .....NOAA..OOAA. + ...........OAA.. +} +# tile 280 (baby orange dragon,male) { ................ ................ @@ -2706,7 +5366,26 @@ Z = (195, 195, 195) .....LCAA..CCAA. ...........CAA.. } -# tile 141 (baby black dragon) +# tile 281 (baby orange dragon,female) +{ + ................ + ................ + ................ + .....LLLA....... + ....NCNCCA...... + ...LCCCCCA...... + ..CHHCALCA.AAA.. + .CHCDA.LCAAAAAA. + ..D..LCCAAAAAAA. + ....LLCCCCCAAAA. + ...LOOCCCCCCAAA. + ..LCOLCCCCCCCAA. + ..LCCLCCOLCACCA. + ..LCALC.ALCACCA. + .....LCAA..CCAA. + ...........CAA.. +} +# tile 282 (baby black dragon,male) { ................ ................ @@ -2725,7 +5404,26 @@ Z = (195, 195, 195) .....AAP...AAPP. ...........APP.. } -# tile 142 (baby blue dragon) +# tile 283 (baby black dragon,female) +{ + ................ + ................ + ................ + .....AAA........ + ....NANAA....... + ...AAAAAA....... + ..CHHA.AA..PPP.. + .CHCD..AA.PPPPP. + ..D..AAAPPP.PPP. + ....AAAAAAAPPPP. + ...AAAAAAAAAPPP. + ..AAAAAAAAAAAPP. + ..AAAAAAAAAPAAP. + ..AAPAA.PAAPAAP. + .....AAP...AAPP. + ...........APP.. +} +# tile 284 (baby blue dragon,male) { ................ ................ @@ -2744,7 +5442,26 @@ Z = (195, 195, 195) .....BEAA..EEAA. ...........EAA.. } -# tile 143 (baby green dragon) +# tile 285 (baby blue dragon,female) +{ + ................ + ................ + ................ + .....BBBA....... + ....NENEEA...... + ...BEEEEEA...... + ..CHHEABEA.AAA.. + CCHCDA.BEAAAAAA. + ..D..BEEAAAAAAA. + ....BBEEEEEAAAA. + ...BOOEEEEEEAAA. + ..BEOBEEEEEEEAA. + ..BEEBEEOBEAEEA. + ..BEABE.ABEAEEA. + .....BEAA..EEAA. + ...........EAA.. +} +# tile 286 (baby green dragon,male) { ................ ................ @@ -2763,7 +5480,26 @@ Z = (195, 195, 195) .....GFAA..FFAA. ...........FAA.. } -# tile 144 (baby yellow dragon) +# tile 287 (baby green dragon,female) +{ + ................ + ................ + ................ + .....GGGA....... + ....NFNFFA...... + ...GFFFFFA...... + ..CHHFAGFA.AAA.. + .CHCDA.GFAAAAAA. + ..D..GFFAAAAAAA. + ....GGFFFFFAAAA. + ...GOOFFFFFFAAA. + ..GFOGFFFFFFFAA. + ..GFFGFFOGFAFFA. + ..GFAGF.AGFAFFA. + .....GFAA..FFAA. + ...........FAA.. +} +# tile 288 (baby yellow dragon,male) { ................ ................ @@ -2782,7 +5518,26 @@ Z = (195, 195, 195) .....NHAA..HHAA. ...........HAA.. } -# tile 145 (gray dragon) +# tile 289 (baby yellow dragon,female) +{ + ................ + ................ + ................ + .....NNNA....... + ....DHDHHA...... + ...NHHHHHA...... + ..CHHHANHA.AAA.. + .CHCDA.NHAAAAAA. + ..D..NHHAAAAAAA. + ....NNHHHHHAAAA. + ...NOOHHHHHHAAA. + ..NHONHHHHHHHAA. + ..NHHNHHONHAHHA. + ..NHANH.ANHAHHA. + .....NHAA..HHAA. + ...........HAA.. +} +# tile 290 (gray dragon,male) { ......BBBPA..... .....NPNPPPA.... @@ -2801,7 +5556,26 @@ Z = (195, 195, 195) ....BPAA...PP.A. ........PPPP.A.. } -# tile 146 (silver dragon) +# tile 291 (gray dragon,female) +{ + ......BBBPA..... + .....NPNPPPA.... + ....BPPPPPPA.... + ..DCHHP..PPA.... + CHCHCD..BPPA.... + HD.D...BPPA..... + ......OBPAAAAAA. + ....BOBPAAAAAAAA + ..BOOBPA.PP.AAA. + .BOOOBPPPPPP.AA. + .BOOOBPPPPPPPAA. + PPOOBBPPPPPPPPA. + BP.OBPPOOPP.P.A. + BPAABP.AAPPAPPA. + ....BPAA...PP.A. + ........PPPP.A.. +} +# tile 292 (silver dragon,male) { ......PPPBA..... .....OBOBBBA.... @@ -2820,7 +5594,26 @@ Z = (195, 195, 195) ....PBAA...BB.A. ........BBBB.A.. } -# tile 147 (shimmering dragon) +# tile 293 (silver dragon,female) +{ + ......PPPBA..... + .....OBOBBBA.... + ....PBBBBBBA.... + ..DCHHB..BBA.... + CHCHCD..PBBA.... + HD.D...PBBA..... + ......NPBAAAAAA. + ....PNPBAAAAAAAA + ..PNNPBA.BB.AAA. + .PNNNPBBBBBB.AA. + .PNNNPBBBBBBBAA. + BBNNPPBBBBBBBBA. + PB.NPBBNNBB.B.A. + PBAAPB.AABBABBA. + ....PBAA...BB.A. + ........BBBB.A.. +} +# tile 294 (shimmering dragon,male) { .I.BF.BBBPAFB... ..BF.NPNPPPAFB.I @@ -2839,7 +5632,26 @@ Z = (195, 195, 195) ....BPAA...PP.AB ........PPPP.AB. } -# tile 148 (red dragon) +# tile 295 (shimmering dragon,female) +{ + .I.BF.BBBPAFB... + ..BF.NPNPPPAFB.I + .BF.BPPPPPPAFB.. + .BDCHHP..PPAFBI. + CBCHCD..BPPAFB.. + HDBB...BPPA.B..I + ..BF..OBPAAAABA. + .BF.BOBPAAAAAFBA + BFBOOBPA.PP.AAFB + .BOOOBPPPPPP.AFB + .BOOOBPPPPPPPAFB + PPOOBBPPPPPPPPFB + BP.OBPPOOPP.P.FB + BPAABP.AAPPAPPFB + ....BPAA...PP.AB + ........PPPP.AB. +} +# tile 296 (red dragon,male) { ......IIIDA..... .....NDNDDDA.... @@ -2858,7 +5670,26 @@ Z = (195, 195, 195) ....IDAAJJJDDJA. ........DDDDJA.. } -# tile 149 (white dragon) +# tile 297 (red dragon,female) +{ + ......IIIDA..... + .....NDNDDDA.... + ....IDDDDDDA.... + ..DCHHD..DDA.... + CHCHCD..IDDA.... + HD.D...IDDA..... + ......HIDAAAAAA. + ....IHIDAAAAAAAA + ..IHHIDAJDDJAAA. + .IHHHIDDDDDDJAA. + .IHHHIDDDDDDDAA. + DDHHIIDDDDDDDDA. + ID.HIDDHHDDJDJA. + IDAAID.AADDADDA. + ....IDAAJJJDDJA. + ........DDDDJA.. +} +# tile 298 (white dragon,male) { ......NNNOA..... .....IOIOOOA.... @@ -2877,7 +5708,26 @@ Z = (195, 195, 195) ....NOAA...OOJA. ........OOOOJA.. } -# tile 150 (orange dragon) +# tile 299 (white dragon,female) +{ + ......NNNOA..... + .....IOIOOOA.... + ....NOOOOOOA.... + ..DCHHO..OOA.... + CHCHCD..NOOA.... + HD.D...NOOA..... + ......ONOAAAAAA. + ....NONOAAAAAAAA + ..NOONOA.OO.AAA. + .NOOONOOOOOOJAA. + .NOOONOOOOOOOAA. + OOOONNOOOOOOOOA. + NO.ONOOOOOO.OJA. + NOAANO.AAOOAOOA. + ....NOAA...OOJA. + ........OOOOJA.. +} +# tile 300 (orange dragon,male) { ......LLLCA..... .....NCNCCCA.... @@ -2896,7 +5746,26 @@ Z = (195, 195, 195) ....LCAA.KKCCJA. ........CCCCJA.. } -# tile 151 (black dragon) +# tile 301 (orange dragon,female) +{ + ......LLLCA..... + .....NCNCCCA.... + ....LCCCCCCA.... + ..DCHHC..CCA.... + CHCHCD..LCCA.... + HD.D...LCCA..... + ......OLCAAAAAA. + ....LOLCAAAAAAAA + ..LOOLCA.CCKAAA. + .LOOOLCCCCCCJAA. + .LOOOLCCCCCCCAA. + CCOOLLCCCCCCCCA. + LC.OLCCOOCCKCJA. + LCAALC.AACCACCA. + ....LCAA.KKCCJA. + ........CCCCJA.. +} +# tile 302 (black dragon,male) { ......AAAA...... .....NANAAA..... @@ -2915,7 +5784,26 @@ Z = (195, 195, 195) ....AAPP...AAAP. ........AAAAA... } -# tile 152 (blue dragon) +# tile 303 (black dragon,female) +{ + ......AAAA...... + .....NANAAA..... + ....AAAAAAA..... + ..DCHHA..AA..... + CHCHCD..AAA..... + HD.D...AAA...... + ......AAA..PPPP. + ....AAAAPPPPPPPP + ..AAAAAAAAA.PPP. + .AAAAAAAAAAAAPP. + .AAAAAAAAAAAAPP. + AAAAAAAAAAAAAAP. + AA.AAAAAAAA.AAP. + AAPPAA.PPAAPAAP. + ....AAPP...AAAP. + ........AAAAA... +} +# tile 304 (blue dragon,male) { ......BBBEA..... .....NENEEEA.... @@ -2934,7 +5822,26 @@ Z = (195, 195, 195) ....BEAA...EEJA. ...P....EEEEJA.. } -# tile 153 (green dragon) +# tile 305 (blue dragon,female) +{ + ......BBBEA..... + .....NENEEEA.... + ....BEEEEEEA.... + ..DCHHE..EEA.... + CHCHCD..BEEA.... + HD.D...BEEA..... + ......OBEAAAAAA. + ....BOBEAAAAAAAA + ..BOOBEA.EE.AAA. + .BOOOBEEEEEEJAA. + .BOOOBEEEEEEEAA. + EEOOBBEEEEEEEEA. + BE.OBEEOOEE.EJA. + BEAABE.AAEEAEEA. + ....BEAA...EEJA. + ...P....EEEEJA.. +} +# tile 306 (green dragon,male) { ......GGGFA..... .....NFNFFFA.... @@ -2953,7 +5860,26 @@ Z = (195, 195, 195) ....GFAA...FFJA. ........FFFFJA.. } -# tile 154 (yellow dragon) +# tile 307 (green dragon,female) +{ + ......GGGFA..... + .....NFNFFFA.... + ....GFFFFFFA.... + ..DCHHF..FFA.... + CHCHCD..GFFA.... + HD.D...GFFA..... + ......OGFAAAAAA. + ....GOGFAAAAAAAA + ..GOOGFA.FF.AAA. + .GOOOGFFFFFFJAA. + .GOOOGFFFFFFFAA. + FFOOGGFFFFFFFFA. + GF.OGFFOOFF.FJA. + GFAAGF.AAFFAFFA. + ....GFAA...FFJA. + ........FFFFJA.. +} +# tile 308 (yellow dragon,male) { ......NNNHA..... .....DHDHHHA.... @@ -2972,7 +5898,26 @@ Z = (195, 195, 195) ....NHAAJJJHHJA. ........HHHHJA.. } -# tile 155 (stalker) +# tile 309 (yellow dragon,female) +{ + ......NNNHA..... + .....DHDHHHA.... + ....NHHHHHHA.... + ..DCHHH..HHA.... + CHCHCD..NHHA.... + HD.D...NHHA..... + ......ONHAAAAAA. + ....NONHAAAAAAAA + ..NOONHAJHHJAAA. + .NOOONHHHHHHJAA. + .NOOONHHHHHHHAA. + HHOONNHHHHHHHHA. + NH.ONHHOOHHJHJA. + NHAANH.AAHHAHHA. + ....NHAAJJJHHJA. + ........HHHHJA.. +} +# tile 310 (stalker,male) { ................ .......PPP...... @@ -2991,7 +5936,26 @@ Z = (195, 195, 195) .....PP..PP..... ................ } -# tile 156 (air elemental) +# tile 311 (stalker,female) +{ + ................ + .......PPP...... + ......P.P.P..... + .....PPPPPP..... + .....PP..PPP.... + ....PPPPPP.P.... + ....P.PPPP.P.... + ....P.PPP..P.... + ....P..PP..P.... + ....P.PPPP.P.... + ....P.P..P.P.... + ....P.P..P.P.... + ......P..P...... + ......P..P...... + .....PP..PP..... + ................ +} +# tile 312 (air elemental,male) { ................ ...P.PPP..P..... @@ -3010,7 +5974,26 @@ Z = (195, 195, 195) ...PP.APPPA..... ................ } -# tile 157 (fire elemental) +# tile 313 (air elemental,female) +{ + ................ + ...P.PPP..P..... + ..P.PAPA.P...... + P..PPPPPP..P.... + .P.PPAAPPP...P.. + ..PPPAAP.P.P.... + ..PAPAAPAP...... + P.PAPPP.AP.P.AA. + ..PA.PP.AP.AAAA. + ..PAPPPPAPAAAA.. + ..PAP.APAPAAAA.. + ..PAP.APAPAAAAA. + ....P.APAAAAAAA. + ..P.P.APPAAAAAA. + ...PP.APPPA..... + ................ +} +# tile 314 (fire elemental,male) { ................ .H..LDDD........ @@ -3029,7 +6012,26 @@ Z = (195, 195, 195) ..LDDCADDDA..... ................ } -# tile 158 (earth elemental) +# tile 315 (fire elemental,female) +{ + ................ + .H..LDDD........ + ...LDADAC.H..... + H..DDDDDD..H.H.. + ..LDDAADDD...... + ..DDDAADCD.H.... + ..DADAACAD...... + H.DADDDCAD...AA. + ..DACDDCAD.AAAA. + ..DADDDDADAAAA.. + ..DADCADADAAAA.. + H.DADCADADAAAAA. + ....DCADAAAAAAA. + .H.LDCADDAAAAAA. + ..LDDCADDDA..... + ................ +} +# tile 316 (earth elemental,male) { ..F............. ....CKKK..F..... @@ -3048,7 +6050,26 @@ Z = (195, 195, 195) ..CKKJAKKKA..... ................ } -# tile 159 (water elemental) +# tile 317 (earth elemental,female) +{ + ..F............. + ....CKKK..F..... + ...CKAKAJ....F.. + ...KKKKKK....... + ..CKKAAKKK.F..F. + .FKKKAAKJK...... + ..KAKAAJAK..F... + ..KAKJJJAK...AA. + F.KAJKKJAK.AAAA. + ..KAKKKKAKAAAA.. + ..KAKJAKAKAAAA.. + ..KAKJAKAKAAAAA. + ....KJAKAAAAAAA. + .F.CKJAKKAAAAAA. + ..CKKJAKKKA..... + ................ +} +# tile 318 (water elemental,male) { ................ ....PBBB..E..... @@ -3067,7 +6088,26 @@ Z = (195, 195, 195) ..PBBEABBBA..... ................ } -# tile 160 (lichen) +# tile 319 (water elemental,female) +{ + ................ + ....PBBB..E..... + .E.PBABAE...E... + ...BBBBBB....... + ..PBBAABBB.E..E. + E.BBBAABEB...... + ..BABAABEB.E.... + ..BABBBBEB...AA. + ..BAPBBEAB.AAAA. + E.BABBBBABAAAA.. + ..BABEABABAAAA.. + ..BABEABABAAAAA. + ....BEABAAAAAAA. + .E.PBEABBAAAAAA. + ..PBBEABBBA..... + ................ +} +# tile 320 (lichen,male) { ................ ................ @@ -3086,7 +6126,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 161 (brown mold) +# tile 321 (lichen,female) +{ + ................ + ................ + ...FFF...FFF.... + ..FCFFFFFCCFA... + .FCOOFFFCOFFFA.. + .FCOOFFFCFFFFA.. + ..FFFFFFFFFFA... + ...AFFFCCFFFA... + ...FFFFCOFFAA... + ..FCCFFCOFCFA... + ..FCOFFCFFOCFA.. + ..FFCFFFCFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 322 (brown mold,male) { ................ ................ @@ -3105,7 +6164,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 162 (yellow mold) +# tile 323 (brown mold,female) +{ + ................ + ................ + ...JJJ...JJJ.... + ..JKJJJJJKKJA... + .JKCCJJJKCJJJA.. + .JKCCJJJKJJJJA.. + ..JJJJJJJJJJA... + ...AJJJKKJJJA... + ...JJJJKCJJAA... + ..JKKJJKCJKJA... + ..JKCJJKJJCKJA.. + ..JJKJJJKJJJJA.. + ...JJJAAJJJJJA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 324 (yellow mold,male) { ................ ................ @@ -3124,7 +6202,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 163 (green mold) +# tile 325 (yellow mold,female) +{ + ................ + ................ + ...HHH...HHH.... + ..HHHHHHHNHHA... + .HHNNOHHNNOHHA.. + .HHNNOOHHOOHHA.. + ..HHOOHHHHHHA... + ...AHHHHHHHHA... + ...HHHHNNOHAA... + ..HHHHHNNOHHA... + ..HNNOHHHONOHA.. + ..HHOHHHHHOOHA.. + ...HHHAAHHHHHA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 326 (green mold,male) { ................ ................ @@ -3143,7 +6240,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 164 (red mold) +# tile 327 (green mold,female) +{ + ................ + ................ + ...FFF...FFF.... + ..FGFFFFFGGFA... + .FGOOFFFGOFFFA.. + .FGOOFFFGFFFFA.. + ..FFFFFFFFFFA... + ...AFFFGGFFFA... + ...FFFFGOFFAA... + ..FGGFFGOFGFA... + ..FGOFFGFFOGFA.. + ..FFGFFFGFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 328 (red mold,male) { ................ ................ @@ -3162,7 +6278,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 165 (shrieker) +# tile 329 (red mold,female) +{ + ................ + ................ + ...DDD...DDD.... + ..DCDDDDDCCDA... + .DLLCDDDCLDDDA.. + .DCCCDDDCDDDDA.. + ..DDDDDDDDDDA... + ...ADDDCCDDDA... + ...DDDDCLDDAA... + ..DCCDDCLDCDA... + ..DCLDDCDDLCDA.. + ..DDCDDDCDDDDA.. + ...DDDAADDDDDA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 330 (shrieker,male) { ................ ................ @@ -3181,7 +6316,26 @@ Z = (195, 195, 195) ...AAAAAAAAAA... ................ } -# tile 166 (violet fungus) +# tile 331 (shrieker,female) +{ + ................ + ................ + ................ + ................ + .....GGGGFF..... + ...GGGGIGIDFF... + .GGGIIGGGIIFFFF. + GIIGIIGGGGGGGDDF + GIIGGGGIIGIIGIDF + GGGGIGGIIGIIGGFF + ..GGGGGGGGGGG... + ......FFF..AAAAA + ....AGGGFFAAAAAA + ...AGGGGGGFAAAA. + ...AAAAAAAAAA... + ................ +} +# tile 332 (violet fungus,male) { ................ ................ @@ -3200,7 +6354,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 167 (gnome) +# tile 333 (violet fungus,female) +{ + ................ + ................ + ...III...III.... + ..ILIIIIILLIA... + .IOOLIIILOIIIA.. + .ILLLIIILIIIIA.. + ..IIIIIIIIIIA... + ...AIIILLIIIA... + ...IIIILOIIAA... + ..ILLIILOILIA... + ..ILOIILIIOLIA.. + ..IILIIILIIIIA.. + ...IIIAAIIIIIA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 334 (gnome,male) { ................ ................ @@ -3219,7 +6392,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 168 (gnome lord) +# tile 335 (gnome,female) +{ + ................ + ................ + ................ + .....DF......... + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + .....OLO...AAA.. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 336 (gnome leader,male) { ................ ................ @@ -3238,7 +6430,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 169 (gnomish wizard) +# tile 337 (gnome leader,female) +{ + ................ + ................ + ......D......... + ......G......... + ......G......... + .....GFF........ + ....HHHHH....... + ....GLLLF.....A. + .....OLO...AAA.. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 338 (gnomish wizard,male) { ................ ................ @@ -3257,7 +6468,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 170 (gnome king) +# tile 339 (gnomish wizard,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + ...FFOLOFF.AAA.. + ...GFOOOFFAAAA.. + ...FAGOFAFAAAA.. + ...GLKNKFFAAA... + ...FFGFFFFA..... + ...GFFFFGFA..... + ................ + ................ +} +# tile 340 (gnome ruler,male) { ................ ................ @@ -3276,7 +6506,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 171 (giant) +# tile 341 (gnome ruler,female) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....GLLLF...A... + .....OLO...AAAA. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 342 (giant,male) { ......JJJJAA.... ....JJJJJJJJA... @@ -3295,7 +6544,26 @@ Z = (195, 195, 195) .....CLJACLJAAAA ...LLLLJ.CLLLKAA } -# tile 172 (stone giant) +# tile 343 (giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLKLKCKCLKLLLA + .LLAALLCCLLAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 344 (stone giant,male) { ......JJJJAA.... ....JJJJJJJJA... @@ -3314,7 +6582,26 @@ Z = (195, 195, 195) .....ALJACLJAAAA ...LLLLJ.CLLLKAA } -# tile 173 (hill giant) +# tile 345 (stone giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLAAKCKCLKLLLA + .LLPPPACCLLAALLA + .LLPPPPAKKJAALLA + .CLCPPPAJJKKCLAA + ..LLPPALACLJLLAA + .....ALJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 346 (hill giant,male) { ......JJJJAA.... ....JJJJJJJJA... @@ -3333,7 +6620,26 @@ Z = (195, 195, 195) .....CLJACLJAAAA ...LLLLJ.LLLLKAA } -# tile 174 (fire giant) +# tile 347 (hill giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ...JJKJJJJJJJAA. + ..LJJCCKCKCJJLA. + ..JLKKKCKCKKLJA. + ..LAAKKCCKJAALAA + ..LAAJJJKKJAALAA + ..LC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 348 (fire giant,male) { ....PPDDDDAA.... ....PDDDDDDDA... @@ -3352,7 +6658,26 @@ Z = (195, 195, 195) .....CLJACLJAAAA ...LLLLJ.LLLLKAA } -# tile 175 (frost giant) +# tile 349 (fire giant,female) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLJAAAA. + ...JPDJJJJJJJAA. + ..LDDHDKCKCJJLA. + ..JLHDDCKCKKLJA. + ..LAHDHCCKJAALAA + JLAADDHJKKJAALAA + JJLJDHHJJJKKCLAA + ..LLJJJJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 350 (frost giant,male) { .....KJJJJAA.... ....KJJJJJJJA... @@ -3371,7 +6696,26 @@ Z = (195, 195, 195) .....CLJACLJAAAA ...LLLLJ.CLLLKAA } -# tile 176 (ettin) +# tile 351 (frost giant,female) +{ + .....KJJJJAA.... + ....KJJJJJJJA... + ....JJLLLLJJA... + ....JEELLEEJA... + ....JLLLLLLJA... + ....AKJJJJJAAA.. + .....KJAAJJAAAA. + ....KKJJJJAJAAAA + ...KJKJJJJAJJAAA + ..KJKKJJJJJKJJAA + ..KAAJKJJAJAAJAA + ..JAAJKKAKJAAJAA + ..LC.JJJJJKKCLAA + ..LL.CJJAJLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 352 (ettin,male) { ....NN..ONOP.... ..NNOOPNNOOPP... @@ -3390,7 +6734,26 @@ Z = (195, 195, 195) .....BPAABPAAAAA ...PPPPA.BPPPFAA } -# tile 177 (storm giant) +# tile 353 (ettin,female) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NPP..NPP..P... + ..ALPPLALPPLA... + ..APPPPAPPPPA... + ..APAAPAPAAPAA.. + ..APPPPAPPPPAAA. + ..BIIIIJJJIIIBAA + .BPPPIIIIIIPPPBA + .PPPFPIIIIPFPPPA + .PPAAPIIIIPAAPPA + .PPAAIIIIIIAAPPA + .BPB.IIFFIIABPAA + ..PP.BPAABPAPPAA + .....BPAABPAAAAA + ...PPPPA.BPPPFAA +} +# tile 354 (storm giant,male) { ......JJJJAA.... ....JJJJJJJJA... @@ -3409,7 +6772,26 @@ Z = (195, 195, 195) .....CLJACCJAAAA ...LLLLJ.LLLLKAA } -# tile 178 (titan) +# tile 355 (storm giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAH.. + .....ALLLLJAHAA. + ...JJKJJJJJHHAA. + ..LJJCCKCKHHLAA. + ..JLKKKCKHHHHHH. + ..LAAKKCCKJAHHAA + ..LAAJJJKKJHHALA + ..LC.JJJJJKHAAAA + ..LL.CLJACHAAAAA + .....CLJACCJAAAA + ...LLLLJ.LLLLKAA +} +# tile 356 (titan,male) { .....AAAAAAA.... ....AALLLLAAA... @@ -3428,7 +6810,26 @@ Z = (195, 195, 195) .....CLJACLJAAAA ...LLLLJ.CLLLKAA } -# tile 179 (minotaur) +# tile 357 (titan,female) +{ + .....AAAAAAA.... + ....AALLLLAAA... + ....A..LL..AA... + ....ALLLLLLAA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCJJJJJJJJCCA. + .CLLLCCKCKCLLLCA + .LLLKJKCKCJKLLLA + .LLAAJJCCJJAALLA + .LLAAJJCCJJAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 358 (minotaur,male) { ................ .O..........O... @@ -3447,7 +6848,26 @@ Z = (195, 195, 195) ....CLCACLCAAAAA ..LLLLL.LLLLLAA. } -# tile 180 (jabberwock) +# tile 359 (minotaur,female) +{ + ................ + .O..........O... + .OOOJJJJJJOOO... + ..OOJJKJJJOO.... + ...JGAKJGAJA.... + ...JJJKJJJJA.... + ....JJKJJJAAA... + ....JKKKJAAAA... + ..CLJAJAKALCAA.A + .CLLJJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LL.JJJJJJJLLAAA + .LL.JJJJJJJLLAAA + ....CLCACLCAAAAA + ..LLLLL.LLLLLAA. +} +# tile 360 (jabberwock,male) { ................ ...DP........... @@ -3466,7 +6886,26 @@ Z = (195, 195, 195) ...IDAA..ID..... ................ } -# tile 181 (vorpal jabberwock) +# tile 361 (jabberwock,female) +{ + ................ + ...DP........... + ....DP.ADOO..... + ..DAIDADIPAD.... + ...DIAPIPA...... + ...DBDDDA....... + ..IBBDADDA..AA.. + .DDDDAODDIAAAA.. + ..OAOA.DDAIAAA.. + ..IOAODDAAADDAA. + ..DDDADDDDAIDA.. + ...AAADDIDIDDD.. + ....IDDAIDDDDA.. + ....IDAAIDAA.... + ...IDAA..ID..... + ................ +} +# tile 362 (vorpal jabberwock,male) { ................ ...GP........... @@ -3485,7 +6924,26 @@ Z = (195, 195, 195) ...FGAA..FG..... ................ } -# tile 182 (Keystone Kop) +# tile 363 (vorpal jabberwock,female) +{ + ................ + ...GP........... + ....GP.AGOO..... + ..GAFGAGFPAG.... + ...GFAPFPA...... + ...GHGGGA....... + ..FHHGAGGA..AA.. + .GGGGAOGGFAAAA.. + ..OAOA.GGAFAAA.. + ..FOAOGGAAAGGAA. + ..GGGAGGGGAFGA.. + ...AAAGGFGFGGG.. + ....FGGAFGGGGA.. + ....FGAAFGAA.... + ...FGAA..FG..... + ................ +} +# tile 364 (Keystone Kop,male) { ................ ....AA.......... @@ -3504,7 +6962,26 @@ Z = (195, 195, 195) ..AA....AA...... ................ } -# tile 183 (Kop Sergeant) +# tile 365 (Keystone Kop,female) +{ + ................ + ....AA.......... + ...AAAA......... + ...AOAA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.PPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 366 (Kop Sergeant,male) { ................ ....AA.......... @@ -3523,7 +7000,26 @@ Z = (195, 195, 195) ..AA....AA...... ................ } -# tile 184 (Kop Lieutenant) +# tile 367 (Kop Sergeant,female) +{ + ................ + ....AA.......... + ...AOOA......... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 368 (Kop Lieutenant,male) { ................ ....AA.......... @@ -3542,7 +7038,26 @@ Z = (195, 195, 195) ..AA....AA...... ................ } -# tile 185 (Kop Kaptain) +# tile 369 (Kop Lieutenant,female) +{ + ................ + ....AA.......... + ...AOOA...C..... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ..OAAAO.AAA..... + .OAAAAA.AAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 370 (Kop Kaptain,male) { ................ ....AA....C..... @@ -3561,7 +7076,26 @@ Z = (195, 195, 195) ..AA....AA...... ................ } -# tile 186 (lich) +# tile 371 (Kop Kaptain,female) +{ + ................ + ....AA....C..... + ...AHHA...C..... + ...AHHA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + .HHAAAAHHAA..... + .AAAAHAAAACCC... + .AA.AHAAA.CPPP.. + ..AAAHAA.PCPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 372 (lich,male) { ................ ................ @@ -3580,7 +7114,26 @@ Z = (195, 195, 195) ......OOO....... ................ } -# tile 187 (demilich) +# tile 373 (lich,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....O.PPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 374 (demilich,male) { ................ ................ @@ -3599,7 +7152,26 @@ Z = (195, 195, 195) ......LLL....... ................ } -# tile 188 (master lich) +# tile 375 (demilich,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....L.PPPAAAA.A. + ......LPPAAA.A.. + .....LLAL.A..... + ...LLLA.LA...... + ......LLL....... + ................ +} +# tile 376 (master lich,male) { ...H............ ...HCH.H........ @@ -3618,7 +7190,26 @@ Z = (195, 195, 195) ......OOO....... ................ } -# tile 189 (arch-lich) +# tile 377 (master lich,female) +{ + ...H............ + ...HCH.H........ + ...HHHCH........ + ..AOAOHH........ + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...PPPPP....AAA. + ..PPPPPPPA..AAA. + .O..PPPPP.AAAAA. + ....OPPPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 378 (arch-lich,male) { ................ ................ @@ -3637,7 +7228,26 @@ Z = (195, 195, 195) ......OOO....... ................ } -# tile 190 (kobold mummy) +# tile 379 (arch-lich,female) +{ + ................ + ................ + ...OOO.......... + ..DODOO......... + ..OOOOO......... + H.OO.O.......... + A....PPP........ + A..OOPPP....AAA. + .AO.PPPPPA..AAA. + .O...PPPP.AAAAA. + .A..O.PPPAAAA.A. + ..A...PPPAAA.A.. + ..A..OPAP.A..... + ..AOOOA.OA...... + ......OOO....... + ................ +} +# tile 380 (kobold mummy,male) { ................ ................ @@ -3656,7 +7266,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 191 (gnome mummy) +# tile 381 (kobold mummy,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NONONO....... + ...OAOAO.OP..... + ....ONN...A..... + ...ONODNA.AA.... + ..OLONNONAAA.A.. + ..NALONANAAAAA.. + ..NAOLOAOAAAAA.. + ....NOLAAAAAA... + ....NANAAAA..... + ...OOANOA....... + ................ + ................ +} +# tile 382 (gnome mummy,male) { ................ ................ @@ -3675,7 +7304,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 192 (orc mummy) +# tile 383 (gnome mummy,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GGFO....... + ....GGFFOOP..... + ....GDODF....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 384 (orc mummy,male) { ................ ................ @@ -3694,7 +7342,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 193 (dwarf mummy) +# tile 385 (orc mummy,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOOP........ + ....DODPOP...... + ....OOOA........ + ..OOOOOOOA.AA... + ..OOOOOOO.AAA... + ..OAOOOAACCC.... + ..OAOOOCCAAA.... + ....OCCOAAAAAA.. + ...CCAOOAAAA.... + ..OOOAOOOA...... + ................ + ................ +} +# tile 386 (dwarf mummy,male) { ................ ................ @@ -3713,7 +7380,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 194 (elf mummy) +# tile 387 (dwarf mummy,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BBEO....... + ....BBEEEOP..... + ....BDODE....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 388 (elf mummy,male) { ................ ................ @@ -3732,7 +7418,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 195 (human mummy) +# tile 389 (elf mummy,female) +{ + ................ + ................ + .........O...... + .......OOOP..... + ......OOOOP..... + ......OEOEAP.... + ......OOOOA..... + ......AOOA....A. + ......OAAO..AAA. + .....OOOOOOAAAA. + ....OALOOLAOAAA. + ....OADOOOAOAA.. + ......OOAOAA.A.. + .....OOA.OOA.... + ................ + ................ +} +# tile 390 (human mummy,male) { ................ ................ @@ -3751,7 +7456,26 @@ Z = (195, 195, 195) ..NNN.NNNA...... ................ } -# tile 196 (ettin mummy) +# tile 391 (human mummy,female) +{ + ................ + ................ + ...ONNO......... + ...NNNNOP....... + ..PANAN.OPP..... + ..PNNNN......... + ..ONOONNP....... + .ONLNNOOO....... + .NJNOOOOO..AAA.. + .OJOOOODN.AAAA.. + .NJOLNOAOAAAAAA. + .OCNO.NKNAAAAA.. + .N.OO.OLAAAAAAA. + ...OOAOOAAA..... + ..NNN.NNNA...... + ................ +} +# tile 392 (ettin mummy,male) { .....NN..ONOO... ...NNOOONNOOOO.. @@ -3770,7 +7494,26 @@ Z = (195, 195, 195) .....NOOANOOAAAA ...OOOOO.OOOOKAA } -# tile 197 (giant mummy) +# tile 393 (ettin mummy,female) +{ + .....NN..ONOO... + ...NNOOONNOOOO.. + ...NOOOONOOOOOO. + ...OFOFOLOFOFO.O + ...OOOOOLOOOOO.P + ...NOOOOLNNOOOA. + ...ONOOOLOOOOAAA + ..OOOONNNNNNNOAA + .ONNNNNNOONOOOOA + .ONODNNOOOOOOOOA + .NNAAONNONOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 394 (giant mummy,male) { ......ONOOAA.... ....ONNNOOOOA... @@ -3789,7 +7532,26 @@ Z = (195, 195, 195) .....NOOANOOAAAA ...OOOOO.OOOOKAA } -# tile 198 (red naga hatchling) +# tile 395 (giant mummy,female) +{ + ......ONOOAA.... + ....ONNNOOOOA... + ....NNOOOOOOO... + ....NFFOOFFOOP.. + ....NONOOOOOAOP. + ....AONOOOOAAAP. + .....ANOOODAAAA. + ..OOOONOOONNNOAA + .ONNNNNOOOOOOOOA + .ONODNNLOOOOOOOA + .NNAAONOLNOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 396 (red naga hatchling,male) { ................ ................ @@ -3808,7 +7570,26 @@ Z = (195, 195, 195) ....IIDDDDDA.... ................ } -# tile 199 (black naga hatchling) +# tile 397 (red naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LDLAA........ + ...IDDAAAAADA... + ...IDDDAAADDA... + ....IIDDDDDA.... + ................ +} +# tile 398 (black naga hatchling,male) { ................ ................ @@ -3827,7 +7608,26 @@ Z = (195, 195, 195) ....AAAAAAAA.... ................ } -# tile 200 (golden naga hatchling) +# tile 399 (black naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLA......... + ...LALAA........ + ...AAAPA..PAA... + ...AAAAPPPAAA... + ....AAAAAAAA.... + ................ +} +# tile 400 (golden naga hatchling,male) { ................ ................ @@ -3846,7 +7646,26 @@ Z = (195, 195, 195) ....NNHHHHHA.... ................ } -# tile 201 (guardian naga hatchling) +# tile 401 (golden naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LHLAA........ + ...NHHAAAAAHA... + ...NHHHAAAHHA... + ....NNHHHHHA.... + ................ +} +# tile 402 (guardian naga hatchling,male) { ................ ................ @@ -3865,7 +7684,26 @@ Z = (195, 195, 195) ....GGFFFFFA.... ................ } -# tile 202 (red naga) +# tile 403 (guardian naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LFLAA........ + ...GFFAAAAAFA... + ...GFFFAAAFFA... + ....GGFFFFFA.... + ................ +} +# tile 404 (red naga,male) { ................ ....KK.......... @@ -3884,7 +7722,26 @@ Z = (195, 195, 195) .....DDAA..DDA.. ..........DA.... } -# tile 203 (black naga) +# tile 405 (red naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLDA..AA.... + ...LDLDA.AAAA... + ...IDDDAAAIIA... + ...IDDDAIDDDIDA. + ...IDDDIDDDDDDDA + ...IDDDDDDAA.DDA + ....DDDDDA..DDA. + .....DDAA..DDA.. + ..........DA.... +} +# tile 406 (black naga,male) { ................ ....KK.......... @@ -3903,7 +7760,26 @@ Z = (195, 195, 195) .....AAPP..AAP.. ..........AP.... } -# tile 204 (golden naga) +# tile 407 (black naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLAA........ + ...LALAA..PPP... + ...AAAAPPPAAP... + ...AAAAPAAAAAAP. + ...AAAAAAAAAAAAP + ...AAAAAAAPP.AAP + ....AAAAAP..AAP. + .....AAPP..AAP.. + ..........AP.... +} +# tile 408 (golden naga,male) { ................ ....KK.......... @@ -3922,7 +7798,26 @@ Z = (195, 195, 195) .....HHAA..HHA.. ..........HA.... } -# tile 205 (guardian naga) +# tile 409 (golden naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLHA..AA.... + ...LHLHA.AAAA... + ...NHHHAAANNA... + ...NHHHANHHHNHA. + ...NHHHNHHHHHHHA + ...NHHHHHHAA.HHA + ....HHHHHA..HHA. + .....HHAA..HHA.. + ..........HA.... +} +# tile 410 (guardian naga,male) { ................ ....KK.......... @@ -3941,7 +7836,26 @@ Z = (195, 195, 195) .....FFAA..FFA.. ..........FA.... } -# tile 206 (ogre) +# tile 411 (guardian naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ..CLAALC........ + ..LLLLLL........ + ..CLLCLC..AA.... + ...CLLCA.AAAA... + ...GLFCAAAGGA... + ...GFFFAAFFFGFA. + ...GFFFGFFFFFFFA + ...GFFFFFFAA.FFA + ....FFFFFA..FFA. + .....FFAA..FFA.. + ..........FA.... +} +# tile 412 (ogre,male) { ................ ................ @@ -3960,7 +7874,26 @@ Z = (195, 195, 195) ....CJJJCLAAAAAA ..LLLLL.LLLLLAA. } -# tile 207 (ogre lord) +# tile 413 (ogre,female) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CAAACJAAA... + ....LDDDLAAAA... + ..CLJLLLKALCAA.A + .CLLAJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 414 (ogre leader,male) { ................ ................ @@ -3979,7 +7912,26 @@ Z = (195, 195, 195) ....CJJJCLAAAAAA ..LLLLL.LLLLLAA. } -# tile 208 (ogre king) +# tile 415 (ogre leader,female) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 416 (ogre tyrant,male) { ...H..C..H...... ...HDCHCDH...... @@ -3998,7 +7950,26 @@ Z = (195, 195, 195) ....CJJJCLAAAAAA ..LLLLL.LLLLLAA. } -# tile 209 (gray ooze) +# tile 417 (ogre tyrant,female) +{ + ...H..C..H...... + ...HDCHCDH...... + ...HHHHHHH...... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CJKAJJJJAKJCAAA + .LJJKAAAAKJJLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 418 (gray ooze,male) { ................ ................ @@ -4017,7 +7988,26 @@ Z = (195, 195, 195) .........KCCCJ.. ................ } -# tile 210 (brown pudding) +# tile 419 (gray ooze,female) +{ + ................ + ................ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAAA.. + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPBBPPAAA. + .PBBPPPBAAPPPAA. + ...PBBBAAAKPPJ.. + ........ACPPAK.. + .........KCCCJ.. + ................ +} +# tile 420 (brown pudding,male) { ................ ................ @@ -4036,7 +8026,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 211 (green slime) +# tile 421 (brown pudding,female) +{ + ................ + ................ + ................ + ................ + ............J... + ....JKKJJJ..JJ.. + ...KKKCJJJJJ.... + ..KKNNJNNJJJ.... + ..KJANJANJJJA... + ..KKJJJJJCJJAA.. + ..JKJJCJJJJJAA.. + ...JJJJJJJJAAA.. + ....JJJJJJAAA... + .....AAAAAAA.... + ................ + ................ +} +# tile 422 (green slime,male) { ................ ................ @@ -4055,7 +8064,26 @@ Z = (195, 195, 195) NGGFGGF..GF..... ..GGF..GGF..G... } -# tile 212 (black pudding) +# tile 423 (green slime,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ............G... + .....G......G..G + .G....G..G.NGN.G + ..NG.NGGNGGGGGGG + ..GGNGGNGGGFGGF. + GGNGGGGGGGGGFF.G + .NGGGGGFGFG..... + NGGGGFGGFG.G..GF + NGGFGGF..GF..... + ..GGF..GGF..G... +} +# tile 424 (black pudding,male) { ........A....... ........AA...... @@ -4074,7 +8102,26 @@ Z = (195, 195, 195) ........AAAAAAAA ..........AAAA.. } -# tile 213 (quantum mechanic) +# tile 425 (black pudding,female) +{ + ........A....... + ........AA...... + .....AAA........ + ....AAAAA....... + ....CACAA....... + ....DADAA....... + ....AAAAA....... + ....AAAAA....... + ....AAAAA....... + .....AAAAA...... + .....AAAAA...... + ......AAAAA..... + ......AAAAAA.... + .......AAAAAA.A. + ........AAAAAAAA + ..........AAAA.. +} +# tile 426 (quantum mechanic,male) { ................ ......LLLL...... @@ -4093,7 +8140,26 @@ Z = (195, 195, 195) ....NAAEBAANN... ................ } -# tile 214 (genetic engineer) +# tile 427 (quantum mechanic,female) +{ + ................ + ......LLLL...... + ...FGGCLCGGF.... + ...GNNGLGNNGL... + B.BGANGGGANGL... + B.BFGGCLCGGFL... + BIB..CLLLCCL.... + BILN.LLAALLAAAA. + BILNN.LLLLJAAAA. + BIB.NNJJJJNAAA.. + BIB.BNNNONNNAA.. + .B...NNNONNLAA.. + .....NBEBENA.A.. + .....NBEBENN.... + ....NAAEBAANN... + ................ +} +# tile 428 (genetic engineer,male) { ................ ......LLLL...... @@ -4112,7 +8178,26 @@ Z = (195, 195, 195) ..AANAAEPAANN... ................ } -# tile 215 (rust monster) +# tile 429 (genetic engineer,female) +{ + ................ + ......LLLL...... + ...LAALLLAAL.... + ...LNNLLLNNLL... + ...LANLLLANLL... + ...LLLLLLLLLL... + .....CLLLCCL.... + ..LN.LLAALL..... + ..LNN.LLLLJ..... + ..A.NNLLLLN..... + .A.ABNNNONNN.... + .AA..NNNONNL.... + .A.A.NPEPENA.... + .AA..NPEPENN.... + ..AANAAEPAANN... + ................ +} +# tile 430 (rust monster,male) { ................ ....EEEE........ @@ -4131,7 +8216,26 @@ Z = (195, 195, 195) ......AAAA...... ................ } -# tile 216 (disenchanter) +# tile 431 (rust monster,female) +{ + ................ + ....EEEE........ + ...EEHEHE....... + ...EEEAEE....... + ...EEPAPE....... + ...EPEAEP...E... + ....EEEE.AAEE... + ....EEEEEAAEEE.. + ...EEEEEEEAEAEE. + ..EEEEEEAAAAE... + ..EEAEEEEAEEEA.. + ..AAEEEEEEEEEAA. + ....AEEEEEEEAAA. + .....EEEEEAA..A. + ......AAAA...... + ................ +} +# tile 432 (disenchanter,male) { ................ ....PPPP........ @@ -4150,7 +8254,26 @@ Z = (195, 195, 195) ......AAAA...... ................ } -# tile 217 (garter snake) +# tile 433 (disenchanter,female) +{ + ................ + ....PPPP........ + ...PPDPDP....... + ...PPPAPP....... + ...PPOAOP....... + ...POPAPO...P... + ....PPPP.AAPP... + ....PPPPPAAPPP.. + ...PPPPPPPAPAPP. + ..PPPPPPAAAAP... + ..PPAPPPPAPPPA.. + ..AAPPPPPPPPPAA. + ....APPPPPPPAAA. + .....PPPPPAA..A. + ......AAAA...... + ................ +} +# tile 434 (garter snake,male) { ................ ................ @@ -4169,7 +8292,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 218 (snake) +# tile 435 (garter snake,female) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOKA........ + ...KKAKA........ + ...KKAKA....KA.. + ....APKAP..KAPP. + .....PKAPP.KAP.. + .....KAAP..KAP.. + ....KAAP..KAAP.. + ....KAAPPKAAP... + ....KAAKKAAP.... + .....KAAAAP..... + ................ + ................ +} +# tile 436 (snake,male) { ................ ................ @@ -4188,7 +8330,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 219 (water moccasin) +# tile 437 (snake,female) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOJA........ + ...KKJAJ........ + ...KKAAJ....KK.. + ...FAAKJ...KJAA. + ..FAFAKJAA.KJA.. + .....KJAA..KJA.. + ....KJAA..KJJA.. + ....KJAAAKJJA... + ....KJJJJJJA.... + .....KJJJJA..... + ................ + ................ +} +# tile 438 (water moccasin,male) { ................ ................ @@ -4207,7 +8368,26 @@ Z = (195, 195, 195) .....AAAAA...... ................ } -# tile 220 (python) +# tile 439 (water moccasin,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AA... + ...OAOAAA.AA.... + ...AAA.AA.AA.... + ...DA..AA.AA.... + ..D.D.AAA..AA... + .....AAA...AA... + .....AAA...AA... + ....AAA...AAA... + ....AAAAAAAA.... + ....AAAAAAA..... + .....AAAAA...... + ................ +} +# tile 440 (python,male) { ................ ................ @@ -4226,7 +8406,26 @@ Z = (195, 195, 195) .....JJJJJAA.... ................ } -# tile 221 (pit viper) +# tile 441 (python,female) +{ + ................ + ................ + ................ + ...KKKA.....JJ.. + ...GAGJA...JJJ.. + ..JKKJAJ..KJJ... + ..KKKAJJ..KJJ.AA + ..KKAAKJA.KKJAA. + .....AKJAA.KJAA. + ....JKJAA..KJJA. + ...JJJAA..KJJJA. + ...JJJAAAKJJJA.. + ...JJJJJJJJJAA.. + ....JJJJJJJAA... + .....JJJJJAA.... + ................ +} +# tile 442 (pit viper,male) { ................ ................ @@ -4245,7 +8444,26 @@ Z = (195, 195, 195) ......AAAA...... ................ } -# tile 222 (cobra) +# tile 443 (pit viper,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AAA.. + ...OAAAAA.AA.AA. + ...AA..AA.AA.AA. + ...D...AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA...AA... + .....AA...AAA... + .....AA..AAA.... + .....AAAAAA..... + ......AAAA...... + ................ +} +# tile 444 (cobra,male) { ................ ................ @@ -4264,7 +8482,26 @@ Z = (195, 195, 195) .....AAAAAAAAA.. ................ } -# tile 223 (troll) +# tile 445 (cobra,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAAA....... + ..PA..AAAA...... + ..A..AAAAA..AA.. + ..D..AAAAA....A. + ......AAA.....A. + ......AA..AAAA.. + .....AA..AA..... + ....AA...AA..... + ....AA....AAAA.. + ....AAA......AA. + .....AAAAAAAAA.. + ................ +} +# tile 446 (troll,male) { ................ ..AAAAAA........ @@ -4283,7 +8520,26 @@ Z = (195, 195, 195) ..KJA..KA....... ................ } -# tile 224 (ice troll) +# tile 447 (troll,female) +{ + ................ + ..AAAAAA........ + AAAANANA........ + .AAKKKJJA....... + AAAKAAAKA....... + AKAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAFGFJJAAAA.. + ..KJA.PFJAAAA... + ...AFAGFAAAAAA.. + ...GFAGP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 448 (ice troll,male) { ................ ..OONOOO........ @@ -4302,7 +8558,26 @@ Z = (195, 195, 195) ..KJA..KA....... ................ } -# tile 225 (rock troll) +# tile 449 (ice troll,female) +{ + ................ + ..OONOOO........ + NONOAOAOO....... + .NOKKKJJO....... + NOJKAAAKOO...... + OKJKAAAKAO...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 450 (rock troll,male) { ................ ...AAAAA........ @@ -4321,7 +8596,26 @@ Z = (195, 195, 195) ..KJA..KA....... ................ } -# tile 226 (water troll) +# tile 451 (rock troll,female) +{ + ................ + ...AAAAA........ + .AAANANAAAA..... + .AAKKKJJAA...... + AAAKAAAKAAAA.... + AKAKAAAKAAA..... + KJJAKKKAJKAA.... + KJAJAAAJJJA..... + KJAPAKJJKJA..... + PKJPPAGFJJAAAA.. + PPPPPAFFJAAAA... + .PPPAAGFAAAAAA.. + ...AFAGF.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 452 (water troll,male) { ................ ...AAAAA........ @@ -4340,7 +8634,26 @@ Z = (195, 195, 195) ..KJA..KA....... ................ } -# tile 227 (Olog-hai) +# tile 453 (water troll,female) +{ + ................ + ...AAAAA........ + ..AANANAA....... + .AAKKKJJAA...... + .AAKAAAKAA...... + .KAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 454 (Olog-hai,male) { ...PPPPP........ ..PPAAAPP....... @@ -4359,7 +8672,26 @@ Z = (195, 195, 195) ..AAA.AAA....... ................ } -# tile 228 (umber hulk) +# tile 455 (Olog-hai,female) +{ + ...PPPPP........ + ..PPAAAPP....... + ..PANANAP....... + ..PAAAAAP....... + .PPAAAAAPP...... + PPPAAAAAPPP..... + AAPPAAAPPAA..... + AAAPPPPPAAA..... + AAAPPPPPAAA..... + .AAAAPPPAAAPPP.. + PONNNNNNAACPP... + ...APAPPAPPPPP.. + ...PPAPP.PP.PP.. + ..AAAAAAAP.PP... + ..AAA.AAA....... + ................ +} +# tile 456 (umber hulk,male) { ................ ...AAAAA........ @@ -4378,7 +8710,26 @@ Z = (195, 195, 195) .AAAP..AAP...... ................ } -# tile 229 (vampire) +# tile 457 (umber hulk,female) +{ + ................ + ...AAAAA........ + ..AAAAAAA....... + .ADADADADA...... + .AAAAAAAAA.A.... + .AAAOAOAAA.AA... + .A.AOAOA.AAA.... + .A.AAAAAPAA..... + .AAAAAAAP....... + .A.AAAAA.PPPPPP. + ...AA.AA.PPPPP.. + ...AA.AAPPPPPPP. + ...AAPAAPPPP.... + ..AAAPAAAPP..... + .AAAP..AAP...... + ................ +} +# tile 458 (vampire,male) { ................ ................ @@ -4397,7 +8748,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 230 (vampire lord) +# tile 459 (vampire,female) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAAAAAAA...... + ..AAAAAAAA...... + ...AAAAAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 460 (vampire leader,male) { ................ .....AAAA....... @@ -4416,7 +8786,26 @@ Z = (195, 195, 195) .N..AAPP..AP.... ................ } -# tile 231 (vampire mage) +# tile 461 (vampire leader,female) +{ + ................ + .....AAAA....... + .N..AAOOAA...... + .NDDAGAAGADA.... + .NADALLLOAD..... + AAAAAAAAAAA..... + AAAAAAAAAAA..... + .AAAAAAAAAA..... + .NAAAAAAAAA..... + .N.AAAAAAAAPPPPP + .NADAAAAAAAPPPPP + .NADDAAAAAAPPPP. + .NAAAAAAAAAPPP.. + .N...AAAPAAPP... + .N..AAPP..AP.... + ................ +} +# tile 462 (vampire mage,male) { ................ ................ @@ -4435,7 +8824,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 232 (Vlad the Impaler) +# tile 463 (vampire mage,female) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAA.A.AA...... + ..AAAACAAA...... + ...AAADAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 464 (Vlad the Impaler,male) { ................ ..N..AAAA....... @@ -4454,7 +8862,26 @@ Z = (195, 195, 195) ..N.AAPP..AP.... ................ } -# tile 233 (barrow wight) +# tile 465 (Vlad the Impaler,female) +{ + ................ + ..N..AAAA....... + ADNDAAOOAADDDA.. + .ANDAGAAGADDA... + ..NDALLLOADA.... + ..NAAAAAAAAAAAAA + .HHHDAAAAADDDDDA + HEHEHJAAAADDDAA. + LLLLLJAAAADDAAPP + .LLLJAAAAADDAPPP + ..NJDAAAAADAPPPP + .ANDDAAAAAAAPPPP + .ANAAAAAAAAPPPP. + ..N..AAAPAAPPP.. + ..N.AAPP..AP.... + ................ +} +# tile 466 (barrow wight,male) { ................ ................ @@ -4473,7 +8900,26 @@ Z = (195, 195, 195) .J.....LLAA..... ................ } -# tile 234 (wraith) +# tile 467 (barrow wight,female) +{ + ................ + ................ + ...LLO.......... + ..DLDLO......... + ..LLLLO......... + ..LJL..P........ + ..OOO.PP...AAAA. + ..POO.PP.AAAAAA. + .LPOO.PP.PAAAA.. + .JJOO.PP.PAAAA.. + .J.O..PL.PPAAA.. + .J.O.PPPPPPAAA.. + .J...PPPPPPPAA.. + .J..LLPPPPPPA... + .J.....LLAA..... + ................ +} +# tile 468 (wraith,male) { ................ ................ @@ -4492,7 +8938,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 235 (Nazgul) +# tile 469 (wraith,female) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + ..AAPPPPAP..AAA. + ..PPPPPOLPAAAAA. + ...A.PPAAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ + ................ + ................ +} +# tile 470 (Nazgul,male) { ................ ................ @@ -4511,7 +8976,26 @@ Z = (195, 195, 195) ......PPPPA..... ................ } -# tile 236 (xorn) +# tile 471 (Nazgul,female) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + .OPAPPPPAP..AAA. + ..PAPPPPAP..AAA. + ..PA.PPPLP..AAA. + ..PP.PPOLPAAAAA. + ...AAPPOAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ +} +# tile 472 (xorn,male) { ................ ................ @@ -4530,7 +9014,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 237 (monkey) +# tile 473 (xorn,female) +{ + ................ + ................ + ................ + ...OB.OP.BP..... + ...BBBBPPPP..... + ...B............ + ...DDBB.BDDA.A.. + ...DDBB.PDDAAAA. + ...B.......AAAA. + ...BOB.BPP.AAAA. + ...BBB.PPP.AAAA. + ...B.......AAA.. + ...BOBBPPBPAA... + ...BO.BP.PPA.... + ................ + ................ +} +# tile 474 (monkey,male) { ................ ................ @@ -4549,7 +9052,26 @@ Z = (195, 195, 195) .....JJA.JJA.... ................ } -# tile 238 (ape) +# tile 475 (monkey,female) +{ + ................ + ................ + ................ + ................ + ................ + .......KKA...... + ......KLLJA..... + ......KLLJA..... + .......KJA...... + .....KKKKKJAA... + ....KJKLLJJJAA.. + ....LAKLLJALAA.. + ......KJJJAAAA.. + ......JAAJAAA... + .....JJA.JJA.... + ................ +} +# tile 476 (ape,male) { ................ ................ @@ -4568,7 +9090,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 239 (owlbear) +# tile 477 (ape,female) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCLACCAJJAAA + ..KKKKCCCAJKJJAA + ..KKAKJAAJJAJJAA + ..KAAKJJJJJAAJAA + ..LC.KJJJJJKCLAA + ..LL.CJJAKLJLLAA + .....CLJACLJAAAA + ...LLLLJACLLLKA. + ................ + ................ +} +# tile 478 (owlbear,male) { ................ ....K.....K..... @@ -4587,7 +9128,26 @@ Z = (195, 195, 195) ...PJPJAJPJPA... ................ } -# tile 240 (yeti) +# tile 479 (owlbear,female) +{ + ................ + ....K.....K..... + ....CK...KK..... + ....CKKKKKK..... + ...KOOOKOOOK.... + ...KOOOKOOOKA..A + ...KOOAJAOOKAAAA + ..CKCJJHJJKAKAAA + .CKKKCKLKKAJJKAA + .KJJJJCKKJJJJJAA + .KJJJPAKJPJJJJAA + ..KJJJAKJJJJJAAA + ...JJPAKJPJJAAA. + ...JAAJAJAAJAA.. + ...PJPJAJPJPA... + ................ +} +# tile 480 (yeti,male) { ................ ....BNNN........ @@ -4606,7 +9166,26 @@ Z = (195, 195, 195) ..BNNA..NNA..... ................ } -# tile 241 (carnivorous ape) +# tile 481 (yeti,female) +{ + ................ + ....BNNN........ + ...BNANAP....... + ..BNNNNNNP...... + ..NNNADANN...... + ..NNNNNNPN...... + ..N.NNBPPNP..... + ..N.NNNNANP..AA. + ..NNBNNNPN.AAAA. + ....NNNNP.KAAA.. + ....NN.NPAKKAA.. + ....NB.NPAACKAA. + ....NNANPAAKKJA. + ...BNNANNPAACKA. + ..BNNA..NNA..... + ................ +} +# tile 482 (carnivorous ape,male) { ................ ................ @@ -4625,7 +9204,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 242 (sasquatch) +# tile 483 (carnivorous ape,female) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCAAACAJJAAA + ..KKKCDDDCAKJJAA + ..KKAKCCCAJAJJAA + ..KAAKJAAJJAAJAA + ..LC.AJJJJJKCLAA + ..LLDDAJAKLJLLAA + ...DDALJACLJAAAA + ..DDALLJACLLLKA. + ................ + ................ +} +# tile 484 (sasquatch,male) { ................ ....CCCCC....... @@ -4644,7 +9242,26 @@ Z = (195, 195, 195) .CJJJKACKJJKA... ................ } -# tile 243 (kobold zombie) +# tile 485 (sasquatch,female) +{ + ................ + ....CCCCC....... + ...CGAJGAJ...... + ..CKKKKJJJ...... + ..CKKAAAKJJ..... + .CKKKAAAKKJ..... + .CKJKKKKKKKJ.... + .CKAJJJJJAKJ.... + .CKAJKKKJAKJ.AA. + .CKJAJKJACKJAAAA + .CKJAJJJACKJAAA. + ..J.AJAKKAJAAAAA + ...CKJAKKJAAAAA. + .KCKJJACKJKJAA.. + .CJJJKACKJJKA... + ................ +} +# tile 486 (kobold zombie,male) { ................ ................ @@ -4663,7 +9280,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 244 (gnome zombie) +# tile 487 (kobold zombie,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NGFBN........ + ...GABAB........ + ....GBFA..A..... + ...GBABFA.AA.... + ..GFBBBIKAAA.A.. + ..BAFBFFEAAAAA.. + ..BAFBFFAAAAAA.. + ....FBFAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 488 (gnome zombie,male) { ................ ................ @@ -4682,7 +9318,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 245 (orc zombie) +# tile 489 (gnome zombie,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GDFDF....... + .....PFP...AAA.. + ...FGFPFEGAAAA.. + ..GAAGFFFAGAAA.. + ....AKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 490 (orc zombie,male) { ................ ................ @@ -4701,7 +9356,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 246 (dwarf zombie) +# tile 491 (orc zombie,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....GPGA........ + .....PFA........ + ..KCCAKKKA.AA... + .BBPCKJ.BBAAA... + BB.AGGFAABBA.... + B..AJJPAAABA.... + ....BAPPPAAAAA.. + ...BJAAEPAAA.... + ..BPPAAAPP...... + ................ + ................ +} +# tile 492 (dwarf zombie,male) { ................ ................ @@ -4720,7 +9394,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 247 (elf zombie) +# tile 493 (dwarf zombie,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BFFFE....... + .....PFP...AAA.. + ...BBPPPEEAAAA.. + ..FBABPEAEAAAA.. + ..F.EBBEFAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 494 (elf zombie,male) { ................ ................ @@ -4739,7 +9432,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 248 (human zombie) +# tile 495 (elf zombie,female) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......FEFEA..... + ......FFFFA..... + ......AFDA....A. + ......GAAG..AAA. + ....FFGGGFFFAAA. + ...FAAAGFAAAFAA. + .....AGGGFAAAA.. + ......GFAFAA.A.. + .....KDA.FKA.... + ................ + ................ +} +# tile 496 (human zombie,male) { ......AAA....... .....FFGAA...... @@ -4758,7 +9470,26 @@ Z = (195, 195, 195) ....GGAGGA...... ................ } -# tile 249 (ettin zombie) +# tile 497 (human zombie,female) +{ + ......AAA....... + .....FFGAA...... + .....AGAFA...... + .....FFGFA...... + ....FKF..JJ..... + ....JJJFJKJ..... + ...FJ.KJJAKJ.... + ..FK..KFJFFJ.... + ..G...KKJG...... + .....BP.BPAAAAA. + .....FPAPFAAAA.. + .....BFABFAAAA.. + .....PFABPAA.... + .....BFABFA..... + ....GGAGGA...... + ................ +} +# tile 498 (ettin zombie,male) { ....NN..ONOP.... ..NNOOPNNOOPP... @@ -4777,7 +9508,26 @@ Z = (195, 195, 195) .....GFAAGFAAAAA ...FFFFA.GFFFFAA } -# tile 250 (ghoul) +# tile 499 (ettin zombie,female) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NFF..NFF..P... + ..ADFFDADFFDA... + ..AFFFFAFFFFA... + ..AFAAFAFAAFAA.. + ..AFFFFAFFFFAAA. + ..GIIIIJJJIIIGAA + .GFFFIIIIIIFFFGA + .GFFFFIIIIFFFFFA + .FFAAFIIIIFAAFFA + .FFAAIIIIIIAAFFA + .FFF.IIFFIIAGFAA + ..FF.GFAAGFAFFAA + .....GFAAGFAAAAA + ...FFFFA.GFFFFAA +} +# tile 500 (ghoul,male) { ......AAA....... .....OOOAA...... @@ -4796,7 +9546,26 @@ Z = (195, 195, 195) ....OOAOOA...... ................ } -# tile 251 (giant zombie) +# tile 501 (ghoul,female) +{ + ......AAA....... + .....OOOAA...... + .....DODOA...... + .....OOOOA...... + ....PPOOOPP..... + ....PPPPPPP..... + ...PP.PPPAPP.... + ..PP..PPPOOP.... + ..O...PPPO...... + .....PP.PPAAAAA. + .....PPAPPAAAA.. + .....PPAPPAAAA.. + .....PPAPPAA.... + .....PPAPPA..... + ....OOAOOA...... + ................ +} +# tile 502 (giant zombie,male) { ......JJJJAA.... ....JJJJJJJJA... @@ -4815,7 +9584,26 @@ Z = (195, 195, 195) ....GFFAGFFAAAAA ...GFFAAGFFFAAAA } -# tile 252 (skeleton) +# tile 503 (giant zombie,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJFFFFJJA... + ....JDDFFDDJA... + ....JFFFFFFJA... + ....AFFAAFFAAA.. + .....AFFFFJAAAA. + ..GGFFJJJJFFGGAA + .GFFFGGFFFFFFFCA + .FFFKFFFFFFKFFFA + FFFAAFFFFFFAAFFA + FFAA.JJJKKJAAFFA + FFA..JJJJJKAGFAA + .....GFAGFFAFFAA + ....GFFAGFFAAAAA + ...GFFAAGFFFAAAA +} +# tile 504 (skeleton,male) { ................ ................ @@ -4834,7 +9622,26 @@ Z = (195, 195, 195) ......OOO....... ................ } -# tile 253 (straw golem) +# tile 505 (skeleton,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + ......O......... + ....OOOOO...AAA. + ...OA.OOOA..AAA. + ..OA.OAAO.AAAAA. + ....OA.OOOAAA.A. + ......OOOAAA.A.. + .....O.AO.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 506 (straw golem,male) { ......LJ........ ......LJHJ...... @@ -4853,7 +9660,26 @@ Z = (195, 195, 195) ....HALA.AHAAL.. ..........L..... } -# tile 254 (paper golem) +# tile 507 (straw golem,female) +{ + ......LJ........ + ......LJHJ...... + ....HJLJH...A... + ....AAAAAL.....A + ....DAADAL.A.AA. + ....LJHJL..AAAA. + ....LLHJLHHCHHL. + ...HHLJL.AJLJL.A + .HHJJLLLLAAA.AA. + ..JL..LALHAAAAAA + .LL..CJLHJHAAAAA + .....HJLAHJHAAA. + .....HJAACALHAAA + ....CJLAAJHALHA. + ....HALA.AHAAL.. + ..........L..... +} +# tile 508 (paper golem,male) { ................ .......OA....... @@ -4872,7 +9698,26 @@ Z = (195, 195, 195) ....OOA...OOA... ................ } -# tile 255 (rope golem) +# tile 509 (paper golem,female) +{ + ................ + .......OA....... + .....NNNOA...... + .....ONNNOA..... + ......ONNOA..... + .......NOA...... + ..NNOA.NOA...... + ..NONOAOAONNOA.. + ..OAOANNOAOOOA.. + ......NNNOAAAAA. + ......ONOAAAAAA. + .......OOAAAAAA. + .....NOAAOAAAAA. + .....NOA..NOAA.. + ....OOA...OOA... + ................ +} +# tile 510 (rope golem,male) { ................ ................ @@ -4891,7 +9736,26 @@ Z = (195, 195, 195) ...O.A....OAA... ....OA.......... } -# tile 256 (gold golem) +# tile 511 (rope golem,female) +{ + ................ + ................ + ......OOO....... + .....O...O...... + .....O...O...AA. + .OO...O..O..A..A + O..O...LL..OO..A + ...O...LOOO.AOA. + ....OOOOOAAAAO.. + .......OO..AA.A. + .......LO.AA...A + ......O..OOAA..A + ....OO..A..O.A.. + ...O..AA...O.A.. + ...O.A....OAA... + ....OA.......... +} +# tile 512 (gold golem,male) { ................ ......HNH....... @@ -4910,7 +9774,26 @@ Z = (195, 195, 195) H...HNC.AHNC.A.H ..H............. } -# tile 257 (leather golem) +# tile 513 (gold golem,female) +{ + ................ + ......HNH....... + ......DND...N... + ......HNH...JC.. + ......HNH...NC.. + ...HHHAAAAHANC.. + ..HNJNHNHNJNAC.A + ..HHHHHHHHHHHA.A + .NCACCCCCCCCA..A + .HH.AAAAAAAAA.AA + .NH.ANC.AHNC.AAA + .NJ.AHC.AHHC.AAA + ..H.ANC.AHNC.AAA + ....HJC.AHJC.AA. + H...HNC.AHNC.A.H + ..H............. +} +# tile 514 (leather golem,male) { ......KKKK...... .....KHKHJ...... @@ -4929,7 +9812,26 @@ Z = (195, 195, 195) ...KJJA..KJJA... ....KA....KA.... } -# tile 258 (wood golem) +# tile 515 (leather golem,female) +{ + ......KKKK...... + .....KHKHJ...... + ....KAKKJJA..... + ...KKAJJJJAJ.... + ..KKJJAJAAKJJ... + .KKKJJAAKKKJJJ.. + ..KKJJJAKKJJJJ.. + ...KKJJJA.AAA.A. + ....AAAA.KJAAAA. + ....KJAAAKKAAAAA + ...KJJAA.KJJAAA. + ...KKJA..KKJAAA. + ..KKJJJAKKJJJAA. + ..KKKJJAKKKJJA.. + ...KJJA..KJJA... + ....KA....KA.... +} +# tile 516 (wood golem,male) { ................ ......KCKJ...... @@ -4948,7 +9850,26 @@ Z = (195, 195, 195) ....KCKJAKCKJA.. ................ } -# tile 259 (flesh golem) +# tile 517 (wood golem,female) +{ + ................ + ......KCKJ...... + ......HCHJ..C... + ......KCKJ..CK.. + ......KCKJ..CKJ. + ...KKKAAAAKACKJ. + ..KCCCCCCCCCAKJA + ..KKKKKKKKKKKAJA + .CJAJJJJJJJJA..A + .CKJAAAAAAAAA.AA + .CKJACKJAKCKJAAA + .CKJACKJAKCKJAAA + ..KJACKJAKCKJAAA + ....KCKJAKCKJAA. + ....KCKJAKCKJA.. + ................ +} +# tile 518 (flesh golem,male) { ................ ................ @@ -4967,7 +9888,26 @@ Z = (195, 195, 195) ..LLDDD..DDDDD.. ................ } -# tile 260 (clay golem) +# tile 519 (flesh golem,female) +{ + ................ + ................ + ...D..DDC....... + .....DLDDL...... + ..DD..LLLLC.D... + ...CDL.LLLLADL.. + ..CLDLA.CLLA.LL. + ..LLLAA.LLCA..L. + .CLLAA.CLLAA..CA + .LLA..CLLALLAAAA + ..LA.CLCAALCAAAA + ...A..LLCACLCAAA + ....LLALLAALLAAA + ..CLLLAAAADLLA.. + ..LLDDD..DDDDD.. + ................ +} +# tile 520 (clay golem,male) { ................ ................ @@ -4986,7 +9926,26 @@ Z = (195, 195, 195) ..CKKKA.CKKKAA.. ................ } -# tile 261 (stone golem) +# tile 521 (clay golem,female) +{ + ................ + ................ + ................ + ....LCCCCK...... + ...LKKKKKKK..... + ...CKAKKAKK..... + ...CKAKKAKK..... + .LCKKKKKKKKLC... + CKKJKKKKKKCKKJ.. + KKKJKKJJKKJKKJAA + .JJAKKJAKKAJJAAA + ..AKKKJAKKKAAAAA + ..CKKKKKKKKKAAAA + ..CKKKAACKKKAA.. + ..CKKKA.CKKKAA.. + ................ +} +# tile 522 (stone golem,male) { ................ ................ @@ -5005,7 +9964,26 @@ Z = (195, 195, 195) ...PPAA.PPPA.... ................ } -# tile 262 (glass golem) +# tile 523 (stone golem,female) +{ + ................ + ................ + ................ + ....BBBPP....... + ...BBPPPPP...... + ...BHAPHAP...... + ...PPPPPPP...... + .BBPPPPPP.BPA... + BPPPP....PPPPAA. + BPP.BPPPP.PPPAAA + .PP.BP.PP.PPPAAA + ...BPP.PPPAAAAAA + ..BPPPAPPPAAAAA. + ..PPPPAPPPPAAA.. + ...PPAA.PPPA.... + ................ +} +# tile 524 (glass golem,male) { ................ .....BBBBBBA.... @@ -5024,7 +10002,26 @@ Z = (195, 195, 195) ..BNPA....NPAA.. ...BA.....BPA... } -# tile 263 (iron golem) +# tile 525 (glass golem,female) +{ + ................ + .....BBBBBBA.... + .....BPNPPPA.... + .....BNPPPNA.... + .....NPPPNPA.... + .....BPPNPPA.... + .......BA...BA.. + .BNBBABPBA.BPNA. + .NPPNABPNBBANPBA + .....BPNPPPAABAA + .....BNPPPAAAAAA + ......BPPNAAAAAA + ....BNABNABPAAA. + ...BNPA...BNAAA. + ..BNPA....NPAA.. + ...BA.....BPA... +} +# tile 526 (iron golem,male) { ................ ......PBP....... @@ -5043,7 +10040,26 @@ Z = (195, 195, 195) ....PBP.APBP.A.. ................ } -# tile 264 (human) +# tile 527 (iron golem,female) +{ + ................ + ......PBP....... + ......HBH...B... + ......PBP...JP.. + ......PBP...BP.. + ...PPPAAAAPABP.. + ..PBJBBBBBJBAP.A + ..PPPPPPPPPPPA.A + .B.A........A..A + .BP.AAAAAAAAA.AA + .BP.ABP.APBP.AAA + .BJ.ABP.APBP.AAA + ..P.ABP.APBP.AAA + ....PJP.APJP.AA. + ....PBP.APBP.A.. + ................ +} +# tile 528 (human,male) { ................ ................ @@ -5062,7 +10078,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 265 (wererat) +# tile 529 (human,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......ELELA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 530 (wererat,male) { ................ ................ @@ -5081,7 +10116,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 266 (werejackal) +# tile 531 (wererat,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......GJGJA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 532 (werejackal,male) { ................ ................ @@ -5100,7 +10154,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 267 (werewolf) +# tile 533 (werejackal,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......IPIPA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 534 (werewolf,male) { ................ ................ @@ -5119,7 +10192,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 268 (elf) +# tile 535 (werewolf,female) +{ + ................ + ................ + ......JJA....... + .....JJJJA...... + .....NJNJA...... + .....LLLLA...... + .....ALLA....... + ....CLAALC.AAA.. + ...CLLLLLLCAAA.. + ...LACLLCALAAA.. + ...LAJJKJALAAA.. + .....JJJKAAAA... + .....JJAJAA.A... + ....KLA.LKA..... + ................ + ................ +} +# tile 536 (elf,male) { ................ .........G...... @@ -5138,7 +10230,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 269 (Woodland-elf) +# tile 537 (elf,female) +{ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 538 (Woodland-elf,male) { ................ ................ @@ -5157,7 +10268,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 270 (Green-elf) +# tile 539 (Woodland-elf,female) +{ + ................ + ................ + .........K...... + .......KKJ...... + ......KKKKA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......KAAK..AAA. + .....LKKKJLAAAA. + ....LAPPJAALAAA. + ..KKLKKKKJALAA.. + ......PPAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 540 (Green-elf,male) { ................ ................ @@ -5176,7 +10306,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 271 (Grey-elf) +# tile 541 (Green-elf,female) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 542 (Grey-elf,male) { ................ ................ @@ -5195,7 +10344,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 272 (elf-lord) +# tile 543 (Grey-elf,female) +{ + ................ + ................ + .........P...... + .......PP....... + ......PPPPA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......PAAP..AAA. + .....LPPP.LAAAA. + ....LAAP.AALAAA. + ....LAPPP.ALAA.. + ......P.A.AA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 544 (elf-leader,male) { ................ ................ @@ -5214,7 +10382,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 273 (Elvenking) +# tile 545 (elf-leader,female) +{ + ................ + ................ + ........II...... + .......HGF...... + ......HGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......HAAH..AAA. + .....LHHHFLAAAA. + ....LAAIIAALAAA. + ....LAHGGFALAA.. + ......HFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 546 (Elvenmonarch,male) { ................ ................ @@ -5233,7 +10420,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 274 (doppelganger) +# tile 547 (Elvenmonarch,female) +{ + ................ + ................ + ......H..H...... + ......HCHH...... + ......HHHHA..... + ......LELEA..... + ......LLLLA..... + .....IALLAI...A. + ....IIIAAIDIAAA. + .....LIIGDLAAAAA + ....LADIFDALAAAA + ....LAIIGDALAAA. + .....IIFAFDAAA.. + ...IIKLAILKDI... + ................ + ................ +} +# tile 548 (doppelganger,male) { ................ ......CCCC..I... @@ -5252,7 +10458,26 @@ Z = (195, 195, 195) ..CD.LLAALLADC.. ................ } -# tile 275 (shopkeeper) +# tile 549 (doppelganger,female) +{ + ................ + ......CCCC..I... + ..I..CD...C..... + ....CD.HHA.C.... + ...CD.HHHHA.C.I. + ...CD.LFLFA.DC.. + .I.CD.LLLLA.DC.. + ...CD.ALLA.DC... + ..CD.LLAALL.ACA. + .CD.LLLLLLLLADC. + .CD.LALLLLALADC. + .CD.LAJJKJALADC. + ..CD..LJJLAAACA. + ...CD.LLALAACA.. + ..CD.LLAALLADC.. + ................ +} +# tile 550 (shopkeeper,male) { ................ ................ @@ -5271,7 +10496,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 276 (guard) +# tile 551 (shopkeeper,female) +{ + ................ + ................ + ......AAAA...... + .....AAAAAA..... + ......JLJL...... + ......LLLL...... + ......ALLA...... + .....EBAABEA.AA. + ....EBBBBBBEAAA. + ....BAEBBEABAAA. + ....LAGFFFALAAA. + ......GFAFAAAA.. + ......GFAFAA.A.. + .....JJA.JJA.... + ................ + ................ +} +# tile 552 (guard,male) { ................ .....BBPPPAA.... @@ -5290,7 +10534,26 @@ Z = (195, 195, 195) .....BPPABPPAAAA ....BPPP.BPPPAAA } -# tile 277 (prisoner) +# tile 553 (guard,female) +{ + ................ + .....BBPPPAA.... + ....BNPPPPPPA... + ....BPPBPPPPA... + ....BAABPAAPA... + ....BCLBPCLPA... + ....AKCPPCJAAA.. + ....BKJJJJAPAAAA + ...BPKJAAJAPPAAA + ..BPPKJJJJAPPPAA + ..PPABKJJAPPAPPA + ..PPABPKAPPPAPPA + ..LC.BPPPPPPCLAA + ..LL.BPPABPPLLAA + .....BPPABPPAAAA + ....BPPP.BPPPAAA +} +# tile 554 (prisoner,male) { ................ ................ @@ -5309,7 +10572,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 278 (Oracle) +# tile 555 (prisoner,female) +{ + ................ + ................ + .......NOA...... + .......LLA...... + .......LLA...... + .......NOA...... + ......NOONA..... + .....NOOOONA.... + ....NANOOOANAA.. + ....PANOOOAPAAA. + ....LANOOOALAAA. + ......NOOOAAAA.. + ......NAANAAA... + ......PAAPAA.... + .....LLA.LLA.... + ................ +} +# tile 556 (Oracle,male) { ................ ................ @@ -5328,7 +10610,26 @@ Z = (195, 195, 195) ....LELLLLELAA.. ................ } -# tile 279 (aligned priest) +# tile 557 (Oracle,female) +{ + ................ + ................ + .......NN....... + LLL...GLLG...LLL + ..L..NLLLLN..L.. + ...L.NLAALN.L... + ....LNLLLLNL.... + .....LNLLNL..AA. + .....NBBEEN.AAAA + ......BBEEAAAAAA + .LLA..BBBEAAALL. + .LLLLBBBEBELLLLA + ..LLCLBLLELLCLAA + ...CLLLLLLLCLAA. + ....LELLLLELAA.. + ................ +} +# tile 558 (aligned priest,male) { ................ INI............. @@ -5347,7 +10648,26 @@ Z = (195, 195, 195) .JACCCJJCCCAA... ................ } -# tile 280 (high priest) +# tile 559 (aligned priest,female) +{ + ................ + INI............. + III..KCCK....... + .J..KCCCCK...... + .J..CAAKCC...... + .LC.CAAACC...... + CLLC.CAACJKC.... + CJLACCCCJKCCC... + .JAACCJJCKCCCK.. + .JKCCCJCCJCCK.AA + .J..CCJCCLJCAAAA + .J..CCJCLLCAAAA. + .J..KCJCCCJAAAA. + .J.ACCJCCCJAAA.. + .JACCCJJCCCAA... + ................ +} +# tile 560 (high priest,male) { .INI............ IIIII.KCCK...... @@ -5366,7 +10686,26 @@ Z = (195, 195, 195) ..HACCCJJCCCAA.. ................ } -# tile 281 (soldier) +# tile 561 (high priest,female) +{ + .INI............ + IIIII.KCCK...... + .IHI.KCAACK..... + ..H..CGAGAC..... + ..LC.CAAAAC..... + .CLLC.CAACJCK... + .CHLACCCCJCCCK.. + ..HAACCJJCCCCCK. + ..HCCCCJCCJCCC.A + ..H..CCJCCLJCAAA + ..H..CCJCLLCAAAA + ..H..KCJCCCJAAAA + ..H..KCJCCCJAAAA + ..H.ACCJCCCJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 562 (soldier,male) { .....J.......... .....JAAA....... @@ -5385,7 +10724,26 @@ Z = (195, 195, 195) .....JJ.JJ...... ................ } -# tile 282 (sergeant) +# tile 563 (soldier,female) +{ + .....J.......... + .....JAAA....... + .....ALLLA...... + .....LLLLC...... + .....JLLC....... + .....JF..F...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....JJ.JJ...... + ................ +} +# tile 564 (sergeant,male) { .....J.......... .....JFFF....... @@ -5404,7 +10762,26 @@ Z = (195, 195, 195) .....AA.AA...... ................ } -# tile 283 (nurse) +# tile 565 (sergeant,female) +{ + .....J.......... + .....JFFF....... + ....FFFFFF...... + .....LLLLC...... + .....JLLC....... + .....JF..G...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 566 (nurse,male) { ................ .......NO....... @@ -5423,7 +10800,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 284 (lieutenant) +# tile 567 (nurse,female) +{ + ................ + .......NO....... + ......NDDO...... + ......NNOOA..... + .....DBLBLD..... + .....CLLLLDC.... + .....DALLACD.... + .....CNAAODCAAA. + .....NNNOOLAAAA. + ....LANNDOALAAA. + ....LANNOOALAAA. + ......NNOOAAAA.. + ......NNAOAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 568 (lieutenant,male) { ................ .......FFF...... @@ -5442,7 +10838,26 @@ Z = (195, 195, 195) .....AA.AA...... ................ } -# tile 285 (captain) +# tile 569 (lieutenant,female) +{ + ................ + .......FFF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....GF.FGA..... + ....FFFFFFFF.... + ....FAFFFFAFAAA. + ....FAFFFFAFAAAA + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 570 (captain,male) { ................ ......FHHF...... @@ -5461,7 +10876,26 @@ Z = (195, 195, 195) .....AA.AAAAA... ................ } -# tile 286 (watchman) +# tile 571 (captain,female) +{ + ................ + ......FHHF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....HF.FHF..... + ....FFFFFFFFAA.. + ....FAFFIFAFAAAA + ....FAFFFFAFAAA. + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.JJJA.. + .....FFAFFJJJA.. + .....AA.AAAAA... + ................ +} +# tile 572 (watchman,male) { ................ ......PPP....... @@ -5480,7 +10914,26 @@ Z = (195, 195, 195) ....JJJ.JJJ..... ................ } -# tile 287 (watch captain) +# tile 573 (watchman,female) +{ + ................ + ......PPP....... + ....PPPPPP...... + .....LLLLC...... + ......LLC....... + .....PP..P...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + ......PAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 574 (watch captain,male) { ......PPP....... .....PHHHP...... @@ -5499,7 +10952,26 @@ Z = (195, 195, 195) ....JJJ.JJJ..... ................ } -# tile 288 (Medusa) +# tile 575 (watch captain,female) +{ + ......PPP....... + .....PHHHP...... + ....PPPPPPP..... + .....LLLLC...... + ......LLC....... + .....HP..H...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + .....JPAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 576 (Medusa,male) { ................ ..GA...GA....... @@ -5518,7 +10990,26 @@ Z = (195, 195, 195) ..IIKIKIKIA..... ................ } -# tile 289 (Wizard of Yendor) +# tile 577 (Medusa,female) +{ + ................ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....A.. + .GAFLLLLA..A..A. + ....JLLKA.A.A.A. + ...KBLLBKAAAAA.. + ..KIIBBIIIAAA.A. + ..IIIKKILLIAAA.. + ..KIILLIALIAA... + ...KIALKAAIAA... + ...IKAAKIIAAA... + ...IIKKIIIAA.... + ..IIKIKIKIA..... + ................ +} +# tile 578 (Wizard of Yendor,male) { .EEE.......EEE.. EFFAE..E..EAFFE. @@ -5537,7 +11028,26 @@ Z = (195, 195, 195) .EEEEEEEEEEEAAA. EEEEEEEEEEEEEEA. } -# tile 290 (Croesus) +# tile 579 (Wizard of Yendor,female) +{ + .EEE.......EEE.. + EFFAE..E..EAFFE. + EAAAE.EEE.EAAAE. + EAAAEEEAEEEAAAE. + EEAAEEDADEEAAEE. + .EEEEAAAAAEEEE.. + ..EEEEAAAEEEE... + ..EEEEEEEEEE.... + ...EEEEEEEE..... + ...EEEEEEEE....A + ....EEEEEE...AAA + ....EEEEEEAAAAAA + ...EEEEEEEEAAAAA + ..EEEEEEEEEAAAAA + .EEEEEEEEEEEAAA. + EEEEEEEEEEEEEEA. +} +# tile 580 (Croesus,male) { ....H..H..H..... ....HCHEHCH..... @@ -5556,7 +11066,26 @@ Z = (195, 195, 195) .GIIIKJJKKIIIGG. ................ } -# tile 291 (Charon) +# tile 581 (Croesus,female) +{ + ....H..H..H..... + ....HCHEHCH..... + ....HHHHHHH..... + ....ALLLLLA..... + ....LLALALL..... + .....LLLLL...... + ....HLLDLLH..... + ...HIALLLAIH.A.A + ...HIHAAAHIHAAAA + ..IIIEHHHIIIIAAA + ..IIIIEHIIIIIAA. + ..ILLIHHHILLIAAA + ...LIIKHIIILAAAA + ..GIIIKJIIIIGAA. + .GIIIKJJKKIIIGG. + ................ +} +# tile 582 (Charon,male) { ................ .......J........ @@ -5575,7 +11104,26 @@ Z = (195, 195, 195) .JJJJJJJJJJJAAA. JJJJJJJJJJJJJJA. } -# tile 292 (ghost) +# tile 583 (Charon,female) +{ + ................ + .......J........ + ......JJJ....... + ....JJJAJJJ..... + ....JJDADJJ..... + ...JJAAAAAJJ.... + ...JJJAAAJJJ.... + ..JJJJJJJJJJ.... + .JJJJJJJJJJJJ... + JJJJJJJJJJJJJJ.A + .OO.JJJJJJ.OOAAA + ....JJJJJJAAAAAA + ...JJJJJJJJAAAAA + ..JJJJJJJJJAAAAA + .JJJJJJJJJJJAAA. + JJJJJJJJJJJJJJA. +} +# tile 584 (ghost,male) { ................ ................ @@ -5594,7 +11142,26 @@ Z = (195, 195, 195) .O...P....P..... ........P....... } -# tile 293 (shade) +# tile 585 (ghost,female) +{ + ................ + ................ + ...NNN.......... + ..NANANN........ + .NNNNNNNNN...... + .NNPAAPNNNNN.... + .NNAAAANNNOONO.. + .NNAAAANONNNPNNO + .NNPAAPNONNOOOP. + .NNNNNNONOPNPPO. + .NNONNOPNNOPOOP. + .NOPNNOOOPPOOP.. + .OOOPOPPOPPP.PP. + .PP.PPOPPP...P.. + .O...P....P..... + ........P....... +} +# tile 586 (shade,male) { ................ ................ @@ -5613,7 +11180,26 @@ Z = (195, 195, 195) AAAA.AAAAJA..... ................ } -# tile 294 (water demon) +# tile 587 (shade,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ........AAAAAAA. + ....AAAAAAAA.... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAA. + ..AAAAAAAAAAAAAA + .AAAAAAAAAAAAA.. + AAAA.AAAAJA..... + ................ +} +# tile 588 (water demon,male) { ................ ................ @@ -5632,45 +11218,26 @@ Z = (195, 195, 195) ....EEAEEA...... ................ } -# tile 295 (succubus) -{ - DD.OHHD......... - DDOHHDGD........ - DDOHDDDDD....... - DDHHDDDA........ - DHHHDJADDDD..... - .HHJJDDDJDDD.... - OHDDCDCDDJDD.... - HHHCDDCDLJ.DD... - HHHCDLJJJAADDA.. - HHHDJJDDDAADAA.. - HHHHDDAADAAAA... - HHHH.DKJDDAA.... - H.H..DDAADDAA... - ..H..DDAA.DAA... - ....DDAA..DDAA.. - ...DDJA...DDDA.. -} -# tile 296 (horned devil) +# tile 589 (water demon,female) { ................ ................ - ..O.......O..... - ..OO.....OO..... - ...LOCDCOL...... - ...CDDDDDC...... - ...DAADAADA..D.. - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - ..CDAKKKACDAAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - ...CDDADDKAA.... - ..CDDAA.DDK..... + ................ + ................ + ..EE.....EE..... + .E.EE...EE.E.... + ....EEEEE....... + ....EBEBE..A.... + ...EEEEEEEAAAA.. + ..EEE...EEEAA.A. + ..EEEEEEEEEAAA.. + ..EEAEEEAEEAAA.. + ...AAEEEAAAAA... + ....EEAEEAA..... + ....EEAEEA...... ................ } -# tile 297 (incubus) +# tile 590 (Amorous Demon,male) { DD.OHHD......... DDOHHDGD........ @@ -5689,7 +11256,64 @@ Z = (195, 195, 195) ...DDKAA..DDAA.. ..DDKAA...DDDA.. } -# tile 298 (erinys) +# tile 595 (Amorous Demon,female) +{ + DD.OHHD......... + DDOHHDGD........ + DDOHDDDDD....... + DDHHDDDA........ + DHHHDJADDDD..... + .HHJJDDDJDDD.... + OHDDCDCDDJDD.... + HHHCDDCDLJ.DD... + HHHCDLJJJAADDA.. + HHHDJJDDDAADAA.. + HHHHDDAADAAAA... + HHHH.DKJDDAA.... + H.H..DDAADDAA... + ..H..DDAA.DAA... + ....DDAA..DDAA.. + ...DDJA...DDDA.. +} +# tile 592 (horned devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + ...LOCDCOL...... + ...CDDDDDC...... + ...DAADAADA..D.. + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + ..CDAKKKACDAAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + ...CDDADDKAA.... + ..CDDAA.DDK..... + ................ +} +# tile 593 (horned devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + ...LOCDCOL...... + ...CDDDDDC...... + ...DAADAADA..D.. + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + ..CDAKKKACDAAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + ...CDDADDKAA.... + ..CDDAA.DDK..... + ................ +} +# tile 596 (erinys,male) { ..GA...GA....... ...FA.FA..GA.... @@ -5708,7 +11332,26 @@ Z = (195, 195, 195) ..BBEBEBEBA..... ................ } -# tile 299 (barbed devil) +# tile 597 (erinys,female) +{ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....... + .GAFDLDLA..A.A.. + ....LLLEA.A.A.A. + ...EBLLBEAAAA.A. + ..EBBBBBBBAAAA.. + ..BBBEBBLLBAA.A. + ..EBBLLBALBAAA.. + ...EBALBAABAA... + ...BEAABBBAAA... + ...BBBBBBBAAA... + ...BBBBBBBAA.... + ..BBEBEBEBA..... + ................ +} +# tile 598 (barbed devil,male) { ................ ................ @@ -5727,7 +11370,26 @@ Z = (195, 195, 195) .CCDDAA.DDKK.... ................ } -# tile 300 (marilith) +# tile 599 (barbed devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + .O.LOCDCOL.O.... + ...CDDDDDC....DD + ...DAADAADA..D.D + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + .C.DAKKKACDKAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + .K.CDDADDKAAK... + .CCDDAA.DDKK.... + ................ +} +# tile 600 (marilith,male) { .D..HHH.....D... DD.HHHHHA...DD.. @@ -5746,7 +11408,26 @@ Z = (195, 195, 195) ..FGFFFFFFFFFA.. ....GFFFFFFAA... } -# tile 301 (vrock) +# tile 601 (marilith,female) +{ + .D..HHH.....D... + DD.HHHHHA...DD.. + .DCHDDDHHAAD..A. + ..HDBDBDHDDAAAA. + .CHKDDDKHAAADD.. + CDDDKKKDHDDDDFF. + D..CDDCDKAAFFFAA + D.KDDKDDDDDDFAA. + D.DKDDKDKAFDFAA. + ..D.GDDFAAFDFFAA + .D.GGFFFAAAFFFFA + ...GFFFFFAAAFFFA + ..FGFFFFFFAFFFFA + ..FGFFFFFFFFFFA. + ..FGFFFFFFFFFA.. + ....GFFFFFFAA... +} +# tile 602 (vrock,male) { ................ ......OPP.O..... @@ -5765,7 +11446,26 @@ Z = (195, 195, 195) .....DDA.DDA.... ................ } -# tile 302 (hezrou) +# tile 603 (vrock,female) +{ + ................ + ......OPP.O..... + ......PPPP...... + .....CPPDP...... + ....CCCPPP...... + ....CCPPPP...... + ....C..PPA...... + .....DDAADD.AAA. + ....DDDDDDDDAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ......DAADAAAA.. + ......DAADAA.A.. + .....DDA.DDA.... + ................ +} +# tile 604 (hezrou,male) { ................ ................ @@ -5784,7 +11484,26 @@ Z = (195, 195, 195) ...........FFFA. ................ } -# tile 303 (bone devil) +# tile 605 (hezrou,female) +{ + ................ + ................ + ....GGGFF....... + ..NGFFNNFFF..... + .DFFFDDNFF.F.... + .GFFFDNFF.FFFAA. + .AFAFFFFFFFFFFAA + .GFFFF.FFF.FGFAA + .GAAAFF..LFGFFAA + ..FFFF.FFLFGFFFA + ..LLA.FLLLJJG.FA + .LLAFFLLFJJGFFFA + ..LAFLLLAAGF.FAA + .....L.LAGFFFFAA + ...........FFFA. + ................ +} +# tile 606 (bone devil,male) { ................ ................ @@ -5803,7 +11522,26 @@ Z = (195, 195, 195) ..NOOAA.OOL..... ................ } -# tile 304 (ice devil) +# tile 607 (bone devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..O.. + ...LNLOLOL....O. + ...LOOOOOL....O. + ...NAAOAAOA..O.. + ...NOOOOOOA.O... + ..NOOOFOOOOAO.A. + ..OOKNOOKOOALA.. + ..OOANOOAOOAKAA. + ..LLANOOALLAAAA. + ....NOOOLAAAAA.. + ...NOOAOOLAA.... + ..NOOAA.OOL..... + ................ +} +# tile 608 (ice devil,male) { ................ ................ @@ -5822,7 +11560,26 @@ Z = (195, 195, 195) ..BNNAA.NNP..... ................ } -# tile 305 (nalfeshnee) +# tile 609 (ice devil,female) +{ + ................ + ................ + ..N.......N..... + ..NN.....NN..... + ...PBPNPNP..BNB. + ...PNNNNNP..N.N. + ...BAANAANA...N. + ...BNNNNNNA.BNB. + ..BNNNFNNNNAN.A. + ..NNKBNNKNNABA.. + ..NNABNNANNA.AA. + ..PPABNNAPPAAAA. + ....BNNNPAAAAA.. + ...BNNANNPAA.... + ..BNNAA.NNP..... + ................ +} +# tile 610 (nalfeshnee,male) { ................ ................ @@ -5841,7 +11598,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 306 (pit fiend) +# tile 611 (nalfeshnee,female) +{ + ................ + ................ + ......BB...BB... + ..KKKKKBB.BB.... + .KADKADKKKB..... + .KKKKKKKDKK..... + .OKDKOKKDDKD.... + .OKDKOKKKDKDD... + .KAAAKKDKAKKD... + ..KKKDDLAKKKD.A. + ...KK.KKKKKDDA.. + ....L..KDAKDAA.. + ......LLAAKDA... + .........LLA.... + ................ + ................ +} +# tile 612 (pit fiend,male) { ................ .K.O.......O.K.. @@ -5860,7 +11636,26 @@ Z = (195, 195, 195) ...CDDAA.DDK.... ................ } -# tile 307 (sandestin) +# tile 613 (pit fiend,female) +{ + ................ + .K.O.......O.K.. + .K.OO.....OO.KJ. + KJJ.LOCDCOL.KJJ. + KJJJKDDDDDKKJJJ. + KJJCKDNDNDKCJJJA + JJCCKDDDDDJCCJJA + JJCCCKDIDJDCCJJA + JACCDDKJJDDCDAJA + JACCKDDDDDKCDAJA + ...CDKDDDKCDDAAA + ....DKDDDKCDAAAA + .....CDDDKAAAA.. + ....CDDADDKA.... + ...CDDAA.DDK.... + ................ +} +# tile 614 (sandestin,male) { .....CCCCC..I... .I..CD....C..... @@ -5879,7 +11674,26 @@ Z = (195, 195, 195) .CD.DDAADDDADC.. ................ } -# tile 308 (balrog) +# tile 615 (sandestin,female) +{ + .....CCCCC..I... + .I..CD....C..... + ...CD.DDD..C..I. + ..CD.DDDDD..C... + ..CD.DNDNDA.DC.. + I.CD.DDDDDA.DC.. + ..CD.ADDDA.DC..A + .CD.DDAAADD.DCAA + CD.DDDDDDDDDADCA + CD.DADDDDDADADCA + CD.DADDDDDADADCA + CD.DADDDDDADADC. + .CD..DDJDDAADCA. + ..CD.DDADDADCA.. + .CD.DDAADDDADC.. + ................ +} +# tile 616 (balrog,male) { ................ .K..O.....O..K.. @@ -5898,7 +11712,26 @@ Z = (195, 195, 195) ..CDDDAA.DDDK.AA ................ } -# tile 309 (Juiblex) +# tile 617 (balrog,female) +{ + ................ + .K..O.....O..K.. + .KJ.O.....O.KJ.. + KJJLOOCDCOOLJJJ. + JJJDDDDDDDDDDKJ. + JCCDDDNDNDDDCCJA + CCDKDDDDDDDJCCCA + CDDKKKDIDJJDCCDA + CDDKDDKJJDDDCDDA + CCDKDDDDDDDKCDDA + JCCDKKDDDKKCDDDA + JJCDKKDDDKKCDDJA + JJ..CCDDDKKAAJJA + J..CDDDADDDKAAJA + ..CDDDAA.DDDK.AA + ................ +} +# tile 618 (Juiblex,male) { ................ DD.........DD... @@ -5917,7 +11750,26 @@ Z = (195, 195, 195) .CCCCCCCCCCCKA.. ................ } -# tile 310 (Yeenoghu) +# tile 619 (Juiblex,female) +{ + ................ + DD.........DD... + NDC.KKKKJ.CND... + .CCKCCCKKCCAA... + ..KCCCCKCCJAA... + ..KCCCCCK.JJAA.. + ..KCCFCCK..JAA.. + ..FKCFCCKK.JAAA. + .FKKFCCKFK..JAA. + .FKCFCCFKFK.JAA. + .FCFCCKFCFK.JAA. + FKCFCFCFCKK.JAA. + CKFCCFCCKKFKJJA. + CCKKCFCKFFKKKKA. + .CCCCCCCCCCCKA.. + ................ +} +# tile 620 (Yeenoghu,male) { ....B.HHP....... ....BPPPP....... @@ -5936,7 +11788,26 @@ Z = (195, 195, 195) ...BPAA.PPA..... ................ } -# tile 311 (Orcus) +# tile 621 (Yeenoghu,female) +{ + ....B.HHP....... + ....BPPPP....... + ...BPLCPPH...... + .KBPPCCPPH...... + .PPPPPPP.H...... + .PP...P.PH...... + ....BPPPPPAAA... + ..BPPPPPPPPAAAA. + .BP.PPPPPAPPAAAA + .B...BPP.AAPAAAA + .B...BPP.AAPAAA. + .....BPPAAAAA.A. + ....BP.PPAA...A. + ...BP.AAPPA..A.. + ...BPAA.PPA..... + ................ +} +# tile 622 (Orcus,male) { ................ .K..O.....O..K.. @@ -5955,7 +11826,26 @@ Z = (195, 195, 195) ...OOPPAOOPPAGA. ................ } -# tile 312 (Geryon) +# tile 623 (Orcus,female) +{ + ................ + .K..O.....O..K.. + KJJO..BBB..O.KJ. + KJJLOBPPPPOLKJJ. + JKJJ.PGPGP.JJKJA + JJKJKPPPPPJJKJJJ + JBPPB.BPPABBPPJJ + PJJPP.BPPAPPJJPA + PJBPPP.AAPPPPJPA + .JBP.PPPP.P.PJAA + .JBPPPP.PPPPPJAA + ..PPP.PPP.PPPAAA + ...P.PPPPPPP.P.A + ...BPPPAPPPPAAPA + ...OOPPAOOPPAGA. + ................ +} +# tile 624 (Geryon,male) { .K...........K.. .K....JJJ....KJ. @@ -5974,7 +11864,26 @@ Z = (195, 195, 195) ....FGGGFFFFFFFA .....FFFFFFFFFA. } -# tile 313 (Dispater) +# tile 625 (Geryon,female) +{ + .K...........K.. + .K....JJJ....KJ. + KJJ..JJJJJ..KJJ. + KJJJKLLLLLKKJJJ. + KJJJKLBLBLKJJJJA + JJJJKLLLLLJJJJJA + JJALLKLLLJLLAJJA + JA.LLLKJJLLLAAJA + ...LJLLLLLKLAAAA + ...LCKLLLKCLAFGF + ...LLGLLFALLFFFA + .....GFFFAAAFFAA + ....GGGGFFAAFFAA + ....GFFFFFAAFGFA + ....FGGGFFFFFFFA + .....FFFFFFFFFA. +} +# tile 626 (Dispater,male) { ................ ......OJJO...... @@ -5993,7 +11902,26 @@ Z = (195, 195, 195) .....PPA.PPA.... ................ } -# tile 314 (Baalzebub) +# tile 627 (Dispater,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ....KACKKJAKAAA. + ....KACKKJAKAAJA + ....KACKKJAKAAJA + ....LACKKJJLAJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 628 (Baalzebub,male) { ......F...F..... .......F.F...... @@ -6012,7 +11940,26 @@ Z = (195, 195, 195) .....FFA..FF.... ................ } -# tile 315 (Asmodeus) +# tile 629 (Baalzebub,female) +{ + ......F...F..... + .......F.F...... + ......BFFFB..... + .....BPPFBPP.... + .....PPPFPPP.... + ......PPFPP..... + .....CAFFFAK.... + ....CKKAFAKKKAA. + ....CAKJFAKAKAA. + ....FACJDAJAFAA. + ....FACKJJJAFAA. + ....FACKKKJAFAA. + ......CKKKJAAA.. + ......CKAKJA.A.. + .....FFA..FF.... + ................ +} +# tile 630 (Asmodeus,male) { ................ ......OJJO...... @@ -6031,7 +11978,26 @@ Z = (195, 195, 195) .....PPA.PPA.... ................ } -# tile 316 (Demogorgon) +# tile 631 (Asmodeus,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKJAKKAJA + ...KA.CKKJAAKAJA + ...LA.CKKJJALJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 632 (Demogorgon,male) { ...KKK..KKK..... ..KBKBK.BKBK.... @@ -6050,7 +12016,26 @@ Z = (195, 195, 195) ..GAGFAFFFAFA... ................ } -# tile 317 (Death) +# tile 633 (Demogorgon,female) +{ + ...KKK..KKK..... + ..KBKBK.BKBK.... + ..KDKKK.KKDK.... + ..DKKFA.GKKD.... + ....GFAAGFAAA... + ...GFFFJFFFA.AAA + ..GFAGFFFAFFAAAA + .GJFAGJFJAFFFAA. + .GFAAGFFFAAFJA.. + .GJA.GFJFAAFFAA. + .GFA.GFFFA.FJAA. + .GJA.GJFJA.FFAA. + .GFAGFAAFFAFFA.. + ..GAGJAAJFAFAA.. + ..GAGFAFFFAFA... + ................ +} +# tile 634 (Death,male) { .BBBB....JJJ.... .BPPPP.JJJJ..... @@ -6069,7 +12054,26 @@ Z = (195, 195, 195) .CJJAAAAAAAAJJA. ACJAAAAAAAAAAAJ. } -# tile 318 (Pestilence) +# tile 635 (Death,female) +{ + .BBBB....JJJ.... + .BPPPP.JJJJ..... + .C....JJJJJ..... + .C....JAAAJ..... + .C...JADADAJ.AAA + OOJ..JAAAAAJAAA. + OOOJJJAAAAAJJJA. + OOJJJJAAAAJOOJJA + .CJJJJAAAJOOOOJA + .C.JJAAAAJAOAAJA + .C..JAAAAJAOAAJA + .C..JAAAAAJOAJAA + .C..JAAAAAJJJAAA + .C.JAAAAAAAJJAA. + .CJJAAAAAAAAJJA. + ACJAAAAAAAAAAAJ. +} +# tile 636 (Pestilence,male) { F........JJJ.... ..F....JJJJ..... @@ -6088,7 +12092,26 @@ Z = (195, 195, 195) ..JJFBFAFFAJJJA. .JJAAFAFAAAAAAJ. } -# tile 319 (Famine) +# tile 637 (Pestilence,female) +{ + F........JJJ.... + ..F....JJJJ..... + B...F.JJJJJ..... + ...B..JAAAJ..... + .F...JADADAJ.... + ...F.JAAAAAJ.AA. + .B..JFAAAAFJAA.. + ...FJJAFABJJAA.. + ..F.JFFBAJJJAAA. + ....FAFFJJJJAAA. + ....JABAJJJJAAA. + ...FJFFJJJJJJAA. + ...JJBFJJJJJJAA. + ...JAABFBJJJJAA. + ..JJFBFAFFAJJJA. + .JJAAFAFAAAAAAJ. +} +# tile 638 (Famine,male) { .........JJJ.... .......JJJ...... @@ -6107,7 +12130,26 @@ Z = (195, 195, 195) K...JJAAAJJAA... K..JJAAAAAJJJA.. } -# tile 320 (mail daemon) +# tile 639 (Famine,female) +{ + .........JJJ.... + .......JJJ...... + K.....JJJJJ..... + K.....JAAAJ..... + K....JADADAJ.... + K....JAAAAAJ...A + K.....JAAAJJ..AA + OOJJJJJJAAJAJ.AA + K...JJJAAJJAJAAA + K.....JAJJJOJAA. + K.....JAOOOAAA.. + K.....JAJJAAA... + K.....JAJJAA.... + K.....JAAJAA.... + K...JJAAAJJAA... + K..JJAAAAAJJJA.. +} +# tile 640 (mail daemon,male) { ...OP.BEEE.PO... ...OOEBEEEEOOD.. @@ -6126,7 +12168,26 @@ Z = (195, 195, 195) ..CDDDAAA.DDDK.. ................ } -# tile 321 (djinni) +# tile 641 (mail daemon,female) +{ + ...OP.BEEE.PO... + ...OOEBEEEEOOD.. + ..DLOBEEEEOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDK.KDAADJJECDD + CCDKEEKKKJEEKCDD + .CCDK.EEEE..CDDD + .CCDAE.EENNNCDD. + .DDDAEEEENDNDDD. + ....BBEEENNNNN.. + ...BEEEAANNNNNA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 642 (djinni,male) { .LL..NNN..LL.... ..L..NGNA.L..... @@ -6145,7 +12206,26 @@ Z = (195, 195, 195) .........IFED... ................ } -# tile 322 (jellyfish) +# tile 643 (djinni,female) +{ + .LL..NNN..LL.... + ..L..NGNA.L..... + ..LAALLLAALA.... + ..LAAKKKAALA.... + ...LCKKKCLA..... + ....LCKCLA...... + ....LICLIA..A... + ....IIIIEA.AA..A + ....EIEEIA.AAAAA + ....IEFEAAAAAAAA + .....DEAIAAAAA.. + .....IGIFAAAA... + .......FEDAAA... + .......I.GEA.A.. + .........IFED... + ................ +} +# tile 644 (jellyfish,male) { ................ .....PBPA....... @@ -6164,7 +12244,26 @@ Z = (195, 195, 195) ..PEE.P.E..E.... .P..E.P..E...... } -# tile 323 (piranha) +# tile 645 (jellyfish,female) +{ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAA... + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPPEPEEE.. + .PBBPPPEPEPPEE.. + .PEPBBEEPEEPEE.. + .PEEEPEEPEEPE... + ..PEEPE..PE.P... + ..P.EP.EEP..P... + ..PEE.P.E..E.... + .P..E.P..E...... +} +# tile 646 (piranha,male) { ................ ................ @@ -6183,7 +12282,26 @@ Z = (195, 195, 195) .....E..P....... ....E..E...E.... } -# tile 324 (shark) +# tile 647 (piranha,female) +{ + ................ + ................ + ................ + ................ + ................ + ....OPP......... + .....OPP........ + ..O..PPAP.....E. + ..POPPPPPA...EEE + ..PPPPP.PPA.E... + ...PP..PPPAAAEE. + ..E.PPPPPPPPPE.. + ..E...PPPPPAA.E. + .....E..PPAE.... + .....E..P....... + ....E..E...E.... +} +# tile 648 (shark,male) { ................ ................ @@ -6202,7 +12320,26 @@ Z = (195, 195, 195) PDNPPEE..EE..... .PPPE..EEE..E... } -# tile 325 (giant eel) +# tile 649 (shark,female) +{ + ................ + ................ + ................ + ...............P + ........P.....PP + ....E..PP....PP. + ...E...PPA..PPP. + ..EEEEPPPA.PPPPP + .E.EEPPP.PPPPPPE + ...EP.P.PPPPPEEE + ..PPPPPPPPPPEEE. + .APPPPPPPPEEEE.E + PPPPPPP..EE..... + NDPPAPEPPP.E..EE + PDNPPEE..EE..... + .PPPE..EEE..E... +} +# tile 650 (giant eel,male) { ................ ................ @@ -6221,7 +12358,26 @@ Z = (195, 195, 195) ...EE.AAAAE.E... ..E...EE.E...E.. } -# tile 326 (electric eel) +# tile 651 (giant eel,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA...AAA.. + ..AAAAAAA.AA.AA. + ..AAAA.AA.AA.AA. + ...AA..AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA.E.AA.E. + ...E.AAEE.AAAE.. + ...E.AAEEAAAEE.. + ..E..AAAAAAE.E.. + ...EE.AAAAE.E... + ..E...EE.E...E.. +} +# tile 652 (electric eel,male) { ................ ................ @@ -6240,7 +12396,26 @@ Z = (195, 195, 195) ...EE.AAADE.E... ..E...EE.E...E.. } -# tile 327 (kraken) +# tile 653 (electric eel,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA........ + ..AAAAAAA....... + ..AAAA.AA....... + ...AA..AA...DD.. + ......AAA..DD... + ......AA...DD... + .....AAA.E.DD.E. + ...E.AAEE.DD.E.. + ...E.AAEEDD.EE.. + ..E..AAADDDE.E.. + ...EE.AAADE.E... + ..E...EE.E...E.. +} +# tile 654 (kraken,male) { ................ ................ @@ -6259,7 +12434,26 @@ Z = (195, 195, 195) EEEEEEE..EE..... ..EEE..EEE..E... } -# tile 328 (newt) +# tile 655 (kraken,female) +{ + ................ + ................ + ..FF..FF........ + ..DDFDDF........ + ..FFFFF.....GG.. + ..NCNFF......GFA + ..CC.FF.....EGFA + ....GFAA.GFAEGFE + ...GFFAGFFFFAGFE + ...GFAAFFAGFAEEE + ..GFFAGFFAGFEEE. + EEGFFAGFFAEEEE.E + .EGFFAGFFEE..... + EEGFFEEEEE.E..EE + EEEEEEE..EE..... + ..EEE..EEE..E... +} +# tile 656 (newt,male) { ................ ................ @@ -6278,7 +12472,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 329 (gecko) +# tile 657 (newt,female) +{ + ................ + ................ + ................ + ................ + ................ + ......JKKJ...... + .....CLCCLLC.... + ....LAAAACCLCA.. + .......LCCLLLCA. + ....LCCCLLLAALA. + ....CALLLLAAAA.. + ...LLLLCLAAA.... + ...LLAAALLA..... + ................ + ................ + ................ +} +# tile 658 (gecko,male) { ................ ................ @@ -6297,7 +12510,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 330 (iguana) +# tile 659 (gecko,female) +{ + ................ + ................ + ...........LLP.. + ..........LLOOA. + ......PO.LLOOOA. + ......OOALOOOA.. + .......LLOOOA... + ...POALOOOAA.... + ...OOLOOOOOOA... + ....ALOOOAOPA... + ...DOOOOA.AA.... + ...OOOAOOA...... + ...OODAOPA...... + ..F.AA.AA....... + ................ + ................ +} +# tile 660 (iguana,male) { ................ ................ @@ -6316,7 +12548,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 331 (baby crocodile) +# tile 661 (iguana,female) +{ + ................ + ................ + ................ + ................ + ................ + ....GPGPGGPF.... + ..GPAAAAFFGPF... + .GPAA.PFFGPPPAA. + ......FGGPPFPPAA + .PFGGGGPPPFAAPPA + .FGPAPPPPFAAAAA. + .GPPPPFPFAAA.A.. + .PPFFAFPPAA..... + D.AAAAAAPPA..... + ................ + ................ +} +# tile 662 (baby crocodile,male) { ................ ................ @@ -6335,7 +12586,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 332 (lizard) +# tile 663 (baby crocodile,female) +{ + ................ + ................ + ................ + ................ + ................ + .....FFOFOFA.... + ....FOGFGGOFF... + ....GAAAAFOGFA.. + ...FAA.GFOGGGFA. + ...GFOOOGGGFAGA. + ...FGAGGGGFAAA.. + ..FGGGGFGFAA.... + ..GGDFAFGGA..... + ...D............ + ................ + ................ +} +# tile 664 (lizard,male) { ................ ................ @@ -6354,7 +12624,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 333 (chameleon) +# tile 665 (lizard,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ....FFFFGFJ..... + ..FFAAAJJGFJ.... + ......JGFFJFAA.. + ...JGGGFFJAAFA.. + ..JFAFFFJAAAA... + ..FFFFJJAAA..... + .JFAAAAFAA...... + .D.............. + ................ + ................ +} +# tile 666 (chameleon,male) { ................ ................ @@ -6373,7 +12662,26 @@ Z = (195, 195, 195) .DD............. ................ } -# tile 334 (crocodile) +# tile 667 (chameleon,female) +{ + ................ + ................ + ................ + .....GGGG....... + ...GGGGGGGG..... + ...GGFFFFGGFA... + ..GPAAAGFFGGFA.. + .GPAA.PFFGGGGAA. + ...GGGGGGGGFGGAA + .PGGBBGGGGFAAGGA + .FGGABGGGFAAAAA. + .GGGGGFGFAAA.A.. + .DGFFAFGGAA..... + D.AAAAAAGGA..... + .DD............. + ................ +} +# tile 668 (crocodile,male) { ................ ................ @@ -6392,7 +12700,26 @@ Z = (195, 195, 195) .DF............. ................ } -# tile 335 (salamander) +# tile 669 (crocodile,female) +{ + ................ + ................ + ................ + ................ + ....FFOFOOFA.... + ...FOGFGFGOFFA.. + ..FGAAAAFFOGFFA. + .FFAA.GFFOGGGGFA + ......FOOGGGGGGA + .G.OOOOGGGGFAGGA + .FOGAGGGGGFAAAA. + FGGGGGFGGFAA.... + GGDDFAFGGGA..... + GDDFAAAAGGA..... + .DF............. + ................ +} +# tile 670 (salamander,male) { ................ ................ @@ -6411,7 +12738,26 @@ Z = (195, 195, 195) ..ACCA.......... ...AAA.......... } -# tile 336 (long worm tail) +# tile 671 (salamander,female) +{ + ................ + ................ + ................ + ......CCC....... + ....CCCCCCC..... + ...CCDDDDCCDA... + ....AAAADDCCDA.. + ......KDDCCCCAA. + ..LLLCCCCCCDCCAA + .KLCCCLLLCDAACCA + .DCEECLKKDAAAAA. + DCCAECDKDAAA.A.. + CCCCCCDCCAA..... + .DAADAAACCA..... + ..ACCA.......... + ...AAA.......... +} +# tile 672 (long worm tail,male) { ........ILLLL... ......IILLAA.... @@ -6430,7 +12776,26 @@ Z = (195, 195, 195) .LLLIIIILLLA.... ...LLLLLAAA..... } -# tile 337 (archeologist) +# tile 673 (long worm tail,female) +{ + ........ILLLL... + ......IILLAA.... + .....ILLAA...... + .....ILA........ + .....ILA........ + ......LLA...II.. + .......LLIIILLLL + ........ILLAAA.L + ...IIIILLALL.... + .ILLLLLAA..LL... + ILLAAAA.....LA.. + ILA.........LA.. + LLA........LLA.. + LILA......LLA... + .LLLIIIILLLA.... + ...LLLLLAAA..... +} +# tile 674 (archeologist,male) { ................ ................ @@ -6449,7 +12814,26 @@ Z = (195, 195, 195) .....CJJ.JKJ.... ................ } -# tile 338 (barbarian) +# tile 675 (archeologist,female) +{ + ................ + ................ + ......KJ.J...... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + ......CJJKAAAA.. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 676 (barbarian,male) { ................ ................ @@ -6468,7 +12852,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 339 (caveman) +# tile 677 (barbarian,female) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + ......ALLA...... + .....LLAALL.AAA. + ....LLLLLLLLAAA. + ....LALLLLALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 678 (cave dweller,male) { ................ ................ @@ -6487,7 +12890,7 @@ Z = (195, 195, 195) ................ ................ } -# tile 340 (cavewoman) +# tile 679 (cave dweller,female) { ................ ................ @@ -6506,7 +12909,7 @@ Z = (195, 195, 195) ................ ................ } -# tile 341 (healer) +# tile 680 (healer,male) { ................ .......NN....... @@ -6525,7 +12928,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 342 (knight) +# tile 681 (healer,female) +{ + ................ + .......NN....... + ......NDDO...... + ......NNNN...... + ......ELEP...... + ......LLLP...... + .......LLP...... + ......O..PA.AAA. + .....NNOOPPAAAA. + ....OOONOPPPAA.. + ....LANOOPALAA.. + ......NOOPAAAA.. + .....NOOOPAA.A.. + ....NOOOOOPA.... + ................ + ................ +} +# tile 682 (knight,male) { ................ ................ @@ -6544,7 +12966,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 343 (monk) +# tile 683 (knight,female) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + ......ALLAA..... + .....BBAABB.AAA. + ....BPPPPPPPAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... + ................ + ................ +} +# tile 684 (monk,male) { ................ ................ @@ -6563,7 +13004,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 344 (priest) +# tile 685 (monk,female) +{ + ................ + ................ + .......CCC...... + ......JCJJJA.... + ......CAAAJA.... + ......CAAAJA.... + ......CKLKCAAAA. + .....CDDDDDDAAAA + ....CDDLALDDDAAA + ....DALLALLADAA. + ....DDDDCDDDDAA. + .....AACCCDAAAA. + .....CDCCCDDA.A. + ....CCCCCCCDD... + ................ + ................ +} +# tile 686 (cleric,male) { ................ ................ @@ -6573,16 +13033,16 @@ Z = (195, 195, 195) ......ALLJA..... ......IJJIAAAA.. .....ODDDDDAAAA. - ....IDNDDDDDAAA. - ...NLNNNDDALAA.. - ......NDDDAAAA.. + ....INNDDDDDAAA. + ...NLNNDDDALAA.. + ......DDDDAAAA.. ......DIIDAAAA.. .....DDIIDDA.A.. ....DIIIIIDD.... ................ ................ } -# tile 345 (priestess) +# tile 687 (cleric,female) { ................ .......JJ....... @@ -6592,16 +13052,16 @@ Z = (195, 195, 195) .....JJLLJJ..... .....JEJJEJAAA.. .....ODEEDDAAAA. - ....IDINDDDDAAA. - ....L.NNNDALAA.. - ......INDDAAAA.. - ......INDDAAAA.. + ....IDINNDDDAAA. + ....L.DNNDALAA.. + ......IDDDAAAA.. + ......IDDDAAAA.. .....DDIIDDA.A.. ....DIIIIIDD.... ................ ................ } -# tile 346 (ranger) +# tile 688 (ranger,male) { ................ ................ @@ -6620,7 +13080,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 347 (rogue) +# tile 689 (ranger,female) +{ + ................ + ................ + ........CJA..... + .......CJJJA.... + .......JEEJA.... + .......JLLJA.... + .......ALLAA.... + ......GGAAGG.AAA + .....BPFFFFPPAAA + .....PAGFFFAPAAA + .....LA.FF.ALAAA + .......BP.PAAAA. + .......BPAPAA.A. + ......PPA.PPA... + ................ + ................ +} +# tile 690 (rogue,male) { ................ ................ @@ -6639,7 +13118,26 @@ Z = (195, 195, 195) .....KKA.KKA.... ................ } -# tile 348 (samurai) +# tile 691 (rogue,female) +{ + ................ + ................ + ................ + .....OA...OA.... + .....OOIDPPA.... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + ......BAABAA..A. + .....KEBBEJAAAA. + ....KAAEEAAKAA.. + ....LAJJHJALAA.. + ......KKJKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 692 (samurai,male) { ................ ................ @@ -6658,7 +13156,26 @@ Z = (195, 195, 195) .....IIA.IIA.... ................ } -# tile 349 (tourist) +# tile 693 (samurai,female) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LABBBBALAAA. + ....LABBBBALAAA. + ......IDDDAAAA.. + ......IDADAA.A.. + .....IIA.IIA.... + ................ +} +# tile 694 (tourist,male) { ................ ................ @@ -6677,7 +13194,45 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 350 (valkyrie) +# tile 695 (tourist,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ...JJJJJJJJJJ... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HGAAGH.AAA. + ....LLGHHGLLAAA. + ....LAHGHGALAAA. + ....LAHHGHALAAA. + ......JJJKAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 696 (valkyrie,male) +{ + D..............D + .D............D. + ..D...LHHL...D.. + ...D.HHHHHL.D... + ....DHELELHD.... + ....HDLLLLD..... + ...HHHDLLD...... + ...HJKJDDKJJAAA. + ..HHLJJDDJJLAAA. + ..H.LADKDCALAAA. + ....LDAKKDALAAA. + ....D.KKJKDAAA.. + ...D..KJAJAD.A.. + ..D..KLA.LKAD... + .D...........D.. + D.............D. +} +# tile 697 (valkyrie,female) { ................ ................ @@ -6696,7 +13251,7 @@ Z = (195, 195, 195) ................ ................ } -# tile 351 (wizard) +# tile 698 (wizard,male) { ................ .........BP..... @@ -6715,7 +13270,26 @@ Z = (195, 195, 195) ....BPPPPPPE.... ................ } -# tile 352 (Lord Carnarvon) +# tile 699 (wizard,female) +{ + ................ + .........BP..... + .......BBPE..... + ......BPPEA..... + ......BAAEA..... + ......BAAEA..... + ......PLLE...... + ......PAAEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 700 (Lord Carnarvon,male) { .......JJ....... ......KJJJ...... @@ -6734,7 +13308,26 @@ Z = (195, 195, 195) .....PPA.PPA.... ................ } -# tile 353 (Pelias) +# tile 701 (Lord Carnarvon,female) +{ + .......JJ....... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CIAAIK.AAA. + ....CKKIIKKKAAA. + ...KKCKKHKJKKAA. + ...KKAKHKJAKKAA. + ...KAIHKKJIAKA.. + ...LAICKKJIALA.. + .....ICKAJIAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 702 (Pelias,male) { ................ .......JJ....... @@ -6753,7 +13346,26 @@ Z = (195, 195, 195) .....PPA.PPA.... ................ } -# tile 354 (Shaman Karnov) +# tile 703 (Pelias,female) +{ + ................ + .......JJ....... + ......KKKJ...... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKKAKKAA. + ...KA.CKKJAAKA.. + ...LA.CKAJAALA.. + ......CKAJAAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 704 (Shaman Karnov,male) { ................ .......JJA...... @@ -6772,7 +13384,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 355 (Earendil) +# tile 705 (Shaman Karnov,female) +{ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LHAJJAHLAA.. + ...LLLHAAHLLLAA. + ...LLLLHHLLLLAA. + ...LLALHHLALLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ +} +# tile 706 (Earendil,male) { .........G...... ....B..GGF..B... @@ -6791,7 +13422,26 @@ Z = (195, 195, 195) .....AAAAAA..... ................ } -# tile 356 (Elwing) +# tile 707 (Earendil,female) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBPLELEABPB.. + ..BBBPLLLLABBB.. + ..PBPPALLAPPP... + ...PPBGAAGBBB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 708 (Elwing,male) { .........G...... ....B..GGF..B... @@ -6810,7 +13460,26 @@ Z = (195, 195, 195) .....AAAAAA..... ................ } -# tile 357 (Hippocrates) +# tile 709 (Elwing,female) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBHLELEHBPB.. + ..BBBHLLLLHBBB.. + ..PBHHALLAHHP... + ...PHHGAAGHHB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 710 (Hippocrates,male) { ................ ....LLLCCD...... @@ -6829,7 +13498,26 @@ Z = (195, 195, 195) .LCCCCCCCDA..... ................ } -# tile 358 (King Arthur) +# tile 711 (Hippocrates,female) +{ + ................ + ....LLLCCD...... + ...LLCCDDA...... + ...LAAAADA...... + ...LBABADA...... + ...LAAAADA...... + ...CCLLDD.B..... + ....CKKDDFBFAAA. + ..LLLCLDDDBFAAA. + .CCCCLDDDFBAAA.. + .LALLCCDDFBDAA.. + ...LCCCCDABFAA.. + ...LCCCCDABAAA.. + ..LLCCCCDAA.AA.. + .LCCCCCCCDA..... + ................ +} +# tile 712 (King Arthur,male) { ................ ................ @@ -6848,7 +13536,26 @@ Z = (195, 195, 195) ....PPAA.PPA.... ................ } -# tile 359 (Grand Master) +# tile 713 (King Arthur,female) +{ + ................ + ................ + ......OHHA...... + .....OHHHHA..... + .....HBLBHA..... + .....HLLLHA..... + .....ALLLAA..... + ....BBAAABB.AAA. + ...BPPPPPPPPAAA. + ...PABPPPPACPAA. + ..NNNNNNNNNCLCA. + .....BPP.PACAA.. + .....BPAPPAA.A.. + .....BPAPPAA.A.. + ....PPAA.PPA.... + ................ +} +# tile 714 (Grand Master,male) { ................ .......LL....... @@ -6867,7 +13574,26 @@ Z = (195, 195, 195) ..JACCCCCCCCAA.. ................ } -# tile 360 (Arch Priest) +# tile 715 (Grand Master,female) +{ + ................ + .......LL....... + ......LLLL...... + ......LLLL...... + ..LC.CALLAC..... + .CLLC.CAACCCC... + .CJLACCCCCCCCC.. + ..JAACCCCCCCCCC. + ..JCCCCCCCCCCC.A + ..J..PPPPPLCCAAA + ..J..CCCCLLCAAAA + ..J..CCCCCCCAAAA + ..J..CCCCCCCAAAA + ..J.ACCCCCCCAAA. + ..JACCCCCCCCAA.. + ................ +} +# tile 716 (Arch Priest,male) { ..N............. .NNN..JLLJ...... @@ -6886,7 +13612,26 @@ Z = (195, 195, 195) ..HACCCJJCCCAA.. ................ } -# tile 361 (Orion) +# tile 717 (Arch Priest,female) +{ + ..N............. + .NNN..JLLJ...... + ..N...JLLJ...... + ..N...LLLL...... + ..LC.CALLAC..... + .CLLC.CAACJDK... + .CHLACCCCJCCDK.. + ..HAACCJJCCCCDK. + ..HCCCCJCCJCCC.A + ..H..DCJCCLJCAAA + ..H..DCJCLLCAAAA + ..H..KCJCCDJAAAA + ..H..KCJCCDJAAAA + ..H.ACCJCCDJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 718 (Orion,male) { ................ ................ @@ -6905,7 +13650,26 @@ Z = (195, 195, 195) ......BPAPAA.A.. .....PPA.PPA.... } -# tile 362 (Master of Thieves) +# tile 719 (Orion,female) +{ + ................ + ................ + .......CJA...... + ......CJJJA..... + ......JEEJA..... + ......JLLJA..... + ......ALLAA..... + .....GGAAGG..... + ....BGFFFFFP.... + ....BPFFFFPPAAA. + ....PAGFFFAPAAA. + ....LANNNNALAAA. + ......BP.PAAAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... +} +# tile 720 (Master of Thieves,male) { ................ ...H.....H...... @@ -6924,7 +13688,26 @@ Z = (195, 195, 195) ...JJA..JJA..... ................ } -# tile 363 (Lord Sato) +# tile 721 (Master of Thieves,female) +{ + ................ + ...H.....H...... + ...HHIDKHH...... + ....IDDDD....... + ....LLLLLA...... + ....LBLBLA...... + ....LLLLLA...... + .....LLLA....... + ....B.AABAA..... + ...KEBBBEJAAA... + ..KAEEEEEAJAAA.. + ..LAJJHHJALAAA.. + ....JKKKJAAAAA.. + ....KJAJKAAAA... + ...JJA..JJA..... + ................ +} +# tile 722 (Lord Sato,male) { .....AAA........ .....AAA........ @@ -6943,7 +13726,26 @@ Z = (195, 195, 195) ..IIIA.IIIAA.... ................ } -# tile 364 (Twoflower) +# tile 723 (Lord Sato,female) +{ + .....AAA........ + .....AAA........ + ...AAAAAAA...... + ..AALLLLLAA..... + ..ALFFLFFLA..... + ..ALLLLLLLA..... + ...AALLLA....... + IIIIIAAAIIIIAAA. + LLDIIIIIIDLLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + ...IIDDDDAAAAAA. + ...IIAAIDAAA..A. + ..IIIA.IIIAA.... + ................ +} +# tile 724 (Twoflower,male) { ................ ................ @@ -6962,7 +13764,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 365 (Norn) +# tile 725 (Twoflower,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + .....NNLNNA..... + ....NALNALNA.... + .....NNANNAA.... + .....AAAAAA.AAA. + ....LLHGHGLLAAA. + ....LAGGGGALAAA. + ....LAHGHGALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 726 (Norn,male) { ................ ................ @@ -6981,7 +13802,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 366 (Neferet the Green) +# tile 727 (Norn,female) +{ + ................ + ................ + ......NNN....... + .....NNNNN...... + .....NELELN..... + ....NNLLLLN..... + ...NNNALLA...... + ...NJKJAAKJJAAA. + ..NNLJJKKJJLAAA. + ..N.LACKJCALAAA. + ....LAKKKKALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 728 (Neferet the Green,male) { ................ ................ @@ -7000,7 +13840,26 @@ Z = (195, 195, 195) ...BPPPPPPPE.... ................ } -# tile 367 (Minion of Huhetotl) +# tile 729 (Neferet the Green,female) +{ + ................ + ................ + ......GGG....... + .....GFFFG...... + ....GFEFEG...... + ....GFFFFEG..... + .N.GPEFFFEE..... + .I..BBEAAEA.AA.. + .I.BBPPBBEEAAAA. + .IGBPPPPPEEEAA.. + .I.PP.EPEAAGAA.. + .I...BPPPAAAAA.. + .N...BPPPEAA.A.. + ....BPPPPPEA.... + ...BPPPPPPPE.... + ................ +} +# tile 730 (Minion of Huhetotl,male) { ...OP......PO... ...OODDDDDDOOD.. @@ -7019,7 +13878,26 @@ Z = (195, 195, 195) ..CDDDAAA.DDDK.. ................ } -# tile 368 (Thoth Amon) +# tile 731 (Minion of Huhetotl,female) +{ + ...OP......PO... + ...OODDDDDDOOD.. + ..DLOOCDDCOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDKKKDAADJJDCDD + CCDKDDKKKJDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 732 (Thoth Amon,male) { ................ ......OJJO...... @@ -7038,7 +13916,26 @@ Z = (195, 195, 195) .....PPA.PPA.... ................ } -# tile 369 (Chromatic Dragon) +# tile 733 (Thoth Amon,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....BPAAPP.AAA. + ....BPPPPPPPAAA. + ...PPBPPPPJPPAA. + ...PPAPPP.APPA.A + ...PA.BPP.AAPA.A + ...LA.BPP..AL.A. + ......BPA.A..A.. + ......BPAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 734 (Chromatic Dragon,male) { ......GGGFA..... .....NFNFEEA.... @@ -7057,7 +13954,26 @@ Z = (195, 195, 195) ....GFAA...CCJA. ........FFFFJA.. } -# tile 370 (Goblin King) +# tile 735 (Chromatic Dragon,female) +{ + ......GGGFA..... + .....NFNFEEA.... + ....GFFFEECA.... + ..DCHHF..CCA.... + CHCHCD..BCCA.... + HD.D...BFFA..... + ......OBFAAAAAA. + ....HOGFAAAAAAAA + ..HOOIEA.EF.AAA. + .HOOOIEEEEFFJAA. + .HOOOIEEFFFDDAA. + HBOOIIEFFFDDCCA. + HB.OIEFOODD.CJA. + HBAAGE.AADDACCA. + ....GFAA...CCJA. + ........FFFFJA.. +} +# tile 736 (Goblin King,male) { ................ ................ @@ -7076,7 +13992,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 371 (Cyclops) +# tile 737 (Goblin King,female) +{ + ................ + ................ + .H..H...H....... + CLC.HCHCH....... + CLC.HHHHH....... + .H..IIIII....... + .HK.IHIHI.I..... + .HICKIIIJKK..... + .H.IIJJJK.AA.... + .H..JICJJAAAAA.. + .H..IIIIJAAAAA.. + ....JIIJJAA..... + ....IJKJJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 738 (Cyclops,male) { ................ ....LLLLL....... @@ -7095,7 +14030,26 @@ Z = (195, 195, 195) ....CJJJCLAAAAAA ..LLLLL.LLLLLAA. } -# tile 372 (Ixoth) +# tile 739 (Cyclops,female) +{ + ................ + ....LLLLL....... + ...CLLLLLC...... + ...LBABNNL...... + ...LBBBNNLJA.... + ...CLNNNLCJA.... + ....LLLLLJAAA... + ....LAALLAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.GGGHGGACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 740 (Ixoth,male) { ....O......O.... ....O......O.... @@ -7114,7 +14068,26 @@ Z = (195, 195, 195) ..CDDDAAA.DDDK.. ................ } -# tile 373 (Master Kaen) +# tile 741 (Ixoth,female) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDGDDGDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 742 (Master Kaen,male) { ................ .......KKA...... @@ -7133,7 +14106,26 @@ Z = (195, 195, 195) ...KJJJJJJJJJA.. ................ } -# tile 374 (Nalzok) +# tile 743 (Master Kaen,female) +{ + ................ + .......KKA...... + ......KJJKA..... + ..KKA.KAAKA.KKA. + .KAAKAKDDKAKAAKA + .KOOJKKOOKKKOOJA + .KJJJJJJJJJKJJJA + ..KJJJJJJJJJJJA. + ....KJJJJJJJA... + ......KJJJAAAAAA + .....KJJJJKAAAAA + .....KJJJJJAAAAA + ....KJJJJJJKAAA. + ...KJJJJJJJJKAA. + ...KJJJJJJJJJA.. + ................ +} +# tile 744 (Nalzok,male) { ....O......O.... ....O......O.... @@ -7152,7 +14144,26 @@ Z = (195, 195, 195) ..CDDDAAA.DDDK.. ................ } -# tile 375 (Scorpius) +# tile 745 (Nalzok,female) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDBDDBDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 746 (Scorpius,male) { .....JLJLJAA.... ....JA.JCJCKAA.. @@ -7171,7 +14182,26 @@ Z = (195, 195, 195) ...D...JAAJA.JJ. ........JA.JA... } -# tile 376 (Master Assassin) +# tile 747 (Scorpius,female) +{ + .....JLJLJAA.... + ....JA.JCJCKAA.. + ....AJ.....JJJA. + ....LA......LCKA + .JAKJA......JJJA + ..JJA......ALCJA + .......ALLAJCJKA + ....JJALCCAAJJA. + .JJALLAJCJJJAA.. + JA.LCCAJAJJAAAA. + ..JACJJJAAACCJAA + GGJJJJJAACCAAAJA + .JJGGAJACAAJJAAA + D.JJAAJAACA.JAA. + ...D...JAAJA.JJ. + ........JA.JA... +} +# tile 748 (Master Assassin,male) { ................ ................ @@ -7190,7 +14220,26 @@ Z = (195, 195, 195) .....AAA.AAA.... ................ } -# tile 377 (Ashikaga Takauji) +# tile 749 (Master Assassin,female) +{ + ................ + ................ + ................ + .......AA....... + ......AAAA...... + .....ABLBLA..... + .....AAAAAA..... + ......AAAA...... + .....AAAAAA..PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 750 (Ashikaga Takauji,male) { ................ ................ @@ -7209,7 +14258,26 @@ Z = (195, 195, 195) .....IIA.IIA.... ................ } -# tile 378 (Lord Surtur) +# tile 751 (Ashikaga Takauji,female) +{ + ................ + ................ + ......AA........ + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LAIIIIALAAA. + ....LALHHLALAAA. + ......IIIIAAAA.. + ......IIAIAA.A.. + .....IIA.IIA.... + ................ +} +# tile 752 (Lord Surtur,male) { ....PPDDDDAA.... ....PDDDDDDDA... @@ -7228,7 +14296,26 @@ Z = (195, 195, 195) .....BPPABPPAAAA ...LLLLJ.BLLLKAA } -# tile 379 (Dark One) +# tile 753 (Lord Surtur,female) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLBAAAA. + ...PPDBBBBBBBAA. + ..BDDHDPBPPPPPA. + ..PPHDDPBPPPPPA. + ..LAHDHPBPPAALAA + JLAADDHBBBBAALAA + JJLJDHHPBPPPCLAA + ..LLJBPPABPPLLAA + .....BPPABPPAAAA + ...LLLLJ.BLLLKAA +} +# tile 754 (Dark One,male) { ................ ......AAA....... @@ -7247,7 +14334,26 @@ Z = (195, 195, 195) AAAAAAAAAAAAAAAA ................ } -# tile 380 (student) +# tile 755 (Dark One,female) +{ + ................ + ......AAA....... + .....AAAAA...... + .....ADADA...... + .....AAAAA...... + ....AAAAAAA..... + ....AAAAAAA..... + ...AAAAAAAAA.... + ...AAAAAAAAA.... + ..AAAAAAAAAAA... + ..AAAAAAAAAAA... + ...AAAAAAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAAA + ................ +} +# tile 756 (student,male) { ................ ................ @@ -7266,7 +14372,26 @@ Z = (195, 195, 195) .....CJJ.JKJ.... ................ } -# tile 381 (chieftain) +# tile 757 (student,female) +{ + ................ + ................ + .....GGFGG...... + .......G........ + ......NDND...... + ...DDDDDDDD..... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 758 (chieftain,male) { ................ ................ @@ -7285,7 +14410,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 382 (neanderthal) +# tile 759 (chieftain,female) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + .....HALLAH..... + ....LLHAAHLLAAA. + ....LLLIILLLAAA. + ....LALIILALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 760 (neanderthal,male) { ................ ................ @@ -7304,7 +14448,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 383 (High-elf) +# tile 761 (neanderthal,female) +{ + ................ + ................ + ................ + ......JJJJ...... + .....JJJJJJ..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....JJAJJAJJ.AA. + ...JLLJAAJLLJAA. + ...LLALJJLALLAA. + ....LALCCLALAAA. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 762 (High-elf,male) { .........G...... .......GGF...... @@ -7323,7 +14486,26 @@ Z = (195, 195, 195) ......GFAFAA.... .....KLA.LKA.... } -# tile 384 (attendant) +# tile 763 (High-elf,female) +{ + .........G...... + .......GGF...... + ......GGGGA..... + ......LILIA..... + ......LLLLA..... + ......ALLA...... + ......GAAG..AA.. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LA.GFAALAA.. + ....LA.GFAALAA.. + ....LAGGGFAL.A.. + ......GFAFAA.A.. + ......GFAFAA.... + ......GFAFAA.... + .....KLA.LKA.... +} +# tile 764 (attendant,male) { ................ ................ @@ -7342,7 +14524,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 385 (page) +# tile 765 (attendant,female) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......BLB....... + .....CLLLD...... + .....CCKKDA.AAA. + .....LLCLDDAAAA. + ....CCCLDDDDAA.. + ....LALCCDALAA.. + ......LCCDAAAA.. + .....LCCCDAA.A.. + ....LCCCCCDA.... + ................ + ................ +} +# tile 766 (page,male) { ................ ................ @@ -7361,7 +14562,26 @@ Z = (195, 195, 195) ................ ................ } -# tile 386 (abbot) +# tile 767 (page,female) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + .......LLAA..... + ......BAABA.AAA. + .....BPPPPPAAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 768 (abbot,male) { ................ ................ @@ -7380,7 +14600,26 @@ Z = (195, 195, 195) ....CDCCCDDA.A.. ...CCCCCCCDD.... } -# tile 387 (acolyte) +# tile 769 (abbot,female) +{ + ................ + ................ + ................ + ................ + ................ + ......KLK....... + ......LLL....... + ....CCLLLJJ..... + ....KCKLKKJAAA.. + ....CDDDDDDAAAA. + ...CDDLALDDDAAA. + ...DALLALLADAA.. + ...DDDDCDDDDAA.. + ....AACCCDAAAA.. + ....CDCCCDDA.A.. + ...CCCCCCCDD.... +} +# tile 770 (acolyte,male) { ................ ................ @@ -7399,7 +14638,26 @@ Z = (195, 195, 195) ....LCCCCCDD.... ................ } -# tile 388 (hunter) +# tile 771 (acolyte,female) +{ + ................ + ................ + ................ + ......JJJJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......CJJCAAAA.. + .....LDDDDDAAAA. + ....CDCCDDDDAAA. + ....L.LCCDALAA.. + ......LCCDAAAA.. + ......LCCDAAAA.. + .....LDCCDDA.A.. + ....LCCCCCDD.... + ................ +} +# tile 772 (hunter,male) { ................ ................ @@ -7418,7 +14676,26 @@ Z = (195, 195, 195) ....JPPA.PPA.... ................ } -# tile 389 (thug) +# tile 773 (hunter,female) +{ + ................ + ................ + ................ + ....J..CJA...... + ...J..CJJJA..... + ...J..JEEJA..... + ..J...JLLJA..... + ..J...ALLAA..... + ..J..GGAAGG.AAA. + ..LPBPFFFFPPAAA. + ..J..AGFFFAPAAA. + ..J....FF.ALAAA. + ...J..BP.PAAAA.. + ...J..BPAPAA.A.. + ....JPPA.PPA.... + ................ +} +# tile 774 (thug,male) { ................ ................ @@ -7437,7 +14714,26 @@ Z = (195, 195, 195) .....KKA.KKA.... ................ } -# tile 390 (ninja) +# tile 775 (thug,female) +{ + ................ + ................ + ................ + .......ID....... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + .....KKAAKKA..A. + ....KKJKKJJKAAA. + ....KAAJJAAKAA.. + ....LAJJJJALAA.. + ......KKJKAAAA.. + ......KAAKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 776 (ninja,male) { ................ ................ @@ -7456,7 +14752,26 @@ Z = (195, 195, 195) .....AAA.AAA.... ................ } -# tile 391 (roshi) +# tile 777 (ninja,female) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....AFLFLA..... + .....AAAAAA..... + ......AAAA...... + ....AAAAAAAA.PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 778 (roshi,male) { ................ ................ @@ -7475,7 +14790,26 @@ Z = (195, 195, 195) .....PPA.PPA.... ................ } -# tile 392 (guide) +# tile 779 (roshi,female) +{ + ................ + ................ + ................ + .......AAAAA.... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....PPPAAPPPAAA. + ....L.PPPP.LAAA. + ....LAOOOOALAAA. + ....LAOOOOALAAA. + ......P...AAAA.. + ......P.A.AA.A.. + .....PPA.PPA.... + ................ +} +# tile 780 (guide,male) { ................ ................ @@ -7494,7 +14828,26 @@ Z = (195, 195, 195) .....LLA.LLA.... ................ } -# tile 393 (warrior) +# tile 781 (guide,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HHAAHH.AAA. + ....LLHHHHLLAAA. + ....LAHHHHALAAA. + ....LAHHHHALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 782 (warrior,male) { .....O....O..... .....NO..ON..... @@ -7513,7 +14866,26 @@ Z = (195, 195, 195) .....KLA.LKA.... ................ } -# tile 394 (apprentice) +# tile 783 (warrior,female) +{ + .....O....O..... + .....NO..ON..... + ......NPPN...... + .....PPPPPP..... + .....PELELP..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ +} +# tile 784 (apprentice,male) { ................ ................ @@ -7532,7 +14904,26 @@ Z = (195, 195, 195) ....BPPPPPPE.... ................ } -# tile 395 (invisible monster) +# tile 785 (apprentice,female) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......GLG....... + .....BLLLE...... + .....BBEEEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 786 (invisible monster, nogender) { ................ ................ diff --git a/win/share/safeproc.c b/win/share/safeproc.c index 490a2c432..6811721e3 100644 --- a/win/share/safeproc.c +++ b/win/share/safeproc.c @@ -3,10 +3,7 @@ /* NetHack may be freely redistributed. See license for details. */ /* must #define SAFEPROCS in xxxconf.h or via CFLAGS or this won't compile */ -#include "config.h" -#include "color.h" -#include "wintype.h" -#include "winprocs.h" +#include "hack.h" /* * *********************************************************** @@ -324,11 +321,12 @@ int x, y; * Print the glyph to the output device. Don't flush the output device. */ void -safe_print_glyph(window, x, y, glyph, bkglyph) +safe_print_glyph(window, x, y, glyph, bkglyph, glyphmod) winid window; xchar x, y; int glyph; int bkglyph UNUSED; +int glyphmod[NUM_GLYPHMOD] UNUSED; { return; } diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 0adefc332..c7766a63b 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -18,10 +18,22 @@ #define Fprintf (void) fprintf -const char *FDECL(tilename, (int, int)); +/* + * Defining OBTAIN_TILEMAP to get a listing of the tile-mappings + * for debugging purposes requires that your link to produce + * the tilemap utility must also include: + * objects.o, monst.o drawing.o + */ +/* #define OBTAIN_TILEMAP */ + +#if defined(OBTAIN_TILEMAP) && !defined(TILETEXT) +FILE *tilemap_file; +#endif + +const char *FDECL(tilename, (int, int, int)); void NDECL(init_tilemap); void FDECL(process_substitutions, (FILE *)); -boolean FDECL(acceptable_tilename, (int, const char *, const char *)); +boolean FDECL(acceptable_tilename, (int, int, const char *, const char *)); #if defined(MICRO) || defined(WIN32) #undef exit @@ -34,17 +46,14 @@ extern void FDECL(exit, (int)); #define STATUES_LOOK_LIKE_MONSTERS #endif -#define MON_GLYPH 1 -#define OBJ_GLYPH 2 -#define OTH_GLYPH 3 /* fortunately unnecessary */ - +enum {MON_GLYPH, OBJ_GLYPH, OTH_GLYPH, TERMINATOR = -1}; #define EXTRA_SCROLL_DESCR_COUNT ((SCR_BLANK_PAPER - SCR_STINKING_CLOUD) - 1) /* note that the ifdefs here should be the opposite sense from monst.c/ * objects.c/rm.h */ -struct conditionals { +struct conditionals_t { int sequence, predecessor; const char *name; } conditionals[] = { @@ -56,7 +65,7 @@ struct conditionals { { MON_GLYPH, PM_BABY_SILVER_DRAGON, "baby shimmering dragon" }, { MON_GLYPH, PM_SILVER_DRAGON, "shimmering dragon" }, { MON_GLYPH, PM_JABBERWOCK, "vorpal jabberwock" }, - { MON_GLYPH, PM_VAMPIRE_LORD, "vampire mage" }, + { MON_GLYPH, PM_VAMPIRE_LEADER, "vampire mage" }, #ifndef CHARON /* not supported yet */ { MON_GLYPH, PM_CROESUS, "Charon" }, #endif @@ -79,7 +88,7 @@ struct conditionals { { OBJ_GLYPH, SCR_STINKING_CLOUD + EXTRA_SCROLL_DESCR_COUNT, "stamped / mail" }, #endif - { 0, 0, 0 } + { TERMINATOR, 0, 0 } }; /* @@ -103,42 +112,42 @@ struct substitute { { GLYPH_CMAP_OFF + S_vwall, GLYPH_CMAP_OFF + S_trwall, "sokoban walls", "In_sokoban(plev)" } }; -#ifdef TILETEXT - +#if defined(TILETEXT) || defined(OBTAIN_TILEMAP) /* - * entry is the position of the tile within the monsters/objects/other set + * file_entry is the position of the tile within the monsters/objects/other set */ const char * -tilename(set, entry) -int set, entry; +tilename(set, file_entry, gend) +int set, file_entry, gend; { - int i, j, condnum, tilenum; + int i, j, condnum, tilenum, gendnum; static char buf[BUFSZ]; (void) def_char_to_objclass(']'); - condnum = tilenum = 0; + condnum = tilenum = gendnum = 0; for (i = 0; i < NUMMONS; i++) { - if (set == MON_GLYPH && tilenum == entry) - return mons[i].mname; - tilenum++; - while (conditionals[condnum].sequence == MON_GLYPH - && conditionals[condnum].predecessor == i) { - if (set == MON_GLYPH && tilenum == entry) - return conditionals[condnum].name; - condnum++; - tilenum++; + if (set == MON_GLYPH && tilenum == file_entry && gend == 0) + return mons[i].pmnames[NEUTRAL]; + for (condnum = 0; conditionals[condnum].sequence != -1; ++condnum) { + if (conditionals[condnum].sequence == MON_GLYPH + && conditionals[condnum].predecessor == i) { + tilenum += 2; + if (set == MON_GLYPH && tilenum == file_entry) + return conditionals[condnum].name; + } } + tilenum += 2; } - if (set == MON_GLYPH && tilenum == entry) + if (set == MON_GLYPH && tilenum == file_entry) return "invisible monster"; tilenum = 0; /* set-relative number */ for (i = 0; i < NUM_OBJECTS; i++) { /* prefer to give the description - that's all the tile's * appearance should reveal */ - if (set == OBJ_GLYPH && tilenum == entry) { + if (set == OBJ_GLYPH && tilenum == file_entry) { if (!obj_descr[i].oc_descr) return obj_descr[i].oc_name; if (!obj_descr[i].oc_name) @@ -148,20 +157,20 @@ int set, entry; obj_descr[i].oc_name); return buf; } - - tilenum++; - while (conditionals[condnum].sequence == OBJ_GLYPH - && conditionals[condnum].predecessor == i) { - if (set == OBJ_GLYPH && tilenum == entry) - return conditionals[condnum].name; - condnum++; - tilenum++; + for (condnum = 0; conditionals[condnum].sequence != -1; ++condnum) { + if (conditionals[condnum].sequence == OBJ_GLYPH + && conditionals[condnum].predecessor == i) { + tilenum++; + if (set == OBJ_GLYPH && tilenum == file_entry) + return conditionals[condnum].name; + } } + tilenum++; } tilenum = 0; /* set-relative number */ for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) { - if (set == OTH_GLYPH && tilenum == entry) { + if (set == OTH_GLYPH && tilenum == file_entry) { if (*defsyms[i].explanation) { return defsyms[i].explanation; } else { @@ -169,18 +178,19 @@ int set, entry; return buf; } } - tilenum++; - while (conditionals[condnum].sequence == OTH_GLYPH - && conditionals[condnum].predecessor == i) { - if (set == OTH_GLYPH && tilenum == entry) - return conditionals[condnum].name; - condnum++; - tilenum++; + for (condnum = 0; conditionals[condnum].sequence != -1; ++condnum) { + if (conditionals[condnum].sequence == OTH_GLYPH + && conditionals[condnum].predecessor == i) { + tilenum++; + if (set == OTH_GLYPH && tilenum == file_entry) + return conditionals[condnum].name; + } } + tilenum++; } /* explosions */ tilenum = MAXPCHARS - MAXEXPCHARS; - i = entry - tilenum; + i = file_entry - tilenum; if (i < (MAXEXPCHARS * EXPL_MAX)) { if (set == OTH_GLYPH) { static const char *explosion_types[] = { @@ -195,7 +205,7 @@ int set, entry; } tilenum += (MAXEXPCHARS * EXPL_MAX); - i = entry - tilenum; + i = file_entry - tilenum; if (i < (NUM_ZAP << 2)) { if (set == OTH_GLYPH) { Sprintf(buf, "zap %d %d", i / 4, i % 4); @@ -204,7 +214,7 @@ int set, entry; } tilenum += (NUM_ZAP << 2); - i = entry - tilenum; + i = file_entry - tilenum; if (i < WARNCOUNT) { if (set == OTH_GLYPH) { Sprintf(buf, "warning %d", i); @@ -213,7 +223,7 @@ int set, entry; } tilenum += WARNCOUNT; - i = entry - tilenum; + i = file_entry - tilenum; if (i < 1) { if (set == OTH_GLYPH) { Sprintf(buf, "unexplored"); @@ -222,17 +232,17 @@ int set, entry; } tilenum += 1; - i = entry - tilenum; + i = file_entry - tilenum; if (i < 1) { if (set == OTH_GLYPH) { Sprintf(buf, "nothing"); return buf; } } - tilenum += 1; + tilenum++; for (i = 0; i < SIZE(substitutes); i++) { - j = entry - tilenum; + j = file_entry - tilenum; if (j <= substitutes[i].last_glyph - substitutes[i].first_glyph) { if (set == OTH_GLYPH) { Sprintf(buf, "sub %s %d", substitutes[i].sub_name, j); @@ -242,12 +252,12 @@ int set, entry; tilenum += substitutes[i].last_glyph - substitutes[i].first_glyph + 1; } - Sprintf(buf, "unknown %d %d", set, entry); + Sprintf(buf, "unknown %d %d", set, file_entry); return buf; } +#endif -#else /* TILETEXT */ - +#ifndef TILETEXT #define TILE_FILE "tile.c" #ifdef AMIGA @@ -260,7 +270,14 @@ int set, entry; #endif #endif -short tilemap[MAX_GLYPH]; +struct tilemap_t { + short tilenum; +#ifdef OBTAIN_TILEMAP + char name[80]; + int glyph; +#endif +} tilemap[MAX_GLYPH]; + #ifdef STATUES_LOOK_LIKE_MONSTERS int lastmontile, lastobjtile, lastothtile, laststatuetile; @@ -275,7 +292,8 @@ int lastmontile, lastobjtile, lastothtile; * set up array to map glyph numbers to tile numbers * * assumes tiles are numbered sequentially through monsters/objects/other, - * with entries for all supported compilation options + * with entries for all supported compilation options. monsters have two + * tiles for each (male + female). * * "other" contains cmap and zaps (the swallow sets are a repeated portion * of cmap), as well as the "flash" glyphs for the new warning system @@ -286,20 +304,21 @@ init_tilemap() { int i, j, condnum, tilenum; int corpsetile, swallowbase; + int file_entry = 0; for (i = 0; i < MAX_GLYPH; i++) { - tilemap[i] = -1; + tilemap[i].tilenum = -1; } - corpsetile = NUMMONS + NUM_INVIS_TILES + CORPSE; - swallowbase = NUMMONS + NUM_INVIS_TILES + NUM_OBJECTS + S_sw_tl; + corpsetile = NUMMONS + NUMMONS + NUM_INVIS_TILES + CORPSE; + swallowbase = NUMMONS + NUMMONS + NUM_INVIS_TILES + NUM_OBJECTS + S_sw_tl; /* add number compiled out */ - for (i = 0; conditionals[i].sequence; i++) { + for (i = 0; conditionals[i].sequence != TERMINATOR; i++) { switch (conditionals[i].sequence) { case MON_GLYPH: - corpsetile++; - swallowbase++; + corpsetile += 2; + swallowbase += 2; break; case OBJ_GLYPH: if (conditionals[i].predecessor < CORPSE) @@ -313,116 +332,238 @@ init_tilemap() } } - condnum = tilenum = 0; +#ifdef OBTAIN_TILEMAP + tilemap_file = fopen("tilemappings.lst", "w"); +#endif + tilenum = 0; for (i = 0; i < NUMMONS; i++) { - tilemap[GLYPH_MON_OFF + i] = tilenum; - tilemap[GLYPH_PET_OFF + i] = tilenum; - tilemap[GLYPH_DETECT_OFF + i] = tilenum; - tilemap[GLYPH_RIDDEN_OFF + i] = tilenum; - tilemap[GLYPH_BODY_OFF + i] = corpsetile; +#ifdef OBTAIN_TILEMAP + char buf[256]; +#endif + tilemap[GLYPH_MON_OFF + i].tilenum = tilenum; + tilemap[GLYPH_PET_OFF + i].tilenum = tilenum; + tilemap[GLYPH_DETECT_OFF + i].tilenum = tilenum; + tilemap[GLYPH_RIDDEN_OFF + i].tilenum = tilenum; + tilemap[GLYPH_BODY_OFF + i].tilenum = corpsetile; j = GLYPH_SWALLOW_OFF + 8 * i; - tilemap[j] = swallowbase; - tilemap[j + 1] = swallowbase + 1; - tilemap[j + 2] = swallowbase + 2; - tilemap[j + 3] = swallowbase + 3; - tilemap[j + 4] = swallowbase + 4; - tilemap[j + 5] = swallowbase + 5; - tilemap[j + 6] = swallowbase + 6; - tilemap[j + 7] = swallowbase + 7; - tilenum++; - while (conditionals[condnum].sequence == MON_GLYPH - && conditionals[condnum].predecessor == i) { - condnum++; - tilenum++; + tilemap[j].tilenum = swallowbase; + tilemap[j + 1].tilenum = swallowbase + 1; + tilemap[j + 2].tilenum = swallowbase + 2; + tilemap[j + 3].tilenum = swallowbase + 3; + tilemap[j + 4].tilenum = swallowbase + 4; + tilemap[j + 5].tilenum = swallowbase + 5; + tilemap[j + 6].tilenum = swallowbase + 6; + tilemap[j + 7].tilenum = swallowbase + 7; +#ifdef OBTAIN_TILEMAP + Sprintf(buf, "%s (%d)", tilename(MON_GLYPH, file_entry, 0), file_entry); + Sprintf(tilemap[GLYPH_MON_OFF + i].name, + "%s (%d)", buf, i); + Sprintf(tilemap[GLYPH_PET_OFF + i].name, + "%s %s (%d)", buf, "pet", i); + Sprintf(tilemap[GLYPH_DETECT_OFF + i].name, + "%s %s (%d)", buf, "detected", i); + Sprintf(tilemap[GLYPH_RIDDEN_OFF + i].name, + "%s %s (%d)", buf, "ridden", i); + Sprintf(tilemap[GLYPH_BODY_OFF + i].name, + "%s %s (%d)", buf, "corpse", i); + Sprintf(tilemap[j + 0].name, "%s swallow0 (%d)", buf, i); + Sprintf(tilemap[j + 1].name, "%s swallow1 (%d)", buf, i); + Sprintf(tilemap[j + 2].name, "%s swallow2 (%d)", buf, i); + Sprintf(tilemap[j + 3].name, "%s swallow3 (%d)", buf, i); + Sprintf(tilemap[j + 4].name, "%s swallow4 (%d)", buf, i); + Sprintf(tilemap[j + 5].name, "%s swallow5 (%d)", buf, i); + Sprintf(tilemap[j + 6].name, "%s swallow6 (%d)", buf, i); + Sprintf(tilemap[j + 7].name, "%s swallow7 (%d)", buf, i); +#endif + for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { + if (conditionals[condnum].sequence == MON_GLYPH + && conditionals[condnum].predecessor == i) { + tilenum += 2; + file_entry += 2; +#ifdef OBTAIN_TILEMAP + Fprintf(tilemap_file, "skipping monst %s (%d)\n", + tilename(MON_GLYPH, file_entry, 0), file_entry); +#endif + } } + tilenum += 2; /* male + female tiles for each */ + file_entry += 2; } - tilemap[GLYPH_INVISIBLE] = tilenum++; + tilemap[GLYPH_INVISIBLE].tilenum = tilenum++; + file_entry++; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_INVISIBLE].name, + "%s (%d)", "invisible mon", file_entry); +#endif lastmontile = tilenum - 1; + file_entry = 0; for (i = 0; i < NUM_OBJECTS; i++) { - tilemap[GLYPH_OBJ_OFF + i] = tilenum; - tilenum++; - while (conditionals[condnum].sequence == OBJ_GLYPH - && conditionals[condnum].predecessor == i) { - condnum++; - tilenum++; + tilemap[GLYPH_OBJ_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_OBJ_OFF + i].name, "%s (%d)", + tilename(OBJ_GLYPH, file_entry, 0), file_entry); +#endif + for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { + if (conditionals[condnum].sequence == OBJ_GLYPH + && conditionals[condnum].predecessor == i) { + tilenum++; + file_entry++; +#ifdef OBTAIN_TILEMAP + Fprintf(tilemap_file, "skipping obj %s (%d)\n", + tilename(OBJ_GLYPH, file_entry, 0), file_entry); +#endif + } } + tilenum++; + file_entry++; } lastobjtile = tilenum - 1; + file_entry = 0; for (i = 0; i < (MAXPCHARS - MAXEXPCHARS); i++) { - tilemap[GLYPH_CMAP_OFF + i] = tilenum; + tilemap[GLYPH_CMAP_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_CMAP_OFF + i].name, "cmap %s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif tilenum++; - while (conditionals[condnum].sequence == OTH_GLYPH - && conditionals[condnum].predecessor == i) { - condnum++; - tilenum++; + file_entry++; + for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { + if (conditionals[condnum].sequence == OTH_GLYPH + && conditionals[condnum].predecessor == i) { + tilenum++; + file_entry++; +#ifdef OBTAIN_TILEMAP + Fprintf(tilemap_file, "skipping cmap %s (%d)\n", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif + } } } for (i = 0; i < (MAXEXPCHARS * EXPL_MAX); i++) { - tilemap[GLYPH_EXPLODE_OFF + i] = tilenum; - tilenum++; - while (conditionals[condnum].sequence == OTH_GLYPH - && conditionals[condnum].predecessor == (i + MAXPCHARS)) { - condnum++; - tilenum++; + tilemap[GLYPH_EXPLODE_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_EXPLODE_OFF + i].name, "explosion %s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif + for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { + if (conditionals[condnum].sequence == OTH_GLYPH + && conditionals[condnum].predecessor == i + MAXPCHARS) { + tilenum++; + file_entry++; +#ifdef OBTAIN_TILEMAP + Fprintf(tilemap_file, "skipping explosion %s (%d)\n", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif + } } + tilenum++; + file_entry++; } for (i = 0; i < NUM_ZAP << 2; i++) { - tilemap[GLYPH_ZAP_OFF + i] = tilenum; + tilemap[GLYPH_ZAP_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_ZAP_OFF + i].name, "zap %s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif tilenum++; - while (conditionals[condnum].sequence == OTH_GLYPH + file_entry++; + for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { + if (conditionals[condnum].sequence == OTH_GLYPH && conditionals[condnum].predecessor == (i + MAXEXPCHARS)) { - condnum++; - tilenum++; +#ifdef OBTAIN_TILEMAP + Fprintf(tilemap_file, "skipping zap %s (%d)\n", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif + file_entry++; + tilenum++; + } } } for (i = 0; i < WARNCOUNT; i++) { - tilemap[GLYPH_WARNING_OFF + i] = tilenum; + tilemap[GLYPH_WARNING_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_WARNING_OFF + i].name, "%s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif tilenum++; + file_entry++; } for (i = 0; i < 1; i++) { - tilemap[GLYPH_UNEXPLORED_OFF + i] = tilenum; + tilemap[GLYPH_UNEXPLORED_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_UNEXPLORED_OFF + i].name, "unexplored %s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif tilenum++; + file_entry++; } for (i = 0; i < 1; i++) { - tilemap[GLYPH_NOTHING + i] = tilenum; + tilemap[GLYPH_NOTHING + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_NOTHING + i].name, " nothing %s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif tilenum++; + file_entry++; } #ifndef STATUES_LOOK_LIKE_MONSTERS /* statue patch: statues still use the same glyph as in vanilla */ for (i = 0; i < NUMMONS; i++) { - tilemap[GLYPH_STATUE_OFF + i] = tilemap[GLYPH_OBJ_OFF + STATUE]; + tilemap[GLYPH_STATUE_OFF + i].tilenum = tilemap[GLYPH_OBJ_OFF + STATUE]; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_STATUE_OFF + i].name, "%s (%d)", + tilename(OTH_GLYPH, file_entry, 0), file_entry); +#endif } #endif lastothtile = tilenum - 1; #ifdef STATUES_LOOK_LIKE_MONSTERS - /* skip over the substitutes to get to the grayscale statues */ + file_entry = 0; + /* fast-forward over the substitutes to grayscale statues loc */ for (i = 0; i < SIZE(substitutes); i++) { tilenum += substitutes[i].last_glyph - substitutes[i].first_glyph + 1; } /* statue patch: statues look more like the monster */ - condnum = 0; /* doing monsters again, so reset */ for (i = 0; i < NUMMONS; i++) { - tilemap[GLYPH_STATUE_OFF + i] = tilenum; - tilenum++; - while (conditionals[condnum].sequence == MON_GLYPH - && conditionals[condnum].predecessor == i) { - condnum++; - tilenum++; + tilemap[GLYPH_STATUE_OFF + i].tilenum = tilenum; +#ifdef OBTAIN_TILEMAP + Sprintf(tilemap[GLYPH_STATUE_OFF + i].name, "statue of %s (%d)", + tilename(MON_GLYPH, file_entry, 0), file_entry); +#endif + for (condnum = 0; conditionals[condnum].sequence != -1; condnum++) { + if (conditionals[condnum].sequence == MON_GLYPH + && conditionals[condnum].predecessor == i) { + file_entry += 2; /* skip female tile too */ + tilenum += 2; +#ifdef OBTAIN_TILEMAP + Fprintf(tilemap_file, "skipping statue of %s (%d)\n", + tilename(MON_GLYPH, file_entry, 0), file_entry); +#endif + } } + tilenum += 2; + file_entry += 2; } - laststatuetile = tilenum - 1; + laststatuetile = tilenum - 2; +#endif /* STATUES_LOOK_LIKE_MONSTERS */ +#ifdef OBTAIN_TILEMAP + for (i = 0; i < MAX_GLYPH; ++i) { + Fprintf(tilemap_file, "[%04d] [%04d] %-80s\n", + i, tilemap[i].tilenum, tilemap[i].name); + } + fclose(tilemap_file); #endif } @@ -451,8 +592,8 @@ FILE *ofp; Fprintf(ofp, "short std_tiles%d[] = { ", span); for (k = substitutes[i].first_glyph; k < substitutes[i].last_glyph; k++) - Fprintf(ofp, "%d, ", tilemap[k]); - Fprintf(ofp, "%d };\n", tilemap[substitutes[i].last_glyph]); + Fprintf(ofp, "%d, ", tilemap[k].tilenum); + Fprintf(ofp, "%d };\n", tilemap[substitutes[i].last_glyph].tilenum); } } @@ -503,6 +644,11 @@ FILE *ofp; Fprintf(ofp, "\nint total_tiles_used = %d;\n", start); } +#ifdef OBTAIN_TILEMAP +extern void NDECL(monst_globals_init); +extern void NDECL(objects_globals_init); +#endif + int main() { @@ -510,6 +656,11 @@ main() char filename[30]; FILE *ofp; +#ifdef OBTAIN_TILEMAP + objects_globals_init(); + monst_globals_init(); +#endif + init_tilemap(); /* @@ -526,7 +677,7 @@ main() Fprintf(ofp, "\nshort glyph2tile[MAX_GLYPH] = {\n"); for (i = 0; i < MAX_GLYPH; i++) { - Fprintf(ofp, " %4d,", tilemap[i]); + Fprintf(ofp, " %4d,", tilemap[i].tilenum); if ((i % 12) == 11 || i == MAX_GLYPH - 1) Fprintf(ofp, "\n"); } @@ -654,17 +805,20 @@ struct { }; boolean -acceptable_tilename(idx, encountered, expected) -int idx; +acceptable_tilename(glyph_set, idx, encountered, expected) +int glyph_set, idx; const char *encountered, *expected; { - if (idx >= 0 && idx < SIZE(altlabels)) { - if (!strcmp(altlabels[idx].expectedlabel, expected)) { - if (!strcmp(altlabels[idx].betterlabel, encountered)) - return TRUE; + if (glyph_set == OTH_GLYPH) { + if (idx >= 0 && idx < SIZE(altlabels)) { + if (!strcmp(altlabels[idx].expectedlabel, expected)) { + if (!strcmp(altlabels[idx].betterlabel, encountered)) + return TRUE; + } } + return FALSE; } - return FALSE; + return TRUE; } /*tilemap.c*/ diff --git a/win/share/tiletext.c b/win/share/tiletext.c index d078c4e37..0970e0e14 100644 --- a/win/share/tiletext.c +++ b/win/share/tiletext.c @@ -26,13 +26,15 @@ static const char *text_sets[] = { "monsters.txt", "objects.txt", "other.txt" }; #endif -extern const char *FDECL(tilename, (int, int)); -extern boolean FDECL(acceptable_tilename, (int, const char *, const char *)); +extern const char *FDECL(tilename, (int, int, int)); +extern boolean FDECL(acceptable_tilename, (int, int, const char *, const char *)); static void FDECL(read_text_colormap, (FILE *)); static boolean FDECL(write_text_colormap, (FILE *)); static boolean FDECL(read_txttile, (FILE *, pixel (*)[TILE_X])); static void FDECL(write_txttile, (FILE *, pixel (*)[TILE_X])); +enum { MONSTER_SET, OBJECT_SET, OTHER_SET}; + /* Ugh. DICE doesn't like %[A-Z], so we have to spell it out... */ #define FORMAT_STRING \ "%[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.] = " \ @@ -108,29 +110,37 @@ read_txttile(txtfile, pixels) FILE *txtfile; pixel (*pixels)[TILE_X]; { - int ph, i, j, k; - char buf[BUFSZ], ttype[BUFSZ]; + int ph, i, j, k, reslt; + char buf[BUFSZ], ttype[BUFSZ], gend[BUFSZ]; const char *p; char c[2]; + static int gidx = 0; - if (fscanf(txtfile, "# %s %d (%[^)])", ttype, &i, buf) <= 0) + gend[0] = '\0'; + if (tile_set == MONSTER_SET) + reslt = fscanf(txtfile, "# %s %d (%[^,],%[^)])", ttype, &i, buf, gend); + else + reslt = fscanf(txtfile, "# %s %d (%[^)])", ttype, &i, buf); + if (reslt <= 0) return FALSE; + if (tile_set == MONSTER_SET && gend[0] == 'f') + gidx = 1; + ph = strcmp(ttype, "placeholder") == 0; if (!ph && strcmp(ttype, "tile") != 0) Fprintf(stderr, "Keyword \"%s\" unexpected for entry %d\n", ttype, i); - if (tile_set != 0) { - /* check tile name, but not relative number, which will - * change when tiles are added - */ - p = tilename(tile_set, tile_set_indx); - if (p && strcmp(p, buf) && !acceptable_tilename(tile_set_indx,buf,p)) { - Fprintf(stderr, "warning: for tile %d (numbered %d) of %s,\n", - tile_set_indx, i, text_sets[tile_set - 1]); - Fprintf(stderr, "\tfound '%s' while expecting '%s'\n", buf, p); - } + /* check tile name, but not relative number, which will + * change when tiles are added + */ + p = tilename(tile_set, tile_set_indx, gidx); + if (p && strcmp(p, buf) + && !acceptable_tilename(tile_set, tile_set_indx, buf, p)) { + Fprintf(stderr, "warning: for tile %d (numbered %d) of %s,\n", + tile_set_indx, i, text_sets[tile_set]); + Fprintf(stderr, "\tfound '%s' while expecting '%s'\n", buf, p); } tile_set_indx++; @@ -196,21 +206,26 @@ pixel (*pixels)[TILE_X]; { const char *p; const char *type; - int i, j, k; + int i = 0, j, k; if (memcmp(placeholder, pixels, sizeof(placeholder)) == 0) type = "placeholder"; else type = "tile"; - if (tile_set == 0) - Fprintf(txtfile, "# %s %d (unknown)\n", type, tile_set_indx); - else { - p = tilename(tile_set, tile_set_indx); - if (p) - Fprintf(txtfile, "# %s %d (%s)\n", type, tile_set_indx, p); - else - Fprintf(txtfile, "# %s %d (null)\n", type, tile_set_indx); + if (tile_set == MONSTER_SET) { + for (i = 0; i < 2; ++i) { + Fprintf(txtfile, "# %s %d (unknown,%s)\n", type, tile_set_indx, + i ? "female" : "male"); + if (i == 0) + tile_set_indx++; + } + } else { + p = tilename(tile_set, tile_set_indx, i); + if (p) + Fprintf(txtfile, "# %s %d (%s)\n", type, tile_set_indx, p); + else + Fprintf(txtfile, "# %s %d (null)\n", type, tile_set_indx); } tile_set_indx++; @@ -302,7 +317,7 @@ const char *type; tile_set = 0; for (i = 0; i < SIZE(text_sets); i++) { if (!strcmp(p, text_sets[i])) - tile_set = i + 1; + tile_set = i; } tile_set_indx = 0; diff --git a/win/shim/winshim.c b/win/shim/winshim.c index b37da9b11..c6e425d70 100644 --- a/win/shim/winshim.c +++ b/win/shim/winshim.c @@ -129,7 +129,7 @@ VDECLCB(shim_mark_synch,(void), "v") VDECLCB(shim_wait_synch,(void), "v") VDECLCB(shim_cliparound,(int x, int y), "vii", A2P x, A2P y) VDECLCB(shim_update_positionbar,(char *posbar), "vp", P2V posbar) -VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph) +VDECLCB(shim_print_glyph,(winid w, int x, int y, int glyph, int bkglyph, int glyphmod[NUM_GLYPHMOD]), "viiiii", A2P w, A2P x, A2P y, A2P glyph, A2P bkglyph, A2P glyphmod) VDECLCB(shim_raw_print,(const char *str), "vs", P2V str) VDECLCB(shim_raw_print_bold,(const char *str), "vs", P2V str) DECLCB(int, shim_nhgetch,(void), "i") @@ -311,4 +311,4 @@ EM_JS(void, local_callback, (const char *cb_name, const char *shim_name, void *r }) #endif /* __EMSCRIPTEN__ */ -#endif /* SHIM_GRAPHICS */ \ No newline at end of file +#endif /* SHIM_GRAPHICS */ diff --git a/win/tty/wintty.c b/win/tty/wintty.c index a0ebef942..c59ea8fe5 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -3415,15 +3415,15 @@ int x, y; */ void -tty_print_glyph(window, x, y, glyph, bkglyph) +tty_print_glyph(window, x, y, glyph, bkglyph, glyphmod) winid window; xchar x, y; int glyph; int bkglyph UNUSED; +unsigned *glyphmod; /* don't mark UNUSED as we need to revisit */ { - int ch; boolean inverse_on = FALSE; - int color; + int ch, color; unsigned special; HUPSKIP(); @@ -3433,8 +3433,10 @@ int bkglyph UNUSED; return; } #endif - /* map glyph to character and color */ - (void) mapglyph(glyph, &ch, &color, &special, x, y, 0); + /* get glyph ttychar, color, and special flags */ + ch = (int) glyphmod[GM_TTYCHAR]; + color = (int) glyphmod[GM_COLOR]; + special = glyphmod[GM_FLAGS]; print_vt_code2(AVTC_SELECT_WINDOW, window); diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 34cb1a9cb..4a84e190a 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -37,8 +37,8 @@ typedef struct mswin_nethack_map_window { int map[COLNO][ROWNO]; /* glyph map */ int bkmap[COLNO][ROWNO]; /* backround glyph map */ + unsigned glyphmod[COLNO][ROWNO][NUM_GLYPHMOD]; boolean mapDirty[COLNO][ROWNO]; /* dirty flag for map */ - int mapMode; /* current map mode */ boolean bAsciiMode; /* switch ASCII/tiled mode */ boolean bFitToScreenMode; /* switch Fit map to screen mode on/off */ @@ -86,7 +86,7 @@ static void nhcoord2display(PNHMapWindow data, int x, int y, LPRECT lpOut); static void paint(PNHMapWindow data, int i, int j); static void dirtyAll(PNHMapWindow data); static void dirty(PNHMapWindow data, int i, int j); -static void setGlyph(PNHMapWindow data, int i, int j, int fg, int bg); +static void setGlyph(PNHMapWindow data, int i, int j, int fg, int bg, unsigned *glyphmod); static void clearAll(PNHMapWindow data); #if (VERSION_MAJOR < 4) && (VERSION_MINOR < 4) && (PATCHLEVEL < 2) @@ -639,7 +639,7 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) case MSNH_MSG_PRINT_GLYPH: { PMSNHMsgPrintGlyph msg_data = (PMSNHMsgPrintGlyph) lParam; setGlyph(data, msg_data->x, msg_data->y, - msg_data->glyph, msg_data->bkglyph); + msg_data->glyph, msg_data->bkglyph, msg_data->glyphmod); } break; case MSNH_MSG_CLIPAROUND: { @@ -708,8 +708,10 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) PMSNHMsgGetText msg_data = (PMSNHMsgGetText) lParam; size_t index; int col, row; +#if 0 int color; - unsigned special; + unsigned special = 0U; +#endif int mgch; index = 0; @@ -717,13 +719,14 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) for (col = 0; col < COLNO; col++) { if (index >= msg_data->max_size) break; - if (data->map[col][row] == NO_GLYPH) { + if (data->map[col][row] == NO_GLYPH) mgch = ' '; - } else { - (void) mapglyph(data->map[col][row], &mgch, &color, - &special, col, row, 0); - } - msg_data->buffer[index] = mgch; + +// } else { +// (void) mapglyph(data->map[col][row], &mgch, &color, +// &special, col, row, 0); +// } + msg_data->buffer[index] = data->glyphmod[col][row][GM_TTYCHAR]; index++; } if (index >= msg_data->max_size - 1) @@ -785,9 +788,9 @@ paintTile(PNHMapWindow data, int i, int j, RECT * rect) int glyph, bkglyph; int layer; #ifdef USE_PILEMARK - int color; - unsigned special; - int mgch; +// int color; +// unsigned special = 0U; +// int mgch; #endif layer = 0; glyph = data->map[i][j]; @@ -811,8 +814,16 @@ paintTile(PNHMapWindow data, int i, int j, RECT * rect) layer++; } +// (void) mapglyph(glyph, &mgch, &color, &special, i, j, 0); +// mgch = (int) data.glyphmod[GM_TTYCHAR]; +// color = (int) data.glyphmod[GM_COLOR]; +// special = glyphmod[GM_FLAGS]; + if ((glyph != NO_GLYPH) && (glyph != bkglyph)) { + /* rely on NetHack core helper routine */ ntile = glyph2tile[glyph]; + if (data->glyphmod[i][j][GM_FLAGS] & MG_FEMALE) + ntile++; t_x = TILEBMP_X(ntile); t_y = TILEBMP_Y(ntile); @@ -834,9 +845,9 @@ paintTile(PNHMapWindow data, int i, int j, RECT * rect) #ifdef USE_PILEMARK /* rely on NetHack core helper routine */ - (void) mapglyph(data->map[i][j], &mgch, &color, &special, - i, j, 0); - if ((glyph != NO_GLYPH) && (special & MG_PET) +// (void) mapglyph(data->map[i][j], &mgch, &color, &special, +// i, j, 0); + if ((glyph != NO_GLYPH) && (data->glyphmod[i][j][GM_FLAGS] & MG_PET) #else if ((glyph != NO_GLYPH) && glyph_is_pet(glyph) #endif @@ -859,7 +870,7 @@ paintTile(PNHMapWindow data, int i, int j, RECT * rect) DeleteDC(hdcPetMark); } #ifdef USE_PILEMARK - if ((glyph != NO_GLYPH) && (special & MG_OBJPILE) + if ((glyph != NO_GLYPH) && (data->glyphmod[i][j][GM_FLAGS] & MG_OBJPILE) && iflags.hilite_pile) { /* apply pilemark transparently over other image */ HDC hdcPileMark; @@ -893,8 +904,8 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) char ch; WCHAR wch; int color; - unsigned special; - int mgch; +// unsigned special; +// int mgch; HBRUSH back_brush; COLORREF OldFg; @@ -909,11 +920,12 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) OldFg = SetTextColor(hDC, nhcolor_to_RGB(color)); #else /* rely on NetHack core helper routine */ - (void) mapglyph(data->map[i][j], &mgch, &color, - &special, i, j, 0); - ch = (char) mgch; - if (((special & MG_PET) && iflags.hilite_pet) - || ((special & (MG_DETECT | MG_BW_LAVA)) +// (void) mapglyph(data->map[i][j], &mgch, &color, +// &special, i, j, 0); + ch = (char) data->glyphmod[i][j][GM_TTYCHAR]; + color = (int) data->glyphmod[i][j][GM_COLOR]; + if (((data->glyphmod[i][j][GM_FLAGS] & MG_PET) && iflags.hilite_pet) + || ((data->glyphmod[i][j][GM_FLAGS] & (MG_DETECT | MG_BW_LAVA)) && iflags.use_inverse)) { back_brush = CreateSolidBrush(nhcolor_to_RGB(CLR_GRAY)); @@ -972,13 +984,19 @@ paintGlyph(PNHMapWindow data, int i, int j, RECT * rect) } } -static void setGlyph(PNHMapWindow data, int i, int j, int fg, int bg) +static void setGlyph(PNHMapWindow data, int i, int j, int fg, int bg, unsigned *glyphmod) { - if ((data->map[i][j] != fg) || (data->bkmap[i][j] != bg)) { + int gm; + + if ((data->map[i][j] != fg) || (data->bkmap[i][j] != bg) + || data->glyphmod[i][j][GM_TTYCHAR] != glyphmod[GM_TTYCHAR] + || data->glyphmod[i][j][GM_COLOR] != glyphmod[GM_COLOR] + || data->glyphmod[i][j][GM_FLAGS] != glyphmod[GM_FLAGS]) { data->map[i][j] = fg; data->bkmap[i][j] = bg; data->mapDirty[i][j] = TRUE; - + for (gm = 0; gm < NUM_GLYPHMOD; ++gm) + data->glyphmod[i][j][gm] = glyphmod[gm]; RECT rect; nhcoord2display(data, i, j, &rect); InvalidateRect(data->hWnd, &rect, FALSE); @@ -991,6 +1009,9 @@ static void clearAll(PNHMapWindow data) for (int y = 0; y < ROWNO; y++) { data->map[x][y] = NO_GLYPH; data->bkmap[x][y] = NO_GLYPH; + data->glyphmod[x][y][GM_TTYCHAR] = ' '; + data->glyphmod[x][y][GM_COLOR] = NO_COLOR; + data->glyphmod[x][y][GM_FLAGS] = 0U; data->mapDirty[x][y] = TRUE; } InvalidateRect(data->hWnd, NULL, FALSE); diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 07fe86791..431d426ca 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -38,6 +38,7 @@ typedef struct mswin_nhmsg_print_glyph { XCHAR_P y; int glyph; int bkglyph; + int glyphmod[NUM_GLYPHMOD]; } MSNHMsgPrintGlyph, *PMSNHMsgPrintGlyph; typedef struct mswin_nhmsg_cliparound { diff --git a/win/win32/mswproc.c b/win/win32/mswproc.c index a439deca5..efebf6160 100644 --- a/win/win32/mswproc.c +++ b/win/win32/mswproc.c @@ -1281,7 +1281,7 @@ mswin_cliparound(int x, int y) } /* -print_glyph(window, x, y, glyph, bkglyph) +print_glyph(window, x, y, glyph, bkglyph, glyphmod) -- Print the glyph at (x,y) on the given window. Glyphs are integers at the interface, mapped to whatever the window- port wants (symbol, font, color, attributes, ...there's @@ -1290,12 +1290,15 @@ print_glyph(window, x, y, glyph, bkglyph) graphical or tiled environments to allow the depiction to fall against a background consistent with the grid around x,y. + -- glyphmod provides extended information about the glyph + that window ports can use to enhance the display in + various ways. */ void -mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) +mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph, unsigned *glyphmod) { - logDebug("mswin_print_glyph(%d, %d, %d, %d, %d)\n", wid, x, y, glyph, bkglyph); + logDebug("mswin_print_glyph(%d, %d, %d, %d, %d, %lu)\n", wid, x, y, glyph, bkglyph, glyphmod); if ((wid >= 0) && (wid < MAXWINDOWS) && (GetNHApp()->windowlist[wid].win != NULL)) { @@ -1306,6 +1309,9 @@ mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph) data.y = y; data.glyph = glyph; data.bkglyph = bkglyph; + data.glyphmod[GM_TTYCHAR] = glyphmod[GM_TTYCHAR]; + data.glyphmod[GM_COLOR] = glyphmod[GM_COLOR]; + data.glyphmod[GM_FLAGS] = glyphmod[GM_FLAGS]; SendMessage(GetNHApp()->windowlist[wid].win, WM_MSNH_COMMAND, (WPARAM) MSNH_MSG_PRINT_GLYPH, (LPARAM) &data); } diff --git a/win/win32/winMS.h b/win/win32/winMS.h index 17cb8d2ef..6ec4e9c3b 100644 --- a/win/win32/winMS.h +++ b/win/win32/winMS.h @@ -162,7 +162,7 @@ void mswin_update_inventory(void); void mswin_mark_synch(void); void mswin_wait_synch(void); void mswin_cliparound(int x, int y); -void mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph); +void mswin_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, int bkglyph, unsigned *glyphmod); void mswin_raw_print(const char *str); void mswin_raw_print_bold(const char *str); void mswin_raw_print_flush(); From a7c63f8abcca5298eeee2d99719879926ca25503 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 26 Dec 2020 18:35:09 -0500 Subject: [PATCH 679/708] switch curses port to use the new tty_print_glyph argument --- win/curses/cursdial.c | 2 +- win/curses/cursmain.c | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 4912f7227..c8cb0c281 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1182,7 +1182,7 @@ menu_display_page(nhmenu *menu, WINDOW * win, int page_num, char *selectors) if (menu_item_ptr->glyph != NO_GLYPH && iflags.use_menu_glyphs) { unsigned special; /*notused */ - mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, 0, 0, 0); +// mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, 0, 0, 0); curses_toggle_color_attr(win, color, NONE, ON); mvwaddch(win, menu_item_ptr->line_num + 1, start_col, curletter); curses_toggle_color_attr(win, color, NONE, OFF); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index baceb8901..0ee3c7f43 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -667,8 +667,13 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, unsigned int special; int attr = -1; +#if 0 /* map glyph to character and color */ - mapglyph(glyph, &ch, &color, &special, x, y, 0); + mapglyph(glyph, &ch, &color, &special, x, y, 0); */ +#endif + special = glyphmod[GM_FLAGS]; + ch = (int) glyphmod[GM_TTYCHAR]; + color = (int) glyphmod[GM_COLOR]; if ((special & MG_PET) && iflags.hilite_pet) { attr = iflags.wc2_petattr; } @@ -693,7 +698,7 @@ curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph, /* water and lava look the same except for color; when color is off, render lava in inverse video so that they look different */ if ((special & (MG_BW_LAVA | MG_BW_ICE)) != 0 && iflags.use_inverse) { - attr = A_REVERSE; /* mapglyph() only sets this if color is off */ + attr = A_REVERSE; /* map_glyphmod() only sets this if color is off */ } } From 772e876e44a2ab913d9fd3448be105134ef5028e Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 26 Dec 2020 19:07:19 -0500 Subject: [PATCH 680/708] incorporate some pmnames feedback Also an update to a fixes37.0 entry --- doc/fixes37.0 | 6 +++--- src/makemon.c | 2 +- src/mkroom.c | 2 +- src/mondata.c | 4 ++-- src/monst.c | 6 +++--- src/wizard.c | 2 +- win/share/monsters.txt | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index d86b9d5ec..0e7111053 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -738,8 +738,7 @@ Qt: add Filter, Layout, and Reset buttons to the extended command selector; to their default settings and clears any pending typed input tiles: male and female variations in monsters.txt; tested only with tile2bmp conversion utility so far; also supported by tilemap utility to - generate tile.c; some window-port modifications still required to - integrate the male and female tile capability into the window port + generate tile.c Unix: can define NOSUSPEND in config.h or src/Makefile's CFLAGS to prevent unixconf.h from enabling SUSPEND without need to modify unixconf.h @@ -838,4 +837,5 @@ replace the single permonst mname field with male, female, and gender-neutral names pmnames[NUM_MGENDERS] fields add a new glyphmod parameter to window interface *_print_glyph() to be used to provide additional details to the window port beyond the glyph; - begin to phase out the mapglyph() calls from within windows ports + begin to phase out the mapglyph() calls from within windows ports; + diff --git a/src/makemon.c b/src/makemon.c index 27f9ad049..0199cedb4 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -247,7 +247,7 @@ register struct monst *mtmp; } break; } - if (mm == PM_ELVENMONARCH) { + if (mm == PM_ELVEN_MONARCH) { if (rn2(3) || (g.in_mklev && Is_earthlevel(&u.uz))) (void) mongets(mtmp, PICK_AXE); if (!rn2(50)) diff --git a/src/mkroom.c b/src/mkroom.c index 405efb312..496b4c426 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -251,7 +251,7 @@ int x,y; { int i = rnd(level_difficulty()); int pm = (i > 9) ? PM_OGRE_TYRANT - : (i > 5) ? PM_ELVENMONARCH + : (i > 5) ? PM_ELVEN_MONARCH : (i > 2) ? PM_DWARF_RULER : PM_GNOME_RULER; struct monst *mon = makemon(&mons[pm], x, y, NO_MM_FLAGS); diff --git a/src/mondata.c b/src/mondata.c index e78806dbe..142d44c2b 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -772,7 +772,7 @@ int *gender_name_var; { "master of assassin", PM_MASTER_ASSASSIN, NEUTRAL }, /* Outdated names */ { "invisible stalker", PM_STALKER, NEUTRAL }, - { "high-elf", PM_ELVENMONARCH, NEUTRAL }, /* PM_HIGH_ELF is obsolete */ + { "high-elf", PM_ELVEN_MONARCH, NEUTRAL }, /* PM_HIGH_ELF is obsolete */ /* other misspellings or incorrect words */ { "wood-elf", PM_WOODLAND_ELF, NEUTRAL }, { "wood elf", PM_WOODLAND_ELF, NEUTRAL }, @@ -1051,7 +1051,7 @@ static const short grownups[][2] = { { PM_WOODLAND_ELF, PM_ELF_NOBLE }, { PM_GREEN_ELF, PM_ELF_NOBLE }, { PM_GREY_ELF, PM_ELF_NOBLE }, - { PM_ELF_NOBLE, PM_ELVENMONARCH }, + { PM_ELF_NOBLE, PM_ELVEN_MONARCH }, { PM_LICH, PM_DEMILICH }, { PM_DEMILICH, PM_MASTER_LICH }, { PM_MASTER_LICH, PM_ARCH_LICH }, diff --git a/src/monst.c b/src/monst.c index 2e44b5413..ac2700d6f 100644 --- a/src/monst.c +++ b/src/monst.c @@ -1692,7 +1692,7 @@ struct permonst _mons2[] = { SIZ(1600, 500, MS_GRUNT, MZ_LARGE), 0, 0, M1_HUMANOID | M1_CARNIVORE, M2_STRONG | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 7, CLR_BROWN), - MON3("ogre lord", "ogre conqueress", "ogre leader", + MON3("ogre lord", "ogre lady", "ogre leader", S_OGRE, LVL(7, 12, 3, 30, -5), (G_GENO | 2), A(ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), @@ -2209,7 +2209,7 @@ struct permonst _mons2[] = { M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS, M2_ELF | M2_STRONG | M2_LORD | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 11, CLR_BRIGHT_BLUE), - MON3("Elvenking", "Elvenqueen", "Elvenmonarch", + MON3("Elvenking", "Elvenqueen", "elven monarch", S_HUMAN, LVL(9, 12, 10, 25, -10), (G_GENO | 1), A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_WEAP, AD_PHYS, 2, 4), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK), @@ -2411,7 +2411,7 @@ struct permonst _mons2[] = { 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 */ - MON3("incubus", "succubus", "Amorous Demon", + MON3("incubus", "succubus", "amorous demon", S_DEMON, LVL(6, 12, 0, 70, -9), (G_NOCORPSE | 1), SEDUCTION_ATTACKS_YES, SIZ(WT_HUMAN, 400, MS_SEDUCE, MZ_HUMAN), MR_FIRE | MR_POISON, 0, M1_HUMANOID | M1_FLY | M1_POIS, diff --git a/src/wizard.c b/src/wizard.c index a4e9d07f1..4f1891566 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -37,7 +37,7 @@ static NEARDATA const int nasties[] = { /* chaotic */ PM_BLACK_DRAGON, PM_RED_DRAGON, PM_ARCH_LICH, PM_VAMPIRE_LEADER, PM_MASTER_MIND_FLAYER, PM_DISENCHANTER, PM_WINGED_GARGOYLE, - PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_NOBLE, PM_ELVENMONARCH, + PM_STORM_GIANT, PM_OLOG_HAI, PM_ELF_NOBLE, PM_ELVEN_MONARCH, PM_OGRE_TYRANT, PM_CAPTAIN, PM_GREMLIN, /* lawful */ PM_SILVER_DRAGON, PM_ORANGE_DRAGON, PM_GREEN_DRAGON, diff --git a/win/share/monsters.txt b/win/share/monsters.txt index e14f4611f..200efe5fd 100644 --- a/win/share/monsters.txt +++ b/win/share/monsters.txt @@ -10401,7 +10401,7 @@ Z = (195, 195, 195) ................ ................ } -# tile 546 (Elvenmonarch,male) +# tile 546 (elven monarch,male) { ................ ................ @@ -10420,7 +10420,7 @@ Z = (195, 195, 195) ................ ................ } -# tile 547 (Elvenmonarch,female) +# tile 547 (elven monarch,female) { ................ ................ From 4c8d33839b7f06c6725cc1ce40070ffd781ab28c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 26 Dec 2020 19:09:54 -0500 Subject: [PATCH 681/708] trailing semicolon bit --- doc/fixes37.0 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 0e7111053..db04f0163 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -837,5 +837,4 @@ replace the single permonst mname field with male, female, and gender-neutral names pmnames[NUM_MGENDERS] fields add a new glyphmod parameter to window interface *_print_glyph() to be used to provide additional details to the window port beyond the glyph; - begin to phase out the mapglyph() calls from within windows ports; - + begin to phase out the mapglyph() calls from within windows ports From ec889df4d31f755221f3d32c672c7f18781d1a15 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sat, 26 Dec 2020 19:21:37 -0500 Subject: [PATCH 682/708] another follow-up bit - punctuation consistency an uppercase entry was left in the monsters.txt tile file, but changed elsewhere --- win/share/monsters.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/win/share/monsters.txt b/win/share/monsters.txt index 200efe5fd..9e11b64b4 100644 --- a/win/share/monsters.txt +++ b/win/share/monsters.txt @@ -11237,7 +11237,7 @@ Z = (195, 195, 195) ....EEAEEA...... ................ } -# tile 590 (Amorous Demon,male) +# tile 590 (amorous demon,male) { DD.OHHD......... DDOHHDGD........ @@ -11256,7 +11256,7 @@ Z = (195, 195, 195) ...DDKAA..DDAA.. ..DDKAA...DDDA.. } -# tile 595 (Amorous Demon,female) +# tile 595 (amorous demon,female) { DD.OHHD......... DDOHHDGD........ From 31ed7f68965f94fb3509a16c4a1d2cd2f4eb4929 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 27 Dec 2020 05:01:39 -0800 Subject: [PATCH 683/708] unix/Makefile.top vs tiles2bmp Add a missing update to sys/unix/Makefile.top. Makefile.dat only requires that tiles2bmp exist, without knowing anything about whether it needs to be rebuilt. So force Makefile.top to make sure that it's up to date, similar to how tiles2x11 gets handled. --- 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 969f3e4d5..75fd32370 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: 1607810996 2020/12/12 22:09:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.63 $ +# NetHack 3.7 Makefile.top $NHDT-Date: 1609074072 2020/12/27 13:01:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ # Copyright (c) 2015 by Kenneth Lorber, Kensington, Maryland # NetHack may be freely redistributed. See license for details. @@ -160,6 +160,7 @@ spec_levs: ( cd dat ; $(MAKE) quest_levs ) nhtiles.bmp: $(GAME) + ( cd util ; $(MAKE) tile2bmp ) ( cd dat ; $(MAKE) nhtiles.bmp ) x11tiles: $(GAME) From 8ccb5985d405115298e161d22cfb433c3da86552 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 27 Dec 2020 05:09:44 -0800 Subject: [PATCH 684/708] curses comment bit Don't require c99, even in code that's suppressed via #if 0. --- win/curses/cursdial.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index c8cb0c281..df0f38c34 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -1182,7 +1182,8 @@ menu_display_page(nhmenu *menu, WINDOW * win, int page_num, char *selectors) if (menu_item_ptr->glyph != NO_GLYPH && iflags.use_menu_glyphs) { unsigned special; /*notused */ -// mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, 0, 0, 0); + /*mapglyph(menu_item_ptr->glyph, &curletter, &color, &special, + 0, 0, 0);*/ curses_toggle_color_attr(win, color, NONE, ON); mvwaddch(win, menu_item_ptr->line_num + 1, start_col, curletter); curses_toggle_color_attr(win, color, NONE, OFF); From 5c4996c701bcff6c12a4daf97f937e7525f87e90 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 27 Dec 2020 05:27:02 -0800 Subject: [PATCH 685/708] mimics in inaccessible locations Suppress insane sanity check. --- src/mon.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/mon.c b/src/mon.c index c6136e779..1b13ddbd6 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1608332750 2020/12/18 23:05:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.361 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1609075599 2020/12/27 13:26:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.363 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -155,6 +155,7 @@ const char *msg; if (!(is_mimic || mtmp->meating)) impossible("non-mimic (%s) posing as %s (%s)", mptr->pmnames[NEUTRAL], what, msg); +#if 0 /* mimics who end up in strange locations do still hide while there */ if (!(accessible(mx, my) || passes_walls(mptr))) { char buf[BUFSZ]; const char *typnam = levltyp_to_name(levl[mx][my].typ); @@ -166,6 +167,7 @@ const char *msg; impossible("mimic%s concealed in inaccessible location: %s (%s)", is_mimic ? "" : "ker", typnam, msg); } +#endif } } From fd13f2a2f27d92e6f601b6499a7db2a7ebbab19f Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 10:45:13 -0500 Subject: [PATCH 686/708] monster gender-related follow-ups remove unintentionally left M2_MALE flag on dwarf lord/lady/leader provide a way to verify gender information relayed from the core in debug mode on tty via #wizmgender debugging extended command --- doc/fixes37.0 | 5 +++++ include/extern.h | 1 + include/flag.h | 1 + src/cmd.c | 2 ++ src/detect.c | 11 +++++++++++ src/monst.c | 3 +-- win/tty/wintty.c | 11 +++++++++-- 7 files changed, 30 insertions(+), 4 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index db04f0163..52a6f0ded 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -457,6 +457,8 @@ adding displacer beast inadvertently introduced a regression in swapping with splitting #if MAIL into #if MAIL_STRUCTURES and #if MAIL made it possible to wish for and write scrolls of mail with MAIL disabled, but attempting to read such a scroll issued impossible "What weird effect is this?" +remove M2_MALE flag that was unintentionally left on dwarf lord/lady/leader + entry and was preventing female incarnations curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support @@ -709,6 +711,9 @@ add support for a single monster species to have distinct male and female tiles consolidate several monsters that differed only by their gender into their single species +added wizmgender debugging command to display female monsters in red inverse; + helpful for debugging gender-related matters on tty; currently ignored + on other window ports Platform- and/or Interface-Specific New Features diff --git a/include/extern.h b/include/extern.h index cf66dd4ff..0d9b86a52 100644 --- a/include/extern.h +++ b/include/extern.h @@ -295,6 +295,7 @@ E void NDECL(sokoban_detect); E void NDECL(dump_map); #endif E void FDECL(reveal_terrain, (int, int)); +E int NDECL(wiz_mgender); /* ### dig.c ### */ diff --git a/include/flag.h b/include/flag.h index 4122dd046..1e45e948a 100644 --- a/include/flag.h +++ b/include/flag.h @@ -294,6 +294,7 @@ struct instance_flags { boolean cmdassist; /* provide detailed assistance for some comnds */ boolean time_botl; /* context.botl for 'time' (moves) only */ boolean wizweight; /* display weight of everything in wizard mode */ + boolean wizmgender; /* test gender info from core in window port */ /* * Window capability support. */ diff --git a/src/cmd.c b/src/cmd.c index 0ae12b0db..7425264f5 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1844,6 +1844,8 @@ struct ext_func_tab extcmdlist[] = { wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { '\0', "lightsources", "show mobile light sources", wiz_light_sources, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, + { '\0', "wizmgender", "force added info about monster gender", + wiz_mgender, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { ':', "look", "look at what is here", dolook, IFBURIED }, { M('l'), "loot", "loot a box on the floor", doloot, AUTOCOMPLETE }, #ifdef DEBUG_MIGRATING_MONS diff --git a/src/detect.c b/src/detect.c index db5e84895..efb56d7b3 100644 --- a/src/detect.c +++ b/src/detect.c @@ -2096,4 +2096,15 @@ int which_subset; /* when not full, whether to suppress objs and/or traps */ return; } +int +wiz_mgender(VOID_ARGS) +{ + iflags.wizmgender = !iflags.wizmgender; + pline("wizmgender toggled %s", iflags.wizmgender ? "on" : "off"); + if (!u.uswallow) + see_monsters(); + map_redisplay(); + return 0; /* no time */ +} + /*detect.c*/ diff --git a/src/monst.c b/src/monst.c index ac2700d6f..fbd1f8a99 100644 --- a/src/monst.c +++ b/src/monst.c @@ -448,8 +448,7 @@ NEARDATA struct permonst mons_init[] = { NO_ATTK, NO_ATTK, NO_ATTK), SIZ(900, 300, MS_HUMANOID, MZ_HUMAN), 0, 0, M1_TUNNEL | M1_NEEDPICK | M1_HUMANOID | M1_OMNIVORE, - M2_DWARF | M2_STRONG | M2_LORD | M2_MALE | M2_GREEDY | M2_JEWELS - | M2_COLLECT, + M2_DWARF | M2_STRONG | M2_LORD | M2_GREEDY | M2_JEWELS | M2_COLLECT, M3_INFRAVISIBLE | M3_INFRAVISION, 6, CLR_BLUE), MON3("dwarf king", "dwarf queen", "dwarf ruler", S_HUMANOID, LVL(6, 6, 10, 20, 6), (G_GENO | 1), diff --git a/win/tty/wintty.c b/win/tty/wintty.c index c59ea8fe5..8d96256eb 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -1,4 +1,4 @@ - /* NetHack 3.7 wintty.c $NHDT-Date: 1608861214 2020/12/25 01:53:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ */ +/* NetHack 3.7 wintty.c $NHDT-Date: 1608861214 2020/12/25 01:53:34 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.264 $ */ /* Copyright (c) David Cohrs, 1991 */ /* NetHack may be freely redistributed. See license for details. */ @@ -3453,7 +3453,14 @@ unsigned *glyphmod; /* don't mark UNUSED as we need to revisit */ #endif #ifdef TEXTCOLOR - if (color != ttyDisplay->color) { + if (iflags.wizmgender && (special & MG_FEMALE) && iflags.use_inverse) { + if (ttyDisplay->color != NO_COLOR) + term_end_color(); + term_start_attr(ATR_INVERSE); + inverse_on = TRUE; + ttyDisplay->color = CLR_RED; + term_start_color(ttyDisplay->color); + } else if (color != ttyDisplay->color) { if (ttyDisplay->color != NO_COLOR) term_end_color(); ttyDisplay->color = color; From f83b3e038aa1fb39e2c93be2ac4a9705f9e1c575 Mon Sep 17 00:00:00 2001 From: Kestrel Date: Sun, 27 Dec 2020 10:56:30 -0600 Subject: [PATCH 687/708] Differentiate male and female ant tiles. Female ants are larger than male ants. I could have added wings to the male ants, but I felt that doing so would lead to a loss in visual clarity. --- win/share/monsters.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/win/share/monsters.txt b/win/share/monsters.txt index 9e11b64b4..679f12333 100644 --- a/win/share/monsters.txt +++ b/win/share/monsters.txt @@ -54,13 +54,13 @@ Z = (195, 195, 195) ................ ................ ................ - ................ - .......JAJKKA... - .....JAAAKJJJA.. - .....AKJJAJJAA.. + ......J......... + ......AJAJKKA... + ....JJAAAKJJJA.. + ....AAKJJAJJAA.. ...KKAJJJAAA.... - ..BJJAAAAAJJA... - ..JBJAJAJAA..... + ..BJJAAAAAJJ.... + ..JBJAJAJAAAJ... .....AJA.JA..... ......JA.JA..... ................ @@ -131,12 +131,12 @@ Z = (195, 195, 195) ................ ................ ................ - .......JAJKKA... - .....JAAAKJJJA.. - .....AKJJAJJAA.. + ......JJAJKKA... + ....JJAAAKJJJA.. + ....AAKJJAJJAA.. .JJKKAJJJAAA.... - JBJJJAAAAAJJA... - JJJBJAJAJAA..... + JBJJJAAAAAJJ.... + JJJBJAJAJAAAJ... JAAJJAJA.JA..... ..JJAAJA.JA..... ................ @@ -168,13 +168,13 @@ Z = (195, 195, 195) ................ ................ ................ - ................ - .......DACCCA... - .....DAAACDDDA.. - .....ACDDADDAA.. + ......D......... + ......ADACCCA... + ....DDAAACDDDA.. + ....AACDDADDAA.. ...CCADDDAAA.... - ..GDDAAAAADDA... - ..DGDADADAA..... + ..GDDAAAAADD.... + ..DGDADADAAAD... .....ADA.DA..... ......DA.DA..... ................ From ea1ffe5112fa5dfef9a7e5a9e6807546169f5ed2 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 12:51:40 -0500 Subject: [PATCH 688/708] tty unused parameter under some configs --- win/tty/wintty.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 8d96256eb..e68e40272 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -3418,7 +3418,11 @@ void tty_print_glyph(window, x, y, glyph, bkglyph, glyphmod) winid window; xchar x, y; +#ifdef TTY_TILES_ESCCODES int glyph; +#else +int glyph UNUSED; +#endif int bkglyph UNUSED; unsigned *glyphmod; /* don't mark UNUSED as we need to revisit */ { From 5d0c1a94f48a43ae48d58c0fc10c70da643cfd1b Mon Sep 17 00:00:00 2001 From: Kestrel Date: Sun, 27 Dec 2020 13:01:27 -0600 Subject: [PATCH 689/708] More monster gender tiles additions. --- win/share/monsters.txt | 222 ++++++++++++++++++++--------------------- 1 file changed, 111 insertions(+), 111 deletions(-) diff --git a/win/share/monsters.txt b/win/share/monsters.txt index 679f12333..e80b56448 100644 --- a/win/share/monsters.txt +++ b/win/share/monsters.txt @@ -811,7 +811,7 @@ Z = (195, 195, 195) ................ ................ ................ - ...P..P.....P... + ...P..P......... ...P.PP......P.. ..PPPP.......P.. ..N.NPP......P.A @@ -849,7 +849,7 @@ Z = (195, 195, 195) ................ ................ ................ - ...P..P.....P... + ...P..P......... ...P.PP......P.. ..PPPP.......P.. ..N.NPP......P.A @@ -889,7 +889,7 @@ Z = (195, 195, 195) ................ ................ ...N..N......... - ...N.NB...N..... + ...N.NB......... ..NNNN.....N.... ..DNDNB....N.A.. ..NNNNB....N.A.. @@ -923,7 +923,7 @@ Z = (195, 195, 195) # tile 47 (warg,female) { ................ - ...P..P....PP... + ...P..P.....P... ...P.PP......P.. ..PPPP.......P.A ..N.NPP......P.A @@ -963,7 +963,7 @@ Z = (195, 195, 195) ................ ................ ................ - ...N..N.....N... + ...N..N......... ...N.NN......N.. ..NNNN.......N.. ..DODNN......N.A @@ -1346,15 +1346,15 @@ Z = (195, 195, 195) ................ ................ ................ - ...........K.... - ............C... - ....C.C.....L.A. - ...CCCCJ....C.A. - ...NCNCJCCLCL.A. - ...CCCCJCCLCCAA. - ....IACCLLCCCAA. - .....CACCJCCJA.. - ......CCA..CA... + ...........N.... + ............N... + ....N.N.....C.A. + ...NNNNC....C.A. + ...ENENNNJJNC.A. + ...NNNNNJJJNNAA. + ....IANNJJNNNAA. + .....NANNWNNWA.. + ......NNA..NA... ................ } # tile 70 (housecat,male) @@ -1383,16 +1383,16 @@ Z = (195, 195, 195) ................ ................ ................ - ...........K.... - ............C... - ...C.C......L.A. - ..CCCCJ.....C.A. - .CNCNCJCLCLCL.A. - .CCCCCJCLCLCCAA. - ..CICJCCLCLCLAA. - ...AACCLCLCCCAA. - ...CCACCJJCCJA.. - .....CCA...CA... + ...........N.... + ............N... + ...N.N......C.A. + ..NNNNC.....C.A. + .NANANCNJJJNN.A. + .NNNNNNNJJNNNAA. + ..NINWNJJJNNNAA. + ...AANNNNNNNNAA. + ...NNANNWWNNWA.. + .....NNA...NA... ................ } # tile 72 (jaguar,male) @@ -1534,17 +1534,17 @@ Z = (195, 195, 195) ................ ................ ................ - ............K... - .............C.. - ...C.C.......L.A - ..CCCCJ......C.A - .CNCNCJCLCCLCL.A - .CCCCCJCLCCLCCAA - ..CDCJCCLCCLCLAA - ...AACCLCCLCCCAA - ....CACCJJJCCJA. - ...CKALAAAAACAA. - .....CCAA...CA.. + ............N... + .............N.. + ...N.N.......C.A + ..NNNNC......C.A + .NANANCNJJJJNN.A + .NNNNNNNJJJNNNAA + ..NDNWNJJJNNNNAA + ...AANNNNNNNNNAA + ....NANNWWWNNWA. + ...NJANAAAAANAA. + .....NNAA...NA.. ................ } # tile 80 (tiger,male) @@ -1768,7 +1768,7 @@ Z = (195, 195, 195) ....JLLLLJ...... ....JKLLKJJ.AA.. ...CLLLLLLCAAA.. - ..CLALLLLALCA... + ..CLALJKJALCA... ..LLAJJKJALLA... ...L.LKJLALAA... .....LLALLA.A... @@ -2527,7 +2527,7 @@ Z = (195, 195, 195) .....GFF..KLK... ....GFFFF..K.... .....KLKA.GLAA.. - ...FGFJFFFAKA.A. + ...FGFLFFFAKA.A. ...GAGFFAAAK.AA. ....LKHKKJAKAA.. ....GFAGKJAKA... @@ -4768,9 +4768,9 @@ Z = (195, 195, 195) ...BF.LFLFA.FB.. .I.BF.LLLLA.FB.. ...BF.ALLA.FB... - ..BF.LLAALL.ABA. - .BF.LLLLLLLLAFB. - .BF.LALLLLALAFB. + ..BF.LJAAJL.ABA. + .BF.LLJJJJLLAFB. + .BF.LAJKJJALAFB. .BF.LAJJKJALAFB. ..BF..LJJLAAABA. ...BF.LLALAABA.. @@ -4879,8 +4879,8 @@ Z = (195, 195, 195) .....OOOOOO..... .....OJLLJO..... .....OLLLLO..... - ....OOJLLJOO.... - ......AJJA...... + ....OOKLLKOO.... + ......AKKA...... .....AAAAAAA.... ....AAAAAAAAA... ...OAAOAAAJLJ... @@ -6402,9 +6402,9 @@ Z = (195, 195, 195) .....GFF........ ....GGFFF....... ....GLLLF....... - .....OLO...AAA.. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. + .....LLL...AAA.. + ...FGGGGFFAAAA.. + ...GAGFFAFAAAA.. ....LKNKFAAAA... ....FGAFFAA..... ....GFAFG.A..... @@ -6440,9 +6440,9 @@ Z = (195, 195, 195) .....GFF........ ....HHHHH....... ....GLLLF.....A. - .....OLO...AAA.. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. + .....LLL...AAA.. + ...FGGGGFFAAAA.. + ...GAGGFAFAAAA.. ....LKNKFAAAA... ....FGAFFAA..... ....GFAFG.A..... @@ -6478,9 +6478,9 @@ Z = (195, 195, 195) .....GFF........ ....GGFFF....... ....GLLLF....... - ...FFOLOFF.AAA.. - ...GFOOOFFAAAA.. - ...FAGOFAFAAAA.. + ...FFLLLFF.AAA.. + ...GFGFGFFAAAA.. + ...FAGGFAFAAAA.. ...GLKNKFFAAA... ...FFGFFFFA..... ...GFFFFGFA..... @@ -6516,9 +6516,9 @@ Z = (195, 195, 195) ....HCHCH....... ....HHHHH....... ....GLLLF...A... - .....OLO...AAAA. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. + .....LLL...AAAA. + ...FGGGGFFAAAA.. + ...GAGFFAFAAAA.. ....LKNKFAAAA... ....FGAFFAA..... ....GFAFG.A..... @@ -6703,13 +6703,13 @@ Z = (195, 195, 195) ....JJLLLLJJA... ....JEELLEEJA... ....JLLLLLLJA... - ....AKJJJJJAAA.. - .....KJAAJJAAAA. - ....KKJJJJAJAAAA - ...KJKJJJJAJJAAA - ..KJKKJJJJJKJJAA - ..KAAJKJJAJAAJAA - ..JAAJKKAKJAAJAA + ....ALLLLLLAAA.. + .....LLAALLAAAA. + ....KKLLLLKKAAAA + ...KJKKKKKKJJAAA + ..KJKKJJJJKKJJAA + ..KAAJKJJKJAAJAA + ..JAAJKKKKJAAJAA ..LC.JJJJJKKCLAA ..LL.CJJAJLJLLAA .....CLJACLJAAAA @@ -6861,7 +6861,7 @@ Z = (195, 195, 195) ..CLJAJAKALCAA.A .CLLJJJJJALLCAAA .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. + .LAAJLLLLJAALAA. .LL.JJJJJJJLLAAA .LL.JJJJJJJLLAAA ....CLCACLCAAAAA @@ -7952,7 +7952,7 @@ Z = (195, 195, 195) } # tile 417 (ogre tyrant,female) { - ...H..C..H...... + ...HH.C.HH...... ...HDCHCDH...... ...HHHHHHH...... ..LCKKLKKCL..... @@ -8143,15 +8143,15 @@ Z = (195, 195, 195) # tile 427 (quantum mechanic,female) { ................ - ......LLLL...... + ......JJJJJ..... ...FGGCLCGGF.... - ...GNNGLGNNGL... + ...GNNGLGNNGJ... B.BGANGGGANGL... - B.BFGGCLCGGFL... - BIB..CLLLCCL.... + B.BFGGCLCGGFLJ.. + BIB.JCLLLCCLJJ.. BILN.LLAALLAAAA. - BILNN.LLLLJAAAA. - BIB.NNJJJJNAAA.. + BILNN.LLLLCAAAA. + BIB.NNCCCCNAAA.. BIB.BNNNONNNAA.. .B...NNNONNLAA.. .....NBEBENA.A.. @@ -8903,17 +8903,17 @@ Z = (195, 195, 195) # tile 467 (barrow wight,female) { ................ - ................ - ...LLO.......... - ..DLDLO......... - ..LLLLO......... - ..LJL..P........ - ..OOO.PP...AAAA. - ..POO.PP.AAAAAA. - .LPOO.PP.PAAAA.. - .JJOO.PP.PAAAA.. - .J.O..PL.PPAAA.. - .J.O.PPPPPPAAA.. + .......OOOOO..... + ..OOOOOOO....... + .ODLDLOO.OOO.... + .OLLLLOOOOOOO... + .OLJLLOPOO...... + .OPLLL.POOOAAAA. + ..PPP.PP.AAAAAA. + .LPPPPPP.PAAAA.. + .JJ.PPPP.PAAAA.. + .J...PPL.PPAAA.. + .J...PPPPPPAAA.. .J...PPPPPPPAA.. .J..LLPPPPPPA... .J.....LLAA..... @@ -9328,8 +9328,8 @@ Z = (195, 195, 195) .....GFF........ ....GGFFF....... ....GDFDF....... - .....PFP...AAA.. - ...FGFPFEGAAAA.. + .....GFF...AAA.. + ...FGFFFEGAAAA.. ..GAAGFFFAGAAA.. ....AKNKFAAAA... ....FGAFFAA..... @@ -10087,9 +10087,9 @@ Z = (195, 195, 195) ......ELELA..... ......LLLLA..... ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. ....LAJJKJALAAA. ......JJJKAAAA.. ......JJAJAA.A.. @@ -10125,9 +10125,9 @@ Z = (195, 195, 195) ......GJGJA..... ......LLLLA..... ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. ....LAJJKJALAAA. ......JJJKAAAA.. ......JJAJAA.A.. @@ -10163,9 +10163,9 @@ Z = (195, 195, 195) ......IPIPA..... ......LLLLA..... ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. ....LAJJKJALAAA. ......JJJKAAAA.. ......JJAJAA.A.. @@ -10201,9 +10201,9 @@ Z = (195, 195, 195) .....NJNJA...... .....LLLLA...... .....ALLA....... - ....CLAALC.AAA.. - ...CLLLLLLCAAA.. - ...LACLLCALAAA.. + ....CJAAJC.AAA.. + ...CLJLLJLCAAA.. + ...LAKJJJALAAA.. ...LAJJKJALAAA.. .....JJJKAAAA... .....JJAJAA.A... @@ -10423,7 +10423,7 @@ Z = (195, 195, 195) # tile 547 (elven monarch,female) { ................ - ................ + ......H..H...... ......H..H...... ......HCHH...... ......HHHHA..... @@ -10542,12 +10542,12 @@ Z = (195, 195, 195) ....BPPBPPPPA... ....BAABPAAPA... ....BCLBPCLPA... - ....AKCPPCJAAA.. - ....BKJJJJAPAAAA - ...BPKJAAJAPPAAA - ..BPPKJJJJAPPPAA - ..PPABKJJAPPAPPA - ..PPABPKAPPPAPPA + ....JCLPPCLJAA.. + ....BPLLLLAPAAAA + ...BPPLAALAPPAAA + ..BPPPPLLPPPPPAA + ..PPABPPPPPPAPPA + ..PPABPPPPPPAPPA ..LC.BPPPPPPCLAA ..LL.BPPABPPLLAA .....BPPABPPAAAA @@ -12818,17 +12818,17 @@ Z = (195, 195, 195) { ................ ................ - ......KJ.J...... + ................ ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - ......CJJKAAAA.. + ......KKLJ...... + .....KLELE...... + ....KJLLLL...... + ....JJALLA...... + ...JJLBAAPL.AAA. + ...JLLBBBPLLAAA. + ....LABPPPALAAA. + ....LALLLLALAAA. + .....AOJJOAAAA.. .....KCJAJJA.A.. .....CJJ.JKJ.... ................ From 6499fc4dd97f38f6cf651806d406bf3d41d59a60 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 27 Dec 2020 12:33:03 -0800 Subject: [PATCH 690/708] some code cleanup, mostly Qt map The Qt routine NetHackQtMapViewport::Clear() was broken, but fixing it hasn't changed the glyph display issue. None of the other changes here would be expected to affect that but they are in/among the sections of code under investigation. --- src/display.c | 18 +++-- win/Qt/qt_map.cpp | 195 ++++++++++++++++++++++------------------------ win/Qt/qt_map.h | 9 ++- 3 files changed, 107 insertions(+), 115 deletions(-) diff --git a/src/display.c b/src/display.c index 8a98c8f55..ea7c4080e 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 display.c $NHDT-Date: 1606919261 2020/12/02 14:27:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */ +/* NetHack 3.7 display.c $NHDT-Date: 1609101156 2020/12/27 20:32:36 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1370,15 +1370,16 @@ see_traps() } } -static unsigned no_gm[NUM_GLYPHMOD] = - {MG_BADXY, (unsigned) ' ', (unsigned) NO_COLOR}; +static unsigned no_gm[NUM_GLYPHMOD] = { + MG_BADXY, (unsigned) ' ', (unsigned) NO_COLOR +}; #ifndef UNBUFFERED_GLYPHMOD -#define Glyphmod_at(x,y,glyph) ( \ - ((x) < 0 || (y) < 0 || (x) >= COLNO || (y) >= ROWNO) \ - ? &no_gm[0] : &g.gbuf[(y)][(x)].glyphmod[0]) +#define Glyphmod_at(x, y, glyph) \ + (((x) < 0 || (y) < 0 || (x) >= COLNO || (y) >= ROWNO) ? &no_gm[0] \ + : &g.gbuf[(y)][(x)].glyphmod[0]) #else static unsigned gm[NUM_GLYPHMOD]; -#define Glyphmod_at(x,y,glyph) glyphmod_at(x, y, glyph) +#define Glyphmod_at(x, y, glyph) glyphmod_at(x, y, glyph) #endif /* @@ -2425,7 +2426,8 @@ unsigned mgflags, *glyphmod; } } - glyphmod[GM_TTYCHAR] = ((mgflags & MG_FLAG_RETURNIDX) != 0) ? idx : g.showsyms[idx]; + glyphmod[GM_TTYCHAR] = ((mgflags & MG_FLAG_RETURNIDX) != 0) ? idx + : g.showsyms[idx]; #ifdef TEXTCOLOR /* Turn off color if no color defined, or rogue level w/o PC graphics. */ diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index b3681b155..34a55eb1f 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -110,16 +110,16 @@ static const QPen& nhcolor_to_pen(int c) #endif NetHackQtMapViewport::NetHackQtMapViewport(NetHackQtClickBuffer& click_sink) : - QWidget(NULL), - rogue_font(NULL), - clicksink(click_sink), - change(10) + QWidget(NULL), + rogue_font(NULL), + clicksink(click_sink), + change(10) { pet_annotation = QPixmap(qt_compact_mode ? pet_mark_small_xpm : pet_mark_xpm); pile_annotation = QPixmap(pile_mark_xpm); - Clear(); + Clear(); // initializes glyph[][], glyphttychar, glyphcolor, glyphflags cursor.setX(0); cursor.setY(0); } @@ -129,16 +129,42 @@ NetHackQtMapViewport::~NetHackQtMapViewport(void) delete rogue_font; } +// pick a font to use for text map; rogue level is always displayed as text +void NetHackQtMapViewport::SetRogueFont(QPainter &painter) +{ + QString fontfamily = iflags.wc_font_map ? iflags.wc_font_map + : "Monospace"; + int maybebold = QFont::Normal; + if (fontfamily.right(5).toLower() == "-bold") { + fontfamily.truncate(fontfamily.length() - 5); + maybebold = QFont::Bold; + } + // Find font... + int pts = 5; + while (pts < 32) { + QFont f(fontfamily, pts, maybebold); + painter.setFont(QFont(fontfamily, pts)); + QFontMetrics fm = painter.fontMetrics(); + if (fm.width("M") > qt_settings->glyphs().width()) + break; + if (fm.height() > qt_settings->glyphs().height()) + break; + pts++; + } + rogue_font = new QFont(fontfamily, pts - 1); +} + void NetHackQtMapViewport::paintEvent(QPaintEvent* event) { - QRect area=event->rect(); + NetHackQtGlyphs &glyphs = qt_settings->glyphs(); + int gW = glyphs.width(), + gH = glyphs.height(); + QRect area = event->rect(); QRect garea; - garea.setCoords( - std::max(0,area.left()/qt_settings->glyphs().width()), - std::max(0,area.top()/qt_settings->glyphs().height()), - std::min(COLNO-1,area.right()/qt_settings->glyphs().width()), - std::min(ROWNO-1,area.bottom()/qt_settings->glyphs().height()) - ); + garea.setCoords(std::max(0, area.left() / gW), + std::max(0, area.top() / gH), + std::min(COLNO - 1, area.right() / gW), + std::min(ROWNO - 1, area.bottom() / gH)); QPainter painter; @@ -150,74 +176,42 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) painter.setClipRect( event->rect() ); // (normally we don't clip) painter.fillRect( event->rect(), Qt::black ); - if ( !rogue_font ) { - // Find font... - int pts = 5; - QString fontfamily = iflags.wc_font_map - ? iflags.wc_font_map : "Monospace"; - bool bold = false; - if ( fontfamily.right(5).toLower() == "-bold" ) { - fontfamily.truncate(fontfamily.length()-5); - bold = true; - } - while ( pts < 32 ) { - QFont f(fontfamily, pts, bold ? QFont::Bold : QFont::Normal); - painter.setFont(QFont(fontfamily, pts)); - QFontMetrics fm = painter.fontMetrics(); - if ( fm.width("M") > qt_settings->glyphs().width() ) - break; - if ( fm.height() > qt_settings->glyphs().height() ) - break; - pts++; - } - rogue_font = new QFont(fontfamily,pts-1); - } + if (!rogue_font) + SetRogueFont(painter); painter.setFont(*rogue_font); for (int j=garea.top(); j<=garea.bottom(); j++) { for (int i=garea.left(); i<=garea.right(); i++) { #if 0 - unsigned short g=Glyph(i,j); - int color; - int ch; + unsigned short g = Glyph(i, j); + int colortmp; + int chtmp; unsigned special; -#else - int color = Glyphcolor(i,j); - int ch = Glyphttychar(i,j); - unsigned special = Glyphflags(i,j); -#endif - painter.setPen( Qt::green ); /* map glyph to character and color */ -// mapglyph(g, &ch, &color, &special, i, j, 0); + mapglyph(g, &chtmp, &colortmp, &special, i, j, 0); + uchar ch = (uchar) chtmp, color = (uchar) colortmp; +#else + uchar color = Glyphcolor(i, j); + uchar ch = Glyphttychar(i, j); + unsigned special = Glyphflags(i, j); +#endif ch = cp437(ch); #ifdef TEXTCOLOR painter.setPen( nhcolor_to_pen(color) ); +#else + painter.setPen( Qt::green ); #endif - if (!DrawWalls( - painter, - i*qt_settings->glyphs().width(), - j*qt_settings->glyphs().height(), - qt_settings->glyphs().width(), - qt_settings->glyphs().height(), - ch)) { - painter.drawText( - i*qt_settings->glyphs().width(), - j*qt_settings->glyphs().height(), - qt_settings->glyphs().width(), - qt_settings->glyphs().height(), - Qt::AlignCenter, - QString(QChar(ch)).left(1) - ); + if (!DrawWalls(painter, i * gW, j * gH, gW, gH, ch)) { + painter.drawText(i * gW, j * gH, gW, gH, Qt::AlignCenter, + QString(QChar(ch)).left(1)); } #ifdef TEXTCOLOR if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), - j*qt_settings->glyphs().height()), + painter.drawPixmap(QPoint(i * gW, j * gH), pet_annotation); } else if ((special & MG_OBJPILE) != 0 && ::iflags.hilite_pile) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), - j*qt_settings->glyphs().height()), + painter.drawPixmap(QPoint(i * gW, j * gH), pile_annotation); } #endif @@ -238,19 +232,16 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) unsigned special = Glyphflags(i, j); #endif bool femflag = (special & MG_FEMALE) ? true : false; - qt_settings->glyphs().drawCell(painter, g, i, j, femflag); -#ifdef TEXTCOLOR + glyphs.drawCell(painter, g, i, j, femflag); + if ((special & MG_PET) != 0 && ::iflags.hilite_pet) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), - j*qt_settings->glyphs().height()), + painter.drawPixmap(QPoint(i * gW, j * gH), pet_annotation); } else if ((special & MG_OBJPILE) != 0 && ::iflags.hilite_pile) { - painter.drawPixmap(QPoint(i*qt_settings->glyphs().width(), - j*qt_settings->glyphs().height()), + painter.drawPixmap(QPoint(i * gW, j * gH), pile_annotation); } -#endif } } } @@ -262,31 +253,26 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) #else painter.setPen( Qt::green ); // REALLY primitive #endif - } else - { - int hp100; - if (Upolyd) { - hp100=u.mhmax ? u.mh*100/u.mhmax : 100; - } else { - hp100=u.uhpmax ? u.uhp*100/u.uhpmax : 100; - } + } else { + int hp = !Upolyd ? u.uhp : u.mh, + hpmax = !Upolyd ? u.uhpmax : u.mhmax, + hp100 = hpmax ? (hp * 100 / hpmax) : 100; - if (hp100 > 75) - painter.setPen(Qt::white); - else if (hp100 > 50) - painter.setPen(Qt::yellow); - else if (hp100 > 25) - painter.setPen(QColor(0xff, 0xbf, 0x00)); // orange - else if (hp100 > 10) - painter.setPen(Qt::red); - else + // this uses a different color scheme from hitpoint bar but has + // the same cutoff thresholds (except for lack of separate 100%) + if (hp100 < 10 || hp < 5) painter.setPen(Qt::magenta); + else if (hp100 < 25 || hp < 10 ) + painter.setPen(Qt::red); + else if (hp100 < 50) + painter.setPen(QColor(0xff, 0xbf, 0x00)); // orange + else if (hp100 < 75) + painter.setPen(Qt::yellow); + else + painter.setPen(Qt::white); } - painter.drawRect(cursor.x() * qt_settings->glyphs().width(), - cursor.y() * qt_settings->glyphs().height(), - qt_settings->glyphs().width() - 1, - qt_settings->glyphs().height() - 1); + painter.drawRect(cursor.x() * gW, cursor.y() * gH, gW - 1, gH - 1); } #if 0 @@ -312,8 +298,7 @@ bool NetHackQtMapViewport::DrawWalls( int x, int y, int w, int h, unsigned ch) { - enum - { + enum wallbits { w_left = 0x01, w_right = 0x02, w_up = 0x04, @@ -562,6 +547,7 @@ void NetHackQtMapViewport::clickCursor() qApp->exit(); } +// [re-]init map display to unexplored with no changed cells void NetHackQtMapViewport::Clear() { for (int j = 0; j < ROWNO; ++j) { @@ -572,11 +558,13 @@ void NetHackQtMapViewport::Clear() Glyphttychar(0, j) = ' '; Glyphcolor(0, j) = NO_COLOR; Glyphflags(0, j) = 0; - for (int i = 1; i < COLNO; ++i) + + for (int i = 1; i < COLNO; ++i) { Glyph(i, j) = GLYPH_UNEXPLORED; - Glyphttychar(0, j) = ' '; - Glyphcolor(0, j) = NO_COLOR; - Glyphflags(0, j) = 0; + Glyphttychar(i, j) = ' '; + Glyphcolor(i, j) = NO_COLOR; + Glyphflags(i, j) = 0; + } } change.clear(); @@ -610,13 +598,14 @@ void NetHackQtMapViewport::CursorTo(int x,int y) Changed(cursor.x(),cursor.y()); } -void NetHackQtMapViewport::PrintGlyph(int x,int y,int theglyph,unsigned *glyphmod) +void NetHackQtMapViewport::PrintGlyph(int x, int y, int theglyph, + unsigned *glyphmod) { - Glyph(x,y)=theglyph; - Glyphttychar(x,y)=glyphmod[GM_TTYCHAR]; - Glyphcolor(x,y)=glyphmod[GM_COLOR]; - Glyphflags(x,y)=glyphmod[GM_FLAGS]; - Changed(x,y); + Glyph(x, y) = theglyph; + Glyphttychar(x, y) = (uchar) glyphmod[GM_TTYCHAR]; + Glyphcolor(x, y) = (uchar) glyphmod[GM_COLOR]; + Glyphflags(x, y) = glyphmod[GM_FLAGS]; + Changed(x, y); } void NetHackQtMapViewport::Changed(int x, int y) diff --git a/win/Qt/qt_map.h b/win/Qt/qt_map.h index 6200e0412..0c6937bae 100644 --- a/win/Qt/qt_map.h +++ b/win/Qt/qt_map.h @@ -32,10 +32,10 @@ private: QFont *rogue_font; unsigned short glyph[ROWNO][COLNO]; unsigned short& Glyph(int x, int y) { return glyph[y][x]; } - unsigned int glyphttychar[ROWNO][COLNO]; - unsigned int& Glyphttychar(int x, int y) { return glyphttychar[y][x]; } - unsigned int glyphcolor[ROWNO][COLNO]; - unsigned int& Glyphcolor(int x, int y) { return glyphcolor[y][x]; } + uchar glyphttychar[ROWNO][COLNO]; + uchar& Glyphttychar(int x, int y) { return glyphttychar[y][x]; } + uchar glyphcolor[ROWNO][COLNO]; + uchar& Glyphcolor(int x, int y) { return glyphcolor[y][x]; } unsigned int glyphflags[ROWNO][COLNO]; unsigned int& Glyphflags(int x, int y) { return glyphflags[y][x]; } QPoint cursor; @@ -51,6 +51,7 @@ private: void PrintGlyph(int x,int y,int glyph,unsigned *glyphmod); void Changed(int x, int y); void updateTiles(); + void SetRogueFont(QPainter &painter); // NetHackQtMapWindow2 passes through many calls to the viewport friend class NetHackQtMapWindow2; From 7e20be61dfb8bff7ee05799f5be16d4ad72ca3ab Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 18:00:48 -0500 Subject: [PATCH 691/708] Art Contribution: Differentiating gendered monster tiles PR #430 From the pull request author NullCGT: This pull request is a response to 0c3b964, in which nhmall expressed interest in contributions that would make gendered tiles visually distinguishable from one another. Since I've spent way too many hours editing NetHack's default tileset and the thought of trying to merge this commit into my variant gives me an absurdly massive headache, I thought I would have a go at it! Making tiles of different genders distinct in NetHack presents an interesting problem. While it would be fun to create highly distinct tiles for every gender, doing so would reduce the accessibility of the game, since players would have to remember many more tiles, and might end up confusing one monster for another. Visual clarity is key. Therefore, I had the following goals when creating this pull request: 1. If there is an interesting way to differentiate tiles by gender, do so. 2. Any sort of differentiation should be minor enough that a user can still tell what a monster is at a glance. Essentially, visual clarity comes before differentiation by gender. 3. Try to use a "TDTTOE method" of differentiating tiles. For example, female cats are more colorful than males, because generally male cats have only two colors of fur. Basically, I spent a lot of time on wikipedia researching sex characteristics of different species. 4. Try not to fall into "female = longer hair / eyelashes." While this feature will unfortunately require some gender-essentialist visual shorthand, this tropes is overdone and exhausting. Please let me know what you think; I'm totally open to feedback on all of this and happy to make modifications. I've attached the resulting tiles file to this post in png form. The alterations made in this pull request are as follows: - Female ants are slightly larger than male ants, just like in real life. I could have added wings to the male ants, but I felt that doing so would lead to some confusion. - Female wolves are slightly smaller than male wolves. There wasn't a great way to show this without making winter wolves look very similar to winter wolf cubs, so I just made the female wolves tails slightly shorter. - Calico cats are almost exclusively female, so I turned the female cats into calico cats. The other piece of logic behind this choice was that players will probably really enjoy seeing different variants of their pets. - Female hobbits, minotaurs, humans, werecreatures, and aleaxes wear slightly different clothing. - Dwarfs are not differentiated in any way whatsoever. According to Terry Pratchett (in Unseen Academicals, if I remember correctly) it is almost impossible to tell what gender a dwarf is, even for fellow dwarfs. I strongly believe that NetHack should follow this tradition. - Female leprechauns, archons, frost giants, guards, and all types of gnomes are clean-shaven. Although of course not one hundred percent accurate, it's convenient visual shorthand. - Centaur tiles have no differentiation because the different types of centaurs are already extremely difficult to tell apart from one another. - Female ogre tyrants and elven monarchs have slightly different crowns. - Female quantum mechanics have a different hairstyle and no beard. Genetic engineers look the same, because the genetic engineer tile is perfect. - Female barrow wights look like old grandmothers with flyaway hair. I kept the hair color the same and used a similar quantity of pixels so that they look similar enough to the males that you can tell they are barrow wights. - Female archeologist tile is a reference to a certain archeologist known for raiding tombs. --- doc/fixes37.0 | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 52a6f0ded..90e698172 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -782,6 +782,7 @@ allow rereading spellbooks to refresh memory at any time (github #261) allow themed rooms constrained by level difficulty (github #344) add a varied form of LIBNH nethack library contribution (github #385, #403) add cross-compile to WASM (github #385, #403, #412) +differentiating gendered monster tiles from NullCGT (#430) Code Cleanup and Reorganization From 953f0652c4e8225343ee60be59173458cd1d6530 Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 27 Dec 2020 17:01:33 -0800 Subject: [PATCH 692/708] reformat Qt/qt_clust.cpp --- win/Qt/qt_clust.cpp | 240 ++++++++++++++++++++++---------------------- 1 file changed, 121 insertions(+), 119 deletions(-) diff --git a/win/Qt/qt_clust.cpp b/win/Qt/qt_clust.cpp index b21a53a74..d63d2d7de 100644 --- a/win/Qt/qt_clust.cpp +++ b/win/Qt/qt_clust.cpp @@ -5,163 +5,165 @@ static void include(QRect& r, const QRect& rect) { - if (rect.left()r.right()) { - r.setRight(rect.right()); - } - if (rect.top()r.bottom()) { - r.setBottom(rect.bottom()); - } + if (rect.left() < r.left()) { + r.setLeft(rect.left()); + } + if (rect.right() > r.right()) { + r.setRight(rect.right()); + } + if (rect.top() < r.top()) { + r.setTop(rect.top()); + } + if (rect.bottom() > r.bottom()) { + r.setBottom(rect.bottom()); + } } /* -A Clusterizer groups rectangles (QRects) into non-overlapping rectangles -by a merging heuristic. -*/ + * A Clusterizer groups rectangles (QRects) into non-overlapping + * rectangles by a merging heuristic. + */ Clusterizer::Clusterizer(int maxclusters) : - cluster(new QRect[maxclusters]), - count(0), - max(maxclusters) -{ } + cluster(new QRect[maxclusters]), + count(0), + max(maxclusters) +{ +} Clusterizer::~Clusterizer() { - delete [] cluster; + delete [] cluster; } void Clusterizer::clear() { - count=0; + count = 0; } void Clusterizer::add(int x, int y) { - add(QRect(x,y,1,1)); + add(QRect(x, y, 1, 1)); } void Clusterizer::add(int x, int y, int w, int h) { - add(QRect(x,y,w,h)); + add(QRect(x, y, w, h)); } void Clusterizer::add(const QRect& rect) { - QRect biggerrect(rect.x()-1,rect.y()-1,rect.width()+2,rect.height()+2); + QRect biggerrect(rect.x() - 1, rect.y() - 1, + rect.width() + 2, rect.height() + 2); - //assert(rect.width()>0 && rect.height()>0); + //assert(rect.width() > 0 && rect.height() > 0); - int cursor; + int cursor; - for (cursor=0; cursor=0) { - include(cluster[cheapest],rect); - return; - } + if (cost < lowestcost) { + bool bad = false; + for (int c = 0; c < count && !bad; c++) { + bad = cluster[c].intersects(larger) && c != cursor; + } + if (!bad) { + cheapest = cursor; + lowestcost = cost; + } + } + } + } + if (cheapest >= 0) { + include(cluster[cheapest], rect); + return; + } - if (count < max) { - cluster[count++]=rect; - return; - } + if (count < max) { + cluster[count++] = rect; + return; + } - // Do cheapest of: - // add to closest cluster - // do cheapest cluster merge, add to new cluster + // Do cheapest of: + // add to closest cluster + // do cheapest cluster merge, add to new cluster - lowestcost=9999999; - cheapest=-1; - for (cursor=0; cursor=0) { - include(cluster[cheapestmerge1],cluster[cheapestmerge2]); - cluster[cheapestmerge2]=cluster[count--]; - } else { - // if (!cheapest) debugRectangles(rect); - include(cluster[cheapest],rect); - } + if (cheapestmerge1 >= 0) { + include(cluster[cheapestmerge1], cluster[cheapestmerge2]); + cluster[cheapestmerge2] = cluster[count--]; + } else { + // if (!cheapest) debugRectangles(rect); + include(cluster[cheapest],rect); + } - // NB: clusters do not intersect (or intersection will - // overwrite). This is a result of the above algorithm, - // given the assumption that (x,y) are ordered topleft - // to bottomright. + // NB: clusters do not intersect (or intersection will + // overwrite). This is a result of the above algorithm, + // given the assumption that (x,y) are ordered topleft + // to bottomright. } const QRect& Clusterizer::operator[](int i) { - return cluster[i]; + return cluster[i]; } From 881eccca9ebb1ac258f7629fe0c5c699439814bf Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 21:20:44 -0500 Subject: [PATCH 693/708] some tile processing fix-ups. Some of the new colors added to some monster tiles did not have gray scale mappings. This fixes the processing by mapping them to *something*, but optimal gray scale mappings for the new colors will require follow-up evaluation at some point. --- win/share/m16807 | 14944 ++++++++++++++++++++++++++++++++++ win/share/monsters.txt | 2 +- win/share/monsters.txt.keep | 14944 ++++++++++++++++++++++++++++++++++ win/share/tiletext.c | 4 +- 4 files changed, 29892 insertions(+), 2 deletions(-) create mode 100644 win/share/m16807 create mode 100644 win/share/monsters.txt.keep diff --git a/win/share/m16807 b/win/share/m16807 new file mode 100644 index 000000000..a7e97fa09 --- /dev/null +++ b/win/share/m16807 @@ -0,0 +1,14944 @@ +. = (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) +# tile 0 (giant ant,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......JAJKKA... + .....JAAAKJJJA.. + .....AKJJAJJAA.. + ...KKAJJJAAA.... + ..BJJAAAAAJJA... + ..JBJAJAJAA..... + .....AJA.JA..... + ......JA.JA..... + ................ +} +# tile 1 (giant ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......J......... + ......AJAJKKA... + ....JJAAAKJJJA.. + ....AAKJJAJJAA.. + ...KKAJJJAAA.... + ..BJJAAAAAJJ.... + ..JBJAJAJAAAJ... + .....AJA.JA..... + ......JA.JA..... + ................ +} +# tile 2 (killer bee,male) +{ + ................ + ................ + .PPP.....PP..... + PPPPP...PBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAA.. + ABJBBJJJJAHAHH.. + .JJABJAJ.J.HH... + .......J.J...... + ................ + ...AAAAAAAAAAA.. + .....AAAAAA..... + ................ +} +# tile 3 (killer bee,female) +{ + ................ + ................ + .PPP.....PP..... + PPPPP...PBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAA.. + ABJBBJJJJAHAHH.. + .JJABJAJ.J.HH... + .......J.J...... + ................ + ...AAAAAAAAAAA.. + .....AAAAAA..... + ................ +} +# tile 4 (soldier ant,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......JAJKKA... + .....JAAAKJJJA.. + .....AKJJAJJAA.. + .JJKKAJJJAAA.... + JBJJJAAAAAJJA... + JJJBJAJAJAA..... + JAAJJAJA.JA..... + ..JJAAJA.JA..... + ................ +} +# tile 5 (soldier ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJAJKKA... + ....JJAAAKJJJA.. + ....AAKJJAJJAA.. + .JJKKAJJJAAA.... + JBJJJAAAAAJJ.... + JJJBJAJAJAAAJ... + JAAJJAJA.JA..... + ..JJAAJA.JA..... + ................ +} +# tile 6 (fire ant,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......DACCCA... + .....DAAACDDDA.. + .....ACDDADDAA.. + ...CCADDDAAA.... + ..GDDAAAAADDA... + ..DGDADADAA..... + .....ADA.DA..... + ......DA.DA..... + ................ +} +# tile 7 (fire ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......D......... + ......ADACCCA... + ....DDAAACDDDA.. + ....AACDDADDAA.. + ...CCADDDAAA.... + ..GDDAAAAADD.... + ..DGDADADAAAD... + .....ADA.DA..... + ......DA.DA..... + ................ +} +# tile 8 (giant beetle,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......KKDKK..... + ....KACLCJJD.... + ...KCLCJJDDDK... + ...DCCJDADDAD... + ...ADJDDDDDDD... + ...BAKDDAADKAA.. + ...ABAKDDK...... + ......AA.AA..... + ................ + ................ +} +# tile 9 (giant beetle,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......KKDKK..... + ....KACLCJJD.... + ...KCLCJJDDDK... + ...DCCJDADDAD... + ...ADJDDDDDDD... + ...BAKDDAADKAA.. + ...ABAKDDK...... + ......AA.AA..... + ................ + ................ +} +# tile 10 (queen bee,male) +{ + ................ + .PPP.....PP..... + PPPPP...PPPP.... + PPPPP..PPBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAAH. + ABJBBJJJJAHAHHH. + .JJABJAJ.JHHHAA. + ...J...J.JAAAHH. + ..JJ..JJ.J.HHAH. + ..JAAAJAAJ..HH.. + .....AAAAAA..... + ................ +} +# tile 11 (queen bee,female) +{ + ................ + .PPP.....PP..... + PPPPP...PPPP.... + PPPPP..PPBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAAH. + ABJBBJJJJAHAHHH. + .JJABJAJ.JHHHAA. + ...J...J.JAAAHH. + ..JJ..JJ.J.HHAH. + ..JAAAJAAJ..HH.. + .....AAAAAA..... + ................ +} +# tile 12 (acid blob,male) +{ + ................ + ................ + ................ + .....KDDA....... + ...DDKDDKA...... + .DDDIIIDJDA..... + D.IIOOIIDAIA.... + .DKNNNODIDA..IA. + IDJNANOJDDJA.... + ADIDNOIDIDDDA... + ...JDIKIADKIA... + .IA.IDID.JDA.... + ...I.DDA....DA.. + .........IA..... + ..IA............ + ................ +} +# tile 13 (acid blob,female) +{ + ................ + ................ + ................ + .....KDDA....... + ...DDKDDKA...... + .DDDIIIDJDA..... + D.IIOOIIDAIA.... + .DKNNNODIDA..IA. + IDJNANOJDDJA.... + ADIDNOIDIDDDA... + ...JDIKIADKIA... + .IA.IDID.JDA.... + ...I.DDA....DA.. + .........IA..... + ..IA............ + ................ +} +# tile 14 (quivering blob,male) +{ + ................ + ................ + .....PPPP....... + .........P...... + .P.OOOPPE..AAA.. + P.OPBBBPOEAEAA.. + P.PBNNNP.OEAAEA. + P.PNNNNNPOEEAEA. + POPNAANNEO.OAEA. + .OPNAANNE..OAAA. + .OPBNNNEPP.OEAA. + BPOPEEEBBPO.EEA. + BBBPBBBBBBPPPPA. + ..BBBBBBBBBBPA.. + ................ + ................ +} +# tile 15 (quivering blob,female) +{ + ................ + ................ + .....PPPP....... + .........P...... + .P.OOOPPE..AAA.. + P.OPBBBPOEAEAA.. + P.PBNNNP.OEAAEA. + P.PNNNNNPOEEAEA. + POPNAANNEO.OAEA. + .OPNAANNE..OAAA. + .OPBNNNEPP.OEAA. + BPOPEEEBBPO.EEA. + BBBPBBBBBBPPPPA. + ..BBBBBBBBBBPA.. + ................ + ................ +} +# tile 16 (gelatinous cube,male) +{ + ................ + ................ + ................ + ................ + ................ + .......LLL...... + .....LLLLLLLL... + ...LLLLLLLLLD... + ...CLLLLLLLDDA.. + ...CGGCLLLDDDAA. + ...CAGCGGDDDDAAA + ...CCCCAGDDDAAAA + .....CCCCDDAAAA. + .......CCDAAA... + ................ + ................ +} +# tile 17 (gelatinous cube,female) +{ + ................ + ................ + ................ + ................ + ................ + .......LLL...... + .....LLLLLLLL... + ...LLLLLLLLLD... + ...CLLLLLLLDDA.. + ...CGGCLLLDDDAA. + ...CAGCGGDDDDAAA + ...CCCCAGDDDAAAA + .....CCCCDDAAAA. + .......CCDAAA... + ................ + ................ +} +# tile 18 (chickatrice,male) +{ + ................ + ................ + ................ + ................ + .......OO....... + ......HAOO...... + .....HHOOH.HHA.. + ........OOHOA... + ........OOFA.... + ........FGGFA... + ........AGFGAA.. + ...........GA... + .......F..FFA... + .......AFFAA.... + ........AA...... + ................ +} +# tile 19 (chickatrice,female) +{ + ................ + ................ + ................ + ................ + .......OO....... + ......HAOO...... + .....HHOOH.HHA.. + ........OOHOA... + ........OOFA.... + ........FGGFA... + ........AGFGAA.. + ...........GA... + .......F..FFA... + .......AFFAA.... + ........AA...... + ................ +} +# tile 20 (cockatrice,male) +{ + ................ + ...D.DD......... + ....DD.......... + ....NL..AA...... + ..HHAN.AAA...... + .HH.NO..AAAA.... + ...AOOLFFFAA.... + ...OOLKGGFFAA... + ...AOAGGFGFFAA.. + .......GFFGFAA.. + .........FGGAA.. + .....FA...FFA... + ....FA....FFA... + ....FA..FFFA.... + .....FFFFA...... + ................ +} +# tile 21 (cockatrice,female) +{ + ................ + ...D.DD......... + ....DD.......... + ....NL..AA...... + ..HHAN.AAA...... + .HH.NO..AAAA.... + ...AOOLFFFAA.... + ...OOLKGGFFAA... + ...AOAGGFGFFAA.. + .......GFFGFAA.. + .........FGGAA.. + .....FA...FFA... + ....FA....FFA... + ....FA..FFFA.... + .....FFFFA...... + ................ +} +# tile 22 (pyrolisk,male) +{ + ................ + ...D.DD......... + ....DD.......... + ....NB..AA...... + ..HHAN.AAA...... + .HH.NB..AAAA.... + ...APBBJJJAA.... + ...PPPKDDKJAA... + ...APADDKDKJAA.. + .......DJKDJAA.. + .........JDDAA.. + .....JA...JJA... + ....JA....JJA... + ....KA..KKKA.... + .....JKKKA...... + ................ +} +# tile 23 (pyrolisk,female) +{ + ................ + ...D.DD......... + ....DD.......... + ....NB..AA...... + ..HHAN.AAA...... + .HH.NB..AAAA.... + ...APBBJJJAA.... + ...PPPKDDKJAA... + ...APADDKDKJAA.. + .......DJKDJAA.. + .........JDDAA.. + .....JA...JJA... + ....JA....JJA... + ....KA..KKKA.... + .....JKKKA...... + ................ +} +# tile 24 (jackal,male) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOAOOOOOOOAA.. + ..AAOOOOOOOOAA.. + ....OJOOOOOLAA.. + ....OJOLKALKAA.. + ...OOAOAAAOAA... + .....OO..OOA.... + ................ +} +# tile 25 (jackal,female) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOAOOOOOOOAA.. + ..AAOOOOOOOOAA.. + ....OJOOOOOLAA.. + ....OJOLKALKAA.. + ...OOAOAAAOAA... + .....OO..OOA.... + ................ +} +# tile 26 (fox,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....C........... + ....C........... + ..CCAC...CCC.... + ..ACCCCCCACCC... + ...AACCCC.ACC... + ....ACAAC..AA... + ...AC.ACA....... + ................ +} +# tile 27 (fox,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....C........... + ....C........... + ..CCAC...CCC.... + ..ACCCCCCACCC... + ...AACCCC.ACC... + ....ACAAC..AA... + ...AC.ACA....... + ................ +} +# tile 28 (coyote,male) +{ + ................ + ................ + ................ + ...K..K......... + ...K.KK......KKK + ..KKKK......KKKA + ..NCNK.KKKKKAAA. + .KCCKKKKKKKKK... + KKCKAKKKKKKKK... + DKKKAKAKKKKAK... + ..AAKAAKAAAAK... + ....AKAKAAAAK... + ...AKKAKA.AKK... + .....AKK........ + ................ + ................ +} +# tile 29 (coyote,female) +{ + ................ + ................ + ................ + ...K..K......... + ...K.KK......KKK + ..KKKK......KKKA + ..NCNK.KKKKKAAA. + .KCCKKKKKKKKK... + KKCKAKKKKKKKK... + DKKKAKAKKKKAK... + ..AAKAAKAAAAK... + ....AKAKAAAAK... + ...AKKAKA.AKK... + .....AKK........ + ................ + ................ +} +# tile 30 (werejackal,male) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOALLOOOOOAA.. + ..AALLLLOOOOAA.. + ....LJLLLOOLAA.. + ....LJLLKALKAA.. + ..LLLALAAAOAA... + ...L.LL..OOA.... + ......L......... +} +# tile 31 (werejackal,female) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOALLOOOOOAA.. + ..AALLLLOOOOAA.. + ....LJLLLOOLAA.. + ....LJLLKALKAA.. + ..LLLALAAAOAA... + ...L.LL..OOA.... + ......L......... +} +# tile 32 (little dog,male) +{ + ................ + ................ + ................ + ................ + ...J..J......... + ...J.JJ...K..... + ..JJJJ.....K.... + ..NJNKK....K.A.. + .JJJCKK....K.A.. + .PJJAKCKKCKKAA.. + .DDAACKKCKKKAA.. + ....KJKJCJKJAA.. + ....KJKJJAJJAA.. + ...KKAKAAAKAA... + .....KK...KA.... + ................ +} +# tile 33 (little dog,female) +{ + ................ + ................ + ................ + ................ + ...J..J......... + ...J.JJ...K..... + ..JJJJ.....K.... + ..NJNKK....K.A.. + .JJJCKK....K.A.. + .PJJAKCKKCKKAA.. + .DDAACKKCKKKAA.. + ....KJKJCJKJAA.. + ....KJKJJAJJAA.. + ...KKAKAAAKAA... + .....KK...KA.... + ................ +} +# tile 34 (dingo,male) +{ + ................ + ................ + ................ + .............C.. + ...C..C.......C. + ...C.CC.......CA + ..CCCCK.......CA + ..ACACCKCCCCCCAA + ..LLCCCKCCCLCCCA + .KCCACKCLLLLACCA + ..AACAACLLAAACCA + ....ACACAAAAAACA + ....CCACAAA..CCA + .....ACCA....... + ................ + ................ +} +# tile 35 (dingo,female) +{ + ................ + ................ + ................ + .............C.. + ...C..C.......C. + ...C.CC.......CA + ..CCCCK.......CA + ..ACACCKCCCCCCAA + ..LLCCCKCCCLCCCA + .KCCACKCLLLLACCA + ..AACAACLLAAACCA + ....ACACAAAAAACA + ....CCACAAA..CCA + .....ACCA....... + ................ + ................ +} +# tile 36 (dog,male) +{ + ................ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKK......K.A + .JJJCKKKK....K.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ....KJKKJJJAJJAA + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 37 (dog,female) +{ + ................ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKK......K.A + .JJJCKKKK....K.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ....KJKKJJJAJJAA + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 38 (large dog,male) +{ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKKK.....K.A + .JJJCKKKKK..JK.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ...JKJKKJJJAJJAA + ....KAKJAAAAKJA. + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 39 (large dog,female) +{ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKKK.....K.A + .JJJCKKKKK..JK.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ...JKJKKJJJAJJAA + ....KAKJAAAAKJA. + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 40 (wolf,male) +{ + ................ + ................ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPAPPPPPPPPPAA + ..AAP.PP..P.P.AA + ....P.PP...A.PAA + ....PAP.AAAAP.A. + ...PPAPAAAAAPAA. + .....PPAA..PPA.. + ................ +} +# tile 41 (wolf,female) +{ + ................ + ................ + ................ + ...P..P......... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPAPPPPPPPPPAA + ..AAP.PP..P.P.AA + ....P.PP...A.PAA + ....PAP.AAAAP.A. + ...PPAPAAAAAPAA. + .....PPAA..PPA.. + ................ +} +# tile 42 (werewolf,male) +{ + ................ + ................ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPALPPPPPPPPAA + ..AALLPL..P.P.AA + ....L.LL...A.PAA + ....LAL.AAAAP.A. + ..LLLALAAAAAPPA. + ...L.LLAA..PP... + .....LL......... +} +# tile 43 (werewolf,female) +{ + ................ + ................ + ................ + ...P..P......... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPALPPPPPPPPAA + ..AALLPL..P.P.AA + ....L.LL...A.PAA + ....LAL.AAAAP.A. + ..LLLALAAAAAPPA. + ...L.LLAA..PP... + .....LL......... +} +# tile 44 (winter wolf cub,male) +{ + ................ + ................ + ................ + ................ + ...N..N......... + ...N.NB...N..... + ..NNNN.....N.... + ..DNDNB....N.A.. + ..NNNNB....N.A.. + .NNNNNNNNNNNAA.. + .DNBBNNNNNNBAA.. + ....NNNNNNNBAA.. + ....NNNBBANBAA.. + ...NBANAAANAA... + .....NB..NBA.... + ................ +} +# tile 45 (winter wolf cub,female) +{ + ................ + ................ + ................ + ................ + ...N..N......... + ...N.NB......... + ..NNNN.....N.... + ..DNDNB....N.A.. + ..NNNNB....N.A.. + .NNNNNNNNNNNAA.. + .DNBBNNNNNNBAA.. + ....NNNNNNNBAA.. + ....NNNBBANBAA.. + ...NBANAAANAA... + .....NB..NBA.... + ................ +} +# tile 46 (warg,male) +{ + ................ + ...P..P....PP... + ...P.PP......P.. + ..PPPP.......P.A + ..N.NPP......P.A + .P..PPPPP....P.A + PPPPDPPPPPPPPPAA + DPPNDPPPPPPPPPAA + ..DDDPPPPPPPPPAA + PNDNP.PPPPPPPPAA + .PPPPAPPPPAPP.A. + ...PAAPPAAAAPPAA + ...PAAP.AAAAP.A. + .PPPAAPAAAAAPAA. + ....PPPAA.PPPA.. + ................ +} +# tile 47 (warg,female) +{ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.A + ..N.NPP......P.A + .P..PPPPP....P.A + PPPPDPPPPPPPPPAA + DPPNDPPPPPPPPPAA + ..DDDPPPPPPPPPAA + PNDNP.PPPPPPPPAA + .PPPPAPPPPAPP.A. + ...PAAPPAAAAPPAA + ...PAAP.AAAAP.A. + .PPPAAPAAAAAPAA. + ....PPPAA.PPPA.. + ................ +} +# tile 48 (winter wolf,male) +{ + ................ + ................ + ................ + ...N..N.....N... + ...N.NN......N.. + ..NNNN.......N.. + ..DODNN......N.A + .NOONNNNN....N.A + NNONANNNNNNNNNAA + DNNBANNNNNNNNNAA + ..AANNNNNNNBNNAA + ....NBNNNBBANNAA + ....NANBAAAANBA. + ...NNANAAAAANAA. + .....NNAA..NNA.. + ................ +} +# tile 49 (winter wolf,female) +{ + ................ + ................ + ................ + ...N..N......... + ...N.NN......N.. + ..NNNN.......N.. + ..DODNN......N.A + .NOONNNNN....N.A + NNONANNNNNNNNNAA + DNNBANNNNNNNNNAA + ..AANNNNNNNBNNAA + ....NBNNNBBANNAA + ....NANBAAAANBA. + ...NNANAAAAANAA. + .....NNAA..NNA.. + ................ +} +# tile 50 (hell hound pup,male) +{ + ................ + ................ + ................ + ................ + ...C..C......... + ...C.CC...C..... + ..CCCC.....C.... + ..DCDCC....C.A.. + .CCCCCC....C.A.. + .PCCACCCCCCCAA.. + .CHAACCCCCCCAA.. + CHC.CCCCCCCCAA.. + .D..CCCCCACCAA.. + ...CCACAAACAA... + .....CC...CA.... + ................ +} +# tile 51 (hell hound pup,female) +{ + ................ + ................ + ................ + ................ + ...C..C......... + ...C.CC...C..... + ..CCCC.....C.... + ..DCDCC....C.A.. + .CCCCCC....C.A.. + .PCCACCCCCCCAA.. + .CHAACCCCCCCAA.. + CHC.CCCCCCCCAA.. + .D..CCCCCACCAA.. + ...CCACAAACAA... + .....CC...CA.... + ................ +} +# tile 52 (hell hound,male) +{ + ................ + ...C..C....CC... + ...C.CC......C.. + ..CCCC.......C.A + ..DJDCC......C.A + .CCCCCCCC....C.A + CCCCDCCCCCCCCCAA + .CHC.CCCCCCCCCAA + CHC..CCCCCCCCCAA + .D..CCCCCCCCCCAA + ...CCACCCCACC.A. + ...CAACCAAAACCAA + ...CAAC.AAAAC.A. + .CCCAACAAAAACAA. + ....CCCAA.CCCA.. + ................ +} +# tile 53 (hell hound,female) +{ + ................ + ...C..C....CC... + ...C.CC......C.. + ..CCCC.......C.A + ..DJDCC......C.A + .CCCCCCCC....C.A + CCCCDCCCCCCCCCAA + .CHC.CCCCCCCCCAA + CHC..CCCCCCCCCAA + .D..CCCCCCCCCCAA + ...CCACCCCACC.A. + ...CAACCAAAACCAA + ...CAAC.AAAAC.A. + .CCCAACAAAAACAA. + ....CCCAA.CCCA.. + ................ +} +# tile 54 (Cerberus,male) +{ + ................ + ..J..J.......... + ..JJJJ.J..J..... + .NJNJ..J.JJ..... + JJJJKAJJJJ....J. + PJJJJANJNKK...J. + DJKJAJJJKJJK..J. + ..AAJPJKAJKJKJJ. + ..JJJDDAJKJJJJJA + ..JJJAAJJJJJJJJA + .JKKKJJJKJJKJJAA + .JJAAKJJKJJJKJAA + JJAAAAJJAAAAJJA. + JAAAAAJAAAAAJAA. + .....JJAA...JA.. + ................ +} +# tile 55 (Cerberus,female) +{ + ................ + ..J..J.......... + ..JJJJ.J..J..... + .NJNJ..J.JJ..... + JJJJKAJJJJ....J. + PJJJJANJNKK...J. + DJKJAJJJKJJK..J. + ..AAJPJKAJKJKJJ. + ..JJJDDAJKJJJJJA + ..JJJAAJJJJJJJJA + .JKKKJJJKJJKJJAA + .JJAAKJJKJJJKJAA + JJAAAAJJAAAAJJA. + JAAAAAJAAAAAJAA. + .....JJAA...JA.. + ................ +} +# tile 56 (gas spore,male) +{ + ................ + ................ + ................ + .....PFGGFP..... + ....PGFFFFFP.... + ...PFFFFFGGFP... + ...FFGGFFGGFF... + ...GFGGFFFFFG... + ...GFFFFFFFFG... + ...FFFFGGFFFF... + ...PGGFGGFGGP... + ....PGFFFFGP.... + .....PFGGFP..... + ................ + ................ + ................ +} +# tile 57 (gas spore,female) +{ + ................ + ................ + ................ + .....PFGGFP..... + ....PGFFFFFP.... + ...PFFFFFGGFP... + ...FFGGFFGGFF... + ...GFGGFFFFFG... + ...GFFFFFFFFG... + ...FFFFGGFFFF... + ...PGGFGGFGGP... + ....PGFFFFGP.... + .....PFGGFP..... + ................ + ................ + ................ +} +# tile 58 (floating eye,male) +{ + ................ + ................ + ......ONNNO..... + ....PNNNNNNNP... + ....NNNNNNNNN... + ...ONNBBBBNNNO.. + ...NNBBEEBBNNN.. + ...NNBEAAEBNNN.. + ...ONBEAAEBNNO.. + ....NBBEEBBNN... + ....PNBBBBNNPAA. + ......ONNNOAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 59 (floating eye,female) +{ + ................ + ................ + ......ONNNO..... + ....PNNNNNNNP... + ....NNNNNNNNN... + ...ONNBBBBNNNO.. + ...NNBBEEBBNNN.. + ...NNBEAAEBNNN.. + ...ONBEAAEBNNO.. + ....NBBEEBBNN... + ....PNBBBBNNPAA. + ......ONNNOAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 60 (freezing sphere,male) +{ + ................ + ................ + ......PBBBP..... + ....PBBBBBBBP... + ....BBBBBBBBB... + ...PBPPPBBBBBP.. + ...BBNNBBPPPBB.. + ...BBANPBNNBBB.. + ...PBBPPBANPBP.. + ....BBBBBBPPB... + ....PBBBBBBBPAA. + ......PBBBPAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 61 (freezing sphere,female) +{ + ................ + ................ + ......PBBBP..... + ....PBBBBBBBP... + ....BBBBBBBBB... + ...PBPPPBBBBBP.. + ...BBNNBBPPPBB.. + ...BBANPBNNBBB.. + ...PBBPPBANPBP.. + ....BBBBBBPPB... + ....PBBBBBBBPAA. + ......PBBBPAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 62 (flaming sphere,male) +{ + ................ + ....C...H....... + ....C....O...C.. + ...C..H.CC...C.. + ...C..C.CC..CC.. + ...DCA.DDC.ACC.. + .AHCDCADDCAADC.. + .AACDCDDDDDADD.. + ..ACDDDJJJDDDD.. + ..ADDCAKDDACDD.. + ...ADAKDDCDAD... + ...ADADHCHCAD... + ....DADDDCDAD... + .....DADDDAD.... + ......JJJJJ..... + ................ +} +# tile 63 (flaming sphere,female) +{ + ................ + ....C...H....... + ....C....O...C.. + ...C..H.CC...C.. + ...C..C.CC..CC.. + ...DCA.DDC.ACC.. + .AHCDCADDCAADC.. + .AACDCDDDDDADD.. + ..ACDDDJJJDDDD.. + ..ADDCAKDDACDD.. + ...ADAKDDCDAD... + ...ADADHCHCAD... + ....DADDDCDAD... + .....DADDDAD.... + ......JJJJJ..... + ................ +} +# tile 64 (shocking sphere,male) +{ + ................ + .....PPPPPP..... + ...PPIAAADAPP... + ..PAAAIAAADDAP.. + ..PHAAAPBOAAAP.. + .PAHHAPBBBOAAAP. + .PHAAAPBBBBAHHP. + .PAAAAPPBBBAAAP. + .PAAAIAPPPAAAIP. + .PIIIAAAAAAIIAP. + ..PIAANAAPAAAIP. + ..PIAANAAAPAAP.. + ...PANANAPAPAP.. + ....PPAIAPAPP... + ......PPPPP..... + ................ +} +# tile 65 (shocking sphere,female) +{ + ................ + .....PPPPPP..... + ...PPIAAADAPP... + ..PAAAIAAADDAP.. + ..PHAAAPBOAAAP.. + .PAHHAPBBBOAAAP. + .PHAAAPBBBBAHHP. + .PAAAAPPBBBAAAP. + .PAAAIAPPPAAAIP. + .PIIIAAAAAAIIAP. + ..PIAANAAPAAAIP. + ..PIAANAAAPAAP.. + ...PANANAPAPAP.. + ....PPAIAPAPP... + ......PPPPP..... + ................ +} +# tile 66 (beholder,male) +{ + ....OA..OA...... + ..OA.DADA.OA.OA. + ...DA.DADADADD.. + ..OADDOOOODDADO. + ...DDHOAAOHDDA.. + ...JDHOAAOHDDJ.. + ...DDDOOOODDDD.. + ...DDDDDDDDDDD.. + ...JDAOAAAOADJ.. + ....DDAAOAADD... + ....PDDDDDDDPAA. + ......JDDDJAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 67 (beholder,female) +{ + ....OA..OA...... + ..OA.DADA.OA.OA. + ...DA.DADADADD.. + ..OADDOOOODDADO. + ...DDHOAAOHDDA.. + ...JDHOAAOHDDJ.. + ...DDDOOOODDDD.. + ...DDDDDDDDDDD.. + ...JDAOAAAOADJ.. + ....DDAAOAADD... + ....PDDDDDDDPAA. + ......JDDDJAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 68 (kitten,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ...........K.... + ............C... + ....C.C.....L.A. + ...CCCCJ....C.A. + ...NCNCJCCLCL.A. + ...CCCCJCCLCCAA. + ....IACCLLCCCAA. + .....CACCJCCJA.. + ......CCA..CA... + ................ +} +# tile 69 (kitten,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ...........N.... + ............N... + ....N.N.....C.A. + ...NNNNC....C.A. + ...ENENNNJJNC.A. + ...NNNNNJJJNNAA. + ....IANNJJNNNAA. + .....NANNWNNWA.. + ......NNA..NA... + ................ +} +# tile 70 (housecat,male) +{ + ................ + ................ + ................ + ................ + ................ + ...........K.... + ............C... + ...C.C......L.A. + ..CCCCJ.....C.A. + .CNCNCJCLCLCL.A. + .CCCCCJCLCLCCAA. + ..CICJCCLCLCLAA. + ...AACCLCLCCCAA. + ...CCACCJJCCJA.. + .....CCA...CA... + ................ +} +# tile 71 (housecat,female) +{ + ................ + ................ + ................ + ................ + ................ + ...........N.... + ............N... + ...N.N......C.A. + ..NNNNC.....C.A. + .NANANCNJJJNN.A. + .NNNNNNNJJNNNAA. + ..NINWNJJJNNNAA. + ...AANNNNNNNNAA. + ...NNANNWWNNWA.. + .....NNA...NA... + ................ +} +# tile 72 (jaguar,male) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + ..CC.CJ......C.A + .CCCCCJ......C.A + .GCGCCJCAACCJC.A + .CCCCCJCCCCCCCAA + .CDDDJCAACCAJCAA + ..CCACCAJCCAACAA + ....CACCJJJCCJA. + ....CACAAAAACJA. + ...CKACAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 73 (jaguar,female) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + ..CC.CJ......C.A + .CCCCCJ......C.A + .GCGCCJCAACCJC.A + .CCCCCJCCCCCCCAA + .CDDDJCAACCAJCAA + ..CCACCAJCCAACAA + ....CACCJJJCCJA. + ....CACAAAAACJA. + ...CKACAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 74 (lynx,male) +{ + ................ + ................ + ................ + ................ + O....O.......... + AC.CCA.......... + .CCCA........CA. + .GCGCOAKKKKK.LA. + .CKCCAJCCCCCKA.. + LLDDLLACLLLCCAA. + ..CC.AACLLLCCAA. + .......CAAAACAA. + ....CACAAAACCA.. + ................ + ................ + ................ +} +# tile 75 (lynx,female) +{ + ................ + ................ + ................ + ................ + O....O.......... + AC.CCA.......... + .CCCA........CA. + .GCGCOAKKKKK.LA. + .CKCCAJCCCCCKA.. + LLDDLLACLLLCCAA. + ..CC.AACLLLCCAA. + .......CAAAACAA. + ....CACAAAACCA.. + ................ + ................ + ................ +} +# tile 76 (panther,male) +{ + ................ + ................ + ............AA.. + ..............A. + ..............A. + .A...A........A. + .EA.AE........A. + .AAAAAEAAAAAAA.. + .AAAAAEAAAAAAA.. + .HAHAA.AAAAAAAA. + .AAAA.AAAAAEAAA. + .AAA..AAAAAEAAA. + .....AA....AAA.. + ..AAAA..AAAA.... + ................ + ................ +} +# tile 77 (panther,female) +{ + ................ + ................ + ............AA.. + ..............A. + ..............A. + .A...A........A. + .EA.AE........A. + .AAAAAEAAAAAAA.. + .AAAAAEAAAAAAA.. + .HAHAA.AAAAAAAA. + .AAAA.AAAAAEAAA. + .AAA..AAAAAEAAA. + .....AA....AAA.. + ..AAAA..AAAA.... + ................ + ................ +} +# tile 78 (large cat,male) +{ + ................ + ................ + ................ + ................ + ............K... + .............C.. + ...C.C.......L.A + ..CCCCJ......C.A + .CNCNCJCLCCLCL.A + .CCCCCJCLCCLCCAA + ..CDCJCCLCCLCLAA + ...AACCLCCLCCCAA + ....CACCJJJCCJA. + ...CKALAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 79 (large cat,female) +{ + ................ + ................ + ................ + ................ + ............N... + .............N.. + ...N.N.......C.A + ..NNNNC......C.A + .NANANCNJJJJNN.A + .NNNNNNNJJJNNNAA + ..NDNWNJJJNNNNAA + ...AANNNNNNNNNAA + ....NANNWWWNNWA. + ...NJANAAAAANAA. + .....NNAA...NA.. + ................ +} +# tile 80 (tiger,male) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + .CCJCC.......C.A + .CAACCJ......A.A + .GAGCCJACACAJC.A + .CCCCCACACACACAA + .ODOCACCACACACAA + .OCOACCJACACACAA + ....CACJAJAJCAA. + ....AACAAAAAAJA. + ...CKACAAAAACAA. + .....CCAA..CCA.. + ................ +} +# tile 81 (tiger,female) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + .CCJCC.......C.A + .CAACCJ......A.A + .GAGCCJACACAJC.A + .CCCCCACACACACAA + .ODOCACCACACACAA + .OCOACCJACACACAA + ....CACJAJAJCAA. + ....AACAAAAAAJA. + ...CKACAAAAACAA. + .....CCAA..CCA.. + ................ +} +# tile 82 (displacer beast,male) +{ + ................ + ........E....... + .......E.E..AA.. + DEEEA..A.E....A. + ....EA.E.D....A. + .A...A.E......A. + .EA.AEAAA.....A. + .AAAAAAAAAA..A.. + .AAAAEAAAAAAAA.. + .HAHAEAAAAAAAAA. + .AAAAEAAAAAAAAA. + .AAA.AAAAAAAAAA. + .....AE.AEEA.EA. + ....AE.AE.EA.EA. + ...AE.AE.EA.EA.. + ................ +} +# tile 83 (displacer beast,female) +{ + ................ + ........E....... + .......E.E..AA.. + DEEEA..A.E....A. + ....EA.E.D....A. + .A...A.E......A. + .EA.AEAAA.....A. + .AAAAAAAAAA..A.. + .AAAAEAAAAAAAA.. + .HAHAEAAAAAAAAA. + .AAAAEAAAAAAAAA. + .AAA.AAAAAAAAAA. + .....AE.AEEA.EA. + ....AE.AE.EA.EA. + ...AE.AE.EA.EA.. + ................ +} +# tile 84 (gremlin,male) +{ + ................ + ................ + ................ + GGGA....AGGG.... + .GGGFAAAGGG..... + ..FFFFFFFF...... + ...NDFFDNA...... + ...GNFFNGA...... + ...GFFFFGA..AA.. + ...AGFFFAFAAAAA. + ..GFAGFAFFFAAAA. + .GFGFAAFFAFAAAA. + .GF.GFAGAAFAAAA. + ....FFAGFAA.AA.. + ...GFA.FGA...... + ................ +} +# tile 85 (gremlin,female) +{ + ................ + ................ + ................ + GGGA....AGGG.... + .GGGFAAAGGG..... + ..FFFFFFFF...... + ...NDFFDNA...... + ...GNFFNGA...... + ...GFFFFGA..AA.. + ...AGFFFAFAAAAA. + ..GFAGFAFFFAAAA. + .GFGFAAFFAFAAAA. + .GF.GFAGAAFAAAA. + ....FFAGFAA.AA.. + ...GFA.FGA...... + ................ +} +# tile 86 (gargoyle,male) +{ + ................ + ................ + ...PAPPPPAP..... + ..PA......AP.... + ..P.DD..DDAP.... + ....PD..DPA..... + ....P....PA..AA. + ....AP...A.AAAAA + ...P.AP.A...AAAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 87 (gargoyle,female) +{ + ................ + ................ + ...PAPPPPAP..... + ..PA......AP.... + ..P.DD..DDAP.... + ....PD..DPA..... + ....P....PA..AA. + ....AP...A.AAAAA + ...P.AP.A...AAAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 88 (winged gargoyle,male) +{ + ...K......K..... + ...KJ....KJ..... + ..KJAPPPPAJJ.... + ..KJ......AJ.... + ..KJDD..DDAJ.... + .KJAPD..DPAJJ... + .KJAP....PAAJAA. + KJA.AP...A.AJJAA + J..P.AP.A...AJAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 89 (winged gargoyle,female) +{ + ...K......K..... + ...KJ....KJ..... + ..KJAPPPPAJJ.... + ..KJ......AJ.... + ..KJDD..DDAJ.... + .KJAPD..DPAJJ... + .KJAP....PAAJAA. + KJA.AP...A.AJJAA + J..P.AP.A...AJAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 90 (hobbit,male) +{ + ................ + ................ + ................ + ................ + ......JJA....... + .....JJJJA...... + ....JLFLFJ...... + ....JLLLLJ...... + ....JKLLKJJ.AA.. + ...CLLLLLLCAAA.. + ..CLALLLLALCA... + ..LLAJJKJALLA... + ...L.LKJLALAA... + .....LLALLA.A... + ....LLL.LLL..... + ................ +} +# tile 91 (hobbit,female) +{ + ................ + ................ + ................ + ................ + ......JJA....... + .....JJJJA...... + ....JLFLFJ...... + ....JLLLLJ...... + ....JKLLKJJ.AA.. + ...CLLLLLLCAAA.. + ..CLALJKJALCA... + ..LLAJJKJALLA... + ...L.LKJLALAA... + .....LLALLA.A... + ....LLL.LLL..... + ................ +} +# tile 92 (dwarf,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BLLLE....... + .....OLO...AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 93 (dwarf,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BLLLE....... + .....OLO...AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 94 (bugbear,male) +{ + ................ + ................ + ......K......... + .K..KKK......... + .KKKKKK......... + KADKADKKK....... + KKKKKKKJKK...... + KAPAPAKJJKJ..... + KAAAAAKKJKJJ.... + .KKKKKJKAKKJ.... + ..KAJJCAKKKJ.AA. + ..KK.KKKKKJJAA.. + ...C..KJAKJAA... + .....CCAAKJA.... + ........CCA..... + ................ +} +# tile 95 (bugbear,female) +{ + ................ + ................ + ......K......... + .K..KKK......... + .KKKKKK......... + KADKADKKK....... + KKKKKKKJKK...... + KAPAPAKJJKJ..... + KAAAAAKKJKJJ.... + .KKKKKJKAKKJ.... + ..KAJJCAKKKJ.AA. + ..KK.KKKKKJJAA.. + ...C..KJAKJAA... + .....CCAAKJA.... + ........CCA..... + ................ +} +# tile 96 (dwarf leader,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....HHHHH....... + ....BLLLE....... + ....BOLOE..AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 97 (dwarf leader,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....HHHHH....... + ....BLLLE....... + ....BOLOE..AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 98 (dwarf ruler,male) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....BLLLE...A... + .....OLO...AAAA. + ...EBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 99 (dwarf ruler,female) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....BLLLE...A... + .....OLO...AAAA. + ...EBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 100 (mind flayer,male) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + ....IIIIIC...... + ....IAIAIF...... + ....IAIAIF...... + ....IAIAIFI..... + .....FIFIFIC.AA. + ....CBIBBF.CAAA. + ...IIIBBFFACAAA. + ......BBFCAAAA.. + ......CFFCAA.... + ....IIC.IIA..... +} +# tile 101 (mind flayer,female) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + ....IIIIIC...... + ....IAIAIF...... + ....IAIAIF...... + ....IAIAIFI..... + .....FIFIFIC.AA. + ....CBIBBF.CAAA. + ...IIIBBFFACAAA. + ......BBFCAAAA.. + ......CFFCAA.... + ....IIC.IIA..... +} +# tile 102 (master mind flayer,male) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + .EEEIIIIICEEEE.. + ..EEIAIAIEEEE... + ...EIAIAIEEE.... + ....IAIAIEEE.... + ....EFIFIEEE.AA. + ....CBIBBEEEAAA. + ...IIIBBEEEEAAA. + ....EEBEEEEAAA.. + ...EEECEEEAA.... + ....IIC.IIA..... +} +# tile 103 (master mind flayer,female) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + .EEEIIIIICEEEE.. + ..EEIAIAIEEEE... + ...EIAIAIEEE.... + ....IAIAIEEE.... + ....EFIFIEEE.AA. + ....CBIBBEEEAAA. + ...IIIBBEEEEAAA. + ....EEBEEEEAAA.. + ...EEECEEEAA.... + ....IIC.IIA..... +} +# tile 104 (manes,male) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP......... + ..PPPPP.PPP.P... + ..P..PPPP....... + ..P..PPPPP...P.. + ..PPPPP.PPP..... + ..P.P.P.PP.P.... + .P...P.PPPP..... + .P....PPP.PP.... + ..P....P.P.P.P.. + ........P....... + ................ + ................ +} +# tile 105 (manes,female) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP......... + ..PPPPP.PPP.P... + ..P..PPPP....... + ..P..PPPPP...P.. + ..PPPPP.PPP..... + ..P.P.P.PP.P.... + .P...P.PPPP..... + .P....PPP.PP.... + ..P....P.P.P.P.. + ........P....... + ................ + ................ +} +# tile 106 (homunculus,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJJ....... + ......LLC....... + ......LLC....... + .....BBPPPAA.... + ....L.BPPACAA... + ......BAPAAAA... + .....LLALCA..... + ................ + ................ +} +# tile 107 (homunculus,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJJ....... + ......LLC....... + ......LLC....... + .....BBPPPAA.... + ....L.BPPACAA... + ......BAPAAAA... + .....LLALCA..... + ................ + ................ +} +# tile 108 (imp,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDO...... + ......CDD....... + .....GGFFFAA.... + ....C.GFFADAA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 109 (imp,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDO...... + ......CDD....... + .....GGFFFAA.... + ....C.GFFADAA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 110 (lemure,male) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP....P.... + ..PPPPP..PP.P... + ..P..PPPPPPPP... + ..P..PPPPPPP.... + ..PPPPPPPPP..... + ....PPPPPPPP.... + ..PPPPPPPPPP.... + ...PPPPPPPPPP... + ..P.P..PPPP.PP.. + ........P.PP.... + ................ + ................ +} +# tile 111 (lemure,female) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP....P.... + ..PPPPP..PP.P... + ..P..PPPPPPPP... + ..P..PPPPPPP.... + ..PPPPPPPPP..... + ....PPPPPPPP.... + ..PPPPPPPPPP.... + ...PPPPPPPPPP... + ..P.P..PPPP.PP.. + ........P.PP.... + ................ + ................ +} +# tile 112 (quasit,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDOD..... + ......CDD.D..... + .....GGFFFAA.... + ....C.GFFAAADA.. + ....C.GFFJJDA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 113 (quasit,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDOD..... + ......CDD.D..... + .....GGFFFAA.... + ....C.GFFAAADA.. + ....C.GFFJJDA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 114 (tengu,male) +{ + ................ + .......PP....... + ......PPPP...... + .....DPPNP...... + ....DDDPPP...... + ....DDPPPP...... + ....D..PPA...... + .....PIAAIP.AAA. + ....PPPIIPPPAAA. + ....PAPPPPAPAAA. + ....PAHHHHAPAAA. + ....LAPPPPALAAA. + ......PPPPAAAA.. + ......PPPPAA.A.. + .....LLA.LLA.... + ................ +} +# tile 115 (tengu,female) +{ + ................ + .......PP....... + ......PPPP...... + .....DPPNP...... + ....DDDPPP...... + ....DDPPPP...... + ....D..PPA...... + .....PIAAIP.AAA. + ....PPPIIPPPAAA. + ....PAPPPPAPAAA. + ....PAHHHHAPAAA. + ....LAPPPPALAAA. + ......PPPPAAAA.. + ......PPPPAA.A.. + .....LLA.LLA.... + ................ +} +# tile 116 (blue jelly,male) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OBEBOE.... + ..OBEOBBEOBBE... + ..OBEOBBEOBBE... + ..BBBGGBGGBEEE.. + ..BBBAGBAGEEEEA. + ..BBBBBBEBEEEEAA + ...BBBBBBBEEEAAA + ....BBBBBEEEAAA. + ......BBBEEAA... + ................ + ................ +} +# tile 117 (blue jelly,female) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OBEBOE.... + ..OBEOBBEOBBE... + ..OBEOBBEOBBE... + ..BBBGGBGGBEEE.. + ..BBBAGBAGEEEEA. + ..BBBBBBEBEEEEAA + ...BBBBBBBEEEAAA + ....BBBBBEEEAAA. + ......BBBEEAA... + ................ + ................ +} +# tile 118 (spotted jelly,male) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OCEBOE.... + ..OCEOCCEOBCE... + ..OCEOBCEOCBD... + ..BBBHHBHHBEDD.. + ..CCBAHBAHEEEEA. + ..BBCBBBEBEEDEAA + ...BBBCBBBEEDAAA + ....BCCCBEEDAAA. + ......CCBEEAA... + ................ + ................ +} +# tile 119 (spotted jelly,female) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OCEBOE.... + ..OCEOCCEOBCE... + ..OCEOBCEOCBD... + ..BBBHHBHHBEDD.. + ..CCBAHBAHEEEEA. + ..BBCBBBEBEEDEAA + ...BBBCBBBEEDAAA + ....BCCCBEEDAAA. + ......CCBEEAA... + ................ + ................ +} +# tile 120 (ochre jelly,male) +{ + ................ + ................ + ................ + .......D........ + ......LCD....... + ...CD.LCDCLD.... + ..LCDLCCDLCCD... + ..LCDLCCDLCCD... + ..CCCGGCGGCDDD.. + ..CCCAGCAGDDDDA. + ..CCCCCCDCDDDDAA + ...CCCCCCCDDDAAA + ....CCCCCDDDAAA. + ......CCCDDAA... + ................ + ................ +} +# tile 121 (ochre jelly,female) +{ + ................ + ................ + ................ + .......D........ + ......LCD....... + ...CD.LCDCLD.... + ..LCDLCCDLCCD... + ..LCDLCCDLCCD... + ..CCCGGCGGCDDD.. + ..CCCAGCAGDDDDA. + ..CCCCCCDCDDDDAA + ...CCCCCCCDDDAAA + ....CCCCCDDDAAA. + ......CCCDDAA... + ................ + ................ +} +# tile 122 (kobold,male) +{ + ................ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.A.. + ..BPBBBBPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 123 (kobold,female) +{ + ................ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.A.. + ..BPBBBBPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 124 (large kobold,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.... + ..BPBBBBPAAA.A.. + ..BAPBPAPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 125 (large kobold,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.... + ..BPBBBBPAAA.A.. + ..BAPBPAPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 126 (kobold leader,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NCCCN........ + ...CABAC........ + ...CBBPC..A..... + ..CCBABCC.AA.... + ..CCBBBCCAAA.A.. + ..BCCBCCPAAAAA.. + ..BACBCAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 127 (kobold leader,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NCCCN........ + ...CABAC........ + ...CBBPC..A..... + ..CCBABCC.AA.... + ..CCBBBCCAAA.A.. + ..BCCBCCPAAAAA.. + ..BACBCAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 128 (kobold shaman,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NHHHN........ + ...HABAH........ + ...HBBPH..A..... + ..HHBABHH.AA.... + .HHHBBBHHHAA.A.. + .HBHHBHHPHAAAA.. + ..BAHBHAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 129 (kobold shaman,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NHHHN........ + ...HABAH........ + ...HBBPH..A..... + ..HHBABHH.AA.... + .HHHBBBHHHAA.A.. + .HBHHBHHPHAAAA.. + ..BAHBHAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 130 (leprechaun,male) +{ + ................ + ................ + ................ + ................ + ......G......... + ......F....K.... + .....GFF..KLK... + ....GFFFF..K.... + .....KLKA.GLAA.. + ...FGFJFFFAKA.A. + ...GAGFFAAAK.AA. + ....LKHKKJAKAA.. + ....GFAGKJAKA... + ...GFAA.GFAK.... + ................ + ................ +} +# tile 131 (leprechaun,female) +{ + ................ + ................ + ................ + ................ + ......G......... + ......F....K.... + .....GFF..KLK... + ....GFFFF..K.... + .....KLKA.GLAA.. + ...FGFLFFFAKA.A. + ...GAGFFAAAK.AA. + ....LKHKKJAKAA.. + ....GFAGKJAKA... + ...GFAA.GFAK.... + ................ + ................ +} +# tile 132 (small mimic,male) +{ + ................ + ................ + ................ + ................ + ......POP....... + ......NNO....... + ......NNO....... + .......OA....... + .....NNNNN..AA.. + ....OONNNOO.AA.. + ....NANOOANAAA.. + ......NAOAAAA... + ......NAOAA.A... + .....NN.OOA..... + ................ + ................ +} +# tile 133 (small mimic,female) +{ + ................ + ................ + ................ + ................ + ......POP....... + ......NNO....... + ......NNO....... + .......OA....... + .....NNNNN..AA.. + ....OONNNOO.AA.. + ....NANOOANAAA.. + ......NAOAAAA... + ......NAOAA.A... + .....NN.OOA..... + ................ + ................ +} +# tile 134 (large mimic,male) +{ + ................ + ................ + ................ + ......LLOA...... + ......NNOA...... + ......NNOA...... + ......ONOA...... + .....NNNNO..AAA. + ....OONNNOO.AAA. + ...NOANNNAOOAAA. + ...NAONONOANAAA. + .....NO.NOAAAA.. + .....NO.NOAA.A.. + ....NNO.NOOA.... + ................ + ................ +} +# tile 135 (large mimic,female) +{ + ................ + ................ + ................ + ......LLOA...... + ......NNOA...... + ......NNOA...... + ......ONOA...... + .....NNNNO..AAA. + ....OONNNOO.AAA. + ...NOANNNAOOAAA. + ...NAONONOANAAA. + .....NO.NOAAAA.. + .....NO.NOAA.A.. + ....NNO.NOOA.... + ................ + ................ +} +# tile 136 (giant mimic,male) +{ + ................ + ......NNO....... + .....NNNNOA..... + .....NNNNOA..... + .....NNNNOA..... + .....ONNNOA..... + ..PONNOOONOOPAAA + .PONONNNNOONOPAA + .ONOANNNNOAONOAA + .NNOANNNNOAOOOAA + ...AANNONNAAAAAA + ....PNO.NNPAAAAA + ....ONO.NNOAA..A + ....NNO.NNOAA..A + ...NNNO.NNOOA... + ................ +} +# tile 137 (giant mimic,female) +{ + ................ + ......NNO....... + .....NNNNOA..... + .....NNNNOA..... + .....NNNNOA..... + .....ONNNOA..... + ..PONNOOONOOPAAA + .PONONNNNOONOPAA + .ONOANNNNOAONOAA + .NNOANNNNOAOOOAA + ...AANNONNAAAAAA + ....PNO.NNPAAAAA + ....ONO.NNOAA..A + ....NNO.NNOAA..A + ...NNNO.NNOOA... + ................ +} +# tile 138 (wood nymph,male) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLFKKKKLA.... + .HKFLFKKKKA..... + OHKJFKKJJK.A.... + HKKLJJGKAAAAAAA. + .JJAJGDKJAAAAA.. + ..JA.KKJJAAAA... + ...J.KKKKJAA.... + ....JKKKKKJA.... + ....KJKJKJKJ.... + ................ +} +# tile 139 (wood nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLFKKKKLA.... + .HKFLFKKKKA..... + OHKJFKKJJK.A.... + HKKLJJGKAAAAAAA. + .JJAJGDKJAAAAA.. + ..JA.KKJJAAAA... + ...J.KKKKJAA.... + ....JKKKKKJA.... + ....KJKJKJKJ.... + ................ +} +# tile 140 (water nymph,male) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLJBBBBLA.... + .HBJLJBBBBA..... + OHBPJBBPPB.A.... + HBBLPPNBAAAAAAA. + .PPAPNDB.AAAAA.. + ..PA.BBPPAAAA... + ...P.BBBBPAA.... + ....PBBBBBPA.... + ....BPBPBPBP.... + ................ +} +# tile 141 (water nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLJBBBBLA.... + .HBJLJBBBBA..... + OHBPJBBPPB.A.... + HBBLPPNBAAAAAAA. + .PPAPNDB.AAAAA.. + ..PA.BBPPAAAA... + ...P.BBBBPAA.... + ....PBBBBBPA.... + ....BPBPBPBP.... + ................ +} +# tile 142 (mountain nymph,male) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLCOOOOLA.... + .HOCLCOOOOA..... + OHOLCOOLLO.A.... + HOOKLLIOAAAAAAA. + .LLALIBOKAAAAA.. + ..LA.OOLLAAAA... + ...L.OOOOLAA.... + ....LOOOOOLA.... + ....OLOLOLOL.... + ................ +} +# tile 143 (mountain nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLCOOOOLA.... + .HOCLCOOOOA..... + OHOLCOOLLO.A.... + HOOKLLIOAAAAAAA. + .LLALIBOKAAAAA.. + ..LA.OOLLAAAA... + ...L.OOOOLAA.... + ....LOOOOOLA.... + ....OLOLOLOL.... + ................ +} +# tile 144 (goblin,male) +{ + ................ + ................ + ................ + ....LK.......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IGIGIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICJAAAAA... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 145 (goblin,female) +{ + ................ + ................ + ................ + ....LK.......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IGIGIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICJAAAAA... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 146 (hobgoblin,male) +{ + ................ + .....LK......... + ....CKA......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IHIHIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICCAAAAA... + ....IIIIJA...... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 147 (hobgoblin,female) +{ + ................ + .....LK......... + ....CKA......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IHIHIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICCAAAAA... + ....IIIIJA...... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 148 (orc,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KCCAKKKA.AA... + ..BPCKJ.P.AAA... + ..BAGGFAAPNO.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BJACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 149 (orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KCCAKKKA.AA... + ..BPCKJ.P.AAA... + ..BAGGFAAPNO.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BJACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 150 (hill orc,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LKLA........ + .....K.A........ + ..KGGAFFKA.AA... + ..JKGFF.K.AAA... + ..JAHHFAAKNO.... + ..JAGFFNOAAA.... + ....GNNFAAAAAA.. + ...GGAGFAAAA.... + ..KJJAKJJA...... + ................ + ................ +} +# tile 151 (hill orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LKLA........ + .....K.A........ + ..KGGAFFKA.AA... + ..JKGFF.K.AAA... + ..JAHHFAAKNO.... + ..JAGFFNOAAA.... + ....GNNFAAAAAA.. + ...GGAGFAAAA.... + ..KJJAKJJA...... + ................ + ................ +} +# tile 152 (Mordor orc,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KIIAIIKA.AA... + ..BPIDD.P.AAA... + ..BAGGFAAP.O.... + ..BAIDDNOAAA.... + ....BNOJAAAAAA.. + ...BIAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 153 (Mordor orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KIIAIIKA.AA... + ..BPIDD.P.AAA... + ..BAGGFAAP.O.... + ..BAIDDNOAAA.... + ....BNOJAAAAAA.. + ...BIAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 154 (Uruk-hai,male) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..IIIAIIIA...... + ..BPIKI.BAAAA... + ..BIG.PPPPAAA... + .NBAD.PDDPAA.... + ..BNNJPDDPAA.... + ....INPPPPAAAA.. + ...BIAK.AAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 155 (Uruk-hai,female) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..IIIAIIIA...... + ..BPIKI.BAAAA... + ..BIG.PPPPAAA... + .NBAD.PDDPAA.... + ..BNNJPDDPAA.... + ....INPPPPAAAA.. + ...BIAK.AAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 156 (orc shaman,male) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..CCCACCCA...... + ..BPCKC.BAAAA... + ..BCGGFJBAAAA... + ..BAJJCJBAAA.... + ..BAJJCJBAAA.... + ....CACJAAAAAA.. + ...BCACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 157 (orc shaman,female) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..CCCACCCA...... + ..BPCKC.BAAAA... + ..BCGGFJBAAAA... + ..BAJJCJBAAA.... + ..BAJJCJBAAA.... + ....CACJAAAAAA.. + ...BCACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 158 (orc-captain,male) +{ + ................ + ................ + .....OA......... + ...NNOOPA....... + ....LPLA........ + ...IPPPA........ + ..DIIPADDA.AA... + ..BPIAD.P.AAA... + ..BAGGFAAP.O.... + ..BAGGFAAP.O.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BDAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 159 (orc-captain,female) +{ + ................ + ................ + .....OA......... + ...NNOOPA....... + ....LPLA........ + ...IPPPA........ + ..DIIPADDA.AA... + ..BPIAD.P.AAA... + ..BAGGFAAP.O.... + ..BAGGFAAP.O.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BDAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 160 (rock piercer,male) +{ + .JKKKKKKKKJAAA.. + ..JJGKGKJJAAAA.. + ...JKKKJJAAAA... + ...JJKKJJAAAA... + ....JKKJAAAA.... + ....JJKJ.AAA.... + ....JJKJ.AAA.... + ....JJJJ..A..... + .....JJ...A..... + .....JJ...A..... + .....JJ......... + .....JJ......... + .....J.......... + .....J.......... + ................ + ................ +} +# tile 161 (rock piercer,female) +{ + .JKKKKKKKKJAAA.. + ..JJGKGKJJAAAA.. + ...JKKKJJAAAA... + ...JJKKJJAAAA... + ....JKKJAAAA.... + ....JJKJ.AAA.... + ....JJKJ.AAA.... + ....JJJJ..A..... + .....JJ...A..... + .....JJ...A..... + .....JJ......... + .....JJ......... + .....J.......... + .....J.......... + ................ + ................ +} +# tile 162 (iron piercer,male) +{ + .BPPPPPPPP.AAA.. + ..BBDPDP..AAAA.. + ...BPPP..AAAA... + ...PBPP..AAAA... + ....BPP.AAAA.... + ....BBP.AAAA.... + ....PBP.AAAA.... + ....PBP...A..... + .....BP...A..... + .....BP...A..... + .....BP......... + .....BP......... + .....B.......... + .....P.......... + ................ + ................ +} +# tile 163 (iron piercer,female) +{ + .BPPPPPPPP.AAA.. + ..BBDPDP..AAAA.. + ...BPPP..AAAA... + ...PBPP..AAAA... + ....BPP.AAAA.... + ....BBP.AAAA.... + ....PBP.AAAA.... + ....PBP...A..... + .....BP...A..... + .....BP...A..... + .....BP......... + .....BP......... + .....B.......... + .....P.......... + ................ + ................ +} +# tile 164 (glass piercer,male) +{ + .NBBBBBBBBPAAA.. + ..NNDBDBPPAAAA.. + ...NBBBPPAAAA... + ...PNBBPPAAAA... + ....NBBPAAAA.... + ....NNBPAAAA.... + ....PNBPAAAA.... + ....PNBP..A..... + .....NB...A..... + .....NB...A..... + .....NB......... + .....NB......... + .....N.......... + .....P.......... + ................ + ................ +} +# tile 165 (glass piercer,female) +{ + .NBBBBBBBBPAAA.. + ..NNDBDBPPAAAA.. + ...NBBBPPAAAA... + ...PNBBPPAAAA... + ....NBBPAAAA.... + ....NNBPAAAA.... + ....PNBPAAAA.... + ....PNBP..A..... + .....NB...A..... + .....NB...A..... + .....NB......... + .....NB......... + .....N.......... + .....P.......... + ................ + ................ +} +# tile 166 (rothe,male) +{ + ................ + ...........K.... + ............K... + ............K... + .......JJJKKJ... + .....JKKKKKKK... + ..AAAKKKKKKKK... + .AAAAAKKKKKKKA.. + AAKKAAKKKKKAKA.. + .KEKKAKKKJAAKA.. + .KKKJAKKAJAAK... + ..KJAAAKAAA..... + ..AAKA.KA....... + ..A..A.K........ + ................ + ................ +} +# tile 167 (rothe,female) +{ + ................ + ...........K.... + ............K... + ............K... + .......JJJKKJ... + .....JKKKKKKK... + ..AAAKKKKKKKK... + .AAAAAKKKKKKKA.. + AAKKAAKKKKKAKA.. + .KEKKAKKKJAAKA.. + .KKKJAKKAJAAK... + ..KJAAAKAAA..... + ..AAKA.KA....... + ..A..A.K........ + ................ + ................ +} +# tile 168 (mumak,male) +{ + ................ + ...........P.... + .PP.........P... + PPP...PPPPP.P... + PPPPPPPPP.PP.... + PPPPBPPBBP.PP... + PPPBPPPPPP.PP... + .PDPPDDPP.PPP... + ..BPPDDP.PPPPA.. + ..PPPPPPPPPPPA.. + ..PPPPO..PAPPA.. + .OOPPOOAPPAPPA.. + OOPPOOAAPPA..... + .PPPAPA.PP...... + PPPA............ + .AA............. +} +# tile 169 (mumak,female) +{ + ................ + ...........P.... + .PP.........P... + PPP...PPPPP.P... + PPPPPPPPP.PP.... + PPPPBPPBBP.PP... + PPPBPPPPPP.PP... + .PDPPDDPP.PPP... + ..BPPDDP.PPPPA.. + ..PPPPPPPPPPPA.. + ..PPPPO..PAPPA.. + .OOPPOOAPPAPPA.. + OOPPOOAAPPA..... + .PPPAPA.PP...... + PPPA............ + .AA............. +} +# tile 170 (leocrotta,male) +{ + ................ + ..A..A.......... + ..AOOA....J..... + ..AOOAA....J.... + .APOAFA....J.... + .APOAAA.JJJJ.... + .AOPAAJKKKKKJ... + .AOAAKJJKKJKJA.. + ...JKKKKKJAKKA.. + ...JKJKKJAAKKA.. + ..JKJAKKAAPAPA.. + ..KKAAKKAAPAPA.. + .PAPAAPAPA...... + .PAPA.PAPA...... + ................ + ................ +} +# tile 171 (leocrotta,female) +{ + ................ + ..A..A.......... + ..AOOA....J..... + ..AOOAA....J.... + .APOAFA....J.... + .APOAAA.JJJJ.... + .AOPAAJKKKKKJ... + .AOAAKJJKKJKJA.. + ...JKKKKKJAKKA.. + ...JKJKKJAAKKA.. + ..JKJAKKAAPAPA.. + ..KKAAKKAAPAPA.. + .PAPAAPAPA...... + .PAPA.PAPA...... + ................ + ................ +} +# tile 172 (wumpus,male) +{ + ................ + ............B... + .............B.. + .......BBBBB.B.. + ....BBBPPBBBB... + ...BOOBBBPBBBB.. + ...OOBBBBBPBBB.. + ..DABBAABBPBBBA. + .BOOBBDABEBBEBAA + .BOBBBBBBEBEBBAA + .BBBBBBBEBBABBAA + .EBBBBBEABBABBAA + ..EEEEEAABBA.... + .....BBA.BB..... + ................ + ................ +} +# tile 173 (wumpus,female) +{ + ................ + ............B... + .............B.. + .......BBBBB.B.. + ....BBBPPBBBB... + ...BOOBBBPBBBB.. + ...OOBBBBBPBBB.. + ..DABBAABBPBBBA. + .BOOBBDABEBBEBAA + .BOBBBBBBEBEBBAA + .BBBBBBBEBBABBAA + .EBBBBBEABBABBAA + ..EEEEEAABBA.... + .....BBA.BB..... + ................ + ................ +} +# tile 174 (titanothere,male) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + .PPPPP.PPPPPPP.. + .PPEPP.PPPP.PPA. + PBPPP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 175 (titanothere,female) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + .PPPPP.PPPPPPP.. + .PPEPP.PPPP.PPA. + PBPPP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 176 (baluchitherium,male) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + BPPPPP.PPPPPPP.. + B.PEPP.PPPP.PPA. + PB.PP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 177 (baluchitherium,female) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + BPPPPP.PPPPPPP.. + B.PEPP.PPPP.PPA. + PB.PP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 178 (mastodon,male) +{ + ................ + ................ + ................ + ................ + ................ + ..O...O......... + .N..POP.P....... + N..PNPPPPP...... + O.PNPPPPPP.PP... + O.POPEPPP.PPPPP. + .OPOPOP..PPPPPAP + ..PPOPP.PPPPPPAA + ..PPAAAPPPPAPPA. + ..P...APPAAAPPA. + .......PPA...... + ................ +} +# tile 179 (mastodon,female) +{ + ................ + ................ + ................ + ................ + ................ + ..O...O......... + .N..POP.P....... + N..PNPPPPP...... + O.PNPPPPPP.PP... + O.POPEPPP.PPPPP. + .OPOPOP..PPPPPAP + ..PPOPP.PPPPPPAA + ..PPAAAPPPPAPPA. + ..P...APPAAAPPA. + .......PPA...... + ................ +} +# tile 180 (sewer rat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKK.... + ..KKKKJKKJKKK... + ..JAKAKJJJKKKJ.. + ..GKGKJKAKKAKKA. + .KKJJJJKAKAAKKA. + .PJJAAKKAJAJKA.. + ..AA.KKA..JKA... + .........JJA.... + ................ +} +# tile 181 (sewer rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKK.... + ..KKKKJKKJKKK... + ..JAKAKJJJKKKJ.. + ..GKGKJKAKKAKKA. + .KKJJJJKAKAAKKA. + .PJJAAKKAJAJKA.. + ..AA.KKA..JKA... + .........JJA.... + ................ +} +# tile 182 (giant rat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 183 (giant rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 184 (rabid rat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJOOOKAJKAAKKA + .PJOOAKKAJJAJKA. + ..AOOOKAA..JKA.. + .OOOOOOOO.JJA... + ................ +} +# tile 185 (rabid rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJOOOKAJKAAKKA + .PJOOAKKAJJAJKA. + ..AOOOKAA..JKA.. + .OOOOOOOO.JJA... + ................ +} +# tile 186 (wererat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..LLLLKJKJJKKKJ. + ..FLFLLJKJJKKKK. + ..LLLLJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 187 (wererat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..LLLLKJKJJKKKJ. + ..FLFLLJKJJKKKK. + ..LLLLJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 188 (rock mole,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......AAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + ..JAJAAAAAAAAAA. + .AAAAAAAAAAAAAA. + AN.NAAAAAAAAAAA. + A...AAAA...AAA.. + AN.NAA.AA...AA.. + .AAAA........... +} +# tile 189 (rock mole,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......AAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + ..JAJAAAAAAAAAA. + .AAAAAAAAAAAAAA. + AN.NAAAAAAAAAAA. + A...AAAA...AAA.. + AN.NAA.AA...AA.. + .AAAA........... +} +# tile 190 (woodchuck,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .......KJA...... + ......NKKNA..... + ......KNOJA..... + ......KNOJA..... + .....KKKKKJA.... + ....JJKLLJJJAA.. + ......KLLJAAAAA. + ......KJJJAAAA.. + .....JJAAJJAA... + ................ +} +# tile 191 (woodchuck,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .......KJA...... + ......NKKNA..... + ......KNOJA..... + ......KNOJA..... + .....KKKKKJA.... + ....JJKLLJJJAA.. + ......KLLJAAAAA. + ......KJJJAAAA.. + .....JJAAJJAA... + ................ +} +# tile 192 (cave spider,male) +{ + ................ + ................ + ................ + ................ + ................ + ........PA...... + .......PA....... + ......PAPBBA.... + ...PA.APBPPPA... + ...ABBPPAPPAA.PA + ...GPPPPAAAPPPAA + ...PPGPAAPPAAAA. + ..D.PAPAPAAPPA.. + ....D.PAAPA.APA. + .....PAA.APA.... + ................ +} +# tile 193 (cave spider,female) +{ + ................ + ................ + ................ + ................ + ................ + ........PA...... + .......PA....... + ......PAPBBA.... + ...PA.APBPPPA... + ...ABBPPAPPAA.PA + ...GPPPPAAAPPPAA + ...PPGPAAPPAAAA. + ..D.PAPAPAAPPA.. + ....D.PAAPA.APA. + .....PAA.APA.... + ................ +} +# tile 194 (centipede,male) +{ + ................ + ................ + ......PBPP...... + ....BBPAAA...... + ..PPBAAA........ + .PAPBBBPPPP..... + ..PAAPPBBBA..... + ....PAAPAPBPP... + ......AABBPP.... + ......BB.PPAP... + ....PBBPPAP.A... + ...GPPPAP.AP.... + ...PPGPAAP...... + ..B.PAA......... + ...B............ + ................ +} +# tile 195 (centipede,female) +{ + ................ + ................ + ......PBPP...... + ....BBPAAA...... + ..PPBAAA........ + .PAPBBBPPPP..... + ..PAAPPBBBA..... + ....PAAPAPBPP... + ......AABBPP.... + ......BB.PPAP... + ....PBBPPAP.A... + ...GPPPAP.AP.... + ...PPGPAAP...... + ..B.PAA......... + ...B............ + ................ +} +# tile 196 (giant spider,male) +{ + ................ + ................ + ................ + ................ + ................ + ........JA...... + .......JA....... + ......JAJKKA.... + ...JA.AJKJJJA... + ...AKKJJAJJAA.JA + ...GJJJJAAAJJJAA + ...JJGJAAJJAAAA. + ..D.JAJAJAAJJA.. + ....D.JAAJA.AJA. + .....JAA.AJA.... + ................ +} +# tile 197 (giant spider,female) +{ + ................ + ................ + ................ + ................ + ................ + ........JA...... + .......JA....... + ......JAJKKA.... + ...JA.AJKJJJA... + ...AKKJJAJJAA.JA + ...GJJJJAAAJJJAA + ...JJGJAAJJAAAA. + ..D.JAJAJAAJJA.. + ....D.JAAJA.AJA. + .....JAA.AJA.... + ................ +} +# tile 198 (scorpion,male) +{ + ................ + ................ + .......JKJKJAA.. + ......JA.JKJKKA. + .......KA...JJJA + ......JA....KKJA + ...........JJJKA + .......AJKKAJJA. + .....AAJKJJJAA.. + ...AKKJJAJJAA... + ...GJJJJAAAJJJA. + ...JJGJAAJJAAAJ. + ..D.JAJAJAAJJA.. + ....D.JAAJA.JAA. + .......JAAJA.... + ................ +} +# tile 199 (scorpion,female) +{ + ................ + ................ + .......JKJKJAA.. + ......JA.JKJKKA. + .......KA...JJJA + ......JA....KKJA + ...........JJJKA + .......AJKKAJJA. + .....AAJKJJJAA.. + ...AKKJJAJJAA... + ...GJJJJAAAJJJA. + ...JJGJAAJJAAAJ. + ..D.JAJAJAAJJA.. + ....D.JAAJA.JAA. + .......JAAJA.... + ................ +} +# tile 200 (lurker above,male) +{ + .AAAAAAAAAAAAAAA + ...AAGFAAGFAAA.. + ...AAAAAAAAAAA.. + ....AODODODOA... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 201 (lurker above,female) +{ + .AAAAAAAAAAAAAAA + ...AAGFAAGFAAA.. + ...AAAAAAAAAAA.. + ....AODODODOA... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 202 (trapper,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....AODODODOA... + ...AAAAAAAAAAA.. + ...AAGFAAGFAAA.. + .AAAAAAAAAAAAAAA +} +# tile 203 (trapper,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....AODODODOA... + ...AAAAAAAAAAA.. + ...AAGFAAGFAAA.. + .AAAAAAAAAAAAAAA +} +# tile 204 (pony,male) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ...KKEKJ........ + ..KKJKKJ........ + ..JJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKJ..... + ...KKKKKKKJJAAA. + ...KJKJJJJJAJA.. + ...JAJAAAAJAA... + ...JAJAAJAJA.... + ...L.JAALAJ..... + .....LA...L..... + ................ +} +# tile 205 (pony,female) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ...KKEKJ........ + ..KKJKKJ........ + ..JJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKJ..... + ...KKKKKKKJJAAA. + ...KJKJJJJJAJA.. + ...JAJAAAAJAA... + ...JAJAAJAJA.... + ...L.JAALAJ..... + .....LA...L..... + ................ +} +# tile 206 (white unicorn,male) +{ + ................ + ..HP............ + ..PHO.NN........ + ...PHNNB........ + ...ONENB........ + ..ONNNNB........ + ..NOANNBAA...... + ...AONNBA....... + ...ONNNONNN..... + ..NONNNNONNOAAA. + ..N.ONONNONAOA.. + ..OAANAAAAOAA... + ...LAOAAOAOA.... + .....OAALAO..... + .....LA...L..... + ................ +} +# tile 207 (white unicorn,female) +{ + ................ + ..HP............ + ..PHO.NN........ + ...PHNNB........ + ...ONENB........ + ..ONNNNB........ + ..NOANNBAA...... + ...AONNBA....... + ...ONNNONNN..... + ..NONNNNONNOAAA. + ..N.ONONNONAOA.. + ..OAANAAAAOAA... + ...LAOAAOAOA.... + .....OAALAO..... + .....LA...L..... + ................ +} +# tile 208 (gray unicorn,male) +{ + ................ + ..HP............ + ..PHO.PP........ + ...PHPPN........ + ....PGPN........ + ...PPPPN........ + ..PPAPPNAA...... + ...APPPNA....... + ....PPP.PPP..... + ..P.PPPP.PP.AAA. + ..P..P.PP.PA.A.. + ..PAAPAAAA.AA... + ...LA.AA.A.A.... + ......AALA...... + .....LA...L..... + ................ +} +# tile 209 (gray unicorn,female) +{ + ................ + ..HP............ + ..PHO.PP........ + ...PHPPN........ + ....PGPN........ + ...PPPPN........ + ..PPAPPNAA...... + ...APPPNA....... + ....PPP.PPP..... + ..P.PPPP.PP.AAA. + ..P..P.PP.PA.A.. + ..PAAPAAAA.AA... + ...LA.AA.A.A.... + ......AALA...... + .....LA...L..... + ................ +} +# tile 210 (black unicorn,male) +{ + ................ + ..HP............ + ..PHO.AA........ + ...PHAAJ........ + ...AADAJ........ + ..AAAAAJ........ + ..AAPAAJPP...... + ...PAAAJP....... + ...AAAAAAAA..... + ..AAAAAAAAAAPPP. + ..A.AAAAAAAPAP.. + ..APPAPPAPAPP... + ...LPAPPAPAP.... + .....APPLPA..... + .....LP...L..... + ................ +} +# tile 211 (black unicorn,female) +{ + ................ + ..HP............ + ..PHO.AA........ + ...PHAAJ........ + ...AADAJ........ + ..AAAAAJ........ + ..AAPAAJPP...... + ...PAAAJP....... + ...AAAAAAAA..... + ..AAAAAAAAAAPPP. + ..A.AAAAAAAPAP.. + ..APPAPPAPAPP... + ...LPAPPAPAP.... + .....APPLPA..... + .....LP...L..... + ................ +} +# tile 212 (horse,male) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ..KKKEKJ........ + .KKKJKKJAA...... + .JJJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKKJA... + ..KKKKKKKKKKJA.. + ..KJJKJJJJJKAJA. + ..JAAJAAAAAJAJA. + ..JAAJAAAJAJAA.. + ..LA.JAA.L.JA... + .....LA....L.... + ................ +} +# tile 213 (horse,female) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ..KKKEKJ........ + .KKKJKKJAA...... + .JJJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKKJA... + ..KKKKKKKKKKJA.. + ..KJJKJJJJJKAJA. + ..JAAJAAAAAJAJA. + ..JAAJAAAJAJAA.. + ..LA.JAA.L.JA... + .....LA....L.... + ................ +} +# tile 214 (warhorse,male) +{ + ................ + .....JJJ........ + ...KKKKJJ....... + .KKKKEKJJ....... + KKKKKKKJJAA..... + JKKKJKKJJAA..... + .JJJAKKJJAA..... + ...AKKKJJA...... + ...KKKKKKKKKJA.. + ..KKKKKKKKKKKJA. + ..KKJKKJKKJKKJJA + ..KJAKJAKJAKJAJA + ..KJAKJAKJAKJA.. + ..LC.KJALC.KJ... + .....LC....LC... + ................ +} +# tile 215 (warhorse,female) +{ + ................ + .....JJJ........ + ...KKKKJJ....... + .KKKKEKJJ....... + KKKKKKKJJAA..... + JKKKJKKJJAA..... + .JJJAKKJJAA..... + ...AKKKJJA...... + ...KKKKKKKKKJA.. + ..KKKKKKKKKKKJA. + ..KKJKKJKKJKKJJA + ..KJAKJAKJAKJAJA + ..KJAKJAKJAKJA.. + ..LC.KJALC.KJ... + .....LC....LC... + ................ +} +# tile 216 (fog cloud,male) +{ + .......P........ + ....P..P........ + .....P.P...P.... + ...P.......P.... + ..P..P.P.P...... + ....PP.PP.P.P... + .P..APAPPP..P... + ...P.PPPP.PP.... + ......PPPPP.P.P. + ...P.PPPPP..P... + ....P..P.PP.P... + .P...P.P...PPP.. + ..P.P....PP..... + .......P....P... + ..P..P.P..P..... + ................ +} +# tile 217 (fog cloud,female) +{ + .......P........ + ....P..P........ + .....P.P...P.... + ...P.......P.... + ..P..P.P.P...... + ....PP.PP.P.P... + .P..APAPPP..P... + ...P.PPPP.PP.... + ......PPPPP.P.P. + ...P.PPPPP..P... + ....P..P.PP.P... + .P...P.P...PPP.. + ..P.P....PP..... + .......P....P... + ..P..P.P..P..... + ................ +} +# tile 218 (dust vortex,male) +{ + ................ + ................ + ....K..KKKK..... + ...K..KKJJJK.... + ..K..KJJJJ..K... + .KJ.KJJ.JKK..K.. + .KJJKJ.JJJJK.... + .KJJJJ....JJK... + .KKJ.J...J.JKK.. + ..KJJ....JJJJK.. + ...KJJJJ.JKJJK.. + .K..KKJ.JJK.JK.. + ..K..JJJJK..K... + ...KJJJKK..K.... + ....KKKK..K..... + ................ +} +# tile 219 (dust vortex,female) +{ + ................ + ................ + ....K..KKKK..... + ...K..KKJJJK.... + ..K..KJJJJ..K... + .KJ.KJJ.JKK..K.. + .KJJKJ.JJJJK.... + .KJJJJ....JJK... + .KKJ.J...J.JKK.. + ..KJJ....JJJJK.. + ...KJJJJ.JKJJK.. + .K..KKJ.JJK.JK.. + ..K..JJJJK..K... + ...KJJJKK..K.... + ....KKKK..K..... + ................ +} +# tile 220 (ice vortex,male) +{ + ................ + ................ + ....N..NNNN..... + ...N..NNOOON.... + ..N..NOOOO..N... + .NO.NOO.ONN..N.. + .NOONO.OOOON.... + .NOOOO....OON... + .NNO.O...O.ONN.. + ..NOO....OOOON.. + ...NOOOO.ONOON.. + .N..NNO.OON.ON.. + ..N..OOOON..N... + ...NOOONN..N.... + ....NNNN..N..... + ................ +} +# tile 221 (ice vortex,female) +{ + ................ + ................ + ....N..NNNN..... + ...N..NNOOON.... + ..N..NOOOO..N... + .NO.NOO.ONN..N.. + .NOONO.OOOON.... + .NOOOO....OON... + .NNO.O...O.ONN.. + ..NOO....OOOON.. + ...NOOOO.ONOON.. + .N..NNO.OON.ON.. + ..N..OOOON..N... + ...NOOONN..N.... + ....NNNN..N..... + ................ +} +# tile 222 (energy vortex,male) +{ + ................ + ................ + ....E..EEEE..... + ...E..EEAAAE.... + ..E..EAAAA..E... + .EA.EAAAAIE..E.. + .EAAIAAAAAAE.... + .EAAAAAAAAAAE... + .EEAAAAAAAAAEE.. + ..EAAAAAAAAAAE.. + ...EAAAAAAIAAE.. + .E..EIAAAAE.AE.. + ..E..AAAAE..E... + ...EAAAEE..E.... + ....EEEE..E..... + ................ +} +# tile 223 (energy vortex,female) +{ + ................ + ................ + ....E..EEEE..... + ...E..EEAAAE.... + ..E..EAAAA..E... + .EA.EAAAAIE..E.. + .EAAIAAAAAAE.... + .EAAAAAAAAAAE... + .EEAAAAAAAAAEE.. + ..EAAAAAAAAAAE.. + ...EAAAAAAIAAE.. + .E..EIAAAAE.AE.. + ..E..AAAAE..E... + ...EAAAEE..E.... + ....EEEE..E..... + ................ +} +# tile 224 (steam vortex,male) +{ + ................ + ................ + ....P..PPPP..... + ...P..PPBBBP.... + ..P..PBBBB..P... + .PB.PBBPBPP..P.. + .PBBPBPBBBBP.... + .PBBBBP.PPBBP... + .PPBPB...BPBPP.. + ..PBBPP.PBBBBP.. + ...PBBBBPBPBBP.. + .P..PPBPBBP.BP.. + ..P..BBBBP..P... + ...PBBBPP..P.... + ....PPPP..P..... + ................ +} +# tile 225 (steam vortex,female) +{ + ................ + ................ + ....P..PPPP..... + ...P..PPBBBP.... + ..P..PBBBB..P... + .PB.PBBPBPP..P.. + .PBBPBPBBBBP.... + .PBBBBP.PPBBP... + .PPBPB...BPBPP.. + ..PBBPP.PBBBBP.. + ...PBBBBPBPBBP.. + .P..PPBPBBP.BP.. + ..P..BBBBP..P... + ...PBBBPP..P.... + ....PPPP..P..... + ................ +} +# tile 226 (fire vortex,male) +{ + ................ + ................ + ....D..DDDD..... + ...D..DDCCCD.... + ..D..DCCCC..D... + .DC.DCCHCDD..D.. + .DCCDCHCCCCD.... + .DCCCCHHHHCCD... + .DDCHCHHHCHCDD.. + ..DCCHHHHCCCCD.. + ...DCCCCHCDCCD.. + .D..DDCHCCD.CD.. + ..D..CCCCD..D... + ...DCCCDD..D.... + ....DDDD..D..... + ................ +} +# tile 227 (fire vortex,female) +{ + ................ + ................ + ....D..DDDD..... + ...D..DDCCCD.... + ..D..DCCCC..D... + .DC.DCCHCDD..D.. + .DCCDCHCCCCD.... + .DCCCCHHHHCCD... + .DDCHCHHHCHCDD.. + ..DCCHHHHCCCCD.. + ...DCCCCHCDCCD.. + .D..DDCHCCD.CD.. + ..D..CCCCD..D... + ...DCCCDD..D.... + ....DDDD..D..... + ................ +} +# tile 228 (baby long worm,male) +{ + ................ + ................ + ................ + ................ + ......CLC....... + ......LLL....... + .....GGAGG.A.... + .....GGAGGAAA... + ......LLLAAA.C.. + ......LLLAA.CC.. + ......CLLCCCCA.. + .......LLLCCA... + ........CLL..... + ................ + ................ + ................ +} +# tile 229 (baby long worm,female) +{ + ................ + ................ + ................ + ................ + ......CLC....... + ......LLL....... + .....GGAGG.A.... + .....GGAGGAAA... + ......LLLAAA.C.. + ......LLLAA.CC.. + ......CLLCCCCA.. + .......LLLCCA... + ........CLL..... + ................ + ................ + ................ +} +# tile 230 (baby purple worm,male) +{ + ................ + ................ + ................ + .......I........ + ......III....... + ......III....... + .....GGAGG.A.... + .....GGAGGAAA... + ......IIIAAA.D.. + ......IIIAA.DD.. + ......IIIDDDDA.. + .......IIIDDA... + ........III..... + ................ + ................ + ................ +} +# tile 231 (baby purple worm,female) +{ + ................ + ................ + ................ + .......I........ + ......III....... + ......III....... + .....GGAGG.A.... + .....GGAGGAAA... + ......IIIAAA.D.. + ......IIIAA.DD.. + ......IIIDDDDA.. + .......IIIDDA... + ........III..... + ................ + ................ + ................ +} +# tile 232 (long worm,male) +{ + ................ + ................ + .....CLC........ + ....CLLLC....... + ....LLLLL....... + ...GGGLGGGAA.... + ...GAGLGAGAAA... + ...GGGLGGGAAA... + ....LLLLLAAACC.. + ....LLLLLAACCC.. + ....CLLLLCCCCA.. + .....LLLLLCCA... + ......CLLLL..... + ................ + ................ + ................ +} +# tile 233 (long worm,female) +{ + ................ + ................ + .....CLC........ + ....CLLLC....... + ....LLLLL....... + ...GGGLGGGAA.... + ...GAGLGAGAAA... + ...GGGLGGGAAA... + ....LLLLLAAACC.. + ....LLLLLAACCC.. + ....CLLLLCCCCA.. + .....LLLLLCCA... + ......CLLLL..... + ................ + ................ + ................ +} +# tile 234 (purple worm,male) +{ + ................ + ................ + .....DID........ + ....DIIID....... + ....IIIII....... + ...GGGIGGGAA.... + ...GAGIGAGAAA... + ...GGGIGGGAAA... + ....IIIIIAAADD.. + ....IIIIIAADDD.. + ....DIIIIDDDDA.. + .....IIIIIDDA... + ......DIIII..... + ................ + ................ + ................ +} +# tile 235 (purple worm,female) +{ + ................ + ................ + .....DID........ + ....DIIID....... + ....IIIII....... + ...GGGIGGGAA.... + ...GAGIGAGAAA... + ...GGGIGGGAAA... + ....IIIIIAAADD.. + ....IIIIIAADDD.. + ....DIIIIDDDDA.. + .....IIIIIDDA... + ......DIIII..... + ................ + ................ + ................ +} +# tile 236 (grid bug,male) +{ + ................ + ................ + ................ + ................ + ..D....NHCN..D.. + .D.D..NHDNCNDED. + D.D.D.NNHCND.DED + .D...D.NNHDND... + .DDD..ENNG.D.DE. + ..DDDDEEEEGD..DE + D.....DEHEE.D... + .D.......H...... + ................ + ................ + ................ + ................ +} +# tile 237 (grid bug,female) +{ + ................ + ................ + ................ + ................ + ..D....NHCN..D.. + .D.D..NHDNCNDED. + D.D.D.NNHCND.DED + .D...D.NNHDND... + .DDD..ENNG.D.DE. + ..DDDDEEEEGD..DE + D.....DEHEE.D... + .D.......H...... + ................ + ................ + ................ + ................ +} +# tile 238 (xan,male) +{ + ................ + ................ + ..........GG.... + ...HHH...GOGG... + .....HH..GGGG... + ...HHHHH.GGG.... + .......GG...AAA. + .....GOGGHHAAAA. + ....GOGG..HHAAA. + NNNGOGG.AAHHHA.. + NANGGGG.AAHAH... + NNNGGNNNAAAAAA.. + ..GGGNANAA.AAA.. + .GGGANNNAA.A.A.. + ..G..AAAAAA..... + ......AA.AA..... +} +# tile 239 (xan,female) +{ + ................ + ................ + ..........GG.... + ...HHH...GOGG... + .....HH..GGGG... + ...HHHHH.GGG.... + .......GG...AAA. + .....GOGGHHAAAA. + ....GOGG..HHAAA. + NNNGOGG.AAHHHA.. + NANGGGG.AAHAH... + NNNGGNNNAAAAAA.. + ..GGGNANAA.AAA.. + .GGGANNNAA.A.A.. + ..G..AAAAAA..... + ......AA.AA..... +} +# tile 240 (yellow light,male) +{ + ................ + ......NA........ + ......HA........ + ..NA.NHNA.NA.... + ...LALHLALA..... + ....NHHHNA...... + ..NLHHHHHLNA.... + NHHHHHHHHHHHNA.. + ..NLHHHHHLNA.... + ....NHHHNA...... + ...LALHLALA..... + ..NA.NNNA.NA.... + ......HA........ + ......NA........ + ................ + ................ +} +# tile 241 (yellow light,female) +{ + ................ + ......NA........ + ......HA........ + ..NA.NHNA.NA.... + ...LALHLALA..... + ....NHHHNA...... + ..NLHHHHHLNA.... + NHHHHHHHHHHHNA.. + ..NLHHHHHLNA.... + ....NHHHNA...... + ...LALHLALA..... + ..NA.NNNA.NA.... + ......HA........ + ......NA........ + ................ + ................ +} +# tile 242 (black light,male) +{ + ................ + ......AA........ + ......AA........ + ..AA.AAAA.AA.... + ...AAAAAAAA..... + ....AAAAAA...... + ..AAAAAAAAAA.... + AAAAAAAAAAAAAA.. + ..AAAAAAAAAA.... + ....AAAAAA...... + ...AAAAAAAA..... + ..AA.AAAA.AA.... + ......AA........ + ......AA........ + ................ + ................ +} +# tile 243 (black light,female) +{ + ................ + ......AA........ + ......AA........ + ..AA.AAAA.AA.... + ...AAAAAAAA..... + ....AAAAAA...... + ..AAAAAAAAAA.... + AAAAAAAAAAAAAA.. + ..AAAAAAAAAA.... + ....AAAAAA...... + ...AAAAAAAA..... + ..AA.AAAA.AA.... + ......AA........ + ......AA........ + ................ + ................ +} +# tile 244 (zruty,male) +{ + ................ + ......FFGF...... + ....OOFGFFFF.... + ...AOFGFOOKFF... + ...FFGFAOAJKKF.. + ..FFFFFFJAAJKK.. + ..ODOFFJAJJKKJA. + ..DDDDJAJJKJJAA. + ..JODOAJJJAJJAAA + .KKJAJJJKJAJJAAA + .KKAAJKKKKJAAAAA + ...AJJKKKKJJAAAA + ...KJJAAAAKJAAA. + ..JKJJJAAJJJJ... + ................ + ................ +} +# tile 245 (zruty,female) +{ + ................ + ......FFGF...... + ....OOFGFFFF.... + ...AOFGFOOKFF... + ...FFGFAOAJKKF.. + ..FFFFFFJAAJKK.. + ..ODOFFJAJJKKJA. + ..DDDDJAJJKJJAA. + ..JODOAJJJAJJAAA + .KKJAJJJKJAJJAAA + .KKAAJKKKKJAAAAA + ...AJJKKKKJJAAAA + ...KJJAAAAKJAAA. + ..JKJJJAAJJJJ... + ................ + ................ +} +# tile 246 (couatl,male) +{ + ................ + ................ + ........I....I.. + ....KKAIII..III. + ...NAOJAKI.IIIII + ...KKJAJJKKK..II + ...KKAAIJJJJJ..I + ...FAA.I...KJ..I + ..FAFA..AAAKJAA. + .......AAAJJAAA. + ......AKKJJAAA.. + ......KJAAAAAJA. + .....JJAA...JA.. + ......JJJJJJA... + ................ + ................ +} +# tile 247 (couatl,female) +{ + ................ + ................ + ........I....I.. + ....KKAIII..III. + ...NAOJAKI.IIIII + ...KKJAJJKKK..II + ...KKAAIJJJJJ..I + ...FAA.I...KJ..I + ..FAFA..AAAKJAA. + .......AAAJJAAA. + ......AKKJJAAA.. + ......KJAAAAAJA. + .....JJAA...JA.. + ......JJJJJJA... + ................ + ................ +} +# tile 248 (Aleax,male) +{ + ................ + ......BBBB..I... + ..I..BF...B..... + ....BF.HHA.B.... + ...BF.HHHHA.B.I. + ...BF.LFLFA.FB.. + .I.BF.LLLLA.FB.. + ...BF.ALLA.FB... + ..BF.LLAALL.ABA. + .BF.LLLLLLLLAFB. + .BF.LALLLLALAFB. + .BF.LAJJKJALAFB. + ..BF..LJJLAAABA. + ...BF.LLALAABA.. + ..BF.LLAALLAFB.. + ................ +} +# tile 249 (Aleax,female) +{ + ................ + ......BBBB..I... + ..I..BF...B..... + ....BF.HHA.B.... + ...BF.HHHHA.B.I. + ...BF.LFLFA.FB.. + .I.BF.LLLLA.FB.. + ...BF.ALLA.FB... + ..BF.LJAAJL.ABA. + .BF.LLJJJJLLAFB. + .BF.LAJKJJALAFB. + .BF.LAJJKJALAFB. + ..BF..LJJLAAABA. + ...BF.LLALAABA.. + ..BF.LLAALLAFB.. + ................ +} +# tile 250 (Angel,male) +{ + ................ + ................ + ......HHHH...... + ................ + .......CC....... + ......CLLC..AA.. + ......PLLP....A. + ......NPPPA.A... + .....BBLLPPAAA.. + .....NNLLPPAAA.. + ......BNNPAAAA.. + ......BNNPAAAA.. + .....BNNNPAA.A.. + .....BNNNNPA.... + ....BNNNNNNP.... + ................ +} +# tile 251 (Angel,female) +{ + ................ + ................ + ......HHHH...... + ................ + .......CC....... + ......CLLC..AA.. + ......PLLP....A. + ......NPPPA.A... + .....BBLLPPAAA.. + .....NNLLPPAAA.. + ......BNNPAAAA.. + ......BNNPAAAA.. + .....BNNNPAA.A.. + .....BNNNNPA.... + ....BNNNNNNP.... + ................ +} +# tile 252 (ki-rin,male) +{ + ................ + ................ + ..LP............ + ..PLO.C.C....... + ...PLCCD........ + ...KCIKD........ + ..KCCCCD........ + ..CKACCDA....... + ...ACCCCCC...A.. + ...KCCCKCCKAA... + ..CAKCKCKCAKA... + ..CAAKAKAKA..... + ...L.KALAK...... + .....LA..L...... + ................ + ................ +} +# tile 253 (ki-rin,female) +{ + ................ + ................ + ..LP............ + ..PLO.C.C....... + ...PLCCD........ + ...KCIKD........ + ..KCCCCD........ + ..CKACCDA....... + ...ACCCCCC...A.. + ...KCCCKCCKAA... + ..CAKCKCKCAKA... + ..CAAKAKAKA..... + ...L.KALAK...... + .....LA..L...... + ................ + ................ +} +# tile 254 (Archon,male) +{ + ................ + ......OOOO...... + .....OOOOOO..... + .....OJLLJO..... + .....OLLLLO..... + ....OOJLLJOO.... + ......AJJA...... + .....AAAAAAA.... + ....AAAAAAAAA... + ...OAAOAAAJLJ... + ..OOAOAAAACJC... + ....LAAAACCJCC.. + .....AAAAAJJJ... + ....AAAAAAAA.... + ................ + ................ +} +# tile 255 (Archon,female) +{ + ................ + ......OOOO...... + .....OOOOOO..... + .....OJLLJO..... + .....OLLLLO..... + ....OOKLLKOO.... + ......AKKA...... + .....AAAAAAA.... + ....AAAAAAAAA... + ...OAAOAAAJLJ... + ..OOAOAAAACJC... + ....LAAAACCJCC.. + .....AAAAAJJJ... + ....AAAAAAAA.... + ................ + ................ +} +# tile 256 (bat,male) +{ + ................ + ................ + ................ + ................ + ...JJJCACJJJ.... + ..JJAAHJHAAJJ... + ..JA...JA..AJ... + ................ + ................ + ......AAAA...... + ....AAAAAAAA.... + ...AAA.AA.AAA... + .......AA....... + ................ + ................ + ................ +} +# tile 257 (bat,female) +{ + ................ + ................ + ................ + ................ + ...JJJCACJJJ.... + ..JJAAHJHAAJJ... + ..JA...JA..AJ... + ................ + ................ + ......AAAA...... + ....AAAAAAAA.... + ...AAA.AA.AAA... + .......AA....... + ................ + ................ + ................ +} +# tile 258 (giant bat,male) +{ + ................ + ................ + ................ + ...JK.J.J.JK.... + ..KJJJCACJJKJ... + .JJJAAHJHAAJJK.. + .KJA...JA..AJJ.. + ..JA.......AJ... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 259 (giant bat,female) +{ + ................ + ................ + ................ + ...JK.J.J.JK.... + ..KJJJCACJJKJ... + .JJJAAHJHAAJJK.. + .KJA...JA..AJJ.. + ..JA.......AJ... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 260 (raven,male) +{ + ..AAAA...AAA.... + .AAAAAA.AAA..... + AAAAAAAAAAA.AA.. + A...AAAAAAAAAAA. + ......AAAAAAAAA. + .....AAAA.....AA + .....ADA.......A + .....PA......... + .....P.......... + .........P.P.P.. + ........P.P.P.P. + .......P.P.P.... + ........P.P.P... + ...........P.... + ................ + ................ +} +# tile 261 (raven,female) +{ + ..AAAA...AAA.... + .AAAAAA.AAA..... + AAAAAAAAAAA.AA.. + A...AAAAAAAAAAA. + ......AAAAAAAAA. + .....AAAA.....AA + .....ADA.......A + .....PA......... + .....P.......... + .........P.P.P.. + ........P.P.P.P. + .......P.P.P.... + ........P.P.P... + ...........P.... + ................ + ................ +} +# tile 262 (vampire bat,male) +{ + ................ + ................ + ................ + ...AA.A.A.AA.... + ..AAAAAAAAAAA... + .AAAA.DAD.AAAA.. + .AAA...A...AAA.. + ..A.........A... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 263 (vampire bat,female) +{ + ................ + ................ + ................ + ...AA.A.A.AA.... + ..AAAAAAAAAAA... + .AAAA.DAD.AAAA.. + .AAA...A...AAA.. + ..A.........A... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 264 (plains centaur,male) +{ + ................ + ...KKA.......... + ...LLAA......... + .AAKKAA......... + .LLAALLA........ + LALLLLALA....... + LALLLKALA.A..... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 265 (plains centaur,female) +{ + ................ + ...KKA.......... + ...LLAA......... + .AAKKAA......... + .LLAALLA........ + LALLLLALA....... + LALLLKALA.A..... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 266 (forest centaur,male) +{ + ................ + ................ + ................ + ...KKA.......... + LA.LLAALA....... + LAALLAALA....... + .LLAALLA........ + ..LLLLA.A....... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKA.A.. + .KAKJJJJKJAAAA.. + .KAAKAAJAKA..... + ..C.KAAKAK...... + ....CA...C...... + ................ +} +# tile 267 (forest centaur,female) +{ + ................ + ................ + ................ + ...KKA.......... + LA.LLAALA....... + LAALLAALA....... + .LLAALLA........ + ..LLLLA.A....... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKA.A.. + .KAKJJJJKJAAAA.. + .KAAKAAJAKA..... + ..C.KAAKAK...... + ....CA...C...... + ................ +} +# tile 268 (mountain centaur,male) +{ + ................ + ................ + ...KKA.......... + ...LLAA......... + ..AKKAA......... + .LJJJJLA........ + LAJKKJALA.A..... + LAKKKKALAAA..... + ..JJJJKJJKAA.... + .KJJJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 269 (mountain centaur,female) +{ + ................ + ................ + ...KKA.......... + ...LLAA......... + ..AKKAA......... + .LJJJJLA........ + LAJKKJALA.A..... + LAKKKKALAAA..... + ..JJJJKJJKAA.... + .KJJJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 270 (baby gray dragon,male) +{ + ................ + ................ + ................ + .....BBBA....... + ....NPNPPA...... + ...BPPPPPA...... + ..CHHPABPA.AAA.. + .CHCDA.BPAAAAAA. + ..D..BPPAAAAAAA. + ....BBPPPPPAAAA. + ...BOOPPPPPPAAA. + ..BPOBPPPPPPPAA. + ..BPPBPPOBPAPPA. + ..BPABP.ABPAPPA. + .....BPAA..PPAA. + ...........PAA.. +} +# tile 271 (baby gray dragon,female) +{ + ................ + ................ + ................ + .....BBBA....... + ....NPNPPA...... + ...BPPPPPA...... + ..CHHPABPA.AAA.. + .CHCDA.BPAAAAAA. + ..D..BPPAAAAAAA. + ....BBPPPPPAAAA. + ...BOOPPPPPPAAA. + ..BPOBPPPPPPPAA. + ..BPPBPPOBPAPPA. + ..BPABP.ABPAPPA. + .....BPAA..PPAA. + ...........PAA.. +} +# tile 272 (baby silver dragon,male) +{ + ................ + ................ + ................ + .....PPPA....... + ....OBOBBA...... + ...PBBBBBA...... + ..CHHBAPBA.AAA.. + .CHCDA.PBAAAAAA. + ..D..PBBAAAAAAA. + ....PPBBBBBAAAA. + ...PNNBBBBBBAAA. + ..PBNPBBBBBBBAA. + ..PBBPBBNPBABBA. + ..PBAPB.APBABBA. + .....PBAA..BBAA. + ...........BAA.. +} +# tile 273 (baby silver dragon,female) +{ + ................ + ................ + ................ + .....PPPA....... + ....OBOBBA...... + ...PBBBBBA...... + ..CHHBAPBA.AAA.. + .CHCDA.PBAAAAAA. + ..D..PBBAAAAAAA. + ....PPBBBBBAAAA. + ...PNNBBBBBBAAA. + ..PBNPBBBBBBBAA. + ..PBBPBBNPBABBA. + ..PBAPB.APBABBA. + .....PBAA..BBAA. + ...........BAA.. +} +# tile 274 (baby shimmering dragon,male) +{ + .I.............. + ...BBBBBBB.I.... + ..BF.FFF.FB...I. + .BF..BBBA.FB.... + BF..NPNPPAFB.I.. + BF.BPPPPPA.B.... + B.CHHPABPAFBAAI. + BCHCDA.BPAAFBAA. + B.D..BPPAAAAFBA. + B...BBPPPPPAAFB. + BF.BOOPPPPPPAAAB + BFBPOBPPPPPPPAFB + BFBPPBPPOBPAPPFB + B.BPABP.ABPAPPFB + B....BPAA..PPAAB + .B.........PAAB. +} +# tile 275 (baby shimmering dragon,female) +{ + .I.............. + ...BBBBBBB.I.... + ..BF.FFF.FB...I. + .BF..BBBA.FB.... + BF..NPNPPAFB.I.. + BF.BPPPPPA.B.... + B.CHHPABPAFBAAI. + BCHCDA.BPAAFBAA. + B.D..BPPAAAAFBA. + B...BBPPPPPAAFB. + BF.BOOPPPPPPAAAB + BFBPOBPPPPPPPAFB + BFBPPBPPOBPAPPFB + B.BPABP.ABPAPPFB + B....BPAA..PPAAB + .B.........PAAB. +} +# tile 276 (baby red dragon,male) +{ + ................ + ................ + ................ + .....IIIA....... + ....NDNDDA...... + ...IDDDDDA...... + ..CHHDAIDA.AAA.. + .CHCDA.IDAAAAAA. + ..D..IDDAAAAAAA. + ....IIDDDDDAAAA. + ...IHHDDDDDDAAA. + ..IDHIDDDDDDDAA. + ..IDDIDDHIDADDA. + ..IDAID.AIDADDA. + .....IDAA..DDAA. + ...........DAA.. +} +# tile 277 (baby red dragon,female) +{ + ................ + ................ + ................ + .....IIIA....... + ....NDNDDA...... + ...IDDDDDA...... + ..CHHDAIDA.AAA.. + .CHCDA.IDAAAAAA. + ..D..IDDAAAAAAA. + ....IIDDDDDAAAA. + ...IHHDDDDDDAAA. + ..IDHIDDDDDDDAA. + ..IDDIDDHIDADDA. + ..IDAID.AIDADDA. + .....IDAA..DDAA. + ...........DAA.. +} +# tile 278 (baby white dragon,male) +{ + ................ + ................ + ................ + .....NNNA....... + ....IOIOOA...... + ...NOOOOOA...... + ..CHHOANOA.AAA.. + .CHCDA.NOAAAAAA. + ..D..NOOAAAAAAA. + ....NNOOOOOAAAA. + ...NOOOOOOOOAAA. + ..NOONOOOOOOOAA. + ..NOONOOONOAOOA. + ..NOANO.ANOAOOA. + .....NOAA..OOAA. + ...........OAA.. +} +# tile 279 (baby white dragon,female) +{ + ................ + ................ + ................ + .....NNNA....... + ....IOIOOA...... + ...NOOOOOA...... + ..CHHOANOA.AAA.. + .CHCDA.NOAAAAAA. + ..D..NOOAAAAAAA. + ....NNOOOOOAAAA. + ...NOOOOOOOOAAA. + ..NOONOOOOOOOAA. + ..NOONOOONOAOOA. + ..NOANO.ANOAOOA. + .....NOAA..OOAA. + ...........OAA.. +} +# tile 280 (baby orange dragon,male) +{ + ................ + ................ + ................ + .....LLLA....... + ....NCNCCA...... + ...LCCCCCA...... + ..CHHCALCA.AAA.. + .CHCDA.LCAAAAAA. + ..D..LCCAAAAAAA. + ....LLCCCCCAAAA. + ...LOOCCCCCCAAA. + ..LCOLCCCCCCCAA. + ..LCCLCCOLCACCA. + ..LCALC.ALCACCA. + .....LCAA..CCAA. + ...........CAA.. +} +# tile 281 (baby orange dragon,female) +{ + ................ + ................ + ................ + .....LLLA....... + ....NCNCCA...... + ...LCCCCCA...... + ..CHHCALCA.AAA.. + .CHCDA.LCAAAAAA. + ..D..LCCAAAAAAA. + ....LLCCCCCAAAA. + ...LOOCCCCCCAAA. + ..LCOLCCCCCCCAA. + ..LCCLCCOLCACCA. + ..LCALC.ALCACCA. + .....LCAA..CCAA. + ...........CAA.. +} +# tile 282 (baby black dragon,male) +{ + ................ + ................ + ................ + .....AAA........ + ....NANAA....... + ...AAAAAA....... + ..CHHA.AA..PPP.. + .CHCD..AA.PPPPP. + ..D..AAAPPP.PPP. + ....AAAAAAAPPPP. + ...AAAAAAAAAPPP. + ..AAAAAAAAAAAPP. + ..AAAAAAAAAPAAP. + ..AAPAA.PAAPAAP. + .....AAP...AAPP. + ...........APP.. +} +# tile 283 (baby black dragon,female) +{ + ................ + ................ + ................ + .....AAA........ + ....NANAA....... + ...AAAAAA....... + ..CHHA.AA..PPP.. + .CHCD..AA.PPPPP. + ..D..AAAPPP.PPP. + ....AAAAAAAPPPP. + ...AAAAAAAAAPPP. + ..AAAAAAAAAAAPP. + ..AAAAAAAAAPAAP. + ..AAPAA.PAAPAAP. + .....AAP...AAPP. + ...........APP.. +} +# tile 284 (baby blue dragon,male) +{ + ................ + ................ + ................ + .....BBBA....... + ....NENEEA...... + ...BEEEEEA...... + ..CHHEABEA.AAA.. + CCHCDA.BEAAAAAA. + ..D..BEEAAAAAAA. + ....BBEEEEEAAAA. + ...BOOEEEEEEAAA. + ..BEOBEEEEEEEAA. + ..BEEBEEOBEAEEA. + ..BEABE.ABEAEEA. + .....BEAA..EEAA. + ...........EAA.. +} +# tile 285 (baby blue dragon,female) +{ + ................ + ................ + ................ + .....BBBA....... + ....NENEEA...... + ...BEEEEEA...... + ..CHHEABEA.AAA.. + CCHCDA.BEAAAAAA. + ..D..BEEAAAAAAA. + ....BBEEEEEAAAA. + ...BOOEEEEEEAAA. + ..BEOBEEEEEEEAA. + ..BEEBEEOBEAEEA. + ..BEABE.ABEAEEA. + .....BEAA..EEAA. + ...........EAA.. +} +# tile 286 (baby green dragon,male) +{ + ................ + ................ + ................ + .....GGGA....... + ....NFNFFA...... + ...GFFFFFA...... + ..CHHFAGFA.AAA.. + .CHCDA.GFAAAAAA. + ..D..GFFAAAAAAA. + ....GGFFFFFAAAA. + ...GOOFFFFFFAAA. + ..GFOGFFFFFFFAA. + ..GFFGFFOGFAFFA. + ..GFAGF.AGFAFFA. + .....GFAA..FFAA. + ...........FAA.. +} +# tile 287 (baby green dragon,female) +{ + ................ + ................ + ................ + .....GGGA....... + ....NFNFFA...... + ...GFFFFFA...... + ..CHHFAGFA.AAA.. + .CHCDA.GFAAAAAA. + ..D..GFFAAAAAAA. + ....GGFFFFFAAAA. + ...GOOFFFFFFAAA. + ..GFOGFFFFFFFAA. + ..GFFGFFOGFAFFA. + ..GFAGF.AGFAFFA. + .....GFAA..FFAA. + ...........FAA.. +} +# tile 288 (baby yellow dragon,male) +{ + ................ + ................ + ................ + .....NNNA....... + ....DHDHHA...... + ...NHHHHHA...... + ..CHHHANHA.AAA.. + .CHCDA.NHAAAAAA. + ..D..NHHAAAAAAA. + ....NNHHHHHAAAA. + ...NOOHHHHHHAAA. + ..NHONHHHHHHHAA. + ..NHHNHHONHAHHA. + ..NHANH.ANHAHHA. + .....NHAA..HHAA. + ...........HAA.. +} +# tile 289 (baby yellow dragon,female) +{ + ................ + ................ + ................ + .....NNNA....... + ....DHDHHA...... + ...NHHHHHA...... + ..CHHHANHA.AAA.. + .CHCDA.NHAAAAAA. + ..D..NHHAAAAAAA. + ....NNHHHHHAAAA. + ...NOOHHHHHHAAA. + ..NHONHHHHHHHAA. + ..NHHNHHONHAHHA. + ..NHANH.ANHAHHA. + .....NHAA..HHAA. + ...........HAA.. +} +# tile 290 (gray dragon,male) +{ + ......BBBPA..... + .....NPNPPPA.... + ....BPPPPPPA.... + ..DCHHP..PPA.... + CHCHCD..BPPA.... + HD.D...BPPA..... + ......OBPAAAAAA. + ....BOBPAAAAAAAA + ..BOOBPA.PP.AAA. + .BOOOBPPPPPP.AA. + .BOOOBPPPPPPPAA. + PPOOBBPPPPPPPPA. + BP.OBPPOOPP.P.A. + BPAABP.AAPPAPPA. + ....BPAA...PP.A. + ........PPPP.A.. +} +# tile 291 (gray dragon,female) +{ + ......BBBPA..... + .....NPNPPPA.... + ....BPPPPPPA.... + ..DCHHP..PPA.... + CHCHCD..BPPA.... + HD.D...BPPA..... + ......OBPAAAAAA. + ....BOBPAAAAAAAA + ..BOOBPA.PP.AAA. + .BOOOBPPPPPP.AA. + .BOOOBPPPPPPPAA. + PPOOBBPPPPPPPPA. + BP.OBPPOOPP.P.A. + BPAABP.AAPPAPPA. + ....BPAA...PP.A. + ........PPPP.A.. +} +# tile 292 (silver dragon,male) +{ + ......PPPBA..... + .....OBOBBBA.... + ....PBBBBBBA.... + ..DCHHB..BBA.... + CHCHCD..PBBA.... + HD.D...PBBA..... + ......NPBAAAAAA. + ....PNPBAAAAAAAA + ..PNNPBA.BB.AAA. + .PNNNPBBBBBB.AA. + .PNNNPBBBBBBBAA. + BBNNPPBBBBBBBBA. + PB.NPBBNNBB.B.A. + PBAAPB.AABBABBA. + ....PBAA...BB.A. + ........BBBB.A.. +} +# tile 293 (silver dragon,female) +{ + ......PPPBA..... + .....OBOBBBA.... + ....PBBBBBBA.... + ..DCHHB..BBA.... + CHCHCD..PBBA.... + HD.D...PBBA..... + ......NPBAAAAAA. + ....PNPBAAAAAAAA + ..PNNPBA.BB.AAA. + .PNNNPBBBBBB.AA. + .PNNNPBBBBBBBAA. + BBNNPPBBBBBBBBA. + PB.NPBBNNBB.B.A. + PBAAPB.AABBABBA. + ....PBAA...BB.A. + ........BBBB.A.. +} +# tile 294 (shimmering dragon,male) +{ + .I.BF.BBBPAFB... + ..BF.NPNPPPAFB.I + .BF.BPPPPPPAFB.. + .BDCHHP..PPAFBI. + CBCHCD..BPPAFB.. + HDBB...BPPA.B..I + ..BF..OBPAAAABA. + .BF.BOBPAAAAAFBA + BFBOOBPA.PP.AAFB + .BOOOBPPPPPP.AFB + .BOOOBPPPPPPPAFB + PPOOBBPPPPPPPPFB + BP.OBPPOOPP.P.FB + BPAABP.AAPPAPPFB + ....BPAA...PP.AB + ........PPPP.AB. +} +# tile 295 (shimmering dragon,female) +{ + .I.BF.BBBPAFB... + ..BF.NPNPPPAFB.I + .BF.BPPPPPPAFB.. + .BDCHHP..PPAFBI. + CBCHCD..BPPAFB.. + HDBB...BPPA.B..I + ..BF..OBPAAAABA. + .BF.BOBPAAAAAFBA + BFBOOBPA.PP.AAFB + .BOOOBPPPPPP.AFB + .BOOOBPPPPPPPAFB + PPOOBBPPPPPPPPFB + BP.OBPPOOPP.P.FB + BPAABP.AAPPAPPFB + ....BPAA...PP.AB + ........PPPP.AB. +} +# tile 296 (red dragon,male) +{ + ......IIIDA..... + .....NDNDDDA.... + ....IDDDDDDA.... + ..DCHHD..DDA.... + CHCHCD..IDDA.... + HD.D...IDDA..... + ......HIDAAAAAA. + ....IHIDAAAAAAAA + ..IHHIDAJDDJAAA. + .IHHHIDDDDDDJAA. + .IHHHIDDDDDDDAA. + DDHHIIDDDDDDDDA. + ID.HIDDHHDDJDJA. + IDAAID.AADDADDA. + ....IDAAJJJDDJA. + ........DDDDJA.. +} +# tile 297 (red dragon,female) +{ + ......IIIDA..... + .....NDNDDDA.... + ....IDDDDDDA.... + ..DCHHD..DDA.... + CHCHCD..IDDA.... + HD.D...IDDA..... + ......HIDAAAAAA. + ....IHIDAAAAAAAA + ..IHHIDAJDDJAAA. + .IHHHIDDDDDDJAA. + .IHHHIDDDDDDDAA. + DDHHIIDDDDDDDDA. + ID.HIDDHHDDJDJA. + IDAAID.AADDADDA. + ....IDAAJJJDDJA. + ........DDDDJA.. +} +# tile 298 (white dragon,male) +{ + ......NNNOA..... + .....IOIOOOA.... + ....NOOOOOOA.... + ..DCHHO..OOA.... + CHCHCD..NOOA.... + HD.D...NOOA..... + ......ONOAAAAAA. + ....NONOAAAAAAAA + ..NOONOA.OO.AAA. + .NOOONOOOOOOJAA. + .NOOONOOOOOOOAA. + OOOONNOOOOOOOOA. + NO.ONOOOOOO.OJA. + NOAANO.AAOOAOOA. + ....NOAA...OOJA. + ........OOOOJA.. +} +# tile 299 (white dragon,female) +{ + ......NNNOA..... + .....IOIOOOA.... + ....NOOOOOOA.... + ..DCHHO..OOA.... + CHCHCD..NOOA.... + HD.D...NOOA..... + ......ONOAAAAAA. + ....NONOAAAAAAAA + ..NOONOA.OO.AAA. + .NOOONOOOOOOJAA. + .NOOONOOOOOOOAA. + OOOONNOOOOOOOOA. + NO.ONOOOOOO.OJA. + NOAANO.AAOOAOOA. + ....NOAA...OOJA. + ........OOOOJA.. +} +# tile 300 (orange dragon,male) +{ + ......LLLCA..... + .....NCNCCCA.... + ....LCCCCCCA.... + ..DCHHC..CCA.... + CHCHCD..LCCA.... + HD.D...LCCA..... + ......OLCAAAAAA. + ....LOLCAAAAAAAA + ..LOOLCA.CCKAAA. + .LOOOLCCCCCCJAA. + .LOOOLCCCCCCCAA. + CCOOLLCCCCCCCCA. + LC.OLCCOOCCKCJA. + LCAALC.AACCACCA. + ....LCAA.KKCCJA. + ........CCCCJA.. +} +# tile 301 (orange dragon,female) +{ + ......LLLCA..... + .....NCNCCCA.... + ....LCCCCCCA.... + ..DCHHC..CCA.... + CHCHCD..LCCA.... + HD.D...LCCA..... + ......OLCAAAAAA. + ....LOLCAAAAAAAA + ..LOOLCA.CCKAAA. + .LOOOLCCCCCCJAA. + .LOOOLCCCCCCCAA. + CCOOLLCCCCCCCCA. + LC.OLCCOOCCKCJA. + LCAALC.AACCACCA. + ....LCAA.KKCCJA. + ........CCCCJA.. +} +# tile 302 (black dragon,male) +{ + ......AAAA...... + .....NANAAA..... + ....AAAAAAA..... + ..DCHHA..AA..... + CHCHCD..AAA..... + HD.D...AAA...... + ......AAA..PPPP. + ....AAAAPPPPPPPP + ..AAAAAAAAA.PPP. + .AAAAAAAAAAAAPP. + .AAAAAAAAAAAAPP. + AAAAAAAAAAAAAAP. + AA.AAAAAAAA.AAP. + AAPPAA.PPAAPAAP. + ....AAPP...AAAP. + ........AAAAA... +} +# tile 303 (black dragon,female) +{ + ......AAAA...... + .....NANAAA..... + ....AAAAAAA..... + ..DCHHA..AA..... + CHCHCD..AAA..... + HD.D...AAA...... + ......AAA..PPPP. + ....AAAAPPPPPPPP + ..AAAAAAAAA.PPP. + .AAAAAAAAAAAAPP. + .AAAAAAAAAAAAPP. + AAAAAAAAAAAAAAP. + AA.AAAAAAAA.AAP. + AAPPAA.PPAAPAAP. + ....AAPP...AAAP. + ........AAAAA... +} +# tile 304 (blue dragon,male) +{ + ......BBBEA..... + .....NENEEEA.... + ....BEEEEEEA.... + ..DCHHE..EEA.... + CHCHCD..BEEA.... + HD.D...BEEA..... + ......OBEAAAAAA. + ....BOBEAAAAAAAA + ..BOOBEA.EE.AAA. + .BOOOBEEEEEEJAA. + .BOOOBEEEEEEEAA. + EEOOBBEEEEEEEEA. + BE.OBEEOOEE.EJA. + BEAABE.AAEEAEEA. + ....BEAA...EEJA. + ...P....EEEEJA.. +} +# tile 305 (blue dragon,female) +{ + ......BBBEA..... + .....NENEEEA.... + ....BEEEEEEA.... + ..DCHHE..EEA.... + CHCHCD..BEEA.... + HD.D...BEEA..... + ......OBEAAAAAA. + ....BOBEAAAAAAAA + ..BOOBEA.EE.AAA. + .BOOOBEEEEEEJAA. + .BOOOBEEEEEEEAA. + EEOOBBEEEEEEEEA. + BE.OBEEOOEE.EJA. + BEAABE.AAEEAEEA. + ....BEAA...EEJA. + ...P....EEEEJA.. +} +# tile 306 (green dragon,male) +{ + ......GGGFA..... + .....NFNFFFA.... + ....GFFFFFFA.... + ..DCHHF..FFA.... + CHCHCD..GFFA.... + HD.D...GFFA..... + ......OGFAAAAAA. + ....GOGFAAAAAAAA + ..GOOGFA.FF.AAA. + .GOOOGFFFFFFJAA. + .GOOOGFFFFFFFAA. + FFOOGGFFFFFFFFA. + GF.OGFFOOFF.FJA. + GFAAGF.AAFFAFFA. + ....GFAA...FFJA. + ........FFFFJA.. +} +# tile 307 (green dragon,female) +{ + ......GGGFA..... + .....NFNFFFA.... + ....GFFFFFFA.... + ..DCHHF..FFA.... + CHCHCD..GFFA.... + HD.D...GFFA..... + ......OGFAAAAAA. + ....GOGFAAAAAAAA + ..GOOGFA.FF.AAA. + .GOOOGFFFFFFJAA. + .GOOOGFFFFFFFAA. + FFOOGGFFFFFFFFA. + GF.OGFFOOFF.FJA. + GFAAGF.AAFFAFFA. + ....GFAA...FFJA. + ........FFFFJA.. +} +# tile 308 (yellow dragon,male) +{ + ......NNNHA..... + .....DHDHHHA.... + ....NHHHHHHA.... + ..DCHHH..HHA.... + CHCHCD..NHHA.... + HD.D...NHHA..... + ......ONHAAAAAA. + ....NONHAAAAAAAA + ..NOONHAJHHJAAA. + .NOOONHHHHHHJAA. + .NOOONHHHHHHHAA. + HHOONNHHHHHHHHA. + NH.ONHHOOHHJHJA. + NHAANH.AAHHAHHA. + ....NHAAJJJHHJA. + ........HHHHJA.. +} +# tile 309 (yellow dragon,female) +{ + ......NNNHA..... + .....DHDHHHA.... + ....NHHHHHHA.... + ..DCHHH..HHA.... + CHCHCD..NHHA.... + HD.D...NHHA..... + ......ONHAAAAAA. + ....NONHAAAAAAAA + ..NOONHAJHHJAAA. + .NOOONHHHHHHJAA. + .NOOONHHHHHHHAA. + HHOONNHHHHHHHHA. + NH.ONHHOOHHJHJA. + NHAANH.AAHHAHHA. + ....NHAAJJJHHJA. + ........HHHHJA.. +} +# tile 310 (stalker,male) +{ + ................ + .......PPP...... + ......P.P.P..... + .....PPPPPP..... + .....PP..PPP.... + ....PPPPPP.P.... + ....P.PPPP.P.... + ....P.PPP..P.... + ....P..PP..P.... + ....P.PPPP.P.... + ....P.P..P.P.... + ....P.P..P.P.... + ......P..P...... + ......P..P...... + .....PP..PP..... + ................ +} +# tile 311 (stalker,female) +{ + ................ + .......PPP...... + ......P.P.P..... + .....PPPPPP..... + .....PP..PPP.... + ....PPPPPP.P.... + ....P.PPPP.P.... + ....P.PPP..P.... + ....P..PP..P.... + ....P.PPPP.P.... + ....P.P..P.P.... + ....P.P..P.P.... + ......P..P...... + ......P..P...... + .....PP..PP..... + ................ +} +# tile 312 (air elemental,male) +{ + ................ + ...P.PPP..P..... + ..P.PAPA.P...... + P..PPPPPP..P.... + .P.PPAAPPP...P.. + ..PPPAAP.P.P.... + ..PAPAAPAP...... + P.PAPPP.AP.P.AA. + ..PA.PP.AP.AAAA. + ..PAPPPPAPAAAA.. + ..PAP.APAPAAAA.. + ..PAP.APAPAAAAA. + ....P.APAAAAAAA. + ..P.P.APPAAAAAA. + ...PP.APPPA..... + ................ +} +# tile 313 (air elemental,female) +{ + ................ + ...P.PPP..P..... + ..P.PAPA.P...... + P..PPPPPP..P.... + .P.PPAAPPP...P.. + ..PPPAAP.P.P.... + ..PAPAAPAP...... + P.PAPPP.AP.P.AA. + ..PA.PP.AP.AAAA. + ..PAPPPPAPAAAA.. + ..PAP.APAPAAAA.. + ..PAP.APAPAAAAA. + ....P.APAAAAAAA. + ..P.P.APPAAAAAA. + ...PP.APPPA..... + ................ +} +# tile 314 (fire elemental,male) +{ + ................ + .H..LDDD........ + ...LDADAC.H..... + H..DDDDDD..H.H.. + ..LDDAADDD...... + ..DDDAADCD.H.... + ..DADAACAD...... + H.DADDDCAD...AA. + ..DACDDCAD.AAAA. + ..DADDDDADAAAA.. + ..DADCADADAAAA.. + H.DADCADADAAAAA. + ....DCADAAAAAAA. + .H.LDCADDAAAAAA. + ..LDDCADDDA..... + ................ +} +# tile 315 (fire elemental,female) +{ + ................ + .H..LDDD........ + ...LDADAC.H..... + H..DDDDDD..H.H.. + ..LDDAADDD...... + ..DDDAADCD.H.... + ..DADAACAD...... + H.DADDDCAD...AA. + ..DACDDCAD.AAAA. + ..DADDDDADAAAA.. + ..DADCADADAAAA.. + H.DADCADADAAAAA. + ....DCADAAAAAAA. + .H.LDCADDAAAAAA. + ..LDDCADDDA..... + ................ +} +# tile 316 (earth elemental,male) +{ + ..F............. + ....CKKK..F..... + ...CKAKAJ....F.. + ...KKKKKK....... + ..CKKAAKKK.F..F. + .FKKKAAKJK...... + ..KAKAAJAK..F... + ..KAKJJJAK...AA. + F.KAJKKJAK.AAAA. + ..KAKKKKAKAAAA.. + ..KAKJAKAKAAAA.. + ..KAKJAKAKAAAAA. + ....KJAKAAAAAAA. + .F.CKJAKKAAAAAA. + ..CKKJAKKKA..... + ................ +} +# tile 317 (earth elemental,female) +{ + ..F............. + ....CKKK..F..... + ...CKAKAJ....F.. + ...KKKKKK....... + ..CKKAAKKK.F..F. + .FKKKAAKJK...... + ..KAKAAJAK..F... + ..KAKJJJAK...AA. + F.KAJKKJAK.AAAA. + ..KAKKKKAKAAAA.. + ..KAKJAKAKAAAA.. + ..KAKJAKAKAAAAA. + ....KJAKAAAAAAA. + .F.CKJAKKAAAAAA. + ..CKKJAKKKA..... + ................ +} +# tile 318 (water elemental,male) +{ + ................ + ....PBBB..E..... + .E.PBABAE...E... + ...BBBBBB....... + ..PBBAABBB.E..E. + E.BBBAABEB...... + ..BABAABEB.E.... + ..BABBBBEB...AA. + ..BAPBBEAB.AAAA. + E.BABBBBABAAAA.. + ..BABEABABAAAA.. + ..BABEABABAAAAA. + ....BEABAAAAAAA. + .E.PBEABBAAAAAA. + ..PBBEABBBA..... + ................ +} +# tile 319 (water elemental,female) +{ + ................ + ....PBBB..E..... + .E.PBABAE...E... + ...BBBBBB....... + ..PBBAABBB.E..E. + E.BBBAABEB...... + ..BABAABEB.E.... + ..BABBBBEB...AA. + ..BAPBBEAB.AAAA. + E.BABBBBABAAAA.. + ..BABEABABAAAA.. + ..BABEABABAAAAA. + ....BEABAAAAAAA. + .E.PBEABBAAAAAA. + ..PBBEABBBA..... + ................ +} +# tile 320 (lichen,male) +{ + ................ + ................ + ...FFF...FFF.... + ..FCFFFFFCCFA... + .FCOOFFFCOFFFA.. + .FCOOFFFCFFFFA.. + ..FFFFFFFFFFA... + ...AFFFCCFFFA... + ...FFFFCOFFAA... + ..FCCFFCOFCFA... + ..FCOFFCFFOCFA.. + ..FFCFFFCFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 321 (lichen,female) +{ + ................ + ................ + ...FFF...FFF.... + ..FCFFFFFCCFA... + .FCOOFFFCOFFFA.. + .FCOOFFFCFFFFA.. + ..FFFFFFFFFFA... + ...AFFFCCFFFA... + ...FFFFCOFFAA... + ..FCCFFCOFCFA... + ..FCOFFCFFOCFA.. + ..FFCFFFCFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 322 (brown mold,male) +{ + ................ + ................ + ...JJJ...JJJ.... + ..JKJJJJJKKJA... + .JKCCJJJKCJJJA.. + .JKCCJJJKJJJJA.. + ..JJJJJJJJJJA... + ...AJJJKKJJJA... + ...JJJJKCJJAA... + ..JKKJJKCJKJA... + ..JKCJJKJJCKJA.. + ..JJKJJJKJJJJA.. + ...JJJAAJJJJJA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 323 (brown mold,female) +{ + ................ + ................ + ...JJJ...JJJ.... + ..JKJJJJJKKJA... + .JKCCJJJKCJJJA.. + .JKCCJJJKJJJJA.. + ..JJJJJJJJJJA... + ...AJJJKKJJJA... + ...JJJJKCJJAA... + ..JKKJJKCJKJA... + ..JKCJJKJJCKJA.. + ..JJKJJJKJJJJA.. + ...JJJAAJJJJJA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 324 (yellow mold,male) +{ + ................ + ................ + ...HHH...HHH.... + ..HHHHHHHNHHA... + .HHNNOHHNNOHHA.. + .HHNNOOHHOOHHA.. + ..HHOOHHHHHHA... + ...AHHHHHHHHA... + ...HHHHNNOHAA... + ..HHHHHNNOHHA... + ..HNNOHHHONOHA.. + ..HHOHHHHHOOHA.. + ...HHHAAHHHHHA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 325 (yellow mold,female) +{ + ................ + ................ + ...HHH...HHH.... + ..HHHHHHHNHHA... + .HHNNOHHNNOHHA.. + .HHNNOOHHOOHHA.. + ..HHOOHHHHHHA... + ...AHHHHHHHHA... + ...HHHHNNOHAA... + ..HHHHHNNOHHA... + ..HNNOHHHONOHA.. + ..HHOHHHHHOOHA.. + ...HHHAAHHHHHA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 326 (green mold,male) +{ + ................ + ................ + ...FFF...FFF.... + ..FGFFFFFGGFA... + .FGOOFFFGOFFFA.. + .FGOOFFFGFFFFA.. + ..FFFFFFFFFFA... + ...AFFFGGFFFA... + ...FFFFGOFFAA... + ..FGGFFGOFGFA... + ..FGOFFGFFOGFA.. + ..FFGFFFGFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 327 (green mold,female) +{ + ................ + ................ + ...FFF...FFF.... + ..FGFFFFFGGFA... + .FGOOFFFGOFFFA.. + .FGOOFFFGFFFFA.. + ..FFFFFFFFFFA... + ...AFFFGGFFFA... + ...FFFFGOFFAA... + ..FGGFFGOFGFA... + ..FGOFFGFFOGFA.. + ..FFGFFFGFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 328 (red mold,male) +{ + ................ + ................ + ...DDD...DDD.... + ..DCDDDDDCCDA... + .DLLCDDDCLDDDA.. + .DCCCDDDCDDDDA.. + ..DDDDDDDDDDA... + ...ADDDCCDDDA... + ...DDDDCLDDAA... + ..DCCDDCLDCDA... + ..DCLDDCDDLCDA.. + ..DDCDDDCDDDDA.. + ...DDDAADDDDDA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 329 (red mold,female) +{ + ................ + ................ + ...DDD...DDD.... + ..DCDDDDDCCDA... + .DLLCDDDCLDDDA.. + .DCCCDDDCDDDDA.. + ..DDDDDDDDDDA... + ...ADDDCCDDDA... + ...DDDDCLDDAA... + ..DCCDDCLDCDA... + ..DCLDDCDDLCDA.. + ..DDCDDDCDDDDA.. + ...DDDAADDDDDA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 330 (shrieker,male) +{ + ................ + ................ + ................ + ................ + .....GGGGFF..... + ...GGGGIGIDFF... + .GGGIIGGGIIFFFF. + GIIGIIGGGGGGGDDF + GIIGGGGIIGIIGIDF + GGGGIGGIIGIIGGFF + ..GGGGGGGGGGG... + ......FFF..AAAAA + ....AGGGFFAAAAAA + ...AGGGGGGFAAAA. + ...AAAAAAAAAA... + ................ +} +# tile 331 (shrieker,female) +{ + ................ + ................ + ................ + ................ + .....GGGGFF..... + ...GGGGIGIDFF... + .GGGIIGGGIIFFFF. + GIIGIIGGGGGGGDDF + GIIGGGGIIGIIGIDF + GGGGIGGIIGIIGGFF + ..GGGGGGGGGGG... + ......FFF..AAAAA + ....AGGGFFAAAAAA + ...AGGGGGGFAAAA. + ...AAAAAAAAAA... + ................ +} +# tile 332 (violet fungus,male) +{ + ................ + ................ + ...III...III.... + ..ILIIIIILLIA... + .IOOLIIILOIIIA.. + .ILLLIIILIIIIA.. + ..IIIIIIIIIIA... + ...AIIILLIIIA... + ...IIIILOIIAA... + ..ILLIILOILIA... + ..ILOIILIIOLIA.. + ..IILIIILIIIIA.. + ...IIIAAIIIIIA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 333 (violet fungus,female) +{ + ................ + ................ + ...III...III.... + ..ILIIIIILLIA... + .IOOLIIILOIIIA.. + .ILLLIIILIIIIA.. + ..IIIIIIIIIIA... + ...AIIILLIIIA... + ...IIIILOIIAA... + ..ILLIILOILIA... + ..ILOIILIIOLIA.. + ..IILIIILIIIIA.. + ...IIIAAIIIIIA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 334 (gnome,male) +{ + ................ + ................ + ................ + .....DF......... + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + .....OLO...AAA.. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 335 (gnome,female) +{ + ................ + ................ + ................ + .....DF......... + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + .....LLL...AAA.. + ...FGGGGFFAAAA.. + ...GAGFFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 336 (gnome leader,male) +{ + ................ + ................ + ......D......... + ......G......... + ......G......... + .....GFF........ + ....HHHHH....... + ....GLLLF.....A. + .....OLO...AAA.. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 337 (gnome leader,female) +{ + ................ + ................ + ......D......... + ......G......... + ......G......... + .....GFF........ + ....HHHHH....... + ....GLLLF.....A. + .....LLL...AAA.. + ...FGGGGFFAAAA.. + ...GAGGFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 338 (gnomish wizard,male) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + ...FFOLOFF.AAA.. + ...GFOOOFFAAAA.. + ...FAGOFAFAAAA.. + ...GLKNKFFAAA... + ...FFGFFFFA..... + ...GFFFFGFA..... + ................ + ................ +} +# tile 339 (gnomish wizard,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + ...FFLLLFF.AAA.. + ...GFGFGFFAAAA.. + ...FAGGFAFAAAA.. + ...GLKNKFFAAA... + ...FFGFFFFA..... + ...GFFFFGFA..... + ................ + ................ +} +# tile 340 (gnome ruler,male) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....GLLLF...A... + .....OLO...AAAA. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 341 (gnome ruler,female) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....GLLLF...A... + .....LLL...AAAA. + ...FGGGGFFAAAA.. + ...GAGFFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 342 (giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLKLKCKCLKLLLA + .LLAALLCCLLAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 343 (giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLKLKCKCLKLLLA + .LLAALLCCLLAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 344 (stone giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLAAKCKCLKLLLA + .LLPPPACCLLAALLA + .LLPPPPAKKJAALLA + .CLCPPPAJJKKCLAA + ..LLPPALACLJLLAA + .....ALJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 345 (stone giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLAAKCKCLKLLLA + .LLPPPACCLLAALLA + .LLPPPPAKKJAALLA + .CLCPPPAJJKKCLAA + ..LLPPALACLJLLAA + .....ALJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 346 (hill giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ...JJKJJJJJJJAA. + ..LJJCCKCKCJJLA. + ..JLKKKCKCKKLJA. + ..LAAKKCCKJAALAA + ..LAAJJJKKJAALAA + ..LC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 347 (hill giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ...JJKJJJJJJJAA. + ..LJJCCKCKCJJLA. + ..JLKKKCKCKKLJA. + ..LAAKKCCKJAALAA + ..LAAJJJKKJAALAA + ..LC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 348 (fire giant,male) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLJAAAA. + ...JPDJJJJJJJAA. + ..LDDHDKCKCJJLA. + ..JLHDDCKCKKLJA. + ..LAHDHCCKJAALAA + JLAADDHJKKJAALAA + JJLJDHHJJJKKCLAA + ..LLJJJJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 349 (fire giant,female) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLJAAAA. + ...JPDJJJJJJJAA. + ..LDDHDKCKCJJLA. + ..JLHDDCKCKKLJA. + ..LAHDHCCKJAALAA + JLAADDHJKKJAALAA + JJLJDHHJJJKKCLAA + ..LLJJJJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 350 (frost giant,male) +{ + .....KJJJJAA.... + ....KJJJJJJJA... + ....JJLLLLJJA... + ....JEELLEEJA... + ....JLLLLLLJA... + ....AKJJJJJAAA.. + .....KJAAJJAAAA. + ....KKJJJJAJAAAA + ...KJKJJJJAJJAAA + ..KJKKJJJJJKJJAA + ..KAAJKJJAJAAJAA + ..JAAJKKAKJAAJAA + ..LC.JJJJJKKCLAA + ..LL.CJJAJLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 351 (frost giant,female) +{ + .....KJJJJAA.... + ....KJJJJJJJA... + ....JJLLLLJJA... + ....JEELLEEJA... + ....JLLLLLLJA... + ....ALLLLLLAAA.. + .....LLAALLAAAA. + ....KKLLLLKKAAAA + ...KJKKKKKKJJAAA + ..KJKKJJJJKKJJAA + ..KAAJKJJKJAAJAA + ..JAAJKKKKJAAJAA + ..LC.JJJJJKKCLAA + ..LL.CJJAJLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 352 (ettin,male) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NPP..NPP..P... + ..ALPPLALPPLA... + ..APPPPAPPPPA... + ..APAAPAPAAPAA.. + ..APPPPAPPPPAAA. + ..BIIIIJJJIIIBAA + .BPPPIIIIIIPPPBA + .PPPFPIIIIPFPPPA + .PPAAPIIIIPAAPPA + .PPAAIIIIIIAAPPA + .BPB.IIFFIIABPAA + ..PP.BPAABPAPPAA + .....BPAABPAAAAA + ...PPPPA.BPPPFAA +} +# tile 353 (ettin,female) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NPP..NPP..P... + ..ALPPLALPPLA... + ..APPPPAPPPPA... + ..APAAPAPAAPAA.. + ..APPPPAPPPPAAA. + ..BIIIIJJJIIIBAA + .BPPPIIIIIIPPPBA + .PPPFPIIIIPFPPPA + .PPAAPIIIIPAAPPA + .PPAAIIIIIIAAPPA + .BPB.IIFFIIABPAA + ..PP.BPAABPAPPAA + .....BPAABPAAAAA + ...PPPPA.BPPPFAA +} +# tile 354 (storm giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAH.. + .....ALLLLJAHAA. + ...JJKJJJJJHHAA. + ..LJJCCKCKHHLAA. + ..JLKKKCKHHHHHH. + ..LAAKKCCKJAHHAA + ..LAAJJJKKJHHALA + ..LC.JJJJJKHAAAA + ..LL.CLJACHAAAAA + .....CLJACCJAAAA + ...LLLLJ.LLLLKAA +} +# tile 355 (storm giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAH.. + .....ALLLLJAHAA. + ...JJKJJJJJHHAA. + ..LJJCCKCKHHLAA. + ..JLKKKCKHHHHHH. + ..LAAKKCCKJAHHAA + ..LAAJJJKKJHHALA + ..LC.JJJJJKHAAAA + ..LL.CLJACHAAAAA + .....CLJACCJAAAA + ...LLLLJ.LLLLKAA +} +# tile 356 (titan,male) +{ + .....AAAAAAA.... + ....AALLLLAAA... + ....A..LL..AA... + ....ALLLLLLAA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCJJJJJJJJCCA. + .CLLLCCKCKCLLLCA + .LLLKJKCKCJKLLLA + .LLAAJJCCJJAALLA + .LLAAJJCCJJAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 357 (titan,female) +{ + .....AAAAAAA.... + ....AALLLLAAA... + ....A..LL..AA... + ....ALLLLLLAA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCJJJJJJJJCCA. + .CLLLCCKCKCLLLCA + .LLLKJKCKCJKLLLA + .LLAAJJCCJJAALLA + .LLAAJJCCJJAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 358 (minotaur,male) +{ + ................ + .O..........O... + .OOOJJJJJJOOO... + ..OOJJKJJJOO.... + ...JGAKJGAJA.... + ...JJJKJJJJA.... + ....JJKJJJAAA... + ....JKKKJAAAA... + ..CLJAJAKALCAA.A + .CLLJJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LL.JJJJJJJLLAAA + .LL.JJJJJJJLLAAA + ....CLCACLCAAAAA + ..LLLLL.LLLLLAA. +} +# tile 359 (minotaur,female) +{ + ................ + .O..........O... + .OOOJJJJJJOOO... + ..OOJJKJJJOO.... + ...JGAKJGAJA.... + ...JJJKJJJJA.... + ....JJKJJJAAA... + ....JKKKJAAAA... + ..CLJAJAKALCAA.A + .CLLJJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAAJLLLLJAALAA. + .LL.JJJJJJJLLAAA + .LL.JJJJJJJLLAAA + ....CLCACLCAAAAA + ..LLLLL.LLLLLAA. +} +# tile 360 (jabberwock,male) +{ + ................ + ...DP........... + ....DP.ADOO..... + ..DAIDADIPAD.... + ...DIAPIPA...... + ...DBDDDA....... + ..IBBDADDA..AA.. + .DDDDAODDIAAAA.. + ..OAOA.DDAIAAA.. + ..IOAODDAAADDAA. + ..DDDADDDDAIDA.. + ...AAADDIDIDDD.. + ....IDDAIDDDDA.. + ....IDAAIDAA.... + ...IDAA..ID..... + ................ +} +# tile 361 (jabberwock,female) +{ + ................ + ...DP........... + ....DP.ADOO..... + ..DAIDADIPAD.... + ...DIAPIPA...... + ...DBDDDA....... + ..IBBDADDA..AA.. + .DDDDAODDIAAAA.. + ..OAOA.DDAIAAA.. + ..IOAODDAAADDAA. + ..DDDADDDDAIDA.. + ...AAADDIDIDDD.. + ....IDDAIDDDDA.. + ....IDAAIDAA.... + ...IDAA..ID..... + ................ +} +# tile 362 (vorpal jabberwock,male) +{ + ................ + ...GP........... + ....GP.AGOO..... + ..GAFGAGFPAG.... + ...GFAPFPA...... + ...GHGGGA....... + ..FHHGAGGA..AA.. + .GGGGAOGGFAAAA.. + ..OAOA.GGAFAAA.. + ..FOAOGGAAAGGAA. + ..GGGAGGGGAFGA.. + ...AAAGGFGFGGG.. + ....FGGAFGGGGA.. + ....FGAAFGAA.... + ...FGAA..FG..... + ................ +} +# tile 363 (vorpal jabberwock,female) +{ + ................ + ...GP........... + ....GP.AGOO..... + ..GAFGAGFPAG.... + ...GFAPFPA...... + ...GHGGGA....... + ..FHHGAGGA..AA.. + .GGGGAOGGFAAAA.. + ..OAOA.GGAFAAA.. + ..FOAOGGAAAGGAA. + ..GGGAGGGGAFGA.. + ...AAAGGFGFGGG.. + ....FGGAFGGGGA.. + ....FGAAFGAA.... + ...FGAA..FG..... + ................ +} +# tile 364 (Keystone Kop,male) +{ + ................ + ....AA.......... + ...AAAA......... + ...AOAA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.PPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 365 (Keystone Kop,female) +{ + ................ + ....AA.......... + ...AAAA......... + ...AOAA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.PPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 366 (Kop Sergeant,male) +{ + ................ + ....AA.......... + ...AOOA......... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 367 (Kop Sergeant,female) +{ + ................ + ....AA.......... + ...AOOA......... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 368 (Kop Lieutenant,male) +{ + ................ + ....AA.......... + ...AOOA...C..... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ..OAAAO.AAA..... + .OAAAAA.AAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 369 (Kop Lieutenant,female) +{ + ................ + ....AA.......... + ...AOOA...C..... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ..OAAAO.AAA..... + .OAAAAA.AAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 370 (Kop Kaptain,male) +{ + ................ + ....AA....C..... + ...AHHA...C..... + ...AHHA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + .HHAAAAHHAA..... + .AAAAHAAAACCC... + .AA.AHAAA.CPPP.. + ..AAAHAA.PCPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 371 (Kop Kaptain,female) +{ + ................ + ....AA....C..... + ...AHHA...C..... + ...AHHA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + .HHAAAAHHAA..... + .AAAAHAAAACCC... + .AA.AHAAA.CPPP.. + ..AAAHAA.PCPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 372 (lich,male) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....O.PPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 373 (lich,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....O.PPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 374 (demilich,male) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....L.PPPAAAA.A. + ......LPPAAA.A.. + .....LLAL.A..... + ...LLLA.LA...... + ......LLL....... + ................ +} +# tile 375 (demilich,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....L.PPPAAAA.A. + ......LPPAAA.A.. + .....LLAL.A..... + ...LLLA.LA...... + ......LLL....... + ................ +} +# tile 376 (master lich,male) +{ + ...H............ + ...HCH.H........ + ...HHHCH........ + ..AOAOHH........ + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...PPPPP....AAA. + ..PPPPPPPA..AAA. + .O..PPPPP.AAAAA. + ....OPPPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 377 (master lich,female) +{ + ...H............ + ...HCH.H........ + ...HHHCH........ + ..AOAOHH........ + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...PPPPP....AAA. + ..PPPPPPPA..AAA. + .O..PPPPP.AAAAA. + ....OPPPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 378 (arch-lich,male) +{ + ................ + ................ + ...OOO.......... + ..DODOO......... + ..OOOOO......... + H.OO.O.......... + A....PPP........ + A..OOPPP....AAA. + .AO.PPPPPA..AAA. + .O...PPPP.AAAAA. + .A..O.PPPAAAA.A. + ..A...PPPAAA.A.. + ..A..OPAP.A..... + ..AOOOA.OA...... + ......OOO....... + ................ +} +# tile 379 (arch-lich,female) +{ + ................ + ................ + ...OOO.......... + ..DODOO......... + ..OOOOO......... + H.OO.O.......... + A....PPP........ + A..OOPPP....AAA. + .AO.PPPPPA..AAA. + .O...PPPP.AAAAA. + .A..O.PPPAAAA.A. + ..A...PPPAAA.A.. + ..A..OPAP.A..... + ..AOOOA.OA...... + ......OOO....... + ................ +} +# tile 380 (kobold mummy,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NONONO....... + ...OAOAO.OP..... + ....ONN...A..... + ...ONODNA.AA.... + ..OLONNONAAA.A.. + ..NALONANAAAAA.. + ..NAOLOAOAAAAA.. + ....NOLAAAAAA... + ....NANAAAA..... + ...OOANOA....... + ................ + ................ +} +# tile 381 (kobold mummy,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NONONO....... + ...OAOAO.OP..... + ....ONN...A..... + ...ONODNA.AA.... + ..OLONNONAAA.A.. + ..NALONANAAAAA.. + ..NAOLOAOAAAAA.. + ....NOLAAAAAA... + ....NANAAAA..... + ...OOANOA....... + ................ + ................ +} +# tile 382 (gnome mummy,male) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GGFO....... + ....GGFFOOP..... + ....GDODF....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 383 (gnome mummy,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GGFO....... + ....GGFFOOP..... + ....GDODF....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 384 (orc mummy,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOOP........ + ....DODPOP...... + ....OOOA........ + ..OOOOOOOA.AA... + ..OOOOOOO.AAA... + ..OAOOOAACCC.... + ..OAOOOCCAAA.... + ....OCCOAAAAAA.. + ...CCAOOAAAA.... + ..OOOAOOOA...... + ................ + ................ +} +# tile 385 (orc mummy,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOOP........ + ....DODPOP...... + ....OOOA........ + ..OOOOOOOA.AA... + ..OOOOOOO.AAA... + ..OAOOOAACCC.... + ..OAOOOCCAAA.... + ....OCCOAAAAAA.. + ...CCAOOAAAA.... + ..OOOAOOOA...... + ................ + ................ +} +# tile 386 (dwarf mummy,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BBEO....... + ....BBEEEOP..... + ....BDODE....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 387 (dwarf mummy,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BBEO....... + ....BBEEEOP..... + ....BDODE....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 388 (elf mummy,male) +{ + ................ + ................ + .........O...... + .......OOOP..... + ......OOOOP..... + ......OEOEAP.... + ......OOOOA..... + ......AOOA....A. + ......OAAO..AAA. + .....OOOOOOAAAA. + ....OALOOLAOAAA. + ....OADOOOAOAA.. + ......OOAOAA.A.. + .....OOA.OOA.... + ................ + ................ +} +# tile 389 (elf mummy,female) +{ + ................ + ................ + .........O...... + .......OOOP..... + ......OOOOP..... + ......OEOEAP.... + ......OOOOA..... + ......AOOA....A. + ......OAAO..AAA. + .....OOOOOOAAAA. + ....OALOOLAOAAA. + ....OADOOOAOAA.. + ......OOAOAA.A.. + .....OOA.OOA.... + ................ + ................ +} +# tile 390 (human mummy,male) +{ + ................ + ................ + ...ONNO......... + ...NNNNOP....... + ..PANAN.OPP..... + ..PNNNN......... + ..ONOONNP....... + .ONLNNOOO....... + .NJNOOOOO..AAA.. + .OJOOOODN.AAAA.. + .NJOLNOAOAAAAAA. + .OCNO.NKNAAAAA.. + .N.OO.OLAAAAAAA. + ...OOAOOAAA..... + ..NNN.NNNA...... + ................ +} +# tile 391 (human mummy,female) +{ + ................ + ................ + ...ONNO......... + ...NNNNOP....... + ..PANAN.OPP..... + ..PNNNN......... + ..ONOONNP....... + .ONLNNOOO....... + .NJNOOOOO..AAA.. + .OJOOOODN.AAAA.. + .NJOLNOAOAAAAAA. + .OCNO.NKNAAAAA.. + .N.OO.OLAAAAAAA. + ...OOAOOAAA..... + ..NNN.NNNA...... + ................ +} +# tile 392 (ettin mummy,male) +{ + .....NN..ONOO... + ...NNOOONNOOOO.. + ...NOOOONOOOOOO. + ...OFOFOLOFOFO.O + ...OOOOOLOOOOO.P + ...NOOOOLNNOOOA. + ...ONOOOLOOOOAAA + ..OOOONNNNNNNOAA + .ONNNNNNOONOOOOA + .ONODNNOOOOOOOOA + .NNAAONNONOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 393 (ettin mummy,female) +{ + .....NN..ONOO... + ...NNOOONNOOOO.. + ...NOOOONOOOOOO. + ...OFOFOLOFOFO.O + ...OOOOOLOOOOO.P + ...NOOOOLNNOOOA. + ...ONOOOLOOOOAAA + ..OOOONNNNNNNOAA + .ONNNNNNOONOOOOA + .ONODNNOOOOOOOOA + .NNAAONNONOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 394 (giant mummy,male) +{ + ......ONOOAA.... + ....ONNNOOOOA... + ....NNOOOOOOO... + ....NFFOOFFOOP.. + ....NONOOOOOAOP. + ....AONOOOOAAAP. + .....ANOOODAAAA. + ..OOOONOOONNNOAA + .ONNNNNOOOOOOOOA + .ONODNNLOOOOOOOA + .NNAAONOLNOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 395 (giant mummy,female) +{ + ......ONOOAA.... + ....ONNNOOOOA... + ....NNOOOOOOO... + ....NFFOOFFOOP.. + ....NONOOOOOAOP. + ....AONOOOOAAAP. + .....ANOOODAAAA. + ..OOOONOOONNNOAA + .ONNNNNOOOOOOOOA + .ONODNNLOOOOOOOA + .NNAAONOLNOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 396 (red naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LDLAA........ + ...IDDAAAAADA... + ...IDDDAAADDA... + ....IIDDDDDA.... + ................ +} +# tile 397 (red naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LDLAA........ + ...IDDAAAAADA... + ...IDDDAAADDA... + ....IIDDDDDA.... + ................ +} +# tile 398 (black naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLA......... + ...LALAA........ + ...AAAPA..PAA... + ...AAAAPPPAAA... + ....AAAAAAAA.... + ................ +} +# tile 399 (black naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLA......... + ...LALAA........ + ...AAAPA..PAA... + ...AAAAPPPAAA... + ....AAAAAAAA.... + ................ +} +# tile 400 (golden naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LHLAA........ + ...NHHAAAAAHA... + ...NHHHAAAHHA... + ....NNHHHHHA.... + ................ +} +# tile 401 (golden naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LHLAA........ + ...NHHAAAAAHA... + ...NHHHAAAHHA... + ....NNHHHHHA.... + ................ +} +# tile 402 (guardian naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LFLAA........ + ...GFFAAAAAFA... + ...GFFFAAAFFA... + ....GGFFFFFA.... + ................ +} +# tile 403 (guardian naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LFLAA........ + ...GFFAAAAAFA... + ...GFFFAAAFFA... + ....GGFFFFFA.... + ................ +} +# tile 404 (red naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLDA..AA.... + ...LDLDA.AAAA... + ...IDDDAAAIIA... + ...IDDDAIDDDIDA. + ...IDDDIDDDDDDDA + ...IDDDDDDAA.DDA + ....DDDDDA..DDA. + .....DDAA..DDA.. + ..........DA.... +} +# tile 405 (red naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLDA..AA.... + ...LDLDA.AAAA... + ...IDDDAAAIIA... + ...IDDDAIDDDIDA. + ...IDDDIDDDDDDDA + ...IDDDDDDAA.DDA + ....DDDDDA..DDA. + .....DDAA..DDA.. + ..........DA.... +} +# tile 406 (black naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLAA........ + ...LALAA..PPP... + ...AAAAPPPAAP... + ...AAAAPAAAAAAP. + ...AAAAAAAAAAAAP + ...AAAAAAAPP.AAP + ....AAAAAP..AAP. + .....AAPP..AAP.. + ..........AP.... +} +# tile 407 (black naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLAA........ + ...LALAA..PPP... + ...AAAAPPPAAP... + ...AAAAPAAAAAAP. + ...AAAAAAAAAAAAP + ...AAAAAAAPP.AAP + ....AAAAAP..AAP. + .....AAPP..AAP.. + ..........AP.... +} +# tile 408 (golden naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLHA..AA.... + ...LHLHA.AAAA... + ...NHHHAAANNA... + ...NHHHANHHHNHA. + ...NHHHNHHHHHHHA + ...NHHHHHHAA.HHA + ....HHHHHA..HHA. + .....HHAA..HHA.. + ..........HA.... +} +# tile 409 (golden naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLHA..AA.... + ...LHLHA.AAAA... + ...NHHHAAANNA... + ...NHHHANHHHNHA. + ...NHHHNHHHHHHHA + ...NHHHHHHAA.HHA + ....HHHHHA..HHA. + .....HHAA..HHA.. + ..........HA.... +} +# tile 410 (guardian naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ..CLAALC........ + ..LLLLLL........ + ..CLLCLC..AA.... + ...CLLCA.AAAA... + ...GLFCAAAGGA... + ...GFFFAAFFFGFA. + ...GFFFGFFFFFFFA + ...GFFFFFFAA.FFA + ....FFFFFA..FFA. + .....FFAA..FFA.. + ..........FA.... +} +# tile 411 (guardian naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ..CLAALC........ + ..LLLLLL........ + ..CLLCLC..AA.... + ...CLLCA.AAAA... + ...GLFCAAAGGA... + ...GFFFAAFFFGFA. + ...GFFFGFFFFFFFA + ...GFFFFFFAA.FFA + ....FFFFFA..FFA. + .....FFAA..FFA.. + ..........FA.... +} +# tile 412 (ogre,male) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CAAACJAAA... + ....LDDDLAAAA... + ..CLJLLLKALCAA.A + .CLLAJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 413 (ogre,female) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CAAACJAAA... + ....LDDDLAAAA... + ..CLJLLLKALCAA.A + .CLLAJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 414 (ogre leader,male) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 415 (ogre leader,female) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 416 (ogre tyrant,male) +{ + ...H..C..H...... + ...HDCHCDH...... + ...HHHHHHH...... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CJKAJJJJAKJCAAA + .LJJKAAAAKJJLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 417 (ogre tyrant,female) +{ + ...HH.C.HH...... + ...HDCHCDH...... + ...HHHHHHH...... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CJKAJJJJAKJCAAA + .LJJKAAAAKJJLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 418 (gray ooze,male) +{ + ................ + ................ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAAA.. + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPBBPPAAA. + .PBBPPPBAAPPPAA. + ...PBBBAAAKPPJ.. + ........ACPPAK.. + .........KCCCJ.. + ................ +} +# tile 419 (gray ooze,female) +{ + ................ + ................ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAAA.. + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPBBPPAAA. + .PBBPPPBAAPPPAA. + ...PBBBAAAKPPJ.. + ........ACPPAK.. + .........KCCCJ.. + ................ +} +# tile 420 (brown pudding,male) +{ + ................ + ................ + ................ + ................ + ............J... + ....JKKJJJ..JJ.. + ...KKKCJJJJJ.... + ..KKNNJNNJJJ.... + ..KJANJANJJJA... + ..KKJJJJJCJJAA.. + ..JKJJCJJJJJAA.. + ...JJJJJJJJAAA.. + ....JJJJJJAAA... + .....AAAAAAA.... + ................ + ................ +} +# tile 421 (brown pudding,female) +{ + ................ + ................ + ................ + ................ + ............J... + ....JKKJJJ..JJ.. + ...KKKCJJJJJ.... + ..KKNNJNNJJJ.... + ..KJANJANJJJA... + ..KKJJJJJCJJAA.. + ..JKJJCJJJJJAA.. + ...JJJJJJJJAAA.. + ....JJJJJJAAA... + .....AAAAAAA.... + ................ + ................ +} +# tile 422 (green slime,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ............G... + .....G......G..G + .G....G..G.NGN.G + ..NG.NGGNGGGGGGG + ..GGNGGNGGGFGGF. + GGNGGGGGGGGGFF.G + .NGGGGGFGFG..... + NGGGGFGGFG.G..GF + NGGFGGF..GF..... + ..GGF..GGF..G... +} +# tile 423 (green slime,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ............G... + .....G......G..G + .G....G..G.NGN.G + ..NG.NGGNGGGGGGG + ..GGNGGNGGGFGGF. + GGNGGGGGGGGGFF.G + .NGGGGGFGFG..... + NGGGGFGGFG.G..GF + NGGFGGF..GF..... + ..GGF..GGF..G... +} +# tile 424 (black pudding,male) +{ + ........A....... + ........AA...... + .....AAA........ + ....AAAAA....... + ....CACAA....... + ....DADAA....... + ....AAAAA....... + ....AAAAA....... + ....AAAAA....... + .....AAAAA...... + .....AAAAA...... + ......AAAAA..... + ......AAAAAA.... + .......AAAAAA.A. + ........AAAAAAAA + ..........AAAA.. +} +# tile 425 (black pudding,female) +{ + ........A....... + ........AA...... + .....AAA........ + ....AAAAA....... + ....CACAA....... + ....DADAA....... + ....AAAAA....... + ....AAAAA....... + ....AAAAA....... + .....AAAAA...... + .....AAAAA...... + ......AAAAA..... + ......AAAAAA.... + .......AAAAAA.A. + ........AAAAAAAA + ..........AAAA.. +} +# tile 426 (quantum mechanic,male) +{ + ................ + ......LLLL...... + ...FGGCLCGGF.... + ...GNNGLGNNGL... + B.BGANGGGANGL... + B.BFGGCLCGGFL... + BIB..CLLLCCL.... + BILN.LLAALLAAAA. + BILNN.LLLLJAAAA. + BIB.NNJJJJNAAA.. + BIB.BNNNONNNAA.. + .B...NNNONNLAA.. + .....NBEBENA.A.. + .....NBEBENN.... + ....NAAEBAANN... + ................ +} +# tile 427 (quantum mechanic,female) +{ + ................ + ......JJJJJ..... + ...FGGCLCGGF.... + ...GNNGLGNNGJ... + B.BGANGGGANGL... + B.BFGGCLCGGFLJ.. + BIB.JCLLLCCLJJ.. + BILN.LLAALLAAAA. + BILNN.LLLLCAAAA. + BIB.NNCCCCNAAA.. + BIB.BNNNONNNAA.. + .B...NNNONNLAA.. + .....NBEBENA.A.. + .....NBEBENN.... + ....NAAEBAANN... + ................ +} +# tile 428 (genetic engineer,male) +{ + ................ + ......LLLL...... + ...LAALLLAAL.... + ...LNNLLLNNLL... + ...LANLLLANLL... + ...LLLLLLLLLL... + .....CLLLCCL.... + ..LN.LLAALL..... + ..LNN.LLLLJ..... + ..A.NNLLLLN..... + .A.ABNNNONNN.... + .AA..NNNONNL.... + .A.A.NPEPENA.... + .AA..NPEPENN.... + ..AANAAEPAANN... + ................ +} +# tile 429 (genetic engineer,female) +{ + ................ + ......LLLL...... + ...LAALLLAAL.... + ...LNNLLLNNLL... + ...LANLLLANLL... + ...LLLLLLLLLL... + .....CLLLCCL.... + ..LN.LLAALL..... + ..LNN.LLLLJ..... + ..A.NNLLLLN..... + .A.ABNNNONNN.... + .AA..NNNONNL.... + .A.A.NPEPENA.... + .AA..NPEPENN.... + ..AANAAEPAANN... + ................ +} +# tile 430 (rust monster,male) +{ + ................ + ....EEEE........ + ...EEHEHE....... + ...EEEAEE....... + ...EEPAPE....... + ...EPEAEP...E... + ....EEEE.AAEE... + ....EEEEEAAEEE.. + ...EEEEEEEAEAEE. + ..EEEEEEAAAAE... + ..EEAEEEEAEEEA.. + ..AAEEEEEEEEEAA. + ....AEEEEEEEAAA. + .....EEEEEAA..A. + ......AAAA...... + ................ +} +# tile 431 (rust monster,female) +{ + ................ + ....EEEE........ + ...EEHEHE....... + ...EEEAEE....... + ...EEPAPE....... + ...EPEAEP...E... + ....EEEE.AAEE... + ....EEEEEAAEEE.. + ...EEEEEEEAEAEE. + ..EEEEEEAAAAE... + ..EEAEEEEAEEEA.. + ..AAEEEEEEEEEAA. + ....AEEEEEEEAAA. + .....EEEEEAA..A. + ......AAAA...... + ................ +} +# tile 432 (disenchanter,male) +{ + ................ + ....PPPP........ + ...PPDPDP....... + ...PPPAPP....... + ...PPOAOP....... + ...POPAPO...P... + ....PPPP.AAPP... + ....PPPPPAAPPP.. + ...PPPPPPPAPAPP. + ..PPPPPPAAAAP... + ..PPAPPPPAPPPA.. + ..AAPPPPPPPPPAA. + ....APPPPPPPAAA. + .....PPPPPAA..A. + ......AAAA...... + ................ +} +# tile 433 (disenchanter,female) +{ + ................ + ....PPPP........ + ...PPDPDP....... + ...PPPAPP....... + ...PPOAOP....... + ...POPAPO...P... + ....PPPP.AAPP... + ....PPPPPAAPPP.. + ...PPPPPPPAPAPP. + ..PPPPPPAAAAP... + ..PPAPPPPAPPPA.. + ..AAPPPPPPPPPAA. + ....APPPPPPPAAA. + .....PPPPPAA..A. + ......AAAA...... + ................ +} +# tile 434 (garter snake,male) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOKA........ + ...KKAKA........ + ...KKAKA....KA.. + ....APKAP..KAPP. + .....PKAPP.KAP.. + .....KAAP..KAP.. + ....KAAP..KAAP.. + ....KAAPPKAAP... + ....KAAKKAAP.... + .....KAAAAP..... + ................ + ................ +} +# tile 435 (garter snake,female) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOKA........ + ...KKAKA........ + ...KKAKA....KA.. + ....APKAP..KAPP. + .....PKAPP.KAP.. + .....KAAP..KAP.. + ....KAAP..KAAP.. + ....KAAPPKAAP... + ....KAAKKAAP.... + .....KAAAAP..... + ................ + ................ +} +# tile 436 (snake,male) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOJA........ + ...KKJAJ........ + ...KKAAJ....KK.. + ...FAAKJ...KJAA. + ..FAFAKJAA.KJA.. + .....KJAA..KJA.. + ....KJAA..KJJA.. + ....KJAAAKJJA... + ....KJJJJJJA.... + .....KJJJJA..... + ................ + ................ +} +# tile 437 (snake,female) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOJA........ + ...KKJAJ........ + ...KKAAJ....KK.. + ...FAAKJ...KJAA. + ..FAFAKJAA.KJA.. + .....KJAA..KJA.. + ....KJAA..KJJA.. + ....KJAAAKJJA... + ....KJJJJJJA.... + .....KJJJJA..... + ................ + ................ +} +# tile 438 (water moccasin,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AA... + ...OAOAAA.AA.... + ...AAA.AA.AA.... + ...DA..AA.AA.... + ..D.D.AAA..AA... + .....AAA...AA... + .....AAA...AA... + ....AAA...AAA... + ....AAAAAAAA.... + ....AAAAAAA..... + .....AAAAA...... + ................ +} +# tile 439 (water moccasin,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AA... + ...OAOAAA.AA.... + ...AAA.AA.AA.... + ...DA..AA.AA.... + ..D.D.AAA..AA... + .....AAA...AA... + .....AAA...AA... + ....AAA...AAA... + ....AAAAAAAA.... + ....AAAAAAA..... + .....AAAAA...... + ................ +} +# tile 440 (python,male) +{ + ................ + ................ + ................ + ...KKKA.....JJ.. + ...GAGJA...JJJ.. + ..JKKJAJ..KJJ... + ..KKKAJJ..KJJ.AA + ..KKAAKJA.KKJAA. + .....AKJAA.KJAA. + ....JKJAA..KJJA. + ...JJJAA..KJJJA. + ...JJJAAAKJJJA.. + ...JJJJJJJJJAA.. + ....JJJJJJJAA... + .....JJJJJAA.... + ................ +} +# tile 441 (python,female) +{ + ................ + ................ + ................ + ...KKKA.....JJ.. + ...GAGJA...JJJ.. + ..JKKJAJ..KJJ... + ..KKKAJJ..KJJ.AA + ..KKAAKJA.KKJAA. + .....AKJAA.KJAA. + ....JKJAA..KJJA. + ...JJJAA..KJJJA. + ...JJJAAAKJJJA.. + ...JJJJJJJJJAA.. + ....JJJJJJJAA... + .....JJJJJAA.... + ................ +} +# tile 442 (pit viper,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AAA.. + ...OAAAAA.AA.AA. + ...AA..AA.AA.AA. + ...D...AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA...AA... + .....AA...AAA... + .....AA..AAA.... + .....AAAAAA..... + ......AAAA...... + ................ +} +# tile 443 (pit viper,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AAA.. + ...OAAAAA.AA.AA. + ...AA..AA.AA.AA. + ...D...AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA...AA... + .....AA...AAA... + .....AA..AAA.... + .....AAAAAA..... + ......AAAA...... + ................ +} +# tile 444 (cobra,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAAA....... + ..PA..AAAA...... + ..A..AAAAA..AA.. + ..D..AAAAA....A. + ......AAA.....A. + ......AA..AAAA.. + .....AA..AA..... + ....AA...AA..... + ....AA....AAAA.. + ....AAA......AA. + .....AAAAAAAAA.. + ................ +} +# tile 445 (cobra,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAAA....... + ..PA..AAAA...... + ..A..AAAAA..AA.. + ..D..AAAAA....A. + ......AAA.....A. + ......AA..AAAA.. + .....AA..AA..... + ....AA...AA..... + ....AA....AAAA.. + ....AAA......AA. + .....AAAAAAAAA.. + ................ +} +# tile 446 (troll,male) +{ + ................ + ..AAAAAA........ + AAAANANA........ + .AAKKKJJA....... + AAAKAAAKA....... + AKAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAFGFJJAAAA.. + ..KJA.PFJAAAA... + ...AFAGFAAAAAA.. + ...GFAGP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 447 (troll,female) +{ + ................ + ..AAAAAA........ + AAAANANA........ + .AAKKKJJA....... + AAAKAAAKA....... + AKAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAFGFJJAAAA.. + ..KJA.PFJAAAA... + ...AFAGFAAAAAA.. + ...GFAGP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 448 (ice troll,male) +{ + ................ + ..OONOOO........ + NONOAOAOO....... + .NOKKKJJO....... + NOJKAAAKOO...... + OKJKAAAKAO...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 449 (ice troll,female) +{ + ................ + ..OONOOO........ + NONOAOAOO....... + .NOKKKJJO....... + NOJKAAAKOO...... + OKJKAAAKAO...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 450 (rock troll,male) +{ + ................ + ...AAAAA........ + .AAANANAAAA..... + .AAKKKJJAA...... + AAAKAAAKAAAA.... + AKAKAAAKAAA..... + KJJAKKKAJKAA.... + KJAJAAAJJJA..... + KJAPAKJJKJA..... + PKJPPAGFJJAAAA.. + PPPPPAFFJAAAA... + .PPPAAGFAAAAAA.. + ...AFAGF.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 451 (rock troll,female) +{ + ................ + ...AAAAA........ + .AAANANAAAA..... + .AAKKKJJAA...... + AAAKAAAKAAAA.... + AKAKAAAKAAA..... + KJJAKKKAJKAA.... + KJAJAAAJJJA..... + KJAPAKJJKJA..... + PKJPPAGFJJAAAA.. + PPPPPAFFJAAAA... + .PPPAAGFAAAAAA.. + ...AFAGF.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 452 (water troll,male) +{ + ................ + ...AAAAA........ + ..AANANAA....... + .AAKKKJJAA...... + .AAKAAAKAA...... + .KAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 453 (water troll,female) +{ + ................ + ...AAAAA........ + ..AANANAA....... + .AAKKKJJAA...... + .AAKAAAKAA...... + .KAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 454 (Olog-hai,male) +{ + ...PPPPP........ + ..PPAAAPP....... + ..PANANAP....... + ..PAAAAAP....... + .PPAAAAAPP...... + PPPAAAAAPPP..... + AAPPAAAPPAA..... + AAAPPPPPAAA..... + AAAPPPPPAAA..... + .AAAAPPPAAAPPP.. + PONNNNNNAACPP... + ...APAPPAPPPPP.. + ...PPAPP.PP.PP.. + ..AAAAAAAP.PP... + ..AAA.AAA....... + ................ +} +# tile 455 (Olog-hai,female) +{ + ...PPPPP........ + ..PPAAAPP....... + ..PANANAP....... + ..PAAAAAP....... + .PPAAAAAPP...... + PPPAAAAAPPP..... + AAPPAAAPPAA..... + AAAPPPPPAAA..... + AAAPPPPPAAA..... + .AAAAPPPAAAPPP.. + PONNNNNNAACPP... + ...APAPPAPPPPP.. + ...PPAPP.PP.PP.. + ..AAAAAAAP.PP... + ..AAA.AAA....... + ................ +} +# tile 456 (umber hulk,male) +{ + ................ + ...AAAAA........ + ..AAAAAAA....... + .ADADADADA...... + .AAAAAAAAA.A.... + .AAAOAOAAA.AA... + .A.AOAOA.AAA.... + .A.AAAAAPAA..... + .AAAAAAAP....... + .A.AAAAA.PPPPPP. + ...AA.AA.PPPPP.. + ...AA.AAPPPPPPP. + ...AAPAAPPPP.... + ..AAAPAAAPP..... + .AAAP..AAP...... + ................ +} +# tile 457 (umber hulk,female) +{ + ................ + ...AAAAA........ + ..AAAAAAA....... + .ADADADADA...... + .AAAAAAAAA.A.... + .AAAOAOAAA.AA... + .A.AOAOA.AAA.... + .A.AAAAAPAA..... + .AAAAAAAP....... + .A.AAAAA.PPPPPP. + ...AA.AA.PPPPP.. + ...AA.AAPPPPPPP. + ...AAPAAPPPP.... + ..AAAPAAAPP..... + .AAAP..AAP...... + ................ +} +# tile 458 (vampire,male) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAAAAAAA...... + ..AAAAAAAA...... + ...AAAAAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 459 (vampire,female) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAAAAAAA...... + ..AAAAAAAA...... + ...AAAAAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 460 (vampire leader,male) +{ + ................ + .....AAAA....... + .N..AAOOAA...... + .NDDAGAAGADA.... + .NADALLLOAD..... + AAAAAAAAAAA..... + AAAAAAAAAAA..... + .AAAAAAAAAA..... + .NAAAAAAAAA..... + .N.AAAAAAAAPPPPP + .NADAAAAAAAPPPPP + .NADDAAAAAAPPPP. + .NAAAAAAAAAPPP.. + .N...AAAPAAPP... + .N..AAPP..AP.... + ................ +} +# tile 461 (vampire leader,female) +{ + ................ + .....AAAA....... + .N..AAOOAA...... + .NDDAGAAGADA.... + .NADALLLOAD..... + AAAAAAAAAAA..... + AAAAAAAAAAA..... + .AAAAAAAAAA..... + .NAAAAAAAAA..... + .N.AAAAAAAAPPPPP + .NADAAAAAAAPPPPP + .NADDAAAAAAPPPP. + .NAAAAAAAAAPPP.. + .N...AAAPAAPP... + .N..AAPP..AP.... + ................ +} +# tile 462 (vampire mage,male) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAA.A.AA...... + ..AAAACAAA...... + ...AAADAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 463 (vampire mage,female) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAA.A.AA...... + ..AAAACAAA...... + ...AAADAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 464 (Vlad the Impaler,male) +{ + ................ + ..N..AAAA....... + ADNDAAOOAADDDA.. + .ANDAGAAGADDA... + ..NDALLLOADA.... + ..NAAAAAAAAAAAAA + .HHHDAAAAADDDDDA + HEHEHJAAAADDDAA. + LLLLLJAAAADDAAPP + .LLLJAAAAADDAPPP + ..NJDAAAAADAPPPP + .ANDDAAAAAAAPPPP + .ANAAAAAAAAPPPP. + ..N..AAAPAAPPP.. + ..N.AAPP..AP.... + ................ +} +# tile 465 (Vlad the Impaler,female) +{ + ................ + ..N..AAAA....... + ADNDAAOOAADDDA.. + .ANDAGAAGADDA... + ..NDALLLOADA.... + ..NAAAAAAAAAAAAA + .HHHDAAAAADDDDDA + HEHEHJAAAADDDAA. + LLLLLJAAAADDAAPP + .LLLJAAAAADDAPPP + ..NJDAAAAADAPPPP + .ANDDAAAAAAAPPPP + .ANAAAAAAAAPPPP. + ..N..AAAPAAPPP.. + ..N.AAPP..AP.... + ................ +} +# tile 466 (barrow wight,male) +{ + ................ + ................ + ...LLO.......... + ..DLDLO......... + ..LLLLO......... + ..LJL..P........ + ..OOO.PP...AAAA. + ..POO.PP.AAAAAA. + .LPOO.PP.PAAAA.. + .JJOO.PP.PAAAA.. + .J.O..PL.PPAAA.. + .J.O.PPPPPPAAA.. + .J...PPPPPPPAA.. + .J..LLPPPPPPA... + .J.....LLAA..... + ................ +} +# tile 467 (barrow wight,female) +{ + ................ + .......OOOOO.... + ..OOOOOOO....... + .ODLDLOO.OOO.... + .OLLLLOOOOOOO... + .OLJLLOPOO...... + .OPLLL.POOOAAAA. + ..PPP.PP.AAAAAA. + .LPPPPPP.PAAAA.. + .JJ.PPPP.PAAAA.. + .J...PPL.PPAAA.. + .J...PPPPPPAAA.. + .J...PPPPPPPAA.. + .J..LLPPPPPPA... + .J.....LLAA..... + ................ +} +# tile 468 (wraith,male) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + ..AAPPPPAP..AAA. + ..PPPPPOLPAAAAA. + ...A.PPAAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ + ................ + ................ +} +# tile 469 (wraith,female) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + ..AAPPPPAP..AAA. + ..PPPPPOLPAAAAA. + ...A.PPAAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ + ................ + ................ +} +# tile 470 (Nazgul,male) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + .OPAPPPPAP..AAA. + ..PAPPPPAP..AAA. + ..PA.PPPLP..AAA. + ..PP.PPOLPAAAAA. + ...AAPPOAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ +} +# tile 471 (Nazgul,female) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + .OPAPPPPAP..AAA. + ..PAPPPPAP..AAA. + ..PA.PPPLP..AAA. + ..PP.PPOLPAAAAA. + ...AAPPOAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ +} +# tile 472 (xorn,male) +{ + ................ + ................ + ................ + ...OB.OP.BP..... + ...BBBBPPPP..... + ...B............ + ...DDBB.BDDA.A.. + ...DDBB.PDDAAAA. + ...B.......AAAA. + ...BOB.BPP.AAAA. + ...BBB.PPP.AAAA. + ...B.......AAA.. + ...BOBBPPBPAA... + ...BO.BP.PPA.... + ................ + ................ +} +# tile 473 (xorn,female) +{ + ................ + ................ + ................ + ...OB.OP.BP..... + ...BBBBPPPP..... + ...B............ + ...DDBB.BDDA.A.. + ...DDBB.PDDAAAA. + ...B.......AAAA. + ...BOB.BPP.AAAA. + ...BBB.PPP.AAAA. + ...B.......AAA.. + ...BOBBPPBPAA... + ...BO.BP.PPA.... + ................ + ................ +} +# tile 474 (monkey,male) +{ + ................ + ................ + ................ + ................ + ................ + .......KKA...... + ......KLLJA..... + ......KLLJA..... + .......KJA...... + .....KKKKKJAA... + ....KJKLLJJJAA.. + ....LAKLLJALAA.. + ......KJJJAAAA.. + ......JAAJAAA... + .....JJA.JJA.... + ................ +} +# tile 475 (monkey,female) +{ + ................ + ................ + ................ + ................ + ................ + .......KKA...... + ......KLLJA..... + ......KLLJA..... + .......KJA...... + .....KKKKKJAA... + ....KJKLLJJJAA.. + ....LAKLLJALAA.. + ......KJJJAAAA.. + ......JAAJAAA... + .....JJA.JJA.... + ................ +} +# tile 476 (ape,male) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCLACCAJJAAA + ..KKKKCCCAJKJJAA + ..KKAKJAAJJAJJAA + ..KAAKJJJJJAAJAA + ..LC.KJJJJJKCLAA + ..LL.CJJAKLJLLAA + .....CLJACLJAAAA + ...LLLLJACLLLKA. + ................ + ................ +} +# tile 477 (ape,female) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCLACCAJJAAA + ..KKKKCCCAJKJJAA + ..KKAKJAAJJAJJAA + ..KAAKJJJJJAAJAA + ..LC.KJJJJJKCLAA + ..LL.CJJAKLJLLAA + .....CLJACLJAAAA + ...LLLLJACLLLKA. + ................ + ................ +} +# tile 478 (owlbear,male) +{ + ................ + ....K.....K..... + ....CK...KK..... + ....CKKKKKK..... + ...KOOOKOOOK.... + ...KOOOKOOOKA..A + ...KOOAJAOOKAAAA + ..CKCJJHJJKAKAAA + .CKKKCKLKKAJJKAA + .KJJJJCKKJJJJJAA + .KJJJPAKJPJJJJAA + ..KJJJAKJJJJJAAA + ...JJPAKJPJJAAA. + ...JAAJAJAAJAA.. + ...PJPJAJPJPA... + ................ +} +# tile 479 (owlbear,female) +{ + ................ + ....K.....K..... + ....CK...KK..... + ....CKKKKKK..... + ...KOOOKOOOK.... + ...KOOOKOOOKA..A + ...KOOAJAOOKAAAA + ..CKCJJHJJKAKAAA + .CKKKCKLKKAJJKAA + .KJJJJCKKJJJJJAA + .KJJJPAKJPJJJJAA + ..KJJJAKJJJJJAAA + ...JJPAKJPJJAAA. + ...JAAJAJAAJAA.. + ...PJPJAJPJPA... + ................ +} +# tile 480 (yeti,male) +{ + ................ + ....BNNN........ + ...BNANAP....... + ..BNNNNNNP...... + ..NNNADANN...... + ..NNNNNNPN...... + ..N.NNBPPNP..... + ..N.NNNNANP..AA. + ..NNBNNNPN.AAAA. + ....NNNNP.KAAA.. + ....NN.NPAKKAA.. + ....NB.NPAACKAA. + ....NNANPAAKKJA. + ...BNNANNPAACKA. + ..BNNA..NNA..... + ................ +} +# tile 481 (yeti,female) +{ + ................ + ....BNNN........ + ...BNANAP....... + ..BNNNNNNP...... + ..NNNADANN...... + ..NNNNNNPN...... + ..N.NNBPPNP..... + ..N.NNNNANP..AA. + ..NNBNNNPN.AAAA. + ....NNNNP.KAAA.. + ....NN.NPAKKAA.. + ....NB.NPAACKAA. + ....NNANPAAKKJA. + ...BNNANNPAACKA. + ..BNNA..NNA..... + ................ +} +# tile 482 (carnivorous ape,male) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCAAACAJJAAA + ..KKKCDDDCAKJJAA + ..KKAKCCCAJAJJAA + ..KAAKJAAJJAAJAA + ..LC.AJJJJJKCLAA + ..LLDDAJAKLJLLAA + ...DDALJACLJAAAA + ..DDALLJACLLLKA. + ................ + ................ +} +# tile 483 (carnivorous ape,female) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCAAACAJJAAA + ..KKKCDDDCAKJJAA + ..KKAKCCCAJAJJAA + ..KAAKJAAJJAAJAA + ..LC.AJJJJJKCLAA + ..LLDDAJAKLJLLAA + ...DDALJACLJAAAA + ..DDALLJACLLLKA. + ................ + ................ +} +# tile 484 (sasquatch,male) +{ + ................ + ....CCCCC....... + ...CGAJGAJ...... + ..CKKKKJJJ...... + ..CKKAAAKJJ..... + .CKKKAAAKKJ..... + .CKJKKKKKKKJ.... + .CKAJJJJJAKJ.... + .CKAJKKKJAKJ.AA. + .CKJAJKJACKJAAAA + .CKJAJJJACKJAAA. + ..J.AJAKKAJAAAAA + ...CKJAKKJAAAAA. + .KCKJJACKJKJAA.. + .CJJJKACKJJKA... + ................ +} +# tile 485 (sasquatch,female) +{ + ................ + ....CCCCC....... + ...CGAJGAJ...... + ..CKKKKJJJ...... + ..CKKAAAKJJ..... + .CKKKAAAKKJ..... + .CKJKKKKKKKJ.... + .CKAJJJJJAKJ.... + .CKAJKKKJAKJ.AA. + .CKJAJKJACKJAAAA + .CKJAJJJACKJAAA. + ..J.AJAKKAJAAAAA + ...CKJAKKJAAAAA. + .KCKJJACKJKJAA.. + .CJJJKACKJJKA... + ................ +} +# tile 486 (kobold zombie,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NGFBN........ + ...GABAB........ + ....GBFA..A..... + ...GBABFA.AA.... + ..GFBBBIKAAA.A.. + ..BAFBFFEAAAAA.. + ..BAFBFFAAAAAA.. + ....FBFAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 487 (kobold zombie,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NGFBN........ + ...GABAB........ + ....GBFA..A..... + ...GBABFA.AA.... + ..GFBBBIKAAA.A.. + ..BAFBFFEAAAAA.. + ..BAFBFFAAAAAA.. + ....FBFAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 488 (gnome zombie,male) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GDFDF....... + .....PFP...AAA.. + ...FGFPFEGAAAA.. + ..GAAGFFFAGAAA.. + ....AKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 489 (gnome zombie,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GDFDF....... + .....GFF...AAA.. + ...FGFFFEGAAAA.. + ..GAAGFFFAGAAA.. + ....AKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 490 (orc zombie,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....GPGA........ + .....PFA........ + ..KCCAKKKA.AA... + .BBPCKJ.BBAAA... + BB.AGGFAABBA.... + B..AJJPAAABA.... + ....BAPPPAAAAA.. + ...BJAAEPAAA.... + ..BPPAAAPP...... + ................ + ................ +} +# tile 491 (orc zombie,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....GPGA........ + .....PFA........ + ..KCCAKKKA.AA... + .BBPCKJ.BBAAA... + BB.AGGFAABBA.... + B..AJJPAAABA.... + ....BAPPPAAAAA.. + ...BJAAEPAAA.... + ..BPPAAAPP...... + ................ + ................ +} +# tile 492 (dwarf zombie,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BFFFE....... + .....PFP...AAA.. + ...BBPPPEEAAAA.. + ..FBABPEAEAAAA.. + ..F.EBBEFAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 493 (dwarf zombie,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BFFFE....... + .....PFP...AAA.. + ...BBPPPEEAAAA.. + ..FBABPEAEAAAA.. + ..F.EBBEFAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 494 (elf zombie,male) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......FEFEA..... + ......FFFFA..... + ......AFDA....A. + ......GAAG..AAA. + ....FFGGGFFFAAA. + ...FAAAGFAAAFAA. + .....AGGGFAAAA.. + ......GFAFAA.A.. + .....KDA.FKA.... + ................ + ................ +} +# tile 495 (elf zombie,female) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......FEFEA..... + ......FFFFA..... + ......AFDA....A. + ......GAAG..AAA. + ....FFGGGFFFAAA. + ...FAAAGFAAAFAA. + .....AGGGFAAAA.. + ......GFAFAA.A.. + .....KDA.FKA.... + ................ + ................ +} +# tile 496 (human zombie,male) +{ + ......AAA....... + .....FFGAA...... + .....AGAFA...... + .....FFGFA...... + ....FKF..JJ..... + ....JJJFJKJ..... + ...FJ.KJJAKJ.... + ..FK..KFJFFJ.... + ..G...KKJG...... + .....BP.BPAAAAA. + .....FPAPFAAAA.. + .....BFABFAAAA.. + .....PFABPAA.... + .....BFABFA..... + ....GGAGGA...... + ................ +} +# tile 497 (human zombie,female) +{ + ......AAA....... + .....FFGAA...... + .....AGAFA...... + .....FFGFA...... + ....FKF..JJ..... + ....JJJFJKJ..... + ...FJ.KJJAKJ.... + ..FK..KFJFFJ.... + ..G...KKJG...... + .....BP.BPAAAAA. + .....FPAPFAAAA.. + .....BFABFAAAA.. + .....PFABPAA.... + .....BFABFA..... + ....GGAGGA...... + ................ +} +# tile 498 (ettin zombie,male) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NFF..NFF..P... + ..ADFFDADFFDA... + ..AFFFFAFFFFA... + ..AFAAFAFAAFAA.. + ..AFFFFAFFFFAAA. + ..GIIIIJJJIIIGAA + .GFFFIIIIIIFFFGA + .GFFFFIIIIFFFFFA + .FFAAFIIIIFAAFFA + .FFAAIIIIIIAAFFA + .FFF.IIFFIIAGFAA + ..FF.GFAAGFAFFAA + .....GFAAGFAAAAA + ...FFFFA.GFFFFAA +} +# tile 499 (ettin zombie,female) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NFF..NFF..P... + ..ADFFDADFFDA... + ..AFFFFAFFFFA... + ..AFAAFAFAAFAA.. + ..AFFFFAFFFFAAA. + ..GIIIIJJJIIIGAA + .GFFFIIIIIIFFFGA + .GFFFFIIIIFFFFFA + .FFAAFIIIIFAAFFA + .FFAAIIIIIIAAFFA + .FFF.IIFFIIAGFAA + ..FF.GFAAGFAFFAA + .....GFAAGFAAAAA + ...FFFFA.GFFFFAA +} +# tile 500 (ghoul,male) +{ + ......AAA....... + .....OOOAA...... + .....DODOA...... + .....OOOOA...... + ....PPOOOPP..... + ....PPPPPPP..... + ...PP.PPPAPP.... + ..PP..PPPOOP.... + ..O...PPPO...... + .....PP.PPAAAAA. + .....PPAPPAAAA.. + .....PPAPPAAAA.. + .....PPAPPAA.... + .....PPAPPA..... + ....OOAOOA...... + ................ +} +# tile 501 (ghoul,female) +{ + ......AAA....... + .....OOOAA...... + .....DODOA...... + .....OOOOA...... + ....PPOOOPP..... + ....PPPPPPP..... + ...PP.PPPAPP.... + ..PP..PPPOOP.... + ..O...PPPO...... + .....PP.PPAAAAA. + .....PPAPPAAAA.. + .....PPAPPAAAA.. + .....PPAPPAA.... + .....PPAPPA..... + ....OOAOOA...... + ................ +} +# tile 502 (giant zombie,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJFFFFJJA... + ....JDDFFDDJA... + ....JFFFFFFJA... + ....AFFAAFFAAA.. + .....AFFFFJAAAA. + ..GGFFJJJJFFGGAA + .GFFFGGFFFFFFFCA + .FFFKFFFFFFKFFFA + FFFAAFFFFFFAAFFA + FFAA.JJJKKJAAFFA + FFA..JJJJJKAGFAA + .....GFAGFFAFFAA + ....GFFAGFFAAAAA + ...GFFAAGFFFAAAA +} +# tile 503 (giant zombie,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJFFFFJJA... + ....JDDFFDDJA... + ....JFFFFFFJA... + ....AFFAAFFAAA.. + .....AFFFFJAAAA. + ..GGFFJJJJFFGGAA + .GFFFGGFFFFFFFCA + .FFFKFFFFFFKFFFA + FFFAAFFFFFFAAFFA + FFAA.JJJKKJAAFFA + FFA..JJJJJKAGFAA + .....GFAGFFAFFAA + ....GFFAGFFAAAAA + ...GFFAAGFFFAAAA +} +# tile 504 (skeleton,male) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + ......O......... + ....OOOOO...AAA. + ...OA.OOOA..AAA. + ..OA.OAAO.AAAAA. + ....OA.OOOAAA.A. + ......OOOAAA.A.. + .....O.AO.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 505 (skeleton,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + ......O......... + ....OOOOO...AAA. + ...OA.OOOA..AAA. + ..OA.OAAO.AAAAA. + ....OA.OOOAAA.A. + ......OOOAAA.A.. + .....O.AO.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 506 (straw golem,male) +{ + ......LJ........ + ......LJHJ...... + ....HJLJH...A... + ....AAAAAL.....A + ....DAADAL.A.AA. + ....LJHJL..AAAA. + ....LLHJLHHCHHL. + ...HHLJL.AJLJL.A + .HHJJLLLLAAA.AA. + ..JL..LALHAAAAAA + .LL..CJLHJHAAAAA + .....HJLAHJHAAA. + .....HJAACALHAAA + ....CJLAAJHALHA. + ....HALA.AHAAL.. + ..........L..... +} +# tile 507 (straw golem,female) +{ + ......LJ........ + ......LJHJ...... + ....HJLJH...A... + ....AAAAAL.....A + ....DAADAL.A.AA. + ....LJHJL..AAAA. + ....LLHJLHHCHHL. + ...HHLJL.AJLJL.A + .HHJJLLLLAAA.AA. + ..JL..LALHAAAAAA + .LL..CJLHJHAAAAA + .....HJLAHJHAAA. + .....HJAACALHAAA + ....CJLAAJHALHA. + ....HALA.AHAAL.. + ..........L..... +} +# tile 508 (paper golem,male) +{ + ................ + .......OA....... + .....NNNOA...... + .....ONNNOA..... + ......ONNOA..... + .......NOA...... + ..NNOA.NOA...... + ..NONOAOAONNOA.. + ..OAOANNOAOOOA.. + ......NNNOAAAAA. + ......ONOAAAAAA. + .......OOAAAAAA. + .....NOAAOAAAAA. + .....NOA..NOAA.. + ....OOA...OOA... + ................ +} +# tile 509 (paper golem,female) +{ + ................ + .......OA....... + .....NNNOA...... + .....ONNNOA..... + ......ONNOA..... + .......NOA...... + ..NNOA.NOA...... + ..NONOAOAONNOA.. + ..OAOANNOAOOOA.. + ......NNNOAAAAA. + ......ONOAAAAAA. + .......OOAAAAAA. + .....NOAAOAAAAA. + .....NOA..NOAA.. + ....OOA...OOA... + ................ +} +# tile 510 (rope golem,male) +{ + ................ + ................ + ......OOO....... + .....O...O...... + .....O...O...AA. + .OO...O..O..A..A + O..O...LL..OO..A + ...O...LOOO.AOA. + ....OOOOOAAAAO.. + .......OO..AA.A. + .......LO.AA...A + ......O..OOAA..A + ....OO..A..O.A.. + ...O..AA...O.A.. + ...O.A....OAA... + ....OA.......... +} +# tile 511 (rope golem,female) +{ + ................ + ................ + ......OOO....... + .....O...O...... + .....O...O...AA. + .OO...O..O..A..A + O..O...LL..OO..A + ...O...LOOO.AOA. + ....OOOOOAAAAO.. + .......OO..AA.A. + .......LO.AA...A + ......O..OOAA..A + ....OO..A..O.A.. + ...O..AA...O.A.. + ...O.A....OAA... + ....OA.......... +} +# tile 512 (gold golem,male) +{ + ................ + ......HNH....... + ......DND...N... + ......HNH...JC.. + ......HNH...NC.. + ...HHHAAAAHANC.. + ..HNJNHNHNJNAC.A + ..HHHHHHHHHHHA.A + .NCACCCCCCCCA..A + .HH.AAAAAAAAA.AA + .NH.ANC.AHNC.AAA + .NJ.AHC.AHHC.AAA + ..H.ANC.AHNC.AAA + ....HJC.AHJC.AA. + H...HNC.AHNC.A.H + ..H............. +} +# tile 513 (gold golem,female) +{ + ................ + ......HNH....... + ......DND...N... + ......HNH...JC.. + ......HNH...NC.. + ...HHHAAAAHANC.. + ..HNJNHNHNJNAC.A + ..HHHHHHHHHHHA.A + .NCACCCCCCCCA..A + .HH.AAAAAAAAA.AA + .NH.ANC.AHNC.AAA + .NJ.AHC.AHHC.AAA + ..H.ANC.AHNC.AAA + ....HJC.AHJC.AA. + H...HNC.AHNC.A.H + ..H............. +} +# tile 514 (leather golem,male) +{ + ......KKKK...... + .....KHKHJ...... + ....KAKKJJA..... + ...KKAJJJJAJ.... + ..KKJJAJAAKJJ... + .KKKJJAAKKKJJJ.. + ..KKJJJAKKJJJJ.. + ...KKJJJA.AAA.A. + ....AAAA.KJAAAA. + ....KJAAAKKAAAAA + ...KJJAA.KJJAAA. + ...KKJA..KKJAAA. + ..KKJJJAKKJJJAA. + ..KKKJJAKKKJJA.. + ...KJJA..KJJA... + ....KA....KA.... +} +# tile 515 (leather golem,female) +{ + ......KKKK...... + .....KHKHJ...... + ....KAKKJJA..... + ...KKAJJJJAJ.... + ..KKJJAJAAKJJ... + .KKKJJAAKKKJJJ.. + ..KKJJJAKKJJJJ.. + ...KKJJJA.AAA.A. + ....AAAA.KJAAAA. + ....KJAAAKKAAAAA + ...KJJAA.KJJAAA. + ...KKJA..KKJAAA. + ..KKJJJAKKJJJAA. + ..KKKJJAKKKJJA.. + ...KJJA..KJJA... + ....KA....KA.... +} +# tile 516 (wood golem,male) +{ + ................ + ......KCKJ...... + ......HCHJ..C... + ......KCKJ..CK.. + ......KCKJ..CKJ. + ...KKKAAAAKACKJ. + ..KCCCCCCCCCAKJA + ..KKKKKKKKKKKAJA + .CJAJJJJJJJJA..A + .CKJAAAAAAAAA.AA + .CKJACKJAKCKJAAA + .CKJACKJAKCKJAAA + ..KJACKJAKCKJAAA + ....KCKJAKCKJAA. + ....KCKJAKCKJA.. + ................ +} +# tile 517 (wood golem,female) +{ + ................ + ......KCKJ...... + ......HCHJ..C... + ......KCKJ..CK.. + ......KCKJ..CKJ. + ...KKKAAAAKACKJ. + ..KCCCCCCCCCAKJA + ..KKKKKKKKKKKAJA + .CJAJJJJJJJJA..A + .CKJAAAAAAAAA.AA + .CKJACKJAKCKJAAA + .CKJACKJAKCKJAAA + ..KJACKJAKCKJAAA + ....KCKJAKCKJAA. + ....KCKJAKCKJA.. + ................ +} +# tile 518 (flesh golem,male) +{ + ................ + ................ + ...D..DDC....... + .....DLDDL...... + ..DD..LLLLC.D... + ...CDL.LLLLADL.. + ..CLDLA.CLLA.LL. + ..LLLAA.LLCA..L. + .CLLAA.CLLAA..CA + .LLA..CLLALLAAAA + ..LA.CLCAALCAAAA + ...A..LLCACLCAAA + ....LLALLAALLAAA + ..CLLLAAAADLLA.. + ..LLDDD..DDDDD.. + ................ +} +# tile 519 (flesh golem,female) +{ + ................ + ................ + ...D..DDC....... + .....DLDDL...... + ..DD..LLLLC.D... + ...CDL.LLLLADL.. + ..CLDLA.CLLA.LL. + ..LLLAA.LLCA..L. + .CLLAA.CLLAA..CA + .LLA..CLLALLAAAA + ..LA.CLCAALCAAAA + ...A..LLCACLCAAA + ....LLALLAALLAAA + ..CLLLAAAADLLA.. + ..LLDDD..DDDDD.. + ................ +} +# tile 520 (clay golem,male) +{ + ................ + ................ + ................ + ....LCCCCK...... + ...LKKKKKKK..... + ...CKAKKAKK..... + ...CKAKKAKK..... + .LCKKKKKKKKLC... + CKKJKKKKKKCKKJ.. + KKKJKKJJKKJKKJAA + .JJAKKJAKKAJJAAA + ..AKKKJAKKKAAAAA + ..CKKKKKKKKKAAAA + ..CKKKAACKKKAA.. + ..CKKKA.CKKKAA.. + ................ +} +# tile 521 (clay golem,female) +{ + ................ + ................ + ................ + ....LCCCCK...... + ...LKKKKKKK..... + ...CKAKKAKK..... + ...CKAKKAKK..... + .LCKKKKKKKKLC... + CKKJKKKKKKCKKJ.. + KKKJKKJJKKJKKJAA + .JJAKKJAKKAJJAAA + ..AKKKJAKKKAAAAA + ..CKKKKKKKKKAAAA + ..CKKKAACKKKAA.. + ..CKKKA.CKKKAA.. + ................ +} +# tile 522 (stone golem,male) +{ + ................ + ................ + ................ + ....BBBPP....... + ...BBPPPPP...... + ...BHAPHAP...... + ...PPPPPPP...... + .BBPPPPPP.BPA... + BPPPP....PPPPAA. + BPP.BPPPP.PPPAAA + .PP.BP.PP.PPPAAA + ...BPP.PPPAAAAAA + ..BPPPAPPPAAAAA. + ..PPPPAPPPPAAA.. + ...PPAA.PPPA.... + ................ +} +# tile 523 (stone golem,female) +{ + ................ + ................ + ................ + ....BBBPP....... + ...BBPPPPP...... + ...BHAPHAP...... + ...PPPPPPP...... + .BBPPPPPP.BPA... + BPPPP....PPPPAA. + BPP.BPPPP.PPPAAA + .PP.BP.PP.PPPAAA + ...BPP.PPPAAAAAA + ..BPPPAPPPAAAAA. + ..PPPPAPPPPAAA.. + ...PPAA.PPPA.... + ................ +} +# tile 524 (glass golem,male) +{ + ................ + .....BBBBBBA.... + .....BPNPPPA.... + .....BNPPPNA.... + .....NPPPNPA.... + .....BPPNPPA.... + .......BA...BA.. + .BNBBABPBA.BPNA. + .NPPNABPNBBANPBA + .....BPNPPPAABAA + .....BNPPPAAAAAA + ......BPPNAAAAAA + ....BNABNABPAAA. + ...BNPA...BNAAA. + ..BNPA....NPAA.. + ...BA.....BPA... +} +# tile 525 (glass golem,female) +{ + ................ + .....BBBBBBA.... + .....BPNPPPA.... + .....BNPPPNA.... + .....NPPPNPA.... + .....BPPNPPA.... + .......BA...BA.. + .BNBBABPBA.BPNA. + .NPPNABPNBBANPBA + .....BPNPPPAABAA + .....BNPPPAAAAAA + ......BPPNAAAAAA + ....BNABNABPAAA. + ...BNPA...BNAAA. + ..BNPA....NPAA.. + ...BA.....BPA... +} +# tile 526 (iron golem,male) +{ + ................ + ......PBP....... + ......HBH...B... + ......PBP...JP.. + ......PBP...BP.. + ...PPPAAAAPABP.. + ..PBJBBBBBJBAP.A + ..PPPPPPPPPPPA.A + .B.A........A..A + .BP.AAAAAAAAA.AA + .BP.ABP.APBP.AAA + .BJ.ABP.APBP.AAA + ..P.ABP.APBP.AAA + ....PJP.APJP.AA. + ....PBP.APBP.A.. + ................ +} +# tile 527 (iron golem,female) +{ + ................ + ......PBP....... + ......HBH...B... + ......PBP...JP.. + ......PBP...BP.. + ...PPPAAAAPABP.. + ..PBJBBBBBJBAP.A + ..PPPPPPPPPPPA.A + .B.A........A..A + .BP.AAAAAAAAA.AA + .BP.ABP.APBP.AAA + .BJ.ABP.APBP.AAA + ..P.ABP.APBP.AAA + ....PJP.APJP.AA. + ....PBP.APBP.A.. + ................ +} +# tile 528 (human,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......ELELA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 529 (human,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......ELELA..... + ......LLLLA..... + ......ALLA...... + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 530 (wererat,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......GJGJA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 531 (wererat,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......GJGJA..... + ......LLLLA..... + ......ALLA...... + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 532 (werejackal,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......IPIPA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 533 (werejackal,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......IPIPA..... + ......LLLLA..... + ......ALLA...... + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 534 (werewolf,male) +{ + ................ + ................ + ......JJA....... + .....JJJJA...... + .....NJNJA...... + .....LLLLA...... + .....ALLA....... + ....CLAALC.AAA.. + ...CLLLLLLCAAA.. + ...LACLLCALAAA.. + ...LAJJKJALAAA.. + .....JJJKAAAA... + .....JJAJAA.A... + ....KLA.LKA..... + ................ + ................ +} +# tile 535 (werewolf,female) +{ + ................ + ................ + ......JJA....... + .....JJJJA...... + .....NJNJA...... + .....LLLLA...... + .....ALLA....... + ....CJAAJC.AAA.. + ...CLJLLJLCAAA.. + ...LAKJJJALAAA.. + ...LAJJKJALAAA.. + .....JJJKAAAA... + .....JJAJAA.A... + ....KLA.LKA..... + ................ + ................ +} +# tile 536 (elf,male) +{ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 537 (elf,female) +{ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 538 (Woodland-elf,male) +{ + ................ + ................ + .........K...... + .......KKJ...... + ......KKKKA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......KAAK..AAA. + .....LKKKJLAAAA. + ....LAPPJAALAAA. + ..KKLKKKKJALAA.. + ......PPAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 539 (Woodland-elf,female) +{ + ................ + ................ + .........K...... + .......KKJ...... + ......KKKKA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......KAAK..AAA. + .....LKKKJLAAAA. + ....LAPPJAALAAA. + ..KKLKKKKJALAA.. + ......PPAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 540 (Green-elf,male) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 541 (Green-elf,female) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 542 (Grey-elf,male) +{ + ................ + ................ + .........P...... + .......PP....... + ......PPPPA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......PAAP..AAA. + .....LPPP.LAAAA. + ....LAAP.AALAAA. + ....LAPPP.ALAA.. + ......P.A.AA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 543 (Grey-elf,female) +{ + ................ + ................ + .........P...... + .......PP....... + ......PPPPA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......PAAP..AAA. + .....LPPP.LAAAA. + ....LAAP.AALAAA. + ....LAPPP.ALAA.. + ......P.A.AA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 544 (elf-leader,male) +{ + ................ + ................ + ........II...... + .......HGF...... + ......HGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......HAAH..AAA. + .....LHHHFLAAAA. + ....LAAIIAALAAA. + ....LAHGGFALAA.. + ......HFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 545 (elf-leader,female) +{ + ................ + ................ + ........II...... + .......HGF...... + ......HGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......HAAH..AAA. + .....LHHHFLAAAA. + ....LAAIIAALAAA. + ....LAHGGFALAA.. + ......HFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 546 (elven monarch,male) +{ + ................ + ................ + ......H..H...... + ......HCHH...... + ......HHHHA..... + ......LELEA..... + ......LLLLA..... + .....IALLAI...A. + ....IIIAAIDIAAA. + .....LIIGDLAAAAA + ....LADIFDALAAAA + ....LAIIGDALAAA. + .....IIFAFDAAA.. + ...IIKLAILKDI... + ................ + ................ +} +# tile 547 (elven monarch,female) +{ + ................ + ......H..H...... + ......H..H...... + ......HCHH...... + ......HHHHA..... + ......LELEA..... + ......LLLLA..... + .....IALLAI...A. + ....IIIAAIDIAAA. + .....LIIGDLAAAAA + ....LADIFDALAAAA + ....LAIIGDALAAA. + .....IIFAFDAAA.. + ...IIKLAILKDI... + ................ + ................ +} +# tile 548 (doppelganger,male) +{ + ................ + ......CCCC..I... + ..I..CD...C..... + ....CD.HHA.C.... + ...CD.HHHHA.C.I. + ...CD.LFLFA.DC.. + .I.CD.LLLLA.DC.. + ...CD.ALLA.DC... + ..CD.LLAALL.ACA. + .CD.LLLLLLLLADC. + .CD.LALLLLALADC. + .CD.LAJJKJALADC. + ..CD..LJJLAAACA. + ...CD.LLALAACA.. + ..CD.LLAALLADC.. + ................ +} +# tile 549 (doppelganger,female) +{ + ................ + ......CCCC..I... + ..I..CD...C..... + ....CD.HHA.C.... + ...CD.HHHHA.C.I. + ...CD.LFLFA.DC.. + .I.CD.LLLLA.DC.. + ...CD.ALLA.DC... + ..CD.LLAALL.ACA. + .CD.LLLLLLLLADC. + .CD.LALLLLALADC. + .CD.LAJJKJALADC. + ..CD..LJJLAAACA. + ...CD.LLALAACA.. + ..CD.LLAALLADC.. + ................ +} +# tile 550 (shopkeeper,male) +{ + ................ + ................ + ......AAAA...... + .....AAAAAA..... + ......JLJL...... + ......LLLL...... + ......ALLA...... + .....EBAABEA.AA. + ....EBBBBBBEAAA. + ....BAEBBEABAAA. + ....LAGFFFALAAA. + ......GFAFAAAA.. + ......GFAFAA.A.. + .....JJA.JJA.... + ................ + ................ +} +# tile 551 (shopkeeper,female) +{ + ................ + ................ + ......AAAA...... + .....AAAAAA..... + ......JLJL...... + ......LLLL...... + ......ALLA...... + .....EBAABEA.AA. + ....EBBBBBBEAAA. + ....BAEBBEABAAA. + ....LAGFFFALAAA. + ......GFAFAAAA.. + ......GFAFAA.A.. + .....JJA.JJA.... + ................ + ................ +} +# tile 552 (guard,male) +{ + ................ + .....BBPPPAA.... + ....BNPPPPPPA... + ....BPPBPPPPA... + ....BAABPAAPA... + ....BCLBPCLPA... + ....AKCPPCJAAA.. + ....BKJJJJAPAAAA + ...BPKJAAJAPPAAA + ..BPPKJJJJAPPPAA + ..PPABKJJAPPAPPA + ..PPABPKAPPPAPPA + ..LC.BPPPPPPCLAA + ..LL.BPPABPPLLAA + .....BPPABPPAAAA + ....BPPP.BPPPAAA +} +# tile 553 (guard,female) +{ + ................ + .....BBPPPAA.... + ....BNPPPPPPA... + ....BPPBPPPPA... + ....BAABPAAPA... + ....BCLBPCLPA... + ....JCLPPCLJAA.. + ....BPLLLLAPAAAA + ...BPPLAALAPPAAA + ..BPPPPLLPPPPPAA + ..PPABPPPPPPAPPA + ..PPABPPPPPPAPPA + ..LC.BPPPPPPCLAA + ..LL.BPPABPPLLAA + .....BPPABPPAAAA + ....BPPP.BPPPAAA +} +# tile 554 (prisoner,male) +{ + ................ + ................ + .......NOA...... + .......LLA...... + .......LLA...... + .......NOA...... + ......NOONA..... + .....NOOOONA.... + ....NANOOOANAA.. + ....PANOOOAPAAA. + ....LANOOOALAAA. + ......NOOOAAAA.. + ......NAANAAA... + ......PAAPAA.... + .....LLA.LLA.... + ................ +} +# tile 555 (prisoner,female) +{ + ................ + ................ + .......NOA...... + .......LLA...... + .......LLA...... + .......NOA...... + ......NOONA..... + .....NOOOONA.... + ....NANOOOANAA.. + ....PANOOOAPAAA. + ....LANOOOALAAA. + ......NOOOAAAA.. + ......NAANAAA... + ......PAAPAA.... + .....LLA.LLA.... + ................ +} +# tile 556 (Oracle,male) +{ + ................ + ................ + .......NN....... + LLL...GLLG...LLL + ..L..NLLLLN..L.. + ...L.NLAALN.L... + ....LNLLLLNL.... + .....LNLLNL..AA. + .....NBBEEN.AAAA + ......BBEEAAAAAA + .LLA..BBBEAAALL. + .LLLLBBBEBELLLLA + ..LLCLBLLELLCLAA + ...CLLLLLLLCLAA. + ....LELLLLELAA.. + ................ +} +# tile 557 (Oracle,female) +{ + ................ + ................ + .......NN....... + LLL...GLLG...LLL + ..L..NLLLLN..L.. + ...L.NLAALN.L... + ....LNLLLLNL.... + .....LNLLNL..AA. + .....NBBEEN.AAAA + ......BBEEAAAAAA + .LLA..BBBEAAALL. + .LLLLBBBEBELLLLA + ..LLCLBLLELLCLAA + ...CLLLLLLLCLAA. + ....LELLLLELAA.. + ................ +} +# tile 558 (aligned priest,male) +{ + ................ + INI............. + III..KCCK....... + .J..KCCCCK...... + .J..CAAKCC...... + .LC.CAAACC...... + CLLC.CAACJKC.... + CJLACCCCJKCCC... + .JAACCJJCKCCCK.. + .JKCCCJCCJCCK.AA + .J..CCJCCLJCAAAA + .J..CCJCLLCAAAA. + .J..KCJCCCJAAAA. + .J.ACCJCCCJAAA.. + .JACCCJJCCCAA... + ................ +} +# tile 559 (aligned priest,female) +{ + ................ + INI............. + III..KCCK....... + .J..KCCCCK...... + .J..CAAKCC...... + .LC.CAAACC...... + CLLC.CAACJKC.... + CJLACCCCJKCCC... + .JAACCJJCKCCCK.. + .JKCCCJCCJCCK.AA + .J..CCJCCLJCAAAA + .J..CCJCLLCAAAA. + .J..KCJCCCJAAAA. + .J.ACCJCCCJAAA.. + .JACCCJJCCCAA... + ................ +} +# tile 560 (high priest,male) +{ + .INI............ + IIIII.KCCK...... + .IHI.KCAACK..... + ..H..CGAGAC..... + ..LC.CAAAAC..... + .CLLC.CAACJCK... + .CHLACCCCJCCCK.. + ..HAACCJJCCCCCK. + ..HCCCCJCCJCCC.A + ..H..CCJCCLJCAAA + ..H..CCJCLLCAAAA + ..H..KCJCCCJAAAA + ..H..KCJCCCJAAAA + ..H.ACCJCCCJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 561 (high priest,female) +{ + .INI............ + IIIII.KCCK...... + .IHI.KCAACK..... + ..H..CGAGAC..... + ..LC.CAAAAC..... + .CLLC.CAACJCK... + .CHLACCCCJCCCK.. + ..HAACCJJCCCCCK. + ..HCCCCJCCJCCC.A + ..H..CCJCCLJCAAA + ..H..CCJCLLCAAAA + ..H..KCJCCCJAAAA + ..H..KCJCCCJAAAA + ..H.ACCJCCCJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 562 (soldier,male) +{ + .....J.......... + .....JAAA....... + .....ALLLA...... + .....LLLLC...... + .....JLLC....... + .....JF..F...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....JJ.JJ...... + ................ +} +# tile 563 (soldier,female) +{ + .....J.......... + .....JAAA....... + .....ALLLA...... + .....LLLLC...... + .....JLLC....... + .....JF..F...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....JJ.JJ...... + ................ +} +# tile 564 (sergeant,male) +{ + .....J.......... + .....JFFF....... + ....FFFFFF...... + .....LLLLC...... + .....JLLC....... + .....JF..G...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 565 (sergeant,female) +{ + .....J.......... + .....JFFF....... + ....FFFFFF...... + .....LLLLC...... + .....JLLC....... + .....JF..G...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 566 (nurse,male) +{ + ................ + .......NO....... + ......NDDO...... + ......NNOOA..... + .....DBLBLD..... + .....CLLLLDC.... + .....DALLACD.... + .....CNAAODCAAA. + .....NNNOOLAAAA. + ....LANNDOALAAA. + ....LANNOOALAAA. + ......NNOOAAAA.. + ......NNAOAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 567 (nurse,female) +{ + ................ + .......NO....... + ......NDDO...... + ......NNOOA..... + .....DBLBLD..... + .....CLLLLDC.... + .....DALLACD.... + .....CNAAODCAAA. + .....NNNOOLAAAA. + ....LANNDOALAAA. + ....LANNOOALAAA. + ......NNOOAAAA.. + ......NNAOAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 568 (lieutenant,male) +{ + ................ + .......FFF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....GF.FGA..... + ....FFFFFFFF.... + ....FAFFFFAFAAA. + ....FAFFFFAFAAAA + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 569 (lieutenant,female) +{ + ................ + .......FFF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....GF.FGA..... + ....FFFFFFFF.... + ....FAFFFFAFAAA. + ....FAFFFFAFAAAA + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 570 (captain,male) +{ + ................ + ......FHHF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....HF.FHF..... + ....FFFFFFFFAA.. + ....FAFFIFAFAAAA + ....FAFFFFAFAAA. + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.JJJA.. + .....FFAFFJJJA.. + .....AA.AAAAA... + ................ +} +# tile 571 (captain,female) +{ + ................ + ......FHHF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....HF.FHF..... + ....FFFFFFFFAA.. + ....FAFFIFAFAAAA + ....FAFFFFAFAAA. + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.JJJA.. + .....FFAFFJJJA.. + .....AA.AAAAA... + ................ +} +# tile 572 (watchman,male) +{ + ................ + ......PPP....... + ....PPPPPP...... + .....LLLLC...... + ......LLC....... + .....PP..P...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + ......PAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 573 (watchman,female) +{ + ................ + ......PPP....... + ....PPPPPP...... + .....LLLLC...... + ......LLC....... + .....PP..P...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + ......PAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 574 (watch captain,male) +{ + ......PPP....... + .....PHHHP...... + ....PPPPPPP..... + .....LLLLC...... + ......LLC....... + .....HP..H...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + .....JPAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 575 (watch captain,female) +{ + ......PPP....... + .....PHHHP...... + ....PPPPPPP..... + .....LLLLC...... + ......LLC....... + .....HP..H...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + .....JPAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 576 (Medusa,male) +{ + ................ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....A.. + .GAFLLLLA..A..A. + ....JLLKA.A.A.A. + ...KBLLBKAAAAA.. + ..KIIBBIIIAAA.A. + ..IIIKKILLIAAA.. + ..KIILLIALIAA... + ...KIALKAAIAA... + ...IKAAKIIAAA... + ...IIKKIIIAA.... + ..IIKIKIKIA..... + ................ +} +# tile 577 (Medusa,female) +{ + ................ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....A.. + .GAFLLLLA..A..A. + ....JLLKA.A.A.A. + ...KBLLBKAAAAA.. + ..KIIBBIIIAAA.A. + ..IIIKKILLIAAA.. + ..KIILLIALIAA... + ...KIALKAAIAA... + ...IKAAKIIAAA... + ...IIKKIIIAA.... + ..IIKIKIKIA..... + ................ +} +# tile 578 (Wizard of Yendor,male) +{ + .EEE.......EEE.. + EFFAE..E..EAFFE. + EAAAE.EEE.EAAAE. + EAAAEEEAEEEAAAE. + EEAAEEDADEEAAEE. + .EEEEAAAAAEEEE.. + ..EEEEAAAEEEE... + ..EEEEEEEEEE.... + ...EEEEEEEE..... + ...EEEEEEEE....A + ....EEEEEE...AAA + ....EEEEEEAAAAAA + ...EEEEEEEEAAAAA + ..EEEEEEEEEAAAAA + .EEEEEEEEEEEAAA. + EEEEEEEEEEEEEEA. +} +# tile 579 (Wizard of Yendor,female) +{ + .EEE.......EEE.. + EFFAE..E..EAFFE. + EAAAE.EEE.EAAAE. + EAAAEEEAEEEAAAE. + EEAAEEDADEEAAEE. + .EEEEAAAAAEEEE.. + ..EEEEAAAEEEE... + ..EEEEEEEEEE.... + ...EEEEEEEE..... + ...EEEEEEEE....A + ....EEEEEE...AAA + ....EEEEEEAAAAAA + ...EEEEEEEEAAAAA + ..EEEEEEEEEAAAAA + .EEEEEEEEEEEAAA. + EEEEEEEEEEEEEEA. +} +# tile 580 (Croesus,male) +{ + ....H..H..H..... + ....HCHEHCH..... + ....HHHHHHH..... + ....ALLLLLA..... + ....LLALALL..... + .....LLLLL...... + ....HLLDLLH..... + ...HIALLLAIH.A.A + ...HIHAAAHIHAAAA + ..IIIEHHHIIIIAAA + ..IIIIEHIIIIIAA. + ..ILLIHHHILLIAAA + ...LIIKHIIILAAAA + ..GIIIKJIIIIGAA. + .GIIIKJJKKIIIGG. + ................ +} +# tile 581 (Croesus,female) +{ + ....H..H..H..... + ....HCHEHCH..... + ....HHHHHHH..... + ....ALLLLLA..... + ....LLALALL..... + .....LLLLL...... + ....HLLDLLH..... + ...HIALLLAIH.A.A + ...HIHAAAHIHAAAA + ..IIIEHHHIIIIAAA + ..IIIIEHIIIIIAA. + ..ILLIHHHILLIAAA + ...LIIKHIIILAAAA + ..GIIIKJIIIIGAA. + .GIIIKJJKKIIIGG. + ................ +} +# tile 582 (Charon,male) +{ + ................ + .......J........ + ......JJJ....... + ....JJJAJJJ..... + ....JJDADJJ..... + ...JJAAAAAJJ.... + ...JJJAAAJJJ.... + ..JJJJJJJJJJ.... + .JJJJJJJJJJJJ... + JJJJJJJJJJJJJJ.A + .OO.JJJJJJ.OOAAA + ....JJJJJJAAAAAA + ...JJJJJJJJAAAAA + ..JJJJJJJJJAAAAA + .JJJJJJJJJJJAAA. + JJJJJJJJJJJJJJA. +} +# tile 583 (Charon,female) +{ + ................ + .......J........ + ......JJJ....... + ....JJJAJJJ..... + ....JJDADJJ..... + ...JJAAAAAJJ.... + ...JJJAAAJJJ.... + ..JJJJJJJJJJ.... + .JJJJJJJJJJJJ... + JJJJJJJJJJJJJJ.A + .OO.JJJJJJ.OOAAA + ....JJJJJJAAAAAA + ...JJJJJJJJAAAAA + ..JJJJJJJJJAAAAA + .JJJJJJJJJJJAAA. + JJJJJJJJJJJJJJA. +} +# tile 584 (ghost,male) +{ + ................ + ................ + ...NNN.......... + ..NANANN........ + .NNNNNNNNN...... + .NNPAAPNNNNN.... + .NNAAAANNNOONO.. + .NNAAAANONNNPNNO + .NNPAAPNONNOOOP. + .NNNNNNONOPNPPO. + .NNONNOPNNOPOOP. + .NOPNNOOOPPOOP.. + .OOOPOPPOPPP.PP. + .PP.PPOPPP...P.. + .O...P....P..... + ........P....... +} +# tile 585 (ghost,female) +{ + ................ + ................ + ...NNN.......... + ..NANANN........ + .NNNNNNNNN...... + .NNPAAPNNNNN.... + .NNAAAANNNOONO.. + .NNAAAANONNNPNNO + .NNPAAPNONNOOOP. + .NNNNNNONOPNPPO. + .NNONNOPNNOPOOP. + .NOPNNOOOPPOOP.. + .OOOPOPPOPPP.PP. + .PP.PPOPPP...P.. + .O...P....P..... + ........P....... +} +# tile 586 (shade,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ........AAAAAAA. + ....AAAAAAAA.... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAA. + ..AAAAAAAAAAAAAA + .AAAAAAAAAAAAA.. + AAAA.AAAAJA..... + ................ +} +# tile 587 (shade,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ........AAAAAAA. + ....AAAAAAAA.... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAA. + ..AAAAAAAAAAAAAA + .AAAAAAAAAAAAA.. + AAAA.AAAAJA..... + ................ +} +# tile 588 (water demon,male) +{ + ................ + ................ + ................ + ................ + ..EE.....EE..... + .E.EE...EE.E.... + ....EEEEE....... + ....EBEBE..A.... + ...EEEEEEEAAAA.. + ..EEE...EEEAA.A. + ..EEEEEEEEEAAA.. + ..EEAEEEAEEAAA.. + ...AAEEEAAAAA... + ....EEAEEAA..... + ....EEAEEA...... + ................ +} +# tile 589 (water demon,female) +{ + ................ + ................ + ................ + ................ + ..EE.....EE..... + .E.EE...EE.E.... + ....EEEEE....... + ....EBEBE..A.... + ...EEEEEEEAAAA.. + ..EEE...EEEAA.A. + ..EEEEEEEEEAAA.. + ..EEAEEEAEEAAA.. + ...AAEEEAAAAA... + ....EEAEEAA..... + ....EEAEEA...... + ................ +} +# tile 590 (amorous demon,male) +{ + DD.OHHD......... + DDOHHDGD........ + DDOHDDDDD....... + DDHHDDDA........ + DDDHDJADDDD..... + DDDJDDDDDDDD.... + .DDDDDCDD.DDD... + .DDCDDDKK..DD... + ..DDKKDDDAADDA.. + ...DDDDDDAAAAA.. + ....DDDDDDDDDA.. + ....DDJDJJAAAAAA + ....JDJJADKAA... + ....DDKAADDKA... + ...DDKAA..DDAA.. + ..DDKAA...DDDA.. +} +# tile 595 (amorous demon,female) +{ + DD.OHHD......... + DDOHHDGD........ + DDOHDDDDD....... + DDHHDDDA........ + DHHHDJADDDD..... + .HHJJDDDJDDD.... + OHDDCDCDDJDD.... + HHHCDDCDLJ.DD... + HHHCDLJJJAADDA.. + HHHDJJDDDAADAA.. + HHHHDDAADAAAA... + HHHH.DKJDDAA.... + H.H..DDAADDAA... + ..H..DDAA.DAA... + ....DDAA..DDAA.. + ...DDJA...DDDA.. +} +# tile 592 (horned devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + ...LOCDCOL...... + ...CDDDDDC...... + ...DAADAADA..D.. + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + ..CDAKKKACDAAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + ...CDDADDKAA.... + ..CDDAA.DDK..... + ................ +} +# tile 593 (horned devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + ...LOCDCOL...... + ...CDDDDDC...... + ...DAADAADA..D.. + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + ..CDAKKKACDAAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + ...CDDADDKAA.... + ..CDDAA.DDK..... + ................ +} +# tile 596 (erinys,male) +{ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....... + .GAFDLDLA..A.A.. + ....LLLEA.A.A.A. + ...EBLLBEAAAA.A. + ..EBBBBBBBAAAA.. + ..BBBEBBLLBAA.A. + ..EBBLLBALBAAA.. + ...EBALBAABAA... + ...BEAABBBAAA... + ...BBBBBBBAAA... + ...BBBBBBBAA.... + ..BBEBEBEBA..... + ................ +} +# tile 597 (erinys,female) +{ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....... + .GAFDLDLA..A.A.. + ....LLLEA.A.A.A. + ...EBLLBEAAAA.A. + ..EBBBBBBBAAAA.. + ..BBBEBBLLBAA.A. + ..EBBLLBALBAAA.. + ...EBALBAABAA... + ...BEAABBBAAA... + ...BBBBBBBAAA... + ...BBBBBBBAA.... + ..BBEBEBEBA..... + ................ +} +# tile 598 (barbed devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + .O.LOCDCOL.O.... + ...CDDDDDC....DD + ...DAADAADA..D.D + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + .C.DAKKKACDKAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + .K.CDDADDKAAK... + .CCDDAA.DDKK.... + ................ +} +# tile 599 (barbed devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + .O.LOCDCOL.O.... + ...CDDDDDC....DD + ...DAADAADA..D.D + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + .C.DAKKKACDKAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + .K.CDDADDKAAK... + .CCDDAA.DDKK.... + ................ +} +# tile 600 (marilith,male) +{ + .D..HHH.....D... + DD.HHHHHA...DD.. + .DCHDDDHHAAD..A. + ..HDBDBDHDDAAAA. + .CHKDDDKHAAADD.. + CDDDKKKDHDDDDFF. + D..CDDCDKAAFFFAA + D.KDDKDDDDDDFAA. + D.DKDDKDKAFDFAA. + ..D.GDDFAAFDFFAA + .D.GGFFFAAAFFFFA + ...GFFFFFAAAFFFA + ..FGFFFFFFAFFFFA + ..FGFFFFFFFFFFA. + ..FGFFFFFFFFFA.. + ....GFFFFFFAA... +} +# tile 601 (marilith,female) +{ + .D..HHH.....D... + DD.HHHHHA...DD.. + .DCHDDDHHAAD..A. + ..HDBDBDHDDAAAA. + .CHKDDDKHAAADD.. + CDDDKKKDHDDDDFF. + D..CDDCDKAAFFFAA + D.KDDKDDDDDDFAA. + D.DKDDKDKAFDFAA. + ..D.GDDFAAFDFFAA + .D.GGFFFAAAFFFFA + ...GFFFFFAAAFFFA + ..FGFFFFFFAFFFFA + ..FGFFFFFFFFFFA. + ..FGFFFFFFFFFA.. + ....GFFFFFFAA... +} +# tile 602 (vrock,male) +{ + ................ + ......OPP.O..... + ......PPPP...... + .....CPPDP...... + ....CCCPPP...... + ....CCPPPP...... + ....C..PPA...... + .....DDAADD.AAA. + ....DDDDDDDDAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ......DAADAAAA.. + ......DAADAA.A.. + .....DDA.DDA.... + ................ +} +# tile 603 (vrock,female) +{ + ................ + ......OPP.O..... + ......PPPP...... + .....CPPDP...... + ....CCCPPP...... + ....CCPPPP...... + ....C..PPA...... + .....DDAADD.AAA. + ....DDDDDDDDAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ......DAADAAAA.. + ......DAADAA.A.. + .....DDA.DDA.... + ................ +} +# tile 604 (hezrou,male) +{ + ................ + ................ + ....GGGFF....... + ..NGFFNNFFF..... + .DFFFDDNFF.F.... + .GFFFDNFF.FFFAA. + .AFAFFFFFFFFFFAA + .GFFFF.FFF.FGFAA + .GAAAFF..LFGFFAA + ..FFFF.FFLFGFFFA + ..LLA.FLLLJJG.FA + .LLAFFLLFJJGFFFA + ..LAFLLLAAGF.FAA + .....L.LAGFFFFAA + ...........FFFA. + ................ +} +# tile 605 (hezrou,female) +{ + ................ + ................ + ....GGGFF....... + ..NGFFNNFFF..... + .DFFFDDNFF.F.... + .GFFFDNFF.FFFAA. + .AFAFFFFFFFFFFAA + .GFFFF.FFF.FGFAA + .GAAAFF..LFGFFAA + ..FFFF.FFLFGFFFA + ..LLA.FLLLJJG.FA + .LLAFFLLFJJGFFFA + ..LAFLLLAAGF.FAA + .....L.LAGFFFFAA + ...........FFFA. + ................ +} +# tile 606 (bone devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..O.. + ...LNLOLOL....O. + ...LOOOOOL....O. + ...NAAOAAOA..O.. + ...NOOOOOOA.O... + ..NOOOFOOOOAO.A. + ..OOKNOOKOOALA.. + ..OOANOOAOOAKAA. + ..LLANOOALLAAAA. + ....NOOOLAAAAA.. + ...NOOAOOLAA.... + ..NOOAA.OOL..... + ................ +} +# tile 607 (bone devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..O.. + ...LNLOLOL....O. + ...LOOOOOL....O. + ...NAAOAAOA..O.. + ...NOOOOOOA.O... + ..NOOOFOOOOAO.A. + ..OOKNOOKOOALA.. + ..OOANOOAOOAKAA. + ..LLANOOALLAAAA. + ....NOOOLAAAAA.. + ...NOOAOOLAA.... + ..NOOAA.OOL..... + ................ +} +# tile 608 (ice devil,male) +{ + ................ + ................ + ..N.......N..... + ..NN.....NN..... + ...PBPNPNP..BNB. + ...PNNNNNP..N.N. + ...BAANAANA...N. + ...BNNNNNNA.BNB. + ..BNNNFNNNNAN.A. + ..NNKBNNKNNABA.. + ..NNABNNANNA.AA. + ..PPABNNAPPAAAA. + ....BNNNPAAAAA.. + ...BNNANNPAA.... + ..BNNAA.NNP..... + ................ +} +# tile 609 (ice devil,female) +{ + ................ + ................ + ..N.......N..... + ..NN.....NN..... + ...PBPNPNP..BNB. + ...PNNNNNP..N.N. + ...BAANAANA...N. + ...BNNNNNNA.BNB. + ..BNNNFNNNNAN.A. + ..NNKBNNKNNABA.. + ..NNABNNANNA.AA. + ..PPABNNAPPAAAA. + ....BNNNPAAAAA.. + ...BNNANNPAA.... + ..BNNAA.NNP..... + ................ +} +# tile 610 (nalfeshnee,male) +{ + ................ + ................ + ......BB...BB... + ..KKKKKBB.BB.... + .KADKADKKKB..... + .KKKKKKKDKK..... + .OKDKOKKDDKD.... + .OKDKOKKKDKDD... + .KAAAKKDKAKKD... + ..KKKDDLAKKKD.A. + ...KK.KKKKKDDA.. + ....L..KDAKDAA.. + ......LLAAKDA... + .........LLA.... + ................ + ................ +} +# tile 611 (nalfeshnee,female) +{ + ................ + ................ + ......BB...BB... + ..KKKKKBB.BB.... + .KADKADKKKB..... + .KKKKKKKDKK..... + .OKDKOKKDDKD.... + .OKDKOKKKDKDD... + .KAAAKKDKAKKD... + ..KKKDDLAKKKD.A. + ...KK.KKKKKDDA.. + ....L..KDAKDAA.. + ......LLAAKDA... + .........LLA.... + ................ + ................ +} +# tile 612 (pit fiend,male) +{ + ................ + .K.O.......O.K.. + .K.OO.....OO.KJ. + KJJ.LOCDCOL.KJJ. + KJJJKDDDDDKKJJJ. + KJJCKDNDNDKCJJJA + JJCCKDDDDDJCCJJA + JJCCCKDIDJDCCJJA + JACCDDKJJDDCDAJA + JACCKDDDDDKCDAJA + ...CDKDDDKCDDAAA + ....DKDDDKCDAAAA + .....CDDDKAAAA.. + ....CDDADDKA.... + ...CDDAA.DDK.... + ................ +} +# tile 613 (pit fiend,female) +{ + ................ + .K.O.......O.K.. + .K.OO.....OO.KJ. + KJJ.LOCDCOL.KJJ. + KJJJKDDDDDKKJJJ. + KJJCKDNDNDKCJJJA + JJCCKDDDDDJCCJJA + JJCCCKDIDJDCCJJA + JACCDDKJJDDCDAJA + JACCKDDDDDKCDAJA + ...CDKDDDKCDDAAA + ....DKDDDKCDAAAA + .....CDDDKAAAA.. + ....CDDADDKA.... + ...CDDAA.DDK.... + ................ +} +# tile 614 (sandestin,male) +{ + .....CCCCC..I... + .I..CD....C..... + ...CD.DDD..C..I. + ..CD.DDDDD..C... + ..CD.DNDNDA.DC.. + I.CD.DDDDDA.DC.. + ..CD.ADDDA.DC..A + .CD.DDAAADD.DCAA + CD.DDDDDDDDDADCA + CD.DADDDDDADADCA + CD.DADDDDDADADCA + CD.DADDDDDADADC. + .CD..DDJDDAADCA. + ..CD.DDADDADCA.. + .CD.DDAADDDADC.. + ................ +} +# tile 615 (sandestin,female) +{ + .....CCCCC..I... + .I..CD....C..... + ...CD.DDD..C..I. + ..CD.DDDDD..C... + ..CD.DNDNDA.DC.. + I.CD.DDDDDA.DC.. + ..CD.ADDDA.DC..A + .CD.DDAAADD.DCAA + CD.DDDDDDDDDADCA + CD.DADDDDDADADCA + CD.DADDDDDADADCA + CD.DADDDDDADADC. + .CD..DDJDDAADCA. + ..CD.DDADDADCA.. + .CD.DDAADDDADC.. + ................ +} +# tile 616 (balrog,male) +{ + ................ + .K..O.....O..K.. + .KJ.O.....O.KJ.. + KJJLOOCDCOOLJJJ. + JJJDDDDDDDDDDKJ. + JCCDDDNDNDDDCCJA + CCDKDDDDDDDJCCCA + CDDKKKDIDJJDCCDA + CDDKDDKJJDDDCDDA + CCDKDDDDDDDKCDDA + JCCDKKDDDKKCDDDA + JJCDKKDDDKKCDDJA + JJ..CCDDDKKAAJJA + J..CDDDADDDKAAJA + ..CDDDAA.DDDK.AA + ................ +} +# tile 617 (balrog,female) +{ + ................ + .K..O.....O..K.. + .KJ.O.....O.KJ.. + KJJLOOCDCOOLJJJ. + JJJDDDDDDDDDDKJ. + JCCDDDNDNDDDCCJA + CCDKDDDDDDDJCCCA + CDDKKKDIDJJDCCDA + CDDKDDKJJDDDCDDA + CCDKDDDDDDDKCDDA + JCCDKKDDDKKCDDDA + JJCDKKDDDKKCDDJA + JJ..CCDDDKKAAJJA + J..CDDDADDDKAAJA + ..CDDDAA.DDDK.AA + ................ +} +# tile 618 (Juiblex,male) +{ + ................ + DD.........DD... + NDC.KKKKJ.CND... + .CCKCCCKKCCAA... + ..KCCCCKCCJAA... + ..KCCCCCK.JJAA.. + ..KCCFCCK..JAA.. + ..FKCFCCKK.JAAA. + .FKKFCCKFK..JAA. + .FKCFCCFKFK.JAA. + .FCFCCKFCFK.JAA. + FKCFCFCFCKK.JAA. + CKFCCFCCKKFKJJA. + CCKKCFCKFFKKKKA. + .CCCCCCCCCCCKA.. + ................ +} +# tile 619 (Juiblex,female) +{ + ................ + DD.........DD... + NDC.KKKKJ.CND... + .CCKCCCKKCCAA... + ..KCCCCKCCJAA... + ..KCCCCCK.JJAA.. + ..KCCFCCK..JAA.. + ..FKCFCCKK.JAAA. + .FKKFCCKFK..JAA. + .FKCFCCFKFK.JAA. + .FCFCCKFCFK.JAA. + FKCFCFCFCKK.JAA. + CKFCCFCCKKFKJJA. + CCKKCFCKFFKKKKA. + .CCCCCCCCCCCKA.. + ................ +} +# tile 620 (Yeenoghu,male) +{ + ....B.HHP....... + ....BPPPP....... + ...BPLCPPH...... + .KBPPCCPPH...... + .PPPPPPP.H...... + .PP...P.PH...... + ....BPPPPPAAA... + ..BPPPPPPPPAAAA. + .BP.PPPPPAPPAAAA + .B...BPP.AAPAAAA + .B...BPP.AAPAAA. + .....BPPAAAAA.A. + ....BP.PPAA...A. + ...BP.AAPPA..A.. + ...BPAA.PPA..... + ................ +} +# tile 621 (Yeenoghu,female) +{ + ....B.HHP....... + ....BPPPP....... + ...BPLCPPH...... + .KBPPCCPPH...... + .PPPPPPP.H...... + .PP...P.PH...... + ....BPPPPPAAA... + ..BPPPPPPPPAAAA. + .BP.PPPPPAPPAAAA + .B...BPP.AAPAAAA + .B...BPP.AAPAAA. + .....BPPAAAAA.A. + ....BP.PPAA...A. + ...BP.AAPPA..A.. + ...BPAA.PPA..... + ................ +} +# tile 622 (Orcus,male) +{ + ................ + .K..O.....O..K.. + KJJO..BBB..O.KJ. + KJJLOBPPPPOLKJJ. + JKJJ.PGPGP.JJKJA + JJKJKPPPPPJJKJJJ + JBPPB.BPPABBPPJJ + PJJPP.BPPAPPJJPA + PJBPPP.AAPPPPJPA + .JBP.PPPP.P.PJAA + .JBPPPP.PPPPPJAA + ..PPP.PPP.PPPAAA + ...P.PPPPPPP.P.A + ...BPPPAPPPPAAPA + ...OOPPAOOPPAGA. + ................ +} +# tile 623 (Orcus,female) +{ + ................ + .K..O.....O..K.. + KJJO..BBB..O.KJ. + KJJLOBPPPPOLKJJ. + JKJJ.PGPGP.JJKJA + JJKJKPPPPPJJKJJJ + JBPPB.BPPABBPPJJ + PJJPP.BPPAPPJJPA + PJBPPP.AAPPPPJPA + .JBP.PPPP.P.PJAA + .JBPPPP.PPPPPJAA + ..PPP.PPP.PPPAAA + ...P.PPPPPPP.P.A + ...BPPPAPPPPAAPA + ...OOPPAOOPPAGA. + ................ +} +# tile 624 (Geryon,male) +{ + .K...........K.. + .K....JJJ....KJ. + KJJ..JJJJJ..KJJ. + KJJJKLLLLLKKJJJ. + KJJJKLBLBLKJJJJA + JJJJKLLLLLJJJJJA + JJALLKLLLJLLAJJA + JA.LLLKJJLLLAAJA + ...LJLLLLLKLAAAA + ...LCKLLLKCLAFGF + ...LLGLLFALLFFFA + .....GFFFAAAFFAA + ....GGGGFFAAFFAA + ....GFFFFFAAFGFA + ....FGGGFFFFFFFA + .....FFFFFFFFFA. +} +# tile 625 (Geryon,female) +{ + .K...........K.. + .K....JJJ....KJ. + KJJ..JJJJJ..KJJ. + KJJJKLLLLLKKJJJ. + KJJJKLBLBLKJJJJA + JJJJKLLLLLJJJJJA + JJALLKLLLJLLAJJA + JA.LLLKJJLLLAAJA + ...LJLLLLLKLAAAA + ...LCKLLLKCLAFGF + ...LLGLLFALLFFFA + .....GFFFAAAFFAA + ....GGGGFFAAFFAA + ....GFFFFFAAFGFA + ....FGGGFFFFFFFA + .....FFFFFFFFFA. +} +# tile 626 (Dispater,male) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ....KACKKJAKAAA. + ....KACKKJAKAAJA + ....KACKKJAKAAJA + ....LACKKJJLAJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 627 (Dispater,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ....KACKKJAKAAA. + ....KACKKJAKAAJA + ....KACKKJAKAAJA + ....LACKKJJLAJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 628 (Baalzebub,male) +{ + ......F...F..... + .......F.F...... + ......BFFFB..... + .....BPPFBPP.... + .....PPPFPPP.... + ......PPFPP..... + .....CAFFFAK.... + ....CKKAFAKKKAA. + ....CAKJFAKAKAA. + ....FACJDAJAFAA. + ....FACKJJJAFAA. + ....FACKKKJAFAA. + ......CKKKJAAA.. + ......CKAKJA.A.. + .....FFA..FF.... + ................ +} +# tile 629 (Baalzebub,female) +{ + ......F...F..... + .......F.F...... + ......BFFFB..... + .....BPPFBPP.... + .....PPPFPPP.... + ......PPFPP..... + .....CAFFFAK.... + ....CKKAFAKKKAA. + ....CAKJFAKAKAA. + ....FACJDAJAFAA. + ....FACKJJJAFAA. + ....FACKKKJAFAA. + ......CKKKJAAA.. + ......CKAKJA.A.. + .....FFA..FF.... + ................ +} +# tile 630 (Asmodeus,male) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKJAKKAJA + ...KA.CKKJAAKAJA + ...LA.CKKJJALJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 631 (Asmodeus,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKJAKKAJA + ...KA.CKKJAAKAJA + ...LA.CKKJJALJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 632 (Demogorgon,male) +{ + ...KKK..KKK..... + ..KBKBK.BKBK.... + ..KDKKK.KKDK.... + ..DKKFA.GKKD.... + ....GFAAGFAAA... + ...GFFFJFFFA.AAA + ..GFAGFFFAFFAAAA + .GJFAGJFJAFFFAA. + .GFAAGFFFAAFJA.. + .GJA.GFJFAAFFAA. + .GFA.GFFFA.FJAA. + .GJA.GJFJA.FFAA. + .GFAGFAAFFAFFA.. + ..GAGJAAJFAFAA.. + ..GAGFAFFFAFA... + ................ +} +# tile 633 (Demogorgon,female) +{ + ...KKK..KKK..... + ..KBKBK.BKBK.... + ..KDKKK.KKDK.... + ..DKKFA.GKKD.... + ....GFAAGFAAA... + ...GFFFJFFFA.AAA + ..GFAGFFFAFFAAAA + .GJFAGJFJAFFFAA. + .GFAAGFFFAAFJA.. + .GJA.GFJFAAFFAA. + .GFA.GFFFA.FJAA. + .GJA.GJFJA.FFAA. + .GFAGFAAFFAFFA.. + ..GAGJAAJFAFAA.. + ..GAGFAFFFAFA... + ................ +} +# tile 634 (Death,male) +{ + .BBBB....JJJ.... + .BPPPP.JJJJ..... + .C....JJJJJ..... + .C....JAAAJ..... + .C...JADADAJ.AAA + OOJ..JAAAAAJAAA. + OOOJJJAAAAAJJJA. + OOJJJJAAAAJOOJJA + .CJJJJAAAJOOOOJA + .C.JJAAAAJAOAAJA + .C..JAAAAJAOAAJA + .C..JAAAAAJOAJAA + .C..JAAAAAJJJAAA + .C.JAAAAAAAJJAA. + .CJJAAAAAAAAJJA. + ACJAAAAAAAAAAAJ. +} +# tile 635 (Death,female) +{ + .BBBB....JJJ.... + .BPPPP.JJJJ..... + .C....JJJJJ..... + .C....JAAAJ..... + .C...JADADAJ.AAA + OOJ..JAAAAAJAAA. + OOOJJJAAAAAJJJA. + OOJJJJAAAAJOOJJA + .CJJJJAAAJOOOOJA + .C.JJAAAAJAOAAJA + .C..JAAAAJAOAAJA + .C..JAAAAAJOAJAA + .C..JAAAAAJJJAAA + .C.JAAAAAAAJJAA. + .CJJAAAAAAAAJJA. + ACJAAAAAAAAAAAJ. +} +# tile 636 (Pestilence,male) +{ + F........JJJ.... + ..F....JJJJ..... + B...F.JJJJJ..... + ...B..JAAAJ..... + .F...JADADAJ.... + ...F.JAAAAAJ.AA. + .B..JFAAAAFJAA.. + ...FJJAFABJJAA.. + ..F.JFFBAJJJAAA. + ....FAFFJJJJAAA. + ....JABAJJJJAAA. + ...FJFFJJJJJJAA. + ...JJBFJJJJJJAA. + ...JAABFBJJJJAA. + ..JJFBFAFFAJJJA. + .JJAAFAFAAAAAAJ. +} +# tile 637 (Pestilence,female) +{ + F........JJJ.... + ..F....JJJJ..... + B...F.JJJJJ..... + ...B..JAAAJ..... + .F...JADADAJ.... + ...F.JAAAAAJ.AA. + .B..JFAAAAFJAA.. + ...FJJAFABJJAA.. + ..F.JFFBAJJJAAA. + ....FAFFJJJJAAA. + ....JABAJJJJAAA. + ...FJFFJJJJJJAA. + ...JJBFJJJJJJAA. + ...JAABFBJJJJAA. + ..JJFBFAFFAJJJA. + .JJAAFAFAAAAAAJ. +} +# tile 638 (Famine,male) +{ + .........JJJ.... + .......JJJ...... + K.....JJJJJ..... + K.....JAAAJ..... + K....JADADAJ.... + K....JAAAAAJ...A + K.....JAAAJJ..AA + OOJJJJJJAAJAJ.AA + K...JJJAAJJAJAAA + K.....JAJJJOJAA. + K.....JAOOOAAA.. + K.....JAJJAAA... + K.....JAJJAA.... + K.....JAAJAA.... + K...JJAAAJJAA... + K..JJAAAAAJJJA.. +} +# tile 639 (Famine,female) +{ + .........JJJ.... + .......JJJ...... + K.....JJJJJ..... + K.....JAAAJ..... + K....JADADAJ.... + K....JAAAAAJ...A + K.....JAAAJJ..AA + OOJJJJJJAAJAJ.AA + K...JJJAAJJAJAAA + K.....JAJJJOJAA. + K.....JAOOOAAA.. + K.....JAJJAAA... + K.....JAJJAA.... + K.....JAAJAA.... + K...JJAAAJJAA... + K..JJAAAAAJJJA.. +} +# tile 640 (mail daemon,male) +{ + ...OP.BEEE.PO... + ...OOEBEEEEOOD.. + ..DLOBEEEEOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDK.KDAADJJECDD + CCDKEEKKKJEEKCDD + .CCDK.EEEE..CDDD + .CCDAE.EENNNCDD. + .DDDAEEEENDNDDD. + ....BBEEENNNNN.. + ...BEEEAANNNNNA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 641 (mail daemon,female) +{ + ...OP.BEEE.PO... + ...OOEBEEEEOOD.. + ..DLOBEEEEOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDK.KDAADJJECDD + CCDKEEKKKJEEKCDD + .CCDK.EEEE..CDDD + .CCDAE.EENNNCDD. + .DDDAEEEENDNDDD. + ....BBEEENNNNN.. + ...BEEEAANNNNNA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 642 (djinni,male) +{ + .LL..NNN..LL.... + ..L..NGNA.L..... + ..LAALLLAALA.... + ..LAAKKKAALA.... + ...LCKKKCLA..... + ....LCKCLA...... + ....LICLIA..A... + ....IIIIEA.AA..A + ....EIEEIA.AAAAA + ....IEFEAAAAAAAA + .....DEAIAAAAA.. + .....IGIFAAAA... + .......FEDAAA... + .......I.GEA.A.. + .........IFED... + ................ +} +# tile 643 (djinni,female) +{ + .LL..NNN..LL.... + ..L..NGNA.L..... + ..LAALLLAALA.... + ..LAAKKKAALA.... + ...LCKKKCLA..... + ....LCKCLA...... + ....LICLIA..A... + ....IIIIEA.AA..A + ....EIEEIA.AAAAA + ....IEFEAAAAAAAA + .....DEAIAAAAA.. + .....IGIFAAAA... + .......FEDAAA... + .......I.GEA.A.. + .........IFED... + ................ +} +# tile 644 (jellyfish,male) +{ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAA... + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPPEPEEE.. + .PBBPPPEPEPPEE.. + .PEPBBEEPEEPEE.. + .PEEEPEEPEEPE... + ..PEEPE..PE.P... + ..P.EP.EEP..P... + ..PEE.P.E..E.... + .P..E.P..E...... +} +# tile 645 (jellyfish,female) +{ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAA... + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPPEPEEE.. + .PBBPPPEPEPPEE.. + .PEPBBEEPEEPEE.. + .PEEEPEEPEEPE... + ..PEEPE..PE.P... + ..P.EP.EEP..P... + ..PEE.P.E..E.... + .P..E.P..E...... +} +# tile 646 (piranha,male) +{ + ................ + ................ + ................ + ................ + ................ + ....OPP......... + .....OPP........ + ..O..PPAP.....E. + ..POPPPPPA...EEE + ..PPPPP.PPA.E... + ...PP..PPPAAAEE. + ..E.PPPPPPPPPE.. + ..E...PPPPPAA.E. + .....E..PPAE.... + .....E..P....... + ....E..E...E.... +} +# tile 647 (piranha,female) +{ + ................ + ................ + ................ + ................ + ................ + ....OPP......... + .....OPP........ + ..O..PPAP.....E. + ..POPPPPPA...EEE + ..PPPPP.PPA.E... + ...PP..PPPAAAEE. + ..E.PPPPPPPPPE.. + ..E...PPPPPAA.E. + .....E..PPAE.... + .....E..P....... + ....E..E...E.... +} +# tile 648 (shark,male) +{ + ................ + ................ + ................ + ...............P + ........P.....PP + ....E..PP....PP. + ...E...PPA..PPP. + ..EEEEPPPA.PPPPP + .E.EEPPP.PPPPPPE + ...EP.P.PPPPPEEE + ..PPPPPPPPPPEEE. + .APPPPPPPPEEEE.E + PPPPPPP..EE..... + NDPPAPEPPP.E..EE + PDNPPEE..EE..... + .PPPE..EEE..E... +} +# tile 649 (shark,female) +{ + ................ + ................ + ................ + ...............P + ........P.....PP + ....E..PP....PP. + ...E...PPA..PPP. + ..EEEEPPPA.PPPPP + .E.EEPPP.PPPPPPE + ...EP.P.PPPPPEEE + ..PPPPPPPPPPEEE. + .APPPPPPPPEEEE.E + PPPPPPP..EE..... + NDPPAPEPPP.E..EE + PDNPPEE..EE..... + .PPPE..EEE..E... +} +# tile 650 (giant eel,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA...AAA.. + ..AAAAAAA.AA.AA. + ..AAAA.AA.AA.AA. + ...AA..AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA.E.AA.E. + ...E.AAEE.AAAE.. + ...E.AAEEAAAEE.. + ..E..AAAAAAE.E.. + ...EE.AAAAE.E... + ..E...EE.E...E.. +} +# tile 651 (giant eel,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA...AAA.. + ..AAAAAAA.AA.AA. + ..AAAA.AA.AA.AA. + ...AA..AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA.E.AA.E. + ...E.AAEE.AAAE.. + ...E.AAEEAAAEE.. + ..E..AAAAAAE.E.. + ...EE.AAAAE.E... + ..E...EE.E...E.. +} +# tile 652 (electric eel,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA........ + ..AAAAAAA....... + ..AAAA.AA....... + ...AA..AA...DD.. + ......AAA..DD... + ......AA...DD... + .....AAA.E.DD.E. + ...E.AAEE.DD.E.. + ...E.AAEEDD.EE.. + ..E..AAADDDE.E.. + ...EE.AAADE.E... + ..E...EE.E...E.. +} +# tile 653 (electric eel,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA........ + ..AAAAAAA....... + ..AAAA.AA....... + ...AA..AA...DD.. + ......AAA..DD... + ......AA...DD... + .....AAA.E.DD.E. + ...E.AAEE.DD.E.. + ...E.AAEEDD.EE.. + ..E..AAADDDE.E.. + ...EE.AAADE.E... + ..E...EE.E...E.. +} +# tile 654 (kraken,male) +{ + ................ + ................ + ..FF..FF........ + ..DDFDDF........ + ..FFFFF.....GG.. + ..NCNFF......GFA + ..CC.FF.....EGFA + ....GFAA.GFAEGFE + ...GFFAGFFFFAGFE + ...GFAAFFAGFAEEE + ..GFFAGFFAGFEEE. + EEGFFAGFFAEEEE.E + .EGFFAGFFEE..... + EEGFFEEEEE.E..EE + EEEEEEE..EE..... + ..EEE..EEE..E... +} +# tile 655 (kraken,female) +{ + ................ + ................ + ..FF..FF........ + ..DDFDDF........ + ..FFFFF.....GG.. + ..NCNFF......GFA + ..CC.FF.....EGFA + ....GFAA.GFAEGFE + ...GFFAGFFFFAGFE + ...GFAAFFAGFAEEE + ..GFFAGFFAGFEEE. + EEGFFAGFFAEEEE.E + .EGFFAGFFEE..... + EEGFFEEEEE.E..EE + EEEEEEE..EE..... + ..EEE..EEE..E... +} +# tile 656 (newt,male) +{ + ................ + ................ + ................ + ................ + ................ + ......JKKJ...... + .....CLCCLLC.... + ....LAAAACCLCA.. + .......LCCLLLCA. + ....LCCCLLLAALA. + ....CALLLLAAAA.. + ...LLLLCLAAA.... + ...LLAAALLA..... + ................ + ................ + ................ +} +# tile 657 (newt,female) +{ + ................ + ................ + ................ + ................ + ................ + ......JKKJ...... + .....CLCCLLC.... + ....LAAAACCLCA.. + .......LCCLLLCA. + ....LCCCLLLAALA. + ....CALLLLAAAA.. + ...LLLLCLAAA.... + ...LLAAALLA..... + ................ + ................ + ................ +} +# tile 658 (gecko,male) +{ + ................ + ................ + ...........LLP.. + ..........LLOOA. + ......PO.LLOOOA. + ......OOALOOOA.. + .......LLOOOA... + ...POALOOOAA.... + ...OOLOOOOOOA... + ....ALOOOAOPA... + ...DOOOOA.AA.... + ...OOOAOOA...... + ...OODAOPA...... + ..F.AA.AA....... + ................ + ................ +} +# tile 659 (gecko,female) +{ + ................ + ................ + ...........LLP.. + ..........LLOOA. + ......PO.LLOOOA. + ......OOALOOOA.. + .......LLOOOA... + ...POALOOOAA.... + ...OOLOOOOOOA... + ....ALOOOAOPA... + ...DOOOOA.AA.... + ...OOOAOOA...... + ...OODAOPA...... + ..F.AA.AA....... + ................ + ................ +} +# tile 660 (iguana,male) +{ + ................ + ................ + ................ + ................ + ................ + ....GPGPGGPF.... + ..GPAAAAFFGPF... + .GPAA.PFFGPPPAA. + ......FGGPPFPPAA + .PFGGGGPPPFAAPPA + .FGPAPPPPFAAAAA. + .GPPPPFPFAAA.A.. + .PPFFAFPPAA..... + D.AAAAAAPPA..... + ................ + ................ +} +# tile 661 (iguana,female) +{ + ................ + ................ + ................ + ................ + ................ + ....GPGPGGPF.... + ..GPAAAAFFGPF... + .GPAA.PFFGPPPAA. + ......FGGPPFPPAA + .PFGGGGPPPFAAPPA + .FGPAPPPPFAAAAA. + .GPPPPFPFAAA.A.. + .PPFFAFPPAA..... + D.AAAAAAPPA..... + ................ + ................ +} +# tile 662 (baby crocodile,male) +{ + ................ + ................ + ................ + ................ + ................ + .....FFOFOFA.... + ....FOGFGGOFF... + ....GAAAAFOGFA.. + ...FAA.GFOGGGFA. + ...GFOOOGGGFAGA. + ...FGAGGGGFAAA.. + ..FGGGGFGFAA.... + ..GGDFAFGGA..... + ...D............ + ................ + ................ +} +# tile 663 (baby crocodile,female) +{ + ................ + ................ + ................ + ................ + ................ + .....FFOFOFA.... + ....FOGFGGOFF... + ....GAAAAFOGFA.. + ...FAA.GFOGGGFA. + ...GFOOOGGGFAGA. + ...FGAGGGGFAAA.. + ..FGGGGFGFAA.... + ..GGDFAFGGA..... + ...D............ + ................ + ................ +} +# tile 664 (lizard,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ....FFFFGFJ..... + ..FFAAAJJGFJ.... + ......JGFFJFAA.. + ...JGGGFFJAAFA.. + ..JFAFFFJAAAA... + ..FFFFJJAAA..... + .JFAAAAFAA...... + .D.............. + ................ + ................ +} +# tile 665 (lizard,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ....FFFFGFJ..... + ..FFAAAJJGFJ.... + ......JGFFJFAA.. + ...JGGGFFJAAFA.. + ..JFAFFFJAAAA... + ..FFFFJJAAA..... + .JFAAAAFAA...... + .D.............. + ................ + ................ +} +# tile 666 (chameleon,male) +{ + ................ + ................ + ................ + .....GGGG....... + ...GGGGGGGG..... + ...GGFFFFGGFA... + ..GPAAAGFFGGFA.. + .GPAA.PFFGGGGAA. + ...GGGGGGGGFGGAA + .PGGBBGGGGFAAGGA + .FGGABGGGFAAAAA. + .GGGGGFGFAAA.A.. + .DGFFAFGGAA..... + D.AAAAAAGGA..... + .DD............. + ................ +} +# tile 667 (chameleon,female) +{ + ................ + ................ + ................ + .....GGGG....... + ...GGGGGGGG..... + ...GGFFFFGGFA... + ..GPAAAGFFGGFA.. + .GPAA.PFFGGGGAA. + ...GGGGGGGGFGGAA + .PGGBBGGGGFAAGGA + .FGGABGGGFAAAAA. + .GGGGGFGFAAA.A.. + .DGFFAFGGAA..... + D.AAAAAAGGA..... + .DD............. + ................ +} +# tile 668 (crocodile,male) +{ + ................ + ................ + ................ + ................ + ....FFOFOOFA.... + ...FOGFGFGOFFA.. + ..FGAAAAFFOGFFA. + .FFAA.GFFOGGGGFA + ......FOOGGGGGGA + .G.OOOOGGGGFAGGA + .FOGAGGGGGFAAAA. + FGGGGGFGGFAA.... + GGDDFAFGGGA..... + GDDFAAAAGGA..... + .DF............. + ................ +} +# tile 669 (crocodile,female) +{ + ................ + ................ + ................ + ................ + ....FFOFOOFA.... + ...FOGFGFGOFFA.. + ..FGAAAAFFOGFFA. + .FFAA.GFFOGGGGFA + ......FOOGGGGGGA + .G.OOOOGGGGFAGGA + .FOGAGGGGGFAAAA. + FGGGGGFGGFAA.... + GGDDFAFGGGA..... + GDDFAAAAGGA..... + .DF............. + ................ +} +# tile 670 (salamander,male) +{ + ................ + ................ + ................ + ......CCC....... + ....CCCCCCC..... + ...CCDDDDCCDA... + ....AAAADDCCDA.. + ......KDDCCCCAA. + ..LLLCCCCCCDCCAA + .KLCCCLLLCDAACCA + .DCEECLKKDAAAAA. + DCCAECDKDAAA.A.. + CCCCCCDCCAA..... + .DAADAAACCA..... + ..ACCA.......... + ...AAA.......... +} +# tile 671 (salamander,female) +{ + ................ + ................ + ................ + ......CCC....... + ....CCCCCCC..... + ...CCDDDDCCDA... + ....AAAADDCCDA.. + ......KDDCCCCAA. + ..LLLCCCCCCDCCAA + .KLCCCLLLCDAACCA + .DCEECLKKDAAAAA. + DCCAECDKDAAA.A.. + CCCCCCDCCAA..... + .DAADAAACCA..... + ..ACCA.......... + ...AAA.......... +} +# tile 672 (long worm tail,male) +{ + ........ILLLL... + ......IILLAA.... + .....ILLAA...... + .....ILA........ + .....ILA........ + ......LLA...II.. + .......LLIIILLLL + ........ILLAAA.L + ...IIIILLALL.... + .ILLLLLAA..LL... + ILLAAAA.....LA.. + ILA.........LA.. + LLA........LLA.. + LILA......LLA... + .LLLIIIILLLA.... + ...LLLLLAAA..... +} +# tile 673 (long worm tail,female) +{ + ........ILLLL... + ......IILLAA.... + .....ILLAA...... + .....ILA........ + .....ILA........ + ......LLA...II.. + .......LLIIILLLL + ........ILLAAA.L + ...IIIILLALL.... + .ILLLLLAA..LL... + ILLAAAA.....LA.. + ILA.........LA.. + LLA........LLA.. + LILA......LLA... + .LLLIIIILLLA.... + ...LLLLLAAA..... +} +# tile 674 (archeologist,male) +{ + ................ + ................ + ......KJ.J...... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + ......CJJKAAAA.. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 675 (archeologist,female) +{ + ................ + ................ + ................ + ......KJJJ...... + ......KKLJ...... + .....KLELE...... + ....KJLLLL...... + ....JJALLA...... + ...JJLBAAPL.AAA. + ...JLLBBBPLLAAA. + ....LABPPPALAAA. + ....LALLLLALAAA. + .....AOJJOAAAA.. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 676 (barbarian,male) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + ......ALLA...... + .....LLAALL.AAA. + ....LLLLLLLLAAA. + ....LALLLLALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 677 (barbarian,female) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + ......ALLA...... + .....LLAALL.AAA. + ....LLLLLLLLAAA. + ....LALLLLALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 678 (cave dweller,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LLAJJALLAAA. + ...LLLLAALLLLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 679 (cave dweller,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JLDDLAJ.... + ....LJALLAJLAAA. + ...LLJCAAJJLLAA. + ...LLACKKJALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 680 (healer,male) +{ + ................ + .......NN....... + ......NDDO...... + ......NNNN...... + ......ELEP...... + ......LLLP...... + .......LLP...... + ......O..PA.AAA. + .....NNOOPPAAAA. + ....OOONOPPPAA.. + ....LANOOPALAA.. + ......NOOPAAAA.. + .....NOOOPAA.A.. + ....NOOOOOPA.... + ................ + ................ +} +# tile 681 (healer,female) +{ + ................ + .......NN....... + ......NDDO...... + ......NNNN...... + ......ELEP...... + ......LLLP...... + .......LLP...... + ......O..PA.AAA. + .....NNOOPPAAAA. + ....OOONOPPPAA.. + ....LANOOPALAA.. + ......NOOPAAAA.. + .....NOOOPAA.A.. + ....NOOOOOPA.... + ................ + ................ +} +# tile 682 (knight,male) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + ......ALLAA..... + .....BBAABB.AAA. + ....BPPPPPPPAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... + ................ + ................ +} +# tile 683 (knight,female) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + ......ALLAA..... + .....BBAABB.AAA. + ....BPPPPPPPAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... + ................ + ................ +} +# tile 684 (monk,male) +{ + ................ + ................ + .......CCC...... + ......JCJJJA.... + ......CAAAJA.... + ......CAAAJA.... + ......CKLKCAAAA. + .....CDDDDDDAAAA + ....CDDLALDDDAAA + ....DALLALLADAA. + ....DDDDCDDDDAA. + .....AACCCDAAAA. + .....CDCCCDDA.A. + ....CCCCCCCDD... + ................ + ................ +} +# tile 685 (monk,female) +{ + ................ + ................ + .......CCC...... + ......JCJJJA.... + ......CAAAJA.... + ......CAAAJA.... + ......CKLKCAAAA. + .....CDDDDDDAAAA + ....CDDLALDDDAAA + ....DALLALLADAA. + ....DDDDCDDDDAA. + .....AACCCDAAAA. + .....CDCCCDDA.A. + ....CCCCCCCDD... + ................ + ................ +} +# tile 686 (cleric,male) +{ + ................ + ................ + ......JLLJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......IJJIAAAA.. + .....ODDDDDAAAA. + ....INNDDDDDAAA. + ...NLNNDDDALAA.. + ......DDDDAAAA.. + ......DIIDAAAA.. + .....DDIIDDA.A.. + ....DIIIIIDD.... + ................ + ................ +} +# tile 687 (cleric,female) +{ + ................ + .......JJ....... + ......JJJJ...... + ......JLLJA..... + ......JLLJJ..... + .....JJLLJJ..... + .....JEJJEJAAA.. + .....ODEEDDAAAA. + ....IDINNDDDAAA. + ....L.DNNDALAA.. + ......IDDDAAAA.. + ......IDDDAAAA.. + .....DDIIDDA.A.. + ....DIIIIIDD.... + ................ + ................ +} +# tile 688 (ranger,male) +{ + ................ + ................ + ........CJA..... + .......CJJJA.... + .......JEEJA.... + .......JLLJA.... + .......ALLAA.... + ......GGAAGG.AAA + .....BPFFFFPPAAA + .....PAGFFFAPAAA + .....LA.FF.ALAAA + .......BP.PAAAA. + .......BPAPAA.A. + ......PPA.PPA... + ................ + ................ +} +# tile 689 (ranger,female) +{ + ................ + ................ + ........CJA..... + .......CJJJA.... + .......JEEJA.... + .......JLLJA.... + .......ALLAA.... + ......GGAAGG.AAA + .....BPFFFFPPAAA + .....PAGFFFAPAAA + .....LA.FF.ALAAA + .......BP.PAAAA. + .......BPAPAA.A. + ......PPA.PPA... + ................ + ................ +} +# tile 690 (rogue,male) +{ + ................ + ................ + ................ + .....OA...OA.... + .....OOIDPPA.... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + ......BAABAA..A. + .....KEBBEJAAAA. + ....KAAEEAAKAA.. + ....LAJJHJALAA.. + ......KKJKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 691 (rogue,female) +{ + ................ + ................ + ................ + .....OA...OA.... + .....OOIDPPA.... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + ......BAABAA..A. + .....KEBBEJAAAA. + ....KAAEEAAKAA.. + ....LAJJHJALAA.. + ......KKJKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 692 (samurai,male) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LABBBBALAAA. + ....LABBBBALAAA. + ......IDDDAAAA.. + ......IDADAA.A.. + .....IIA.IIA.... + ................ +} +# tile 693 (samurai,female) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LABBBBALAAA. + ....LABBBBALAAA. + ......IDDDAAAA.. + ......IDADAA.A.. + .....IIA.IIA.... + ................ +} +# tile 694 (tourist,male) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ...JJJJJJJJJJ... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HGAAGH.AAA. + ....LLGHHGLLAAA. + ....LAHGHGALAAA. + ....LAHHGHALAAA. + ......JJJKAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 695 (tourist,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ...JJJJJJJJJJ... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HGAAGH.AAA. + ....LLGHHGLLAAA. + ....LAHGHGALAAA. + ....LAHHGHALAAA. + ......JJJKAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 696 (valkyrie,male) +{ + D..............D + .D............D. + ..D...LHHL...D.. + ...D.HHHHHL.D... + ....DHELELHD.... + ....HDLLLLD..... + ...HHHDLLD...... + ...HJKJDDKJJAAA. + ..HHLJJDDJJLAAA. + ..H.LADKDCALAAA. + ....LDAKKDALAAA. + ....D.KKJKDAAA.. + ...D..KJAJAD.A.. + ..D..KLA.LKAD... + .D...........D.. + D.............D. +} +# tile 697 (valkyrie,female) +{ + ................ + ................ + ......LHHL...... + .....HHHHHL..... + ....LHELELH..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 698 (wizard,male) +{ + ................ + .........BP..... + .......BBPE..... + ......BPPEA..... + ......BAAEA..... + ......BAAEA..... + ......PLLE...... + ......PAAEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 699 (wizard,female) +{ + ................ + .........BP..... + .......BBPE..... + ......BPPEA..... + ......BAAEA..... + ......BAAEA..... + ......PLLE...... + ......PAAEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 700 (Lord Carnarvon,male) +{ + .......JJ....... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CIAAIK.AAA. + ....CKKIIKKKAAA. + ...KKCKKHKJKKAA. + ...KKAKHKJAKKAA. + ...KAIHKKJIAKA.. + ...LAICKKJIALA.. + .....ICKAJIAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 701 (Lord Carnarvon,female) +{ + .......JJ....... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CIAAIK.AAA. + ....CKKIIKKKAAA. + ...KKCKKHKJKKAA. + ...KKAKHKJAKKAA. + ...KAIHKKJIAKA.. + ...LAICKKJIALA.. + .....ICKAJIAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 702 (Pelias,male) +{ + ................ + .......JJ....... + ......KKKJ...... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKKAKKAA. + ...KA.CKKJAAKA.. + ...LA.CKAJAALA.. + ......CKAJAAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 703 (Pelias,female) +{ + ................ + .......JJ....... + ......KKKJ...... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKKAKKAA. + ...KA.CKKJAAKA.. + ...LA.CKAJAALA.. + ......CKAJAAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 704 (Shaman Karnov,male) +{ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LHAJJAHLAA.. + ...LLLHAAHLLLAA. + ...LLLLHHLLLLAA. + ...LLALHHLALLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ +} +# tile 705 (Shaman Karnov,female) +{ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LHAJJAHLAA.. + ...LLLHAAHLLLAA. + ...LLLLHHLLLLAA. + ...LLALHHLALLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ +} +# tile 706 (Earendil,male) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBPLELEABPB.. + ..BBBPLLLLABBB.. + ..PBPPALLAPPP... + ...PPBGAAGBBB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 707 (Earendil,female) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBPLELEABPB.. + ..BBBPLLLLABBB.. + ..PBPPALLAPPP... + ...PPBGAAGBBB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 708 (Elwing,male) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBHLELEHBPB.. + ..BBBHLLLLHBBB.. + ..PBHHALLAHHP... + ...PHHGAAGHHB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 709 (Elwing,female) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBHLELEHBPB.. + ..BBBHLLLLHBBB.. + ..PBHHALLAHHP... + ...PHHGAAGHHB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 710 (Hippocrates,male) +{ + ................ + ....LLLCCD...... + ...LLCCDDA...... + ...LAAAADA...... + ...LBABADA...... + ...LAAAADA...... + ...CCLLDD.B..... + ....CKKDDFBFAAA. + ..LLLCLDDDBFAAA. + .CCCCLDDDFBAAA.. + .LALLCCDDFBDAA.. + ...LCCCCDABFAA.. + ...LCCCCDABAAA.. + ..LLCCCCDAA.AA.. + .LCCCCCCCDA..... + ................ +} +# tile 711 (Hippocrates,female) +{ + ................ + ....LLLCCD...... + ...LLCCDDA...... + ...LAAAADA...... + ...LBABADA...... + ...LAAAADA...... + ...CCLLDD.B..... + ....CKKDDFBFAAA. + ..LLLCLDDDBFAAA. + .CCCCLDDDFBAAA.. + .LALLCCDDFBDAA.. + ...LCCCCDABFAA.. + ...LCCCCDABAAA.. + ..LLCCCCDAA.AA.. + .LCCCCCCCDA..... + ................ +} +# tile 712 (King Arthur,male) +{ + ................ + ................ + ......OHHA...... + .....OHHHHA..... + .....HBLBHA..... + .....HLLLHA..... + .....ALLLAA..... + ....BBAAABB.AAA. + ...BPPPPPPPPAAA. + ...PABPPPPACPAA. + ..NNNNNNNNNCLCA. + .....BPP.PACAA.. + .....BPAPPAA.A.. + .....BPAPPAA.A.. + ....PPAA.PPA.... + ................ +} +# tile 713 (King Arthur,female) +{ + ................ + ................ + ......OHHA...... + .....OHHHHA..... + .....HBLBHA..... + .....HLLLHA..... + .....ALLLAA..... + ....BBAAABB.AAA. + ...BPPPPPPPPAAA. + ...PABPPPPACPAA. + ..NNNNNNNNNCLCA. + .....BPP.PACAA.. + .....BPAPPAA.A.. + .....BPAPPAA.A.. + ....PPAA.PPA.... + ................ +} +# tile 714 (Grand Master,male) +{ + ................ + .......LL....... + ......LLLL...... + ......LLLL...... + ..LC.CALLAC..... + .CLLC.CAACCCC... + .CJLACCCCCCCCC.. + ..JAACCCCCCCCCC. + ..JCCCCCCCCCCC.A + ..J..PPPPPLCCAAA + ..J..CCCCLLCAAAA + ..J..CCCCCCCAAAA + ..J..CCCCCCCAAAA + ..J.ACCCCCCCAAA. + ..JACCCCCCCCAA.. + ................ +} +# tile 715 (Grand Master,female) +{ + ................ + .......LL....... + ......LLLL...... + ......LLLL...... + ..LC.CALLAC..... + .CLLC.CAACCCC... + .CJLACCCCCCCCC.. + ..JAACCCCCCCCCC. + ..JCCCCCCCCCCC.A + ..J..PPPPPLCCAAA + ..J..CCCCLLCAAAA + ..J..CCCCCCCAAAA + ..J..CCCCCCCAAAA + ..J.ACCCCCCCAAA. + ..JACCCCCCCCAA.. + ................ +} +# tile 716 (Arch Priest,male) +{ + ..N............. + .NNN..JLLJ...... + ..N...JLLJ...... + ..N...LLLL...... + ..LC.CALLAC..... + .CLLC.CAACJDK... + .CHLACCCCJCCDK.. + ..HAACCJJCCCCDK. + ..HCCCCJCCJCCC.A + ..H..DCJCCLJCAAA + ..H..DCJCLLCAAAA + ..H..KCJCCDJAAAA + ..H..KCJCCDJAAAA + ..H.ACCJCCDJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 717 (Arch Priest,female) +{ + ..N............. + .NNN..JLLJ...... + ..N...JLLJ...... + ..N...LLLL...... + ..LC.CALLAC..... + .CLLC.CAACJDK... + .CHLACCCCJCCDK.. + ..HAACCJJCCCCDK. + ..HCCCCJCCJCCC.A + ..H..DCJCCLJCAAA + ..H..DCJCLLCAAAA + ..H..KCJCCDJAAAA + ..H..KCJCCDJAAAA + ..H.ACCJCCDJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 718 (Orion,male) +{ + ................ + ................ + .......CJA...... + ......CJJJA..... + ......JEEJA..... + ......JLLJA..... + ......ALLAA..... + .....GGAAGG..... + ....BGFFFFFP.... + ....BPFFFFPPAAA. + ....PAGFFFAPAAA. + ....LANNNNALAAA. + ......BP.PAAAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... +} +# tile 719 (Orion,female) +{ + ................ + ................ + .......CJA...... + ......CJJJA..... + ......JEEJA..... + ......JLLJA..... + ......ALLAA..... + .....GGAAGG..... + ....BGFFFFFP.... + ....BPFFFFPPAAA. + ....PAGFFFAPAAA. + ....LANNNNALAAA. + ......BP.PAAAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... +} +# tile 720 (Master of Thieves,male) +{ + ................ + ...H.....H...... + ...HHIDKHH...... + ....IDDDD....... + ....LLLLLA...... + ....LBLBLA...... + ....LLLLLA...... + .....LLLA....... + ....B.AABAA..... + ...KEBBBEJAAA... + ..KAEEEEEAJAAA.. + ..LAJJHHJALAAA.. + ....JKKKJAAAAA.. + ....KJAJKAAAA... + ...JJA..JJA..... + ................ +} +# tile 721 (Master of Thieves,female) +{ + ................ + ...H.....H...... + ...HHIDKHH...... + ....IDDDD....... + ....LLLLLA...... + ....LBLBLA...... + ....LLLLLA...... + .....LLLA....... + ....B.AABAA..... + ...KEBBBEJAAA... + ..KAEEEEEAJAAA.. + ..LAJJHHJALAAA.. + ....JKKKJAAAAA.. + ....KJAJKAAAA... + ...JJA..JJA..... + ................ +} +# tile 722 (Lord Sato,male) +{ + .....AAA........ + .....AAA........ + ...AAAAAAA...... + ..AALLLLLAA..... + ..ALFFLFFLA..... + ..ALLLLLLLA..... + ...AALLLA....... + IIIIIAAAIIIIAAA. + LLDIIIIIIDLLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + ...IIDDDDAAAAAA. + ...IIAAIDAAA..A. + ..IIIA.IIIAA.... + ................ +} +# tile 723 (Lord Sato,female) +{ + .....AAA........ + .....AAA........ + ...AAAAAAA...... + ..AALLLLLAA..... + ..ALFFLFFLA..... + ..ALLLLLLLA..... + ...AALLLA....... + IIIIIAAAIIIIAAA. + LLDIIIIIIDLLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + ...IIDDDDAAAAAA. + ...IIAAIDAAA..A. + ..IIIA.IIIAA.... + ................ +} +# tile 724 (Twoflower,male) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + .....NNLNNA..... + ....NALNALNA.... + .....NNANNAA.... + .....AAAAAA.AAA. + ....LLHGHGLLAAA. + ....LAGGGGALAAA. + ....LAHGHGALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 725 (Twoflower,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + .....NNLNNA..... + ....NALNALNA.... + .....NNANNAA.... + .....AAAAAA.AAA. + ....LLHGHGLLAAA. + ....LAGGGGALAAA. + ....LAHGHGALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 726 (Norn,male) +{ + ................ + ................ + ......NNN....... + .....NNNNN...... + .....NELELN..... + ....NNLLLLN..... + ...NNNALLA...... + ...NJKJAAKJJAAA. + ..NNLJJKKJJLAAA. + ..N.LACKJCALAAA. + ....LAKKKKALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 727 (Norn,female) +{ + ................ + ................ + ......NNN....... + .....NNNNN...... + .....NELELN..... + ....NNLLLLN..... + ...NNNALLA...... + ...NJKJAAKJJAAA. + ..NNLJJKKJJLAAA. + ..N.LACKJCALAAA. + ....LAKKKKALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 728 (Neferet the Green,male) +{ + ................ + ................ + ......GGG....... + .....GFFFG...... + ....GFEFEG...... + ....GFFFFEG..... + .N.GPEFFFEE..... + .I..BBEAAEA.AA.. + .I.BBPPBBEEAAAA. + .IGBPPPPPEEEAA.. + .I.PP.EPEAAGAA.. + .I...BPPPAAAAA.. + .N...BPPPEAA.A.. + ....BPPPPPEA.... + ...BPPPPPPPE.... + ................ +} +# tile 729 (Neferet the Green,female) +{ + ................ + ................ + ......GGG....... + .....GFFFG...... + ....GFEFEG...... + ....GFFFFEG..... + .N.GPEFFFEE..... + .I..BBEAAEA.AA.. + .I.BBPPBBEEAAAA. + .IGBPPPPPEEEAA.. + .I.PP.EPEAAGAA.. + .I...BPPPAAAAA.. + .N...BPPPEAA.A.. + ....BPPPPPEA.... + ...BPPPPPPPE.... + ................ +} +# tile 730 (Minion of Huhetotl,male) +{ + ...OP......PO... + ...OODDDDDDOOD.. + ..DLOOCDDCOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDKKKDAADJJDCDD + CCDKDDKKKJDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 731 (Minion of Huhetotl,female) +{ + ...OP......PO... + ...OODDDDDDOOD.. + ..DLOOCDDCOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDKKKDAADJJDCDD + CCDKDDKKKJDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 732 (Thoth Amon,male) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....BPAAPP.AAA. + ....BPPPPPPPAAA. + ...PPBPPPPJPPAA. + ...PPAPPP.APPA.A + ...PA.BPP.AAPA.A + ...LA.BPP..AL.A. + ......BPA.A..A.. + ......BPAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 733 (Thoth Amon,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....BPAAPP.AAA. + ....BPPPPPPPAAA. + ...PPBPPPPJPPAA. + ...PPAPPP.APPA.A + ...PA.BPP.AAPA.A + ...LA.BPP..AL.A. + ......BPA.A..A.. + ......BPAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 734 (Chromatic Dragon,male) +{ + ......GGGFA..... + .....NFNFEEA.... + ....GFFFEECA.... + ..DCHHF..CCA.... + CHCHCD..BCCA.... + HD.D...BFFA..... + ......OBFAAAAAA. + ....HOGFAAAAAAAA + ..HOOIEA.EF.AAA. + .HOOOIEEEEFFJAA. + .HOOOIEEFFFDDAA. + HBOOIIEFFFDDCCA. + HB.OIEFOODD.CJA. + HBAAGE.AADDACCA. + ....GFAA...CCJA. + ........FFFFJA.. +} +# tile 735 (Chromatic Dragon,female) +{ + ......GGGFA..... + .....NFNFEEA.... + ....GFFFEECA.... + ..DCHHF..CCA.... + CHCHCD..BCCA.... + HD.D...BFFA..... + ......OBFAAAAAA. + ....HOGFAAAAAAAA + ..HOOIEA.EF.AAA. + .HOOOIEEEEFFJAA. + .HOOOIEEFFFDDAA. + HBOOIIEFFFDDCCA. + HB.OIEFOODD.CJA. + HBAAGE.AADDACCA. + ....GFAA...CCJA. + ........FFFFJA.. +} +# tile 736 (Goblin King,male) +{ + ................ + ................ + .H..H...H....... + CLC.HCHCH....... + CLC.HHHHH....... + .H..IIIII....... + .HK.IHIHI.I..... + .HICKIIIJKK..... + .H.IIJJJK.AA.... + .H..JICJJAAAAA.. + .H..IIIIJAAAAA.. + ....JIIJJAA..... + ....IJKJJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 737 (Goblin King,female) +{ + ................ + ................ + .H..H...H....... + CLC.HCHCH....... + CLC.HHHHH....... + .H..IIIII....... + .HK.IHIHI.I..... + .HICKIIIJKK..... + .H.IIJJJK.AA.... + .H..JICJJAAAAA.. + .H..IIIIJAAAAA.. + ....JIIJJAA..... + ....IJKJJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 738 (Cyclops,male) +{ + ................ + ....LLLLL....... + ...CLLLLLC...... + ...LBABNNL...... + ...LBBBNNLJA.... + ...CLNNNLCJA.... + ....LLLLLJAAA... + ....LAALLAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.GGGHGGACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 739 (Cyclops,female) +{ + ................ + ....LLLLL....... + ...CLLLLLC...... + ...LBABNNL...... + ...LBBBNNLJA.... + ...CLNNNLCJA.... + ....LLLLLJAAA... + ....LAALLAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.GGGHGGACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 740 (Ixoth,male) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDGDDGDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 741 (Ixoth,female) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDGDDGDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 742 (Master Kaen,male) +{ + ................ + .......KKA...... + ......KJJKA..... + ..KKA.KAAKA.KKA. + .KAAKAKDDKAKAAKA + .KOOJKKOOKKKOOJA + .KJJJJJJJJJKJJJA + ..KJJJJJJJJJJJA. + ....KJJJJJJJA... + ......KJJJAAAAAA + .....KJJJJKAAAAA + .....KJJJJJAAAAA + ....KJJJJJJKAAA. + ...KJJJJJJJJKAA. + ...KJJJJJJJJJA.. + ................ +} +# tile 743 (Master Kaen,female) +{ + ................ + .......KKA...... + ......KJJKA..... + ..KKA.KAAKA.KKA. + .KAAKAKDDKAKAAKA + .KOOJKKOOKKKOOJA + .KJJJJJJJJJKJJJA + ..KJJJJJJJJJJJA. + ....KJJJJJJJA... + ......KJJJAAAAAA + .....KJJJJKAAAAA + .....KJJJJJAAAAA + ....KJJJJJJKAAA. + ...KJJJJJJJJKAA. + ...KJJJJJJJJJA.. + ................ +} +# tile 744 (Nalzok,male) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDBDDBDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 745 (Nalzok,female) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDBDDBDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 746 (Scorpius,male) +{ + .....JLJLJAA.... + ....JA.JCJCKAA.. + ....AJ.....JJJA. + ....LA......LCKA + .JAKJA......JJJA + ..JJA......ALCJA + .......ALLAJCJKA + ....JJALCCAAJJA. + .JJALLAJCJJJAA.. + JA.LCCAJAJJAAAA. + ..JACJJJAAACCJAA + GGJJJJJAACCAAAJA + .JJGGAJACAAJJAAA + D.JJAAJAACA.JAA. + ...D...JAAJA.JJ. + ........JA.JA... +} +# tile 747 (Scorpius,female) +{ + .....JLJLJAA.... + ....JA.JCJCKAA.. + ....AJ.....JJJA. + ....LA......LCKA + .JAKJA......JJJA + ..JJA......ALCJA + .......ALLAJCJKA + ....JJALCCAAJJA. + .JJALLAJCJJJAA.. + JA.LCCAJAJJAAAA. + ..JACJJJAAACCJAA + GGJJJJJAACCAAAJA + .JJGGAJACAAJJAAA + D.JJAAJAACA.JAA. + ...D...JAAJA.JJ. + ........JA.JA... +} +# tile 748 (Master Assassin,male) +{ + ................ + ................ + ................ + .......AA....... + ......AAAA...... + .....ABLBLA..... + .....AAAAAA..... + ......AAAA...... + .....AAAAAA..PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 749 (Master Assassin,female) +{ + ................ + ................ + ................ + .......AA....... + ......AAAA...... + .....ABLBLA..... + .....AAAAAA..... + ......AAAA...... + .....AAAAAA..PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 750 (Ashikaga Takauji,male) +{ + ................ + ................ + ......AA........ + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LAIIIIALAAA. + ....LALHHLALAAA. + ......IIIIAAAA.. + ......IIAIAA.A.. + .....IIA.IIA.... + ................ +} +# tile 751 (Ashikaga Takauji,female) +{ + ................ + ................ + ......AA........ + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LAIIIIALAAA. + ....LALHHLALAAA. + ......IIIIAAAA.. + ......IIAIAA.A.. + .....IIA.IIA.... + ................ +} +# tile 752 (Lord Surtur,male) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLBAAAA. + ...PPDBBBBBBBAA. + ..BDDHDPBPPPPPA. + ..PPHDDPBPPPPPA. + ..LAHDHPBPPAALAA + JLAADDHBBBBAALAA + JJLJDHHPBPPPCLAA + ..LLJBPPABPPLLAA + .....BPPABPPAAAA + ...LLLLJ.BLLLKAA +} +# tile 753 (Lord Surtur,female) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLBAAAA. + ...PPDBBBBBBBAA. + ..BDDHDPBPPPPPA. + ..PPHDDPBPPPPPA. + ..LAHDHPBPPAALAA + JLAADDHBBBBAALAA + JJLJDHHPBPPPCLAA + ..LLJBPPABPPLLAA + .....BPPABPPAAAA + ...LLLLJ.BLLLKAA +} +# tile 754 (Dark One,male) +{ + ................ + ......AAA....... + .....AAAAA...... + .....ADADA...... + .....AAAAA...... + ....AAAAAAA..... + ....AAAAAAA..... + ...AAAAAAAAA.... + ...AAAAAAAAA.... + ..AAAAAAAAAAA... + ..AAAAAAAAAAA... + ...AAAAAAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAAA + ................ +} +# tile 755 (Dark One,female) +{ + ................ + ......AAA....... + .....AAAAA...... + .....ADADA...... + .....AAAAA...... + ....AAAAAAA..... + ....AAAAAAA..... + ...AAAAAAAAA.... + ...AAAAAAAAA.... + ..AAAAAAAAAAA... + ..AAAAAAAAAAA... + ...AAAAAAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAAA + ................ +} +# tile 756 (student,male) +{ + ................ + ................ + .....GGFGG...... + .......G........ + ......NDND...... + ...DDDDDDDD..... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 757 (student,female) +{ + ................ + ................ + .....GGFGG...... + .......G........ + ......NDND...... + ...DDDDDDDD..... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 758 (chieftain,male) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + .....HALLAH..... + ....LLHAAHLLAAA. + ....LLLIILLLAAA. + ....LALIILALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 759 (chieftain,female) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + .....HALLAH..... + ....LLHAAHLLAAA. + ....LLLIILLLAAA. + ....LALIILALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 760 (neanderthal,male) +{ + ................ + ................ + ................ + ......JJJJ...... + .....JJJJJJ..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....JJAJJAJJ.AA. + ...JLLJAAJLLJAA. + ...LLALJJLALLAA. + ....LALCCLALAAA. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 761 (neanderthal,female) +{ + ................ + ................ + ................ + ......JJJJ...... + .....JJJJJJ..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....JJAJJAJJ.AA. + ...JLLJAAJLLJAA. + ...LLALJJLALLAA. + ....LALCCLALAAA. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 762 (High-elf,male) +{ + .........G...... + .......GGF...... + ......GGGGA..... + ......LILIA..... + ......LLLLA..... + ......ALLA...... + ......GAAG..AA.. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LA.GFAALAA.. + ....LA.GFAALAA.. + ....LAGGGFAL.A.. + ......GFAFAA.A.. + ......GFAFAA.... + ......GFAFAA.... + .....KLA.LKA.... +} +# tile 763 (High-elf,female) +{ + .........G...... + .......GGF...... + ......GGGGA..... + ......LILIA..... + ......LLLLA..... + ......ALLA...... + ......GAAG..AA.. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LA.GFAALAA.. + ....LA.GFAALAA.. + ....LAGGGFAL.A.. + ......GFAFAA.A.. + ......GFAFAA.... + ......GFAFAA.... + .....KLA.LKA.... +} +# tile 764 (attendant,male) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......BLB....... + .....CLLLD...... + .....CCKKDA.AAA. + .....LLCLDDAAAA. + ....CCCLDDDDAA.. + ....LALCCDALAA.. + ......LCCDAAAA.. + .....LCCCDAA.A.. + ....LCCCCCDA.... + ................ + ................ +} +# tile 765 (attendant,female) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......BLB....... + .....CLLLD...... + .....CCKKDA.AAA. + .....LLCLDDAAAA. + ....CCCLDDDDAA.. + ....LALCCDALAA.. + ......LCCDAAAA.. + .....LCCCDAA.A.. + ....LCCCCCDA.... + ................ + ................ +} +# tile 766 (page,male) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + .......LLAA..... + ......BAABA.AAA. + .....BPPPPPAAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 767 (page,female) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + .......LLAA..... + ......BAABA.AAA. + .....BPPPPPAAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 768 (abbot,male) +{ + ................ + ................ + ................ + ................ + ................ + ......KLK....... + ......LLL....... + ....CCLLLJJ..... + ....KCKLKKJAAA.. + ....CDDDDDDAAAA. + ...CDDLALDDDAAA. + ...DALLALLADAA.. + ...DDDDCDDDDAA.. + ....AACCCDAAAA.. + ....CDCCCDDA.A.. + ...CCCCCCCDD.... +} +# tile 769 (abbot,female) +{ + ................ + ................ + ................ + ................ + ................ + ......KLK....... + ......LLL....... + ....CCLLLJJ..... + ....KCKLKKJAAA.. + ....CDDDDDDAAAA. + ...CDDLALDDDAAA. + ...DALLALLADAA.. + ...DDDDCDDDDAA.. + ....AACCCDAAAA.. + ....CDCCCDDA.A.. + ...CCCCCCCDD.... +} +# tile 770 (acolyte,male) +{ + ................ + ................ + ................ + ......JJJJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......CJJCAAAA.. + .....LDDDDDAAAA. + ....CDCCDDDDAAA. + ....L.LCCDALAA.. + ......LCCDAAAA.. + ......LCCDAAAA.. + .....LDCCDDA.A.. + ....LCCCCCDD.... + ................ +} +# tile 771 (acolyte,female) +{ + ................ + ................ + ................ + ......JJJJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......CJJCAAAA.. + .....LDDDDDAAAA. + ....CDCCDDDDAAA. + ....L.LCCDALAA.. + ......LCCDAAAA.. + ......LCCDAAAA.. + .....LDCCDDA.A.. + ....LCCCCCDD.... + ................ +} +# tile 772 (hunter,male) +{ + ................ + ................ + ................ + ....J..CJA...... + ...J..CJJJA..... + ...J..JEEJA..... + ..J...JLLJA..... + ..J...ALLAA..... + ..J..GGAAGG.AAA. + ..LPBPFFFFPPAAA. + ..J..AGFFFAPAAA. + ..J....FF.ALAAA. + ...J..BP.PAAAA.. + ...J..BPAPAA.A.. + ....JPPA.PPA.... + ................ +} +# tile 773 (hunter,female) +{ + ................ + ................ + ................ + ....J..CJA...... + ...J..CJJJA..... + ...J..JEEJA..... + ..J...JLLJA..... + ..J...ALLAA..... + ..J..GGAAGG.AAA. + ..LPBPFFFFPPAAA. + ..J..AGFFFAPAAA. + ..J....FF.ALAAA. + ...J..BP.PAAAA.. + ...J..BPAPAA.A.. + ....JPPA.PPA.... + ................ +} +# tile 774 (thug,male) +{ + ................ + ................ + ................ + .......ID....... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + .....KKAAKKA..A. + ....KKJKKJJKAAA. + ....KAAJJAAKAA.. + ....LAJJJJALAA.. + ......KKJKAAAA.. + ......KAAKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 775 (thug,female) +{ + ................ + ................ + ................ + .......ID....... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + .....KKAAKKA..A. + ....KKJKKJJKAAA. + ....KAAJJAAKAA.. + ....LAJJJJALAA.. + ......KKJKAAAA.. + ......KAAKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 776 (ninja,male) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....AFLFLA..... + .....AAAAAA..... + ......AAAA...... + ....AAAAAAAA.PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 777 (ninja,female) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....AFLFLA..... + .....AAAAAA..... + ......AAAA...... + ....AAAAAAAA.PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 778 (roshi,male) +{ + ................ + ................ + ................ + .......AAAAA.... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....PPPAAPPPAAA. + ....L.PPPP.LAAA. + ....LAOOOOALAAA. + ....LAOOOOALAAA. + ......P...AAAA.. + ......P.A.AA.A.. + .....PPA.PPA.... + ................ +} +# tile 779 (roshi,female) +{ + ................ + ................ + ................ + .......AAAAA.... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....PPPAAPPPAAA. + ....L.PPPP.LAAA. + ....LAOOOOALAAA. + ....LAOOOOALAAA. + ......P...AAAA.. + ......P.A.AA.A.. + .....PPA.PPA.... + ................ +} +# tile 780 (guide,male) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HHAAHH.AAA. + ....LLHHHHLLAAA. + ....LAHHHHALAAA. + ....LAHHHHALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 781 (guide,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HHAAHH.AAA. + ....LLHHHHLLAAA. + ....LAHHHHALAAA. + ....LAHHHHALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 782 (warrior,male) +{ + .....O....O..... + .....NO..ON..... + ......NPPN...... + .....PPPPPP..... + .....PELELP..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ +} +# tile 783 (warrior,female) +{ + .....O....O..... + .....NO..ON..... + ......NPPN...... + .....PPPPPP..... + .....PELELP..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ +} +# tile 784 (apprentice,male) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......GLG....... + .....BLLLE...... + .....BBEEEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 785 (apprentice,female) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......GLG....... + .....BLLLE...... + .....BBEEEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 786 (invisible monster, nogender) +{ + ................ + ................ + .....NNNN....... + ....NNNNNN...... + ...NNAAAANN..... + ...NNA...NNA.... + ....AA...NNA.... + ........NNAA.... + .......NNAA..... + ......NNAA...... + ......NNA....... + .......AA....... + ......NN........ + ......NNA....... + .......AA....... + ................ +} diff --git a/win/share/monsters.txt b/win/share/monsters.txt index e80b56448..a7e97fa09 100644 --- a/win/share/monsters.txt +++ b/win/share/monsters.txt @@ -8903,7 +8903,7 @@ Z = (195, 195, 195) # tile 467 (barrow wight,female) { ................ - .......OOOOO..... + .......OOOOO.... ..OOOOOOO....... .ODLDLOO.OOO.... .OLLLLOOOOOOO... diff --git a/win/share/monsters.txt.keep b/win/share/monsters.txt.keep new file mode 100644 index 000000000..e80b56448 --- /dev/null +++ b/win/share/monsters.txt.keep @@ -0,0 +1,14944 @@ +. = (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) +# tile 0 (giant ant,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......JAJKKA... + .....JAAAKJJJA.. + .....AKJJAJJAA.. + ...KKAJJJAAA.... + ..BJJAAAAAJJA... + ..JBJAJAJAA..... + .....AJA.JA..... + ......JA.JA..... + ................ +} +# tile 1 (giant ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......J......... + ......AJAJKKA... + ....JJAAAKJJJA.. + ....AAKJJAJJAA.. + ...KKAJJJAAA.... + ..BJJAAAAAJJ.... + ..JBJAJAJAAAJ... + .....AJA.JA..... + ......JA.JA..... + ................ +} +# tile 2 (killer bee,male) +{ + ................ + ................ + .PPP.....PP..... + PPPPP...PBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAA.. + ABJBBJJJJAHAHH.. + .JJABJAJ.J.HH... + .......J.J...... + ................ + ...AAAAAAAAAAA.. + .....AAAAAA..... + ................ +} +# tile 3 (killer bee,female) +{ + ................ + ................ + .PPP.....PP..... + PPPPP...PBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAA.. + ABJBBJJJJAHAHH.. + .JJABJAJ.J.HH... + .......J.J...... + ................ + ...AAAAAAAAAAA.. + .....AAAAAA..... + ................ +} +# tile 4 (soldier ant,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......JAJKKA... + .....JAAAKJJJA.. + .....AKJJAJJAA.. + .JJKKAJJJAAA.... + JBJJJAAAAAJJA... + JJJBJAJAJAA..... + JAAJJAJA.JA..... + ..JJAAJA.JA..... + ................ +} +# tile 5 (soldier ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJAJKKA... + ....JJAAAKJJJA.. + ....AAKJJAJJAA.. + .JJKKAJJJAAA.... + JBJJJAAAAAJJ.... + JJJBJAJAJAAAJ... + JAAJJAJA.JA..... + ..JJAAJA.JA..... + ................ +} +# tile 6 (fire ant,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......DACCCA... + .....DAAACDDDA.. + .....ACDDADDAA.. + ...CCADDDAAA.... + ..GDDAAAAADDA... + ..DGDADADAA..... + .....ADA.DA..... + ......DA.DA..... + ................ +} +# tile 7 (fire ant,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......D......... + ......ADACCCA... + ....DDAAACDDDA.. + ....AACDDADDAA.. + ...CCADDDAAA.... + ..GDDAAAAADD.... + ..DGDADADAAAD... + .....ADA.DA..... + ......DA.DA..... + ................ +} +# tile 8 (giant beetle,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......KKDKK..... + ....KACLCJJD.... + ...KCLCJJDDDK... + ...DCCJDADDAD... + ...ADJDDDDDDD... + ...BAKDDAADKAA.. + ...ABAKDDK...... + ......AA.AA..... + ................ + ................ +} +# tile 9 (giant beetle,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ......KKDKK..... + ....KACLCJJD.... + ...KCLCJJDDDK... + ...DCCJDADDAD... + ...ADJDDDDDDD... + ...BAKDDAADKAA.. + ...ABAKDDK...... + ......AA.AA..... + ................ + ................ +} +# tile 10 (queen bee,male) +{ + ................ + .PPP.....PP..... + PPPPP...PPPP.... + PPPPP..PPBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAAH. + ABJBBJJJJAHAHHH. + .JJABJAJ.JHHHAA. + ...J...J.JAAAHH. + ..JJ..JJ.J.HHAH. + ..JAAAJAAJ..HH.. + .....AAAAAA..... + ................ +} +# tile 11 (queen bee,female) +{ + ................ + .PPP.....PP..... + PPPPP...PPPP.... + PPPPP..PPBPP.... + PBPPP..PBPPP.... + .PPBP.PPLPLL.... + ...PP.PLLALHAH.. + ...AKKKLAHAAHH.. + BBJJJJJJJAHHAAH. + ABJBBJJJJAHAHHH. + .JJABJAJ.JHHHAA. + ...J...J.JAAAHH. + ..JJ..JJ.J.HHAH. + ..JAAAJAAJ..HH.. + .....AAAAAA..... + ................ +} +# tile 12 (acid blob,male) +{ + ................ + ................ + ................ + .....KDDA....... + ...DDKDDKA...... + .DDDIIIDJDA..... + D.IIOOIIDAIA.... + .DKNNNODIDA..IA. + IDJNANOJDDJA.... + ADIDNOIDIDDDA... + ...JDIKIADKIA... + .IA.IDID.JDA.... + ...I.DDA....DA.. + .........IA..... + ..IA............ + ................ +} +# tile 13 (acid blob,female) +{ + ................ + ................ + ................ + .....KDDA....... + ...DDKDDKA...... + .DDDIIIDJDA..... + D.IIOOIIDAIA.... + .DKNNNODIDA..IA. + IDJNANOJDDJA.... + ADIDNOIDIDDDA... + ...JDIKIADKIA... + .IA.IDID.JDA.... + ...I.DDA....DA.. + .........IA..... + ..IA............ + ................ +} +# tile 14 (quivering blob,male) +{ + ................ + ................ + .....PPPP....... + .........P...... + .P.OOOPPE..AAA.. + P.OPBBBPOEAEAA.. + P.PBNNNP.OEAAEA. + P.PNNNNNPOEEAEA. + POPNAANNEO.OAEA. + .OPNAANNE..OAAA. + .OPBNNNEPP.OEAA. + BPOPEEEBBPO.EEA. + BBBPBBBBBBPPPPA. + ..BBBBBBBBBBPA.. + ................ + ................ +} +# tile 15 (quivering blob,female) +{ + ................ + ................ + .....PPPP....... + .........P...... + .P.OOOPPE..AAA.. + P.OPBBBPOEAEAA.. + P.PBNNNP.OEAAEA. + P.PNNNNNPOEEAEA. + POPNAANNEO.OAEA. + .OPNAANNE..OAAA. + .OPBNNNEPP.OEAA. + BPOPEEEBBPO.EEA. + BBBPBBBBBBPPPPA. + ..BBBBBBBBBBPA.. + ................ + ................ +} +# tile 16 (gelatinous cube,male) +{ + ................ + ................ + ................ + ................ + ................ + .......LLL...... + .....LLLLLLLL... + ...LLLLLLLLLD... + ...CLLLLLLLDDA.. + ...CGGCLLLDDDAA. + ...CAGCGGDDDDAAA + ...CCCCAGDDDAAAA + .....CCCCDDAAAA. + .......CCDAAA... + ................ + ................ +} +# tile 17 (gelatinous cube,female) +{ + ................ + ................ + ................ + ................ + ................ + .......LLL...... + .....LLLLLLLL... + ...LLLLLLLLLD... + ...CLLLLLLLDDA.. + ...CGGCLLLDDDAA. + ...CAGCGGDDDDAAA + ...CCCCAGDDDAAAA + .....CCCCDDAAAA. + .......CCDAAA... + ................ + ................ +} +# tile 18 (chickatrice,male) +{ + ................ + ................ + ................ + ................ + .......OO....... + ......HAOO...... + .....HHOOH.HHA.. + ........OOHOA... + ........OOFA.... + ........FGGFA... + ........AGFGAA.. + ...........GA... + .......F..FFA... + .......AFFAA.... + ........AA...... + ................ +} +# tile 19 (chickatrice,female) +{ + ................ + ................ + ................ + ................ + .......OO....... + ......HAOO...... + .....HHOOH.HHA.. + ........OOHOA... + ........OOFA.... + ........FGGFA... + ........AGFGAA.. + ...........GA... + .......F..FFA... + .......AFFAA.... + ........AA...... + ................ +} +# tile 20 (cockatrice,male) +{ + ................ + ...D.DD......... + ....DD.......... + ....NL..AA...... + ..HHAN.AAA...... + .HH.NO..AAAA.... + ...AOOLFFFAA.... + ...OOLKGGFFAA... + ...AOAGGFGFFAA.. + .......GFFGFAA.. + .........FGGAA.. + .....FA...FFA... + ....FA....FFA... + ....FA..FFFA.... + .....FFFFA...... + ................ +} +# tile 21 (cockatrice,female) +{ + ................ + ...D.DD......... + ....DD.......... + ....NL..AA...... + ..HHAN.AAA...... + .HH.NO..AAAA.... + ...AOOLFFFAA.... + ...OOLKGGFFAA... + ...AOAGGFGFFAA.. + .......GFFGFAA.. + .........FGGAA.. + .....FA...FFA... + ....FA....FFA... + ....FA..FFFA.... + .....FFFFA...... + ................ +} +# tile 22 (pyrolisk,male) +{ + ................ + ...D.DD......... + ....DD.......... + ....NB..AA...... + ..HHAN.AAA...... + .HH.NB..AAAA.... + ...APBBJJJAA.... + ...PPPKDDKJAA... + ...APADDKDKJAA.. + .......DJKDJAA.. + .........JDDAA.. + .....JA...JJA... + ....JA....JJA... + ....KA..KKKA.... + .....JKKKA...... + ................ +} +# tile 23 (pyrolisk,female) +{ + ................ + ...D.DD......... + ....DD.......... + ....NB..AA...... + ..HHAN.AAA...... + .HH.NB..AAAA.... + ...APBBJJJAA.... + ...PPPKDDKJAA... + ...APADDKDKJAA.. + .......DJKDJAA.. + .........JDDAA.. + .....JA...JJA... + ....JA....JJA... + ....KA..KKKA.... + .....JKKKA...... + ................ +} +# tile 24 (jackal,male) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOAOOOOOOOAA.. + ..AAOOOOOOOOAA.. + ....OJOOOOOLAA.. + ....OJOLKALKAA.. + ...OOAOAAAOAA... + .....OO..OOA.... + ................ +} +# tile 25 (jackal,female) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOAOOOOOOOAA.. + ..AAOOOOOOOOAA.. + ....OJOOOOOLAA.. + ....OJOLKALKAA.. + ...OOAOAAAOAA... + .....OO..OOA.... + ................ +} +# tile 26 (fox,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....C........... + ....C........... + ..CCAC...CCC.... + ..ACCCCCCACCC... + ...AACCCC.ACC... + ....ACAAC..AA... + ...AC.ACA....... + ................ +} +# tile 27 (fox,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....C........... + ....C........... + ..CCAC...CCC.... + ..ACCCCCCACCC... + ...AACCCC.ACC... + ....ACAAC..AA... + ...AC.ACA....... + ................ +} +# tile 28 (coyote,male) +{ + ................ + ................ + ................ + ...K..K......... + ...K.KK......KKK + ..KKKK......KKKA + ..NCNK.KKKKKAAA. + .KCCKKKKKKKKK... + KKCKAKKKKKKKK... + DKKKAKAKKKKAK... + ..AAKAAKAAAAK... + ....AKAKAAAAK... + ...AKKAKA.AKK... + .....AKK........ + ................ + ................ +} +# tile 29 (coyote,female) +{ + ................ + ................ + ................ + ...K..K......... + ...K.KK......KKK + ..KKKK......KKKA + ..NCNK.KKKKKAAA. + .KCCKKKKKKKKK... + KKCKAKKKKKKKK... + DKKKAKAKKKKAK... + ..AAKAAKAAAAK... + ....AKAKAAAAK... + ...AKKAKA.AKK... + .....AKK........ + ................ + ................ +} +# tile 30 (werejackal,male) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOALLOOOOOAA.. + ..AALLLLOOOOAA.. + ....LJLLLOOLAA.. + ....LJLLKALKAA.. + ..LLLALAAAOAA... + ...L.LL..OOA.... + ......L......... +} +# tile 31 (werejackal,female) +{ + ................ + ................ + ................ + ................ + ...O..O......... + ...O.OO...O..... + ..OOOO.....O.... + ..IOIOO....O.A.. + .OLLOOOL...O.A.. + DOOOALLOOOOOAA.. + ..AALLLLOOOOAA.. + ....LJLLLOOLAA.. + ....LJLLKALKAA.. + ..LLLALAAAOAA... + ...L.LL..OOA.... + ......L......... +} +# tile 32 (little dog,male) +{ + ................ + ................ + ................ + ................ + ...J..J......... + ...J.JJ...K..... + ..JJJJ.....K.... + ..NJNKK....K.A.. + .JJJCKK....K.A.. + .PJJAKCKKCKKAA.. + .DDAACKKCKKKAA.. + ....KJKJCJKJAA.. + ....KJKJJAJJAA.. + ...KKAKAAAKAA... + .....KK...KA.... + ................ +} +# tile 33 (little dog,female) +{ + ................ + ................ + ................ + ................ + ...J..J......... + ...J.JJ...K..... + ..JJJJ.....K.... + ..NJNKK....K.A.. + .JJJCKK....K.A.. + .PJJAKCKKCKKAA.. + .DDAACKKCKKKAA.. + ....KJKJCJKJAA.. + ....KJKJJAJJAA.. + ...KKAKAAAKAA... + .....KK...KA.... + ................ +} +# tile 34 (dingo,male) +{ + ................ + ................ + ................ + .............C.. + ...C..C.......C. + ...C.CC.......CA + ..CCCCK.......CA + ..ACACCKCCCCCCAA + ..LLCCCKCCCLCCCA + .KCCACKCLLLLACCA + ..AACAACLLAAACCA + ....ACACAAAAAACA + ....CCACAAA..CCA + .....ACCA....... + ................ + ................ +} +# tile 35 (dingo,female) +{ + ................ + ................ + ................ + .............C.. + ...C..C.......C. + ...C.CC.......CA + ..CCCCK.......CA + ..ACACCKCCCCCCAA + ..LLCCCKCCCLCCCA + .KCCACKCLLLLACCA + ..AACAACLLAAACCA + ....ACACAAAAAACA + ....CCACAAA..CCA + .....ACCA....... + ................ + ................ +} +# tile 36 (dog,male) +{ + ................ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKK......K.A + .JJJCKKKK....K.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ....KJKKJJJAJJAA + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 37 (dog,female) +{ + ................ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKK......K.A + .JJJCKKKK....K.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ....KJKKJJJAJJAA + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 38 (large dog,male) +{ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKKK.....K.A + .JJJCKKKKK..JK.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ...JKJKKJJJAJJAA + ....KAKJAAAAKJA. + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 39 (large dog,female) +{ + ................ + ................ + ...J..J.....K... + ...J.JJ......K.. + ..JJJJ.......K.. + ..NJNKKK.....K.A + .JJJCKKKKK..JK.A + .PJCAKCKKKKCKKAA + .DDAACKKKKCKKKAA + ..AAKJKKJJCJKJAA + ...JKJKKJJJAJJAA + ....KAKJAAAAKJA. + ....KAKJAAAAKJA. + ...KKAKAAAAAKAA. + .....KKAA...KA.. + ................ +} +# tile 40 (wolf,male) +{ + ................ + ................ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPAPPPPPPPPPAA + ..AAP.PP..P.P.AA + ....P.PP...A.PAA + ....PAP.AAAAP.A. + ...PPAPAAAAAPAA. + .....PPAA..PPA.. + ................ +} +# tile 41 (wolf,female) +{ + ................ + ................ + ................ + ...P..P......... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPAPPPPPPPPPAA + ..AAP.PP..P.P.AA + ....P.PP...A.PAA + ....PAP.AAAAP.A. + ...PPAPAAAAAPAA. + .....PPAA..PPA.. + ................ +} +# tile 42 (werewolf,male) +{ + ................ + ................ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPALPPPPPPPPAA + ..AALLPL..P.P.AA + ....L.LL...A.PAA + ....LAL.AAAAP.A. + ..LLLALAAAAAPPA. + ...L.LLAA..PP... + .....LL......... +} +# tile 43 (werewolf,female) +{ + ................ + ................ + ................ + ...P..P......... + ...P.PP......P.. + ..PPPP.......P.. + ..N.NPP......P.A + .P..PPPPP....P.A + PP.PAPPPPPPPPPAA + DPPPALPPPPPPPPAA + ..AALLPL..P.P.AA + ....L.LL...A.PAA + ....LAL.AAAAP.A. + ..LLLALAAAAAPPA. + ...L.LLAA..PP... + .....LL......... +} +# tile 44 (winter wolf cub,male) +{ + ................ + ................ + ................ + ................ + ...N..N......... + ...N.NB...N..... + ..NNNN.....N.... + ..DNDNB....N.A.. + ..NNNNB....N.A.. + .NNNNNNNNNNNAA.. + .DNBBNNNNNNBAA.. + ....NNNNNNNBAA.. + ....NNNBBANBAA.. + ...NBANAAANAA... + .....NB..NBA.... + ................ +} +# tile 45 (winter wolf cub,female) +{ + ................ + ................ + ................ + ................ + ...N..N......... + ...N.NB......... + ..NNNN.....N.... + ..DNDNB....N.A.. + ..NNNNB....N.A.. + .NNNNNNNNNNNAA.. + .DNBBNNNNNNBAA.. + ....NNNNNNNBAA.. + ....NNNBBANBAA.. + ...NBANAAANAA... + .....NB..NBA.... + ................ +} +# tile 46 (warg,male) +{ + ................ + ...P..P....PP... + ...P.PP......P.. + ..PPPP.......P.A + ..N.NPP......P.A + .P..PPPPP....P.A + PPPPDPPPPPPPPPAA + DPPNDPPPPPPPPPAA + ..DDDPPPPPPPPPAA + PNDNP.PPPPPPPPAA + .PPPPAPPPPAPP.A. + ...PAAPPAAAAPPAA + ...PAAP.AAAAP.A. + .PPPAAPAAAAAPAA. + ....PPPAA.PPPA.. + ................ +} +# tile 47 (warg,female) +{ + ................ + ...P..P.....P... + ...P.PP......P.. + ..PPPP.......P.A + ..N.NPP......P.A + .P..PPPPP....P.A + PPPPDPPPPPPPPPAA + DPPNDPPPPPPPPPAA + ..DDDPPPPPPPPPAA + PNDNP.PPPPPPPPAA + .PPPPAPPPPAPP.A. + ...PAAPPAAAAPPAA + ...PAAP.AAAAP.A. + .PPPAAPAAAAAPAA. + ....PPPAA.PPPA.. + ................ +} +# tile 48 (winter wolf,male) +{ + ................ + ................ + ................ + ...N..N.....N... + ...N.NN......N.. + ..NNNN.......N.. + ..DODNN......N.A + .NOONNNNN....N.A + NNONANNNNNNNNNAA + DNNBANNNNNNNNNAA + ..AANNNNNNNBNNAA + ....NBNNNBBANNAA + ....NANBAAAANBA. + ...NNANAAAAANAA. + .....NNAA..NNA.. + ................ +} +# tile 49 (winter wolf,female) +{ + ................ + ................ + ................ + ...N..N......... + ...N.NN......N.. + ..NNNN.......N.. + ..DODNN......N.A + .NOONNNNN....N.A + NNONANNNNNNNNNAA + DNNBANNNNNNNNNAA + ..AANNNNNNNBNNAA + ....NBNNNBBANNAA + ....NANBAAAANBA. + ...NNANAAAAANAA. + .....NNAA..NNA.. + ................ +} +# tile 50 (hell hound pup,male) +{ + ................ + ................ + ................ + ................ + ...C..C......... + ...C.CC...C..... + ..CCCC.....C.... + ..DCDCC....C.A.. + .CCCCCC....C.A.. + .PCCACCCCCCCAA.. + .CHAACCCCCCCAA.. + CHC.CCCCCCCCAA.. + .D..CCCCCACCAA.. + ...CCACAAACAA... + .....CC...CA.... + ................ +} +# tile 51 (hell hound pup,female) +{ + ................ + ................ + ................ + ................ + ...C..C......... + ...C.CC...C..... + ..CCCC.....C.... + ..DCDCC....C.A.. + .CCCCCC....C.A.. + .PCCACCCCCCCAA.. + .CHAACCCCCCCAA.. + CHC.CCCCCCCCAA.. + .D..CCCCCACCAA.. + ...CCACAAACAA... + .....CC...CA.... + ................ +} +# tile 52 (hell hound,male) +{ + ................ + ...C..C....CC... + ...C.CC......C.. + ..CCCC.......C.A + ..DJDCC......C.A + .CCCCCCCC....C.A + CCCCDCCCCCCCCCAA + .CHC.CCCCCCCCCAA + CHC..CCCCCCCCCAA + .D..CCCCCCCCCCAA + ...CCACCCCACC.A. + ...CAACCAAAACCAA + ...CAAC.AAAAC.A. + .CCCAACAAAAACAA. + ....CCCAA.CCCA.. + ................ +} +# tile 53 (hell hound,female) +{ + ................ + ...C..C....CC... + ...C.CC......C.. + ..CCCC.......C.A + ..DJDCC......C.A + .CCCCCCCC....C.A + CCCCDCCCCCCCCCAA + .CHC.CCCCCCCCCAA + CHC..CCCCCCCCCAA + .D..CCCCCCCCCCAA + ...CCACCCCACC.A. + ...CAACCAAAACCAA + ...CAAC.AAAAC.A. + .CCCAACAAAAACAA. + ....CCCAA.CCCA.. + ................ +} +# tile 54 (Cerberus,male) +{ + ................ + ..J..J.......... + ..JJJJ.J..J..... + .NJNJ..J.JJ..... + JJJJKAJJJJ....J. + PJJJJANJNKK...J. + DJKJAJJJKJJK..J. + ..AAJPJKAJKJKJJ. + ..JJJDDAJKJJJJJA + ..JJJAAJJJJJJJJA + .JKKKJJJKJJKJJAA + .JJAAKJJKJJJKJAA + JJAAAAJJAAAAJJA. + JAAAAAJAAAAAJAA. + .....JJAA...JA.. + ................ +} +# tile 55 (Cerberus,female) +{ + ................ + ..J..J.......... + ..JJJJ.J..J..... + .NJNJ..J.JJ..... + JJJJKAJJJJ....J. + PJJJJANJNKK...J. + DJKJAJJJKJJK..J. + ..AAJPJKAJKJKJJ. + ..JJJDDAJKJJJJJA + ..JJJAAJJJJJJJJA + .JKKKJJJKJJKJJAA + .JJAAKJJKJJJKJAA + JJAAAAJJAAAAJJA. + JAAAAAJAAAAAJAA. + .....JJAA...JA.. + ................ +} +# tile 56 (gas spore,male) +{ + ................ + ................ + ................ + .....PFGGFP..... + ....PGFFFFFP.... + ...PFFFFFGGFP... + ...FFGGFFGGFF... + ...GFGGFFFFFG... + ...GFFFFFFFFG... + ...FFFFGGFFFF... + ...PGGFGGFGGP... + ....PGFFFFGP.... + .....PFGGFP..... + ................ + ................ + ................ +} +# tile 57 (gas spore,female) +{ + ................ + ................ + ................ + .....PFGGFP..... + ....PGFFFFFP.... + ...PFFFFFGGFP... + ...FFGGFFGGFF... + ...GFGGFFFFFG... + ...GFFFFFFFFG... + ...FFFFGGFFFF... + ...PGGFGGFGGP... + ....PGFFFFGP.... + .....PFGGFP..... + ................ + ................ + ................ +} +# tile 58 (floating eye,male) +{ + ................ + ................ + ......ONNNO..... + ....PNNNNNNNP... + ....NNNNNNNNN... + ...ONNBBBBNNNO.. + ...NNBBEEBBNNN.. + ...NNBEAAEBNNN.. + ...ONBEAAEBNNO.. + ....NBBEEBBNN... + ....PNBBBBNNPAA. + ......ONNNOAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 59 (floating eye,female) +{ + ................ + ................ + ......ONNNO..... + ....PNNNNNNNP... + ....NNNNNNNNN... + ...ONNBBBBNNNO.. + ...NNBBEEBBNNN.. + ...NNBEAAEBNNN.. + ...ONBEAAEBNNO.. + ....NBBEEBBNN... + ....PNBBBBNNPAA. + ......ONNNOAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 60 (freezing sphere,male) +{ + ................ + ................ + ......PBBBP..... + ....PBBBBBBBP... + ....BBBBBBBBB... + ...PBPPPBBBBBP.. + ...BBNNBBPPPBB.. + ...BBANPBNNBBB.. + ...PBBPPBANPBP.. + ....BBBBBBPPB... + ....PBBBBBBBPAA. + ......PBBBPAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 61 (freezing sphere,female) +{ + ................ + ................ + ......PBBBP..... + ....PBBBBBBBP... + ....BBBBBBBBB... + ...PBPPPBBBBBP.. + ...BBNNBBPPPBB.. + ...BBANPBNNBBB.. + ...PBBPPBANPBP.. + ....BBBBBBPPB... + ....PBBBBBBBPAA. + ......PBBBPAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 62 (flaming sphere,male) +{ + ................ + ....C...H....... + ....C....O...C.. + ...C..H.CC...C.. + ...C..C.CC..CC.. + ...DCA.DDC.ACC.. + .AHCDCADDCAADC.. + .AACDCDDDDDADD.. + ..ACDDDJJJDDDD.. + ..ADDCAKDDACDD.. + ...ADAKDDCDAD... + ...ADADHCHCAD... + ....DADDDCDAD... + .....DADDDAD.... + ......JJJJJ..... + ................ +} +# tile 63 (flaming sphere,female) +{ + ................ + ....C...H....... + ....C....O...C.. + ...C..H.CC...C.. + ...C..C.CC..CC.. + ...DCA.DDC.ACC.. + .AHCDCADDCAADC.. + .AACDCDDDDDADD.. + ..ACDDDJJJDDDD.. + ..ADDCAKDDACDD.. + ...ADAKDDCDAD... + ...ADADHCHCAD... + ....DADDDCDAD... + .....DADDDAD.... + ......JJJJJ..... + ................ +} +# tile 64 (shocking sphere,male) +{ + ................ + .....PPPPPP..... + ...PPIAAADAPP... + ..PAAAIAAADDAP.. + ..PHAAAPBOAAAP.. + .PAHHAPBBBOAAAP. + .PHAAAPBBBBAHHP. + .PAAAAPPBBBAAAP. + .PAAAIAPPPAAAIP. + .PIIIAAAAAAIIAP. + ..PIAANAAPAAAIP. + ..PIAANAAAPAAP.. + ...PANANAPAPAP.. + ....PPAIAPAPP... + ......PPPPP..... + ................ +} +# tile 65 (shocking sphere,female) +{ + ................ + .....PPPPPP..... + ...PPIAAADAPP... + ..PAAAIAAADDAP.. + ..PHAAAPBOAAAP.. + .PAHHAPBBBOAAAP. + .PHAAAPBBBBAHHP. + .PAAAAPPBBBAAAP. + .PAAAIAPPPAAAIP. + .PIIIAAAAAAIIAP. + ..PIAANAAPAAAIP. + ..PIAANAAAPAAP.. + ...PANANAPAPAP.. + ....PPAIAPAPP... + ......PPPPP..... + ................ +} +# tile 66 (beholder,male) +{ + ....OA..OA...... + ..OA.DADA.OA.OA. + ...DA.DADADADD.. + ..OADDOOOODDADO. + ...DDHOAAOHDDA.. + ...JDHOAAOHDDJ.. + ...DDDOOOODDDD.. + ...DDDDDDDDDDD.. + ...JDAOAAAOADJ.. + ....DDAAOAADD... + ....PDDDDDDDPAA. + ......JDDDJAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 67 (beholder,female) +{ + ....OA..OA...... + ..OA.DADA.OA.OA. + ...DA.DADADADD.. + ..OADDOOOODDADO. + ...DDHOAAOHDDA.. + ...JDHOAAOHDDJ.. + ...DDDOOOODDDD.. + ...DDDDDDDDDDD.. + ...JDAOAAAOADJ.. + ....DDAAOAADD... + ....PDDDDDDDPAA. + ......JDDDJAAAA. + ......AAAAAAAAA. + .......AAAAAAA.. + ................ + ................ +} +# tile 68 (kitten,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ...........K.... + ............C... + ....C.C.....L.A. + ...CCCCJ....C.A. + ...NCNCJCCLCL.A. + ...CCCCJCCLCCAA. + ....IACCLLCCCAA. + .....CACCJCCJA.. + ......CCA..CA... + ................ +} +# tile 69 (kitten,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ...........N.... + ............N... + ....N.N.....C.A. + ...NNNNC....C.A. + ...ENENNNJJNC.A. + ...NNNNNJJJNNAA. + ....IANNJJNNNAA. + .....NANNWNNWA.. + ......NNA..NA... + ................ +} +# tile 70 (housecat,male) +{ + ................ + ................ + ................ + ................ + ................ + ...........K.... + ............C... + ...C.C......L.A. + ..CCCCJ.....C.A. + .CNCNCJCLCLCL.A. + .CCCCCJCLCLCCAA. + ..CICJCCLCLCLAA. + ...AACCLCLCCCAA. + ...CCACCJJCCJA.. + .....CCA...CA... + ................ +} +# tile 71 (housecat,female) +{ + ................ + ................ + ................ + ................ + ................ + ...........N.... + ............N... + ...N.N......C.A. + ..NNNNC.....C.A. + .NANANCNJJJNN.A. + .NNNNNNNJJNNNAA. + ..NINWNJJJNNNAA. + ...AANNNNNNNNAA. + ...NNANNWWNNWA.. + .....NNA...NA... + ................ +} +# tile 72 (jaguar,male) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + ..CC.CJ......C.A + .CCCCCJ......C.A + .GCGCCJCAACCJC.A + .CCCCCJCCCCCCCAA + .CDDDJCAACCAJCAA + ..CCACCAJCCAACAA + ....CACCJJJCCJA. + ....CACAAAAACJA. + ...CKACAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 73 (jaguar,female) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + ..CC.CJ......C.A + .CCCCCJ......C.A + .GCGCCJCAACCJC.A + .CCCCCJCCCCCCCAA + .CDDDJCAACCAJCAA + ..CCACCAJCCAACAA + ....CACCJJJCCJA. + ....CACAAAAACJA. + ...CKACAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 74 (lynx,male) +{ + ................ + ................ + ................ + ................ + O....O.......... + AC.CCA.......... + .CCCA........CA. + .GCGCOAKKKKK.LA. + .CKCCAJCCCCCKA.. + LLDDLLACLLLCCAA. + ..CC.AACLLLCCAA. + .......CAAAACAA. + ....CACAAAACCA.. + ................ + ................ + ................ +} +# tile 75 (lynx,female) +{ + ................ + ................ + ................ + ................ + O....O.......... + AC.CCA.......... + .CCCA........CA. + .GCGCOAKKKKK.LA. + .CKCCAJCCCCCKA.. + LLDDLLACLLLCCAA. + ..CC.AACLLLCCAA. + .......CAAAACAA. + ....CACAAAACCA.. + ................ + ................ + ................ +} +# tile 76 (panther,male) +{ + ................ + ................ + ............AA.. + ..............A. + ..............A. + .A...A........A. + .EA.AE........A. + .AAAAAEAAAAAAA.. + .AAAAAEAAAAAAA.. + .HAHAA.AAAAAAAA. + .AAAA.AAAAAEAAA. + .AAA..AAAAAEAAA. + .....AA....AAA.. + ..AAAA..AAAA.... + ................ + ................ +} +# tile 77 (panther,female) +{ + ................ + ................ + ............AA.. + ..............A. + ..............A. + .A...A........A. + .EA.AE........A. + .AAAAAEAAAAAAA.. + .AAAAAEAAAAAAA.. + .HAHAA.AAAAAAAA. + .AAAA.AAAAAEAAA. + .AAA..AAAAAEAAA. + .....AA....AAA.. + ..AAAA..AAAA.... + ................ + ................ +} +# tile 78 (large cat,male) +{ + ................ + ................ + ................ + ................ + ............K... + .............C.. + ...C.C.......L.A + ..CCCCJ......C.A + .CNCNCJCLCCLCL.A + .CCCCCJCLCCLCCAA + ..CDCJCCLCCLCLAA + ...AACCLCCLCCCAA + ....CACCJJJCCJA. + ...CKALAAAAACAA. + .....CCAA...CA.. + ................ +} +# tile 79 (large cat,female) +{ + ................ + ................ + ................ + ................ + ............N... + .............N.. + ...N.N.......C.A + ..NNNNC......C.A + .NANANCNJJJJNN.A + .NNNNNNNJJJNNNAA + ..NDNWNJJJNNNNAA + ...AANNNNNNNNNAA + ....NANNWWWNNWA. + ...NJANAAAAANAA. + .....NNAA...NA.. + ................ +} +# tile 80 (tiger,male) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + .CCJCC.......C.A + .CAACCJ......A.A + .GAGCCJACACAJC.A + .CCCCCACACACACAA + .ODOCACCACACACAA + .OCOACCJACACACAA + ....CACJAJAJCAA. + ....AACAAAAAAJA. + ...CKACAAAAACAA. + .....CCAA..CCA.. + ................ +} +# tile 81 (tiger,female) +{ + ................ + ................ + ................ + ................ + ..C..C......C... + .CCJCC.......C.A + .CAACCJ......A.A + .GAGCCJACACAJC.A + .CCCCCACACACACAA + .ODOCACCACACACAA + .OCOACCJACACACAA + ....CACJAJAJCAA. + ....AACAAAAAAJA. + ...CKACAAAAACAA. + .....CCAA..CCA.. + ................ +} +# tile 82 (displacer beast,male) +{ + ................ + ........E....... + .......E.E..AA.. + DEEEA..A.E....A. + ....EA.E.D....A. + .A...A.E......A. + .EA.AEAAA.....A. + .AAAAAAAAAA..A.. + .AAAAEAAAAAAAA.. + .HAHAEAAAAAAAAA. + .AAAAEAAAAAAAAA. + .AAA.AAAAAAAAAA. + .....AE.AEEA.EA. + ....AE.AE.EA.EA. + ...AE.AE.EA.EA.. + ................ +} +# tile 83 (displacer beast,female) +{ + ................ + ........E....... + .......E.E..AA.. + DEEEA..A.E....A. + ....EA.E.D....A. + .A...A.E......A. + .EA.AEAAA.....A. + .AAAAAAAAAA..A.. + .AAAAEAAAAAAAA.. + .HAHAEAAAAAAAAA. + .AAAAEAAAAAAAAA. + .AAA.AAAAAAAAAA. + .....AE.AEEA.EA. + ....AE.AE.EA.EA. + ...AE.AE.EA.EA.. + ................ +} +# tile 84 (gremlin,male) +{ + ................ + ................ + ................ + GGGA....AGGG.... + .GGGFAAAGGG..... + ..FFFFFFFF...... + ...NDFFDNA...... + ...GNFFNGA...... + ...GFFFFGA..AA.. + ...AGFFFAFAAAAA. + ..GFAGFAFFFAAAA. + .GFGFAAFFAFAAAA. + .GF.GFAGAAFAAAA. + ....FFAGFAA.AA.. + ...GFA.FGA...... + ................ +} +# tile 85 (gremlin,female) +{ + ................ + ................ + ................ + GGGA....AGGG.... + .GGGFAAAGGG..... + ..FFFFFFFF...... + ...NDFFDNA...... + ...GNFFNGA...... + ...GFFFFGA..AA.. + ...AGFFFAFAAAAA. + ..GFAGFAFFFAAAA. + .GFGFAAFFAFAAAA. + .GF.GFAGAAFAAAA. + ....FFAGFAA.AA.. + ...GFA.FGA...... + ................ +} +# tile 86 (gargoyle,male) +{ + ................ + ................ + ...PAPPPPAP..... + ..PA......AP.... + ..P.DD..DDAP.... + ....PD..DPA..... + ....P....PA..AA. + ....AP...A.AAAAA + ...P.AP.A...AAAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 87 (gargoyle,female) +{ + ................ + ................ + ...PAPPPPAP..... + ..PA......AP.... + ..P.DD..DDAP.... + ....PD..DPA..... + ....P....PA..AA. + ....AP...A.AAAAA + ...P.AP.A...AAAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 88 (winged gargoyle,male) +{ + ...K......K..... + ...KJ....KJ..... + ..KJAPPPPAJJ.... + ..KJ......AJ.... + ..KJDD..DDAJ.... + .KJAPD..DPAJJ... + .KJAP....PAAJAA. + KJA.AP...A.AJJAA + J..P.AP.A...AJAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 89 (winged gargoyle,female) +{ + ...K......K..... + ...KJ....KJ..... + ..KJAPPPPAJJ.... + ..KJ......AJ.... + ..KJDD..DDAJ.... + .KJAPD..DPAJJ... + .KJAP....PAAJAA. + KJA.AP...A.AJJAA + J..P.AP.A...AJAA + ..P.P.AA..A.AAAA + ..PA.P.APAA.AAAA + ..PA.P....A.AA.. + .....P....AAAA.. + .....P.AP.AA.... + ....PFA.FPA..... + ................ +} +# tile 90 (hobbit,male) +{ + ................ + ................ + ................ + ................ + ......JJA....... + .....JJJJA...... + ....JLFLFJ...... + ....JLLLLJ...... + ....JKLLKJJ.AA.. + ...CLLLLLLCAAA.. + ..CLALLLLALCA... + ..LLAJJKJALLA... + ...L.LKJLALAA... + .....LLALLA.A... + ....LLL.LLL..... + ................ +} +# tile 91 (hobbit,female) +{ + ................ + ................ + ................ + ................ + ......JJA....... + .....JJJJA...... + ....JLFLFJ...... + ....JLLLLJ...... + ....JKLLKJJ.AA.. + ...CLLLLLLCAAA.. + ..CLALJKJALCA... + ..LLAJJKJALLA... + ...L.LKJLALAA... + .....LLALLA.A... + ....LLL.LLL..... + ................ +} +# tile 92 (dwarf,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BLLLE....... + .....OLO...AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 93 (dwarf,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BLLLE....... + .....OLO...AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 94 (bugbear,male) +{ + ................ + ................ + ......K......... + .K..KKK......... + .KKKKKK......... + KADKADKKK....... + KKKKKKKJKK...... + KAPAPAKJJKJ..... + KAAAAAKKJKJJ.... + .KKKKKJKAKKJ.... + ..KAJJCAKKKJ.AA. + ..KK.KKKKKJJAA.. + ...C..KJAKJAA... + .....CCAAKJA.... + ........CCA..... + ................ +} +# tile 95 (bugbear,female) +{ + ................ + ................ + ......K......... + .K..KKK......... + .KKKKKK......... + KADKADKKK....... + KKKKKKKJKK...... + KAPAPAKJJKJ..... + KAAAAAKKJKJJ.... + .KKKKKJKAKKJ.... + ..KAJJCAKKKJ.AA. + ..KK.KKKKKJJAA.. + ...C..KJAKJAA... + .....CCAAKJA.... + ........CCA..... + ................ +} +# tile 96 (dwarf leader,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....HHHHH....... + ....BLLLE....... + ....BOLOE..AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 97 (dwarf leader,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....HHHHH....... + ....BLLLE....... + ....BOLOE..AAA.. + ...BBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 98 (dwarf ruler,male) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....BLLLE...A... + .....OLO...AAAA. + ...EBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 99 (dwarf ruler,female) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....BLLLE...A... + .....OLO...AAAA. + ...EBOOOEEAAAA.. + ...BABOEAEAAAA.. + ....LBBELAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 100 (mind flayer,male) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + ....IIIIIC...... + ....IAIAIF...... + ....IAIAIF...... + ....IAIAIFI..... + .....FIFIFIC.AA. + ....CBIBBF.CAAA. + ...IIIBBFFACAAA. + ......BBFCAAAA.. + ......CFFCAA.... + ....IIC.IIA..... +} +# tile 101 (mind flayer,female) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + ....IIIIIC...... + ....IAIAIF...... + ....IAIAIF...... + ....IAIAIFI..... + .....FIFIFIC.AA. + ....CBIBBF.CAAA. + ...IIIBBFFACAAA. + ......BBFCAAAA.. + ......CFFCAA.... + ....IIC.IIA..... +} +# tile 102 (master mind flayer,male) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + .EEEIIIIICEEEE.. + ..EEIAIAIEEEE... + ...EIAIAIEEE.... + ....IAIAIEEE.... + ....EFIFIEEE.AA. + ....CBIBBEEEAAA. + ...IIIBBEEEEAAA. + ....EEBEEEEAAA.. + ...EEECEEEAA.... + ....IIC.IIA..... +} +# tile 103 (master mind flayer,female) +{ + ................ + .......IIIIC.... + .....IIIIIIC.... + ....IIIIIIIC.... + ...IGIIIIGC..... + ...IIGINGIC..... + .EEEIIIIICEEEE.. + ..EEIAIAIEEEE... + ...EIAIAIEEE.... + ....IAIAIEEE.... + ....EFIFIEEE.AA. + ....CBIBBEEEAAA. + ...IIIBBEEEEAAA. + ....EEBEEEEAAA.. + ...EEECEEEAA.... + ....IIC.IIA..... +} +# tile 104 (manes,male) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP......... + ..PPPPP.PPP.P... + ..P..PPPP....... + ..P..PPPPP...P.. + ..PPPPP.PPP..... + ..P.P.P.PP.P.... + .P...P.PPPP..... + .P....PPP.PP.... + ..P....P.P.P.P.. + ........P....... + ................ + ................ +} +# tile 105 (manes,female) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP......... + ..PPPPP.PPP.P... + ..P..PPPP....... + ..P..PPPPP...P.. + ..PPPPP.PPP..... + ..P.P.P.PP.P.... + .P...P.PPPP..... + .P....PPP.PP.... + ..P....P.P.P.P.. + ........P....... + ................ + ................ +} +# tile 106 (homunculus,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJJ....... + ......LLC....... + ......LLC....... + .....BBPPPAA.... + ....L.BPPACAA... + ......BAPAAAA... + .....LLALCA..... + ................ + ................ +} +# tile 107 (homunculus,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ......JJJ....... + ......LLC....... + ......LLC....... + .....BBPPPAA.... + ....L.BPPACAA... + ......BAPAAAA... + .....LLALCA..... + ................ + ................ +} +# tile 108 (imp,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDO...... + ......CDD....... + .....GGFFFAA.... + ....C.GFFADAA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 109 (imp,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDO...... + ......CDD....... + .....GGFFFAA.... + ....C.GFFADAA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 110 (lemure,male) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP....P.... + ..PPPPP..PP.P... + ..P..PPPPPPPP... + ..P..PPPPPPP.... + ..PPPPPPPPP..... + ....PPPPPPPP.... + ..PPPPPPPPPP.... + ...PPPPPPPPPP... + ..P.P..PPPP.PP.. + ........P.PP.... + ................ + ................ +} +# tile 111 (lemure,female) +{ + ................ + ................ + ....PP.......... + ...PPPP......... + ..PAPAP....P.... + ..PPPPP..PP.P... + ..P..PPPPPPPP... + ..P..PPPPPPP.... + ..PPPPPPPPP..... + ....PPPPPPPP.... + ..PPPPPPPPPP.... + ...PPPPPPPPPP... + ..P.P..PPPP.PP.. + ........P.PP.... + ................ + ................ +} +# tile 112 (quasit,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDOD..... + ......CDD.D..... + .....GGFFFAA.... + ....C.GFFAAADA.. + ....C.GFFJJDA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 113 (quasit,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .....O.D.O...... + .....OCDDOD..... + ......CDD.D..... + .....GGFFFAA.... + ....C.GFFAAADA.. + ....C.GFFJJDA... + ......GAFAAAA... + .....CDADDA..... + ................ + ................ +} +# tile 114 (tengu,male) +{ + ................ + .......PP....... + ......PPPP...... + .....DPPNP...... + ....DDDPPP...... + ....DDPPPP...... + ....D..PPA...... + .....PIAAIP.AAA. + ....PPPIIPPPAAA. + ....PAPPPPAPAAA. + ....PAHHHHAPAAA. + ....LAPPPPALAAA. + ......PPPPAAAA.. + ......PPPPAA.A.. + .....LLA.LLA.... + ................ +} +# tile 115 (tengu,female) +{ + ................ + .......PP....... + ......PPPP...... + .....DPPNP...... + ....DDDPPP...... + ....DDPPPP...... + ....D..PPA...... + .....PIAAIP.AAA. + ....PPPIIPPPAAA. + ....PAPPPPAPAAA. + ....PAHHHHAPAAA. + ....LAPPPPALAAA. + ......PPPPAAAA.. + ......PPPPAA.A.. + .....LLA.LLA.... + ................ +} +# tile 116 (blue jelly,male) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OBEBOE.... + ..OBEOBBEOBBE... + ..OBEOBBEOBBE... + ..BBBGGBGGBEEE.. + ..BBBAGBAGEEEEA. + ..BBBBBBEBEEEEAA + ...BBBBBBBEEEAAA + ....BBBBBEEEAAA. + ......BBBEEAA... + ................ + ................ +} +# tile 117 (blue jelly,female) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OBEBOE.... + ..OBEOBBEOBBE... + ..OBEOBBEOBBE... + ..BBBGGBGGBEEE.. + ..BBBAGBAGEEEEA. + ..BBBBBBEBEEEEAA + ...BBBBBBBEEEAAA + ....BBBBBEEEAAA. + ......BBBEEAA... + ................ + ................ +} +# tile 118 (spotted jelly,male) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OCEBOE.... + ..OCEOCCEOBCE... + ..OCEOBCEOCBD... + ..BBBHHBHHBEDD.. + ..CCBAHBAHEEEEA. + ..BBCBBBEBEEDEAA + ...BBBCBBBEEDAAA + ....BCCCBEEDAAA. + ......CCBEEAA... + ................ + ................ +} +# tile 119 (spotted jelly,female) +{ + ................ + ................ + ................ + .......E........ + ......OBE....... + ...BE.OCEBOE.... + ..OCEOCCEOBCE... + ..OCEOBCEOCBD... + ..BBBHHBHHBEDD.. + ..CCBAHBAHEEEEA. + ..BBCBBBEBEEDEAA + ...BBBCBBBEEDAAA + ....BCCCBEEDAAA. + ......CCBEEAA... + ................ + ................ +} +# tile 120 (ochre jelly,male) +{ + ................ + ................ + ................ + .......D........ + ......LCD....... + ...CD.LCDCLD.... + ..LCDLCCDLCCD... + ..LCDLCCDLCCD... + ..CCCGGCGGCDDD.. + ..CCCAGCAGDDDDA. + ..CCCCCCDCDDDDAA + ...CCCCCCCDDDAAA + ....CCCCCDDDAAA. + ......CCCDDAA... + ................ + ................ +} +# tile 121 (ochre jelly,female) +{ + ................ + ................ + ................ + .......D........ + ......LCD....... + ...CD.LCDCLD.... + ..LCDLCCDLCCD... + ..LCDLCCDLCCD... + ..CCCGGCGGCDDD.. + ..CCCAGCAGDDDDA. + ..CCCCCCDCDDDDAA + ...CCCCCCCDDDAAA + ....CCCCCDDDAAA. + ......CCCDDAA... + ................ + ................ +} +# tile 122 (kobold,male) +{ + ................ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.A.. + ..BPBBBBPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 123 (kobold,female) +{ + ................ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.A.. + ..BPBBBBPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 124 (large kobold,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.... + ..BPBBBBPAAA.A.. + ..BAPBPAPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 125 (large kobold,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NBPBN........ + ...BABAB........ + ....BBPA..A..... + ...BBABPA.AA.... + ..BPBBBBPAAA.A.. + ..BAPBPAPAAAAA.. + ..BAPBPAPAAAAA.. + ....PBPAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 126 (kobold leader,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NCCCN........ + ...CABAC........ + ...CBBPC..A..... + ..CCBABCC.AA.... + ..CCBBBCCAAA.A.. + ..BCCBCCPAAAAA.. + ..BACBCAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 127 (kobold leader,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NCCCN........ + ...CABAC........ + ...CBBPC..A..... + ..CCBABCC.AA.... + ..CCBBBCCAAA.A.. + ..BCCBCCPAAAAA.. + ..BACBCAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 128 (kobold shaman,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NHHHN........ + ...HABAH........ + ...HBBPH..A..... + ..HHBABHH.AA.... + .HHHBBBHHHAA.A.. + .HBHHBHHPHAAAA.. + ..BAHBHAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 129 (kobold shaman,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NHHHN........ + ...HABAH........ + ...HBBPH..A..... + ..HHBABHH.AA.... + .HHHBBBHHHAA.A.. + .HBHHBHHPHAAAA.. + ..BAHBHAPAAAAA.. + ....BBBAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 130 (leprechaun,male) +{ + ................ + ................ + ................ + ................ + ......G......... + ......F....K.... + .....GFF..KLK... + ....GFFFF..K.... + .....KLKA.GLAA.. + ...FGFJFFFAKA.A. + ...GAGFFAAAK.AA. + ....LKHKKJAKAA.. + ....GFAGKJAKA... + ...GFAA.GFAK.... + ................ + ................ +} +# tile 131 (leprechaun,female) +{ + ................ + ................ + ................ + ................ + ......G......... + ......F....K.... + .....GFF..KLK... + ....GFFFF..K.... + .....KLKA.GLAA.. + ...FGFLFFFAKA.A. + ...GAGFFAAAK.AA. + ....LKHKKJAKAA.. + ....GFAGKJAKA... + ...GFAA.GFAK.... + ................ + ................ +} +# tile 132 (small mimic,male) +{ + ................ + ................ + ................ + ................ + ......POP....... + ......NNO....... + ......NNO....... + .......OA....... + .....NNNNN..AA.. + ....OONNNOO.AA.. + ....NANOOANAAA.. + ......NAOAAAA... + ......NAOAA.A... + .....NN.OOA..... + ................ + ................ +} +# tile 133 (small mimic,female) +{ + ................ + ................ + ................ + ................ + ......POP....... + ......NNO....... + ......NNO....... + .......OA....... + .....NNNNN..AA.. + ....OONNNOO.AA.. + ....NANOOANAAA.. + ......NAOAAAA... + ......NAOAA.A... + .....NN.OOA..... + ................ + ................ +} +# tile 134 (large mimic,male) +{ + ................ + ................ + ................ + ......LLOA...... + ......NNOA...... + ......NNOA...... + ......ONOA...... + .....NNNNO..AAA. + ....OONNNOO.AAA. + ...NOANNNAOOAAA. + ...NAONONOANAAA. + .....NO.NOAAAA.. + .....NO.NOAA.A.. + ....NNO.NOOA.... + ................ + ................ +} +# tile 135 (large mimic,female) +{ + ................ + ................ + ................ + ......LLOA...... + ......NNOA...... + ......NNOA...... + ......ONOA...... + .....NNNNO..AAA. + ....OONNNOO.AAA. + ...NOANNNAOOAAA. + ...NAONONOANAAA. + .....NO.NOAAAA.. + .....NO.NOAA.A.. + ....NNO.NOOA.... + ................ + ................ +} +# tile 136 (giant mimic,male) +{ + ................ + ......NNO....... + .....NNNNOA..... + .....NNNNOA..... + .....NNNNOA..... + .....ONNNOA..... + ..PONNOOONOOPAAA + .PONONNNNOONOPAA + .ONOANNNNOAONOAA + .NNOANNNNOAOOOAA + ...AANNONNAAAAAA + ....PNO.NNPAAAAA + ....ONO.NNOAA..A + ....NNO.NNOAA..A + ...NNNO.NNOOA... + ................ +} +# tile 137 (giant mimic,female) +{ + ................ + ......NNO....... + .....NNNNOA..... + .....NNNNOA..... + .....NNNNOA..... + .....ONNNOA..... + ..PONNOOONOOPAAA + .PONONNNNOONOPAA + .ONOANNNNOAONOAA + .NNOANNNNOAOOOAA + ...AANNONNAAAAAA + ....PNO.NNPAAAAA + ....ONO.NNOAA..A + ....NNO.NNOAA..A + ...NNNO.NNOOA... + ................ +} +# tile 138 (wood nymph,male) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLFKKKKLA.... + .HKFLFKKKKA..... + OHKJFKKJJK.A.... + HKKLJJGKAAAAAAA. + .JJAJGDKJAAAAA.. + ..JA.KKJJAAAA... + ...J.KKKKJAA.... + ....JKKKKKJA.... + ....KJKJKJKJ.... + ................ +} +# tile 139 (wood nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLFKKKKLA.... + .HKFLFKKKKA..... + OHKJFKKJJK.A.... + HKKLJJGKAAAAAAA. + .JJAJGDKJAAAAA.. + ..JA.KKJJAAAA... + ...J.KKKKJAA.... + ....JKKKKKJA.... + ....KJKJKJKJ.... + ................ +} +# tile 140 (water nymph,male) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLJBBBBLA.... + .HBJLJBBBBA..... + OHBPJBBPPB.A.... + HBBLPPNBAAAAAAA. + .PPAPNDB.AAAAA.. + ..PA.BBPPAAAA... + ...P.BBBBPAA.... + ....PBBBBBPA.... + ....BPBPBPBP.... + ................ +} +# tile 141 (water nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLJBBBBLA.... + .HBJLJBBBBA..... + OHBPJBBPPB.A.... + HBBLPPNBAAAAAAA. + .PPAPNDB.AAAAA.. + ..PA.BBPPAAAA... + ...P.BBBBPAA.... + ....PBBBBBPA.... + ....BPBPBPBP.... + ................ +} +# tile 142 (mountain nymph,male) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLCOOOOLA.... + .HOCLCOOOOA..... + OHOLCOOLLO.A.... + HOOKLLIOAAAAAAA. + .LLALIBOKAAAAA.. + ..LA.OOLLAAAA... + ...L.OOOOLAA.... + ....LOOOOOLA.... + ....OLOLOLOL.... + ................ +} +# tile 143 (mountain nymph,female) +{ + ................ + ................ + ...OH........... + ..OHHL.......... + ..OHLL.......... + ..HHLA.......... + .OHLLCOOOOLA.... + .HOCLCOOOOA..... + OHOLCOOLLO.A.... + HOOKLLIOAAAAAAA. + .LLALIBOKAAAAA.. + ..LA.OOLLAAAA... + ...L.OOOOLAA.... + ....LOOOOOLA.... + ....OLOLOLOL.... + ................ +} +# tile 144 (goblin,male) +{ + ................ + ................ + ................ + ....LK.......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IGIGIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICJAAAAA... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 145 (goblin,female) +{ + ................ + ................ + ................ + ....LK.......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IGIGIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICJAAAAA... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 146 (hobgoblin,male) +{ + ................ + .....LK......... + ....CKA......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IHIHIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICCAAAAA... + ....IIIIJA...... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 147 (hobgoblin,female) +{ + ................ + .....LK......... + ....CKA......... + ...CJA.......... + ..KJA........... + .JJA.IIK...AA... + .IK.IHIHIJAA.... + J.ICKIIIJK...... + ...IIJJJK.A..... + ....KICCAAAAA... + ....IIIIJA...... + ....ICKKJA...... + ....IKAIJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 148 (orc,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KCCAKKKA.AA... + ..BPCKJ.P.AAA... + ..BAGGFAAPNO.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BJACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 149 (orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KCCAKKKA.AA... + ..BPCKJ.P.AAA... + ..BAGGFAAPNO.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BJACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 150 (hill orc,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LKLA........ + .....K.A........ + ..KGGAFFKA.AA... + ..JKGFF.K.AAA... + ..JAHHFAAKNO.... + ..JAGFFNOAAA.... + ....GNNFAAAAAA.. + ...GGAGFAAAA.... + ..KJJAKJJA...... + ................ + ................ +} +# tile 151 (hill orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LKLA........ + .....K.A........ + ..KGGAFFKA.AA... + ..JKGFF.K.AAA... + ..JAHHFAAKNO.... + ..JAGFFNOAAA.... + ....GNNFAAAAAA.. + ...GGAGFAAAA.... + ..KJJAKJJA...... + ................ + ................ +} +# tile 152 (Mordor orc,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KIIAIIKA.AA... + ..BPIDD.P.AAA... + ..BAGGFAAP.O.... + ..BAIDDNOAAA.... + ....BNOJAAAAAA.. + ...BIAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 153 (Mordor orc,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..KIIAIIKA.AA... + ..BPIDD.P.AAA... + ..BAGGFAAP.O.... + ..BAIDDNOAAA.... + ....BNOJAAAAAA.. + ...BIAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 154 (Uruk-hai,male) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..IIIAIIIA...... + ..BPIKI.BAAAA... + ..BIG.PPPPAAA... + .NBAD.PDDPAA.... + ..BNNJPDDPAA.... + ....INPPPPAAAA.. + ...BIAK.AAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 155 (Uruk-hai,female) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..IIIAIIIA...... + ..BPIKI.BAAAA... + ..BIG.PPPPAAA... + .NBAD.PDDPAA.... + ..BNNJPDDPAA.... + ....INPPPPAAAA.. + ...BIAK.AAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 156 (orc shaman,male) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..CCCACCCA...... + ..BPCKC.BAAAA... + ..BCGGFJBAAAA... + ..BAJJCJBAAA.... + ..BAJJCJBAAA.... + ....CACJAAAAAA.. + ...BCACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 157 (orc shaman,female) +{ + ................ + ................ + .....OA......... + ....NOPA........ + ....LPLA........ + .....P.A........ + ..CCCACCCA...... + ..BPCKC.BAAAA... + ..BCGGFJBAAAA... + ..BAJJCJBAAA.... + ..BAJJCJBAAA.... + ....CACJAAAAAA.. + ...BCACPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 158 (orc-captain,male) +{ + ................ + ................ + .....OA......... + ...NNOOPA....... + ....LPLA........ + ...IPPPA........ + ..DIIPADDA.AA... + ..BPIAD.P.AAA... + ..BAGGFAAP.O.... + ..BAGGFAAP.O.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BDAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 159 (orc-captain,female) +{ + ................ + ................ + .....OA......... + ...NNOOPA....... + ....LPLA........ + ...IPPPA........ + ..DIIPADDA.AA... + ..BPIAD.P.AAA... + ..BAGGFAAP.O.... + ..BAGGFAAP.O.... + ..BAJJPNOAAA.... + ....BNOJAAAAAA.. + ...BDAIPAAAA.... + ..BPPABPPA...... + ................ + ................ +} +# tile 160 (rock piercer,male) +{ + .JKKKKKKKKJAAA.. + ..JJGKGKJJAAAA.. + ...JKKKJJAAAA... + ...JJKKJJAAAA... + ....JKKJAAAA.... + ....JJKJ.AAA.... + ....JJKJ.AAA.... + ....JJJJ..A..... + .....JJ...A..... + .....JJ...A..... + .....JJ......... + .....JJ......... + .....J.......... + .....J.......... + ................ + ................ +} +# tile 161 (rock piercer,female) +{ + .JKKKKKKKKJAAA.. + ..JJGKGKJJAAAA.. + ...JKKKJJAAAA... + ...JJKKJJAAAA... + ....JKKJAAAA.... + ....JJKJ.AAA.... + ....JJKJ.AAA.... + ....JJJJ..A..... + .....JJ...A..... + .....JJ...A..... + .....JJ......... + .....JJ......... + .....J.......... + .....J.......... + ................ + ................ +} +# tile 162 (iron piercer,male) +{ + .BPPPPPPPP.AAA.. + ..BBDPDP..AAAA.. + ...BPPP..AAAA... + ...PBPP..AAAA... + ....BPP.AAAA.... + ....BBP.AAAA.... + ....PBP.AAAA.... + ....PBP...A..... + .....BP...A..... + .....BP...A..... + .....BP......... + .....BP......... + .....B.......... + .....P.......... + ................ + ................ +} +# tile 163 (iron piercer,female) +{ + .BPPPPPPPP.AAA.. + ..BBDPDP..AAAA.. + ...BPPP..AAAA... + ...PBPP..AAAA... + ....BPP.AAAA.... + ....BBP.AAAA.... + ....PBP.AAAA.... + ....PBP...A..... + .....BP...A..... + .....BP...A..... + .....BP......... + .....BP......... + .....B.......... + .....P.......... + ................ + ................ +} +# tile 164 (glass piercer,male) +{ + .NBBBBBBBBPAAA.. + ..NNDBDBPPAAAA.. + ...NBBBPPAAAA... + ...PNBBPPAAAA... + ....NBBPAAAA.... + ....NNBPAAAA.... + ....PNBPAAAA.... + ....PNBP..A..... + .....NB...A..... + .....NB...A..... + .....NB......... + .....NB......... + .....N.......... + .....P.......... + ................ + ................ +} +# tile 165 (glass piercer,female) +{ + .NBBBBBBBBPAAA.. + ..NNDBDBPPAAAA.. + ...NBBBPPAAAA... + ...PNBBPPAAAA... + ....NBBPAAAA.... + ....NNBPAAAA.... + ....PNBPAAAA.... + ....PNBP..A..... + .....NB...A..... + .....NB...A..... + .....NB......... + .....NB......... + .....N.......... + .....P.......... + ................ + ................ +} +# tile 166 (rothe,male) +{ + ................ + ...........K.... + ............K... + ............K... + .......JJJKKJ... + .....JKKKKKKK... + ..AAAKKKKKKKK... + .AAAAAKKKKKKKA.. + AAKKAAKKKKKAKA.. + .KEKKAKKKJAAKA.. + .KKKJAKKAJAAK... + ..KJAAAKAAA..... + ..AAKA.KA....... + ..A..A.K........ + ................ + ................ +} +# tile 167 (rothe,female) +{ + ................ + ...........K.... + ............K... + ............K... + .......JJJKKJ... + .....JKKKKKKK... + ..AAAKKKKKKKK... + .AAAAAKKKKKKKA.. + AAKKAAKKKKKAKA.. + .KEKKAKKKJAAKA.. + .KKKJAKKAJAAK... + ..KJAAAKAAA..... + ..AAKA.KA....... + ..A..A.K........ + ................ + ................ +} +# tile 168 (mumak,male) +{ + ................ + ...........P.... + .PP.........P... + PPP...PPPPP.P... + PPPPPPPPP.PP.... + PPPPBPPBBP.PP... + PPPBPPPPPP.PP... + .PDPPDDPP.PPP... + ..BPPDDP.PPPPA.. + ..PPPPPPPPPPPA.. + ..PPPPO..PAPPA.. + .OOPPOOAPPAPPA.. + OOPPOOAAPPA..... + .PPPAPA.PP...... + PPPA............ + .AA............. +} +# tile 169 (mumak,female) +{ + ................ + ...........P.... + .PP.........P... + PPP...PPPPP.P... + PPPPPPPPP.PP.... + PPPPBPPBBP.PP... + PPPBPPPPPP.PP... + .PDPPDDPP.PPP... + ..BPPDDP.PPPPA.. + ..PPPPPPPPPPPA.. + ..PPPPO..PAPPA.. + .OOPPOOAPPAPPA.. + OOPPOOAAPPA..... + .PPPAPA.PP...... + PPPA............ + .AA............. +} +# tile 170 (leocrotta,male) +{ + ................ + ..A..A.......... + ..AOOA....J..... + ..AOOAA....J.... + .APOAFA....J.... + .APOAAA.JJJJ.... + .AOPAAJKKKKKJ... + .AOAAKJJKKJKJA.. + ...JKKKKKJAKKA.. + ...JKJKKJAAKKA.. + ..JKJAKKAAPAPA.. + ..KKAAKKAAPAPA.. + .PAPAAPAPA...... + .PAPA.PAPA...... + ................ + ................ +} +# tile 171 (leocrotta,female) +{ + ................ + ..A..A.......... + ..AOOA....J..... + ..AOOAA....J.... + .APOAFA....J.... + .APOAAA.JJJJ.... + .AOPAAJKKKKKJ... + .AOAAKJJKKJKJA.. + ...JKKKKKJAKKA.. + ...JKJKKJAAKKA.. + ..JKJAKKAAPAPA.. + ..KKAAKKAAPAPA.. + .PAPAAPAPA...... + .PAPA.PAPA...... + ................ + ................ +} +# tile 172 (wumpus,male) +{ + ................ + ............B... + .............B.. + .......BBBBB.B.. + ....BBBPPBBBB... + ...BOOBBBPBBBB.. + ...OOBBBBBPBBB.. + ..DABBAABBPBBBA. + .BOOBBDABEBBEBAA + .BOBBBBBBEBEBBAA + .BBBBBBBEBBABBAA + .EBBBBBEABBABBAA + ..EEEEEAABBA.... + .....BBA.BB..... + ................ + ................ +} +# tile 173 (wumpus,female) +{ + ................ + ............B... + .............B.. + .......BBBBB.B.. + ....BBBPPBBBB... + ...BOOBBBPBBBB.. + ...OOBBBBBPBBB.. + ..DABBAABBPBBBA. + .BOOBBDABEBBEBAA + .BOBBBBBBEBEBBAA + .BBBBBBBEBBABBAA + .EBBBBBEABBABBAA + ..EEEEEAABBA.... + .....BBA.BB..... + ................ + ................ +} +# tile 174 (titanothere,male) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + .PPPPP.PPPPPPP.. + .PPEPP.PPPP.PPA. + PBPPP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 175 (titanothere,female) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + .PPPPP.PPPPPPP.. + .PPEPP.PPPP.PPA. + PBPPP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 176 (baluchitherium,male) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + BPPPPP.PPPPPPP.. + B.PEPP.PPPP.PPA. + PB.PP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 177 (baluchitherium,female) +{ + ................ + ................ + ................ + ..........PPP.P. + .......PPPPPPPAP + .....PPPPPPPPP.A + ..P.P.PPPPPPPP.A + ..PPP.PPPPPPPPPA + ..PPPP.PPPPPPPPA + BPPPPP.PPPPPPP.. + B.PEPP.PPPP.PPA. + PB.PP.PPP.AAPPA. + PPPP.AAPPAA..... + .PP.PPAPPA...... + ................ + ................ +} +# tile 178 (mastodon,male) +{ + ................ + ................ + ................ + ................ + ................ + ..O...O......... + .N..POP.P....... + N..PNPPPPP...... + O.PNPPPPPP.PP... + O.POPEPPP.PPPPP. + .OPOPOP..PPPPPAP + ..PPOPP.PPPPPPAA + ..PPAAAPPPPAPPA. + ..P...APPAAAPPA. + .......PPA...... + ................ +} +# tile 179 (mastodon,female) +{ + ................ + ................ + ................ + ................ + ................ + ..O...O......... + .N..POP.P....... + N..PNPPPPP...... + O.PNPPPPPP.PP... + O.POPEPPP.PPPPP. + .OPOPOP..PPPPPAP + ..PPOPP.PPPPPPAA + ..PPAAAPPPPAPPA. + ..P...APPAAAPPA. + .......PPA...... + ................ +} +# tile 180 (sewer rat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKK.... + ..KKKKJKKJKKK... + ..JAKAKJJJKKKJ.. + ..GKGKJKAKKAKKA. + .KKJJJJKAKAAKKA. + .PJJAAKKAJAJKA.. + ..AA.KKA..JKA... + .........JJA.... + ................ +} +# tile 181 (sewer rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKK.... + ..KKKKJKKJKKK... + ..JAKAKJJJKKKJ.. + ..GKGKJKAKKAKKA. + .KKJJJJKAKAAKKA. + .PJJAAKKAJAJKA.. + ..AA.KKA..JKA... + .........JJA.... + ................ +} +# tile 182 (giant rat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 183 (giant rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 184 (rabid rat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJOOOKAJKAAKKA + .PJOOAKKAJJAJKA. + ..AOOOKAA..JKA.. + .OOOOOOOO.JJA... + ................ +} +# tile 185 (rabid rat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..JAKAKJKJJKKKJ. + ..GAGAKJKJJKKKK. + ..AKAKJKKAKKAKKA + .KKJOOOKAJKAAKKA + .PJOOAKKAJJAJKA. + ..AOOOKAA..JKA.. + .OOOOOOOO.JJA... + ................ +} +# tile 186 (wererat,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..LLLLKJKJJKKKJ. + ..FLFLLJKJJKKKK. + ..LLLLJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 187 (wererat,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ..K..K.JKKKKK... + ..KKKKJKKKJKKK.. + ..LLLLKJKJJKKKJ. + ..FLFLLJKJJKKKK. + ..LLLLJKKAKKAKKA + .KKJJJJKAJKAAKKA + .PJJAAKKAJJAJKA. + ..AA.KKAA..JKA.. + ..........JJA... + ................ +} +# tile 188 (rock mole,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......AAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + ..JAJAAAAAAAAAA. + .AAAAAAAAAAAAAA. + AN.NAAAAAAAAAAA. + A...AAAA...AAA.. + AN.NAA.AA...AA.. + .AAAA........... +} +# tile 189 (rock mole,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + .......AAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + ..JAJAAAAAAAAAA. + .AAAAAAAAAAAAAA. + AN.NAAAAAAAAAAA. + A...AAAA...AAA.. + AN.NAA.AA...AA.. + .AAAA........... +} +# tile 190 (woodchuck,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .......KJA...... + ......NKKNA..... + ......KNOJA..... + ......KNOJA..... + .....KKKKKJA.... + ....JJKLLJJJAA.. + ......KLLJAAAAA. + ......KJJJAAAA.. + .....JJAAJJAA... + ................ +} +# tile 191 (woodchuck,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + .......KJA...... + ......NKKNA..... + ......KNOJA..... + ......KNOJA..... + .....KKKKKJA.... + ....JJKLLJJJAA.. + ......KLLJAAAAA. + ......KJJJAAAA.. + .....JJAAJJAA... + ................ +} +# tile 192 (cave spider,male) +{ + ................ + ................ + ................ + ................ + ................ + ........PA...... + .......PA....... + ......PAPBBA.... + ...PA.APBPPPA... + ...ABBPPAPPAA.PA + ...GPPPPAAAPPPAA + ...PPGPAAPPAAAA. + ..D.PAPAPAAPPA.. + ....D.PAAPA.APA. + .....PAA.APA.... + ................ +} +# tile 193 (cave spider,female) +{ + ................ + ................ + ................ + ................ + ................ + ........PA...... + .......PA....... + ......PAPBBA.... + ...PA.APBPPPA... + ...ABBPPAPPAA.PA + ...GPPPPAAAPPPAA + ...PPGPAAPPAAAA. + ..D.PAPAPAAPPA.. + ....D.PAAPA.APA. + .....PAA.APA.... + ................ +} +# tile 194 (centipede,male) +{ + ................ + ................ + ......PBPP...... + ....BBPAAA...... + ..PPBAAA........ + .PAPBBBPPPP..... + ..PAAPPBBBA..... + ....PAAPAPBPP... + ......AABBPP.... + ......BB.PPAP... + ....PBBPPAP.A... + ...GPPPAP.AP.... + ...PPGPAAP...... + ..B.PAA......... + ...B............ + ................ +} +# tile 195 (centipede,female) +{ + ................ + ................ + ......PBPP...... + ....BBPAAA...... + ..PPBAAA........ + .PAPBBBPPPP..... + ..PAAPPBBBA..... + ....PAAPAPBPP... + ......AABBPP.... + ......BB.PPAP... + ....PBBPPAP.A... + ...GPPPAP.AP.... + ...PPGPAAP...... + ..B.PAA......... + ...B............ + ................ +} +# tile 196 (giant spider,male) +{ + ................ + ................ + ................ + ................ + ................ + ........JA...... + .......JA....... + ......JAJKKA.... + ...JA.AJKJJJA... + ...AKKJJAJJAA.JA + ...GJJJJAAAJJJAA + ...JJGJAAJJAAAA. + ..D.JAJAJAAJJA.. + ....D.JAAJA.AJA. + .....JAA.AJA.... + ................ +} +# tile 197 (giant spider,female) +{ + ................ + ................ + ................ + ................ + ................ + ........JA...... + .......JA....... + ......JAJKKA.... + ...JA.AJKJJJA... + ...AKKJJAJJAA.JA + ...GJJJJAAAJJJAA + ...JJGJAAJJAAAA. + ..D.JAJAJAAJJA.. + ....D.JAAJA.AJA. + .....JAA.AJA.... + ................ +} +# tile 198 (scorpion,male) +{ + ................ + ................ + .......JKJKJAA.. + ......JA.JKJKKA. + .......KA...JJJA + ......JA....KKJA + ...........JJJKA + .......AJKKAJJA. + .....AAJKJJJAA.. + ...AKKJJAJJAA... + ...GJJJJAAAJJJA. + ...JJGJAAJJAAAJ. + ..D.JAJAJAAJJA.. + ....D.JAAJA.JAA. + .......JAAJA.... + ................ +} +# tile 199 (scorpion,female) +{ + ................ + ................ + .......JKJKJAA.. + ......JA.JKJKKA. + .......KA...JJJA + ......JA....KKJA + ...........JJJKA + .......AJKKAJJA. + .....AAJKJJJAA.. + ...AKKJJAJJAA... + ...GJJJJAAAJJJA. + ...JJGJAAJJAAAJ. + ..D.JAJAJAAJJA.. + ....D.JAAJA.JAA. + .......JAAJA.... + ................ +} +# tile 200 (lurker above,male) +{ + .AAAAAAAAAAAAAAA + ...AAGFAAGFAAA.. + ...AAAAAAAAAAA.. + ....AODODODOA... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 201 (lurker above,female) +{ + .AAAAAAAAAAAAAAA + ...AAGFAAGFAAA.. + ...AAAAAAAAAAA.. + ....AODODODOA... + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ +} +# tile 202 (trapper,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....AODODODOA... + ...AAAAAAAAAAA.. + ...AAGFAAGFAAA.. + .AAAAAAAAAAAAAAA +} +# tile 203 (trapper,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ....AODODODOA... + ...AAAAAAAAAAA.. + ...AAGFAAGFAAA.. + .AAAAAAAAAAAAAAA +} +# tile 204 (pony,male) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ...KKEKJ........ + ..KKJKKJ........ + ..JJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKJ..... + ...KKKKKKKJJAAA. + ...KJKJJJJJAJA.. + ...JAJAAAAJAA... + ...JAJAAJAJA.... + ...L.JAALAJ..... + .....LA...L..... + ................ +} +# tile 205 (pony,female) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ...KKEKJ........ + ..KKJKKJ........ + ..JJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKJ..... + ...KKKKKKKJJAAA. + ...KJKJJJJJAJA.. + ...JAJAAAAJAA... + ...JAJAAJAJA.... + ...L.JAALAJ..... + .....LA...L..... + ................ +} +# tile 206 (white unicorn,male) +{ + ................ + ..HP............ + ..PHO.NN........ + ...PHNNB........ + ...ONENB........ + ..ONNNNB........ + ..NOANNBAA...... + ...AONNBA....... + ...ONNNONNN..... + ..NONNNNONNOAAA. + ..N.ONONNONAOA.. + ..OAANAAAAOAA... + ...LAOAAOAOA.... + .....OAALAO..... + .....LA...L..... + ................ +} +# tile 207 (white unicorn,female) +{ + ................ + ..HP............ + ..PHO.NN........ + ...PHNNB........ + ...ONENB........ + ..ONNNNB........ + ..NOANNBAA...... + ...AONNBA....... + ...ONNNONNN..... + ..NONNNNONNOAAA. + ..N.ONONNONAOA.. + ..OAANAAAAOAA... + ...LAOAAOAOA.... + .....OAALAO..... + .....LA...L..... + ................ +} +# tile 208 (gray unicorn,male) +{ + ................ + ..HP............ + ..PHO.PP........ + ...PHPPN........ + ....PGPN........ + ...PPPPN........ + ..PPAPPNAA...... + ...APPPNA....... + ....PPP.PPP..... + ..P.PPPP.PP.AAA. + ..P..P.PP.PA.A.. + ..PAAPAAAA.AA... + ...LA.AA.A.A.... + ......AALA...... + .....LA...L..... + ................ +} +# tile 209 (gray unicorn,female) +{ + ................ + ..HP............ + ..PHO.PP........ + ...PHPPN........ + ....PGPN........ + ...PPPPN........ + ..PPAPPNAA...... + ...APPPNA....... + ....PPP.PPP..... + ..P.PPPP.PP.AAA. + ..P..P.PP.PA.A.. + ..PAAPAAAA.AA... + ...LA.AA.A.A.... + ......AALA...... + .....LA...L..... + ................ +} +# tile 210 (black unicorn,male) +{ + ................ + ..HP............ + ..PHO.AA........ + ...PHAAJ........ + ...AADAJ........ + ..AAAAAJ........ + ..AAPAAJPP...... + ...PAAAJP....... + ...AAAAAAAA..... + ..AAAAAAAAAAPPP. + ..A.AAAAAAAPAP.. + ..APPAPPAPAPP... + ...LPAPPAPAP.... + .....APPLPA..... + .....LP...L..... + ................ +} +# tile 211 (black unicorn,female) +{ + ................ + ..HP............ + ..PHO.AA........ + ...PHAAJ........ + ...AADAJ........ + ..AAAAAJ........ + ..AAPAAJPP...... + ...PAAAJP....... + ...AAAAAAAA..... + ..AAAAAAAAAAPPP. + ..A.AAAAAAAPAP.. + ..APPAPPAPAPP... + ...LPAPPAPAP.... + .....APPLPA..... + .....LP...L..... + ................ +} +# tile 212 (horse,male) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ..KKKEKJ........ + .KKKJKKJAA...... + .JJJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKKJA... + ..KKKKKKKKKKJA.. + ..KJJKJJJJJKAJA. + ..JAAJAAAAAJAJA. + ..JAAJAAAJAJAA.. + ..LA.JAA.L.JA... + .....LA....L.... + ................ +} +# tile 213 (horse,female) +{ + ................ + ................ + .....JJ......... + ....KKKJ........ + ..KKKEKJ........ + .KKKJKKJAA...... + .JJJAKKJAA...... + ...AKKKJA....... + ...KKKKKKKKJA... + ..KKKKKKKKKKJA.. + ..KJJKJJJJJKAJA. + ..JAAJAAAAAJAJA. + ..JAAJAAAJAJAA.. + ..LA.JAA.L.JA... + .....LA....L.... + ................ +} +# tile 214 (warhorse,male) +{ + ................ + .....JJJ........ + ...KKKKJJ....... + .KKKKEKJJ....... + KKKKKKKJJAA..... + JKKKJKKJJAA..... + .JJJAKKJJAA..... + ...AKKKJJA...... + ...KKKKKKKKKJA.. + ..KKKKKKKKKKKJA. + ..KKJKKJKKJKKJJA + ..KJAKJAKJAKJAJA + ..KJAKJAKJAKJA.. + ..LC.KJALC.KJ... + .....LC....LC... + ................ +} +# tile 215 (warhorse,female) +{ + ................ + .....JJJ........ + ...KKKKJJ....... + .KKKKEKJJ....... + KKKKKKKJJAA..... + JKKKJKKJJAA..... + .JJJAKKJJAA..... + ...AKKKJJA...... + ...KKKKKKKKKJA.. + ..KKKKKKKKKKKJA. + ..KKJKKJKKJKKJJA + ..KJAKJAKJAKJAJA + ..KJAKJAKJAKJA.. + ..LC.KJALC.KJ... + .....LC....LC... + ................ +} +# tile 216 (fog cloud,male) +{ + .......P........ + ....P..P........ + .....P.P...P.... + ...P.......P.... + ..P..P.P.P...... + ....PP.PP.P.P... + .P..APAPPP..P... + ...P.PPPP.PP.... + ......PPPPP.P.P. + ...P.PPPPP..P... + ....P..P.PP.P... + .P...P.P...PPP.. + ..P.P....PP..... + .......P....P... + ..P..P.P..P..... + ................ +} +# tile 217 (fog cloud,female) +{ + .......P........ + ....P..P........ + .....P.P...P.... + ...P.......P.... + ..P..P.P.P...... + ....PP.PP.P.P... + .P..APAPPP..P... + ...P.PPPP.PP.... + ......PPPPP.P.P. + ...P.PPPPP..P... + ....P..P.PP.P... + .P...P.P...PPP.. + ..P.P....PP..... + .......P....P... + ..P..P.P..P..... + ................ +} +# tile 218 (dust vortex,male) +{ + ................ + ................ + ....K..KKKK..... + ...K..KKJJJK.... + ..K..KJJJJ..K... + .KJ.KJJ.JKK..K.. + .KJJKJ.JJJJK.... + .KJJJJ....JJK... + .KKJ.J...J.JKK.. + ..KJJ....JJJJK.. + ...KJJJJ.JKJJK.. + .K..KKJ.JJK.JK.. + ..K..JJJJK..K... + ...KJJJKK..K.... + ....KKKK..K..... + ................ +} +# tile 219 (dust vortex,female) +{ + ................ + ................ + ....K..KKKK..... + ...K..KKJJJK.... + ..K..KJJJJ..K... + .KJ.KJJ.JKK..K.. + .KJJKJ.JJJJK.... + .KJJJJ....JJK... + .KKJ.J...J.JKK.. + ..KJJ....JJJJK.. + ...KJJJJ.JKJJK.. + .K..KKJ.JJK.JK.. + ..K..JJJJK..K... + ...KJJJKK..K.... + ....KKKK..K..... + ................ +} +# tile 220 (ice vortex,male) +{ + ................ + ................ + ....N..NNNN..... + ...N..NNOOON.... + ..N..NOOOO..N... + .NO.NOO.ONN..N.. + .NOONO.OOOON.... + .NOOOO....OON... + .NNO.O...O.ONN.. + ..NOO....OOOON.. + ...NOOOO.ONOON.. + .N..NNO.OON.ON.. + ..N..OOOON..N... + ...NOOONN..N.... + ....NNNN..N..... + ................ +} +# tile 221 (ice vortex,female) +{ + ................ + ................ + ....N..NNNN..... + ...N..NNOOON.... + ..N..NOOOO..N... + .NO.NOO.ONN..N.. + .NOONO.OOOON.... + .NOOOO....OON... + .NNO.O...O.ONN.. + ..NOO....OOOON.. + ...NOOOO.ONOON.. + .N..NNO.OON.ON.. + ..N..OOOON..N... + ...NOOONN..N.... + ....NNNN..N..... + ................ +} +# tile 222 (energy vortex,male) +{ + ................ + ................ + ....E..EEEE..... + ...E..EEAAAE.... + ..E..EAAAA..E... + .EA.EAAAAIE..E.. + .EAAIAAAAAAE.... + .EAAAAAAAAAAE... + .EEAAAAAAAAAEE.. + ..EAAAAAAAAAAE.. + ...EAAAAAAIAAE.. + .E..EIAAAAE.AE.. + ..E..AAAAE..E... + ...EAAAEE..E.... + ....EEEE..E..... + ................ +} +# tile 223 (energy vortex,female) +{ + ................ + ................ + ....E..EEEE..... + ...E..EEAAAE.... + ..E..EAAAA..E... + .EA.EAAAAIE..E.. + .EAAIAAAAAAE.... + .EAAAAAAAAAAE... + .EEAAAAAAAAAEE.. + ..EAAAAAAAAAAE.. + ...EAAAAAAIAAE.. + .E..EIAAAAE.AE.. + ..E..AAAAE..E... + ...EAAAEE..E.... + ....EEEE..E..... + ................ +} +# tile 224 (steam vortex,male) +{ + ................ + ................ + ....P..PPPP..... + ...P..PPBBBP.... + ..P..PBBBB..P... + .PB.PBBPBPP..P.. + .PBBPBPBBBBP.... + .PBBBBP.PPBBP... + .PPBPB...BPBPP.. + ..PBBPP.PBBBBP.. + ...PBBBBPBPBBP.. + .P..PPBPBBP.BP.. + ..P..BBBBP..P... + ...PBBBPP..P.... + ....PPPP..P..... + ................ +} +# tile 225 (steam vortex,female) +{ + ................ + ................ + ....P..PPPP..... + ...P..PPBBBP.... + ..P..PBBBB..P... + .PB.PBBPBPP..P.. + .PBBPBPBBBBP.... + .PBBBBP.PPBBP... + .PPBPB...BPBPP.. + ..PBBPP.PBBBBP.. + ...PBBBBPBPBBP.. + .P..PPBPBBP.BP.. + ..P..BBBBP..P... + ...PBBBPP..P.... + ....PPPP..P..... + ................ +} +# tile 226 (fire vortex,male) +{ + ................ + ................ + ....D..DDDD..... + ...D..DDCCCD.... + ..D..DCCCC..D... + .DC.DCCHCDD..D.. + .DCCDCHCCCCD.... + .DCCCCHHHHCCD... + .DDCHCHHHCHCDD.. + ..DCCHHHHCCCCD.. + ...DCCCCHCDCCD.. + .D..DDCHCCD.CD.. + ..D..CCCCD..D... + ...DCCCDD..D.... + ....DDDD..D..... + ................ +} +# tile 227 (fire vortex,female) +{ + ................ + ................ + ....D..DDDD..... + ...D..DDCCCD.... + ..D..DCCCC..D... + .DC.DCCHCDD..D.. + .DCCDCHCCCCD.... + .DCCCCHHHHCCD... + .DDCHCHHHCHCDD.. + ..DCCHHHHCCCCD.. + ...DCCCCHCDCCD.. + .D..DDCHCCD.CD.. + ..D..CCCCD..D... + ...DCCCDD..D.... + ....DDDD..D..... + ................ +} +# tile 228 (baby long worm,male) +{ + ................ + ................ + ................ + ................ + ......CLC....... + ......LLL....... + .....GGAGG.A.... + .....GGAGGAAA... + ......LLLAAA.C.. + ......LLLAA.CC.. + ......CLLCCCCA.. + .......LLLCCA... + ........CLL..... + ................ + ................ + ................ +} +# tile 229 (baby long worm,female) +{ + ................ + ................ + ................ + ................ + ......CLC....... + ......LLL....... + .....GGAGG.A.... + .....GGAGGAAA... + ......LLLAAA.C.. + ......LLLAA.CC.. + ......CLLCCCCA.. + .......LLLCCA... + ........CLL..... + ................ + ................ + ................ +} +# tile 230 (baby purple worm,male) +{ + ................ + ................ + ................ + .......I........ + ......III....... + ......III....... + .....GGAGG.A.... + .....GGAGGAAA... + ......IIIAAA.D.. + ......IIIAA.DD.. + ......IIIDDDDA.. + .......IIIDDA... + ........III..... + ................ + ................ + ................ +} +# tile 231 (baby purple worm,female) +{ + ................ + ................ + ................ + .......I........ + ......III....... + ......III....... + .....GGAGG.A.... + .....GGAGGAAA... + ......IIIAAA.D.. + ......IIIAA.DD.. + ......IIIDDDDA.. + .......IIIDDA... + ........III..... + ................ + ................ + ................ +} +# tile 232 (long worm,male) +{ + ................ + ................ + .....CLC........ + ....CLLLC....... + ....LLLLL....... + ...GGGLGGGAA.... + ...GAGLGAGAAA... + ...GGGLGGGAAA... + ....LLLLLAAACC.. + ....LLLLLAACCC.. + ....CLLLLCCCCA.. + .....LLLLLCCA... + ......CLLLL..... + ................ + ................ + ................ +} +# tile 233 (long worm,female) +{ + ................ + ................ + .....CLC........ + ....CLLLC....... + ....LLLLL....... + ...GGGLGGGAA.... + ...GAGLGAGAAA... + ...GGGLGGGAAA... + ....LLLLLAAACC.. + ....LLLLLAACCC.. + ....CLLLLCCCCA.. + .....LLLLLCCA... + ......CLLLL..... + ................ + ................ + ................ +} +# tile 234 (purple worm,male) +{ + ................ + ................ + .....DID........ + ....DIIID....... + ....IIIII....... + ...GGGIGGGAA.... + ...GAGIGAGAAA... + ...GGGIGGGAAA... + ....IIIIIAAADD.. + ....IIIIIAADDD.. + ....DIIIIDDDDA.. + .....IIIIIDDA... + ......DIIII..... + ................ + ................ + ................ +} +# tile 235 (purple worm,female) +{ + ................ + ................ + .....DID........ + ....DIIID....... + ....IIIII....... + ...GGGIGGGAA.... + ...GAGIGAGAAA... + ...GGGIGGGAAA... + ....IIIIIAAADD.. + ....IIIIIAADDD.. + ....DIIIIDDDDA.. + .....IIIIIDDA... + ......DIIII..... + ................ + ................ + ................ +} +# tile 236 (grid bug,male) +{ + ................ + ................ + ................ + ................ + ..D....NHCN..D.. + .D.D..NHDNCNDED. + D.D.D.NNHCND.DED + .D...D.NNHDND... + .DDD..ENNG.D.DE. + ..DDDDEEEEGD..DE + D.....DEHEE.D... + .D.......H...... + ................ + ................ + ................ + ................ +} +# tile 237 (grid bug,female) +{ + ................ + ................ + ................ + ................ + ..D....NHCN..D.. + .D.D..NHDNCNDED. + D.D.D.NNHCND.DED + .D...D.NNHDND... + .DDD..ENNG.D.DE. + ..DDDDEEEEGD..DE + D.....DEHEE.D... + .D.......H...... + ................ + ................ + ................ + ................ +} +# tile 238 (xan,male) +{ + ................ + ................ + ..........GG.... + ...HHH...GOGG... + .....HH..GGGG... + ...HHHHH.GGG.... + .......GG...AAA. + .....GOGGHHAAAA. + ....GOGG..HHAAA. + NNNGOGG.AAHHHA.. + NANGGGG.AAHAH... + NNNGGNNNAAAAAA.. + ..GGGNANAA.AAA.. + .GGGANNNAA.A.A.. + ..G..AAAAAA..... + ......AA.AA..... +} +# tile 239 (xan,female) +{ + ................ + ................ + ..........GG.... + ...HHH...GOGG... + .....HH..GGGG... + ...HHHHH.GGG.... + .......GG...AAA. + .....GOGGHHAAAA. + ....GOGG..HHAAA. + NNNGOGG.AAHHHA.. + NANGGGG.AAHAH... + NNNGGNNNAAAAAA.. + ..GGGNANAA.AAA.. + .GGGANNNAA.A.A.. + ..G..AAAAAA..... + ......AA.AA..... +} +# tile 240 (yellow light,male) +{ + ................ + ......NA........ + ......HA........ + ..NA.NHNA.NA.... + ...LALHLALA..... + ....NHHHNA...... + ..NLHHHHHLNA.... + NHHHHHHHHHHHNA.. + ..NLHHHHHLNA.... + ....NHHHNA...... + ...LALHLALA..... + ..NA.NNNA.NA.... + ......HA........ + ......NA........ + ................ + ................ +} +# tile 241 (yellow light,female) +{ + ................ + ......NA........ + ......HA........ + ..NA.NHNA.NA.... + ...LALHLALA..... + ....NHHHNA...... + ..NLHHHHHLNA.... + NHHHHHHHHHHHNA.. + ..NLHHHHHLNA.... + ....NHHHNA...... + ...LALHLALA..... + ..NA.NNNA.NA.... + ......HA........ + ......NA........ + ................ + ................ +} +# tile 242 (black light,male) +{ + ................ + ......AA........ + ......AA........ + ..AA.AAAA.AA.... + ...AAAAAAAA..... + ....AAAAAA...... + ..AAAAAAAAAA.... + AAAAAAAAAAAAAA.. + ..AAAAAAAAAA.... + ....AAAAAA...... + ...AAAAAAAA..... + ..AA.AAAA.AA.... + ......AA........ + ......AA........ + ................ + ................ +} +# tile 243 (black light,female) +{ + ................ + ......AA........ + ......AA........ + ..AA.AAAA.AA.... + ...AAAAAAAA..... + ....AAAAAA...... + ..AAAAAAAAAA.... + AAAAAAAAAAAAAA.. + ..AAAAAAAAAA.... + ....AAAAAA...... + ...AAAAAAAA..... + ..AA.AAAA.AA.... + ......AA........ + ......AA........ + ................ + ................ +} +# tile 244 (zruty,male) +{ + ................ + ......FFGF...... + ....OOFGFFFF.... + ...AOFGFOOKFF... + ...FFGFAOAJKKF.. + ..FFFFFFJAAJKK.. + ..ODOFFJAJJKKJA. + ..DDDDJAJJKJJAA. + ..JODOAJJJAJJAAA + .KKJAJJJKJAJJAAA + .KKAAJKKKKJAAAAA + ...AJJKKKKJJAAAA + ...KJJAAAAKJAAA. + ..JKJJJAAJJJJ... + ................ + ................ +} +# tile 245 (zruty,female) +{ + ................ + ......FFGF...... + ....OOFGFFFF.... + ...AOFGFOOKFF... + ...FFGFAOAJKKF.. + ..FFFFFFJAAJKK.. + ..ODOFFJAJJKKJA. + ..DDDDJAJJKJJAA. + ..JODOAJJJAJJAAA + .KKJAJJJKJAJJAAA + .KKAAJKKKKJAAAAA + ...AJJKKKKJJAAAA + ...KJJAAAAKJAAA. + ..JKJJJAAJJJJ... + ................ + ................ +} +# tile 246 (couatl,male) +{ + ................ + ................ + ........I....I.. + ....KKAIII..III. + ...NAOJAKI.IIIII + ...KKJAJJKKK..II + ...KKAAIJJJJJ..I + ...FAA.I...KJ..I + ..FAFA..AAAKJAA. + .......AAAJJAAA. + ......AKKJJAAA.. + ......KJAAAAAJA. + .....JJAA...JA.. + ......JJJJJJA... + ................ + ................ +} +# tile 247 (couatl,female) +{ + ................ + ................ + ........I....I.. + ....KKAIII..III. + ...NAOJAKI.IIIII + ...KKJAJJKKK..II + ...KKAAIJJJJJ..I + ...FAA.I...KJ..I + ..FAFA..AAAKJAA. + .......AAAJJAAA. + ......AKKJJAAA.. + ......KJAAAAAJA. + .....JJAA...JA.. + ......JJJJJJA... + ................ + ................ +} +# tile 248 (Aleax,male) +{ + ................ + ......BBBB..I... + ..I..BF...B..... + ....BF.HHA.B.... + ...BF.HHHHA.B.I. + ...BF.LFLFA.FB.. + .I.BF.LLLLA.FB.. + ...BF.ALLA.FB... + ..BF.LLAALL.ABA. + .BF.LLLLLLLLAFB. + .BF.LALLLLALAFB. + .BF.LAJJKJALAFB. + ..BF..LJJLAAABA. + ...BF.LLALAABA.. + ..BF.LLAALLAFB.. + ................ +} +# tile 249 (Aleax,female) +{ + ................ + ......BBBB..I... + ..I..BF...B..... + ....BF.HHA.B.... + ...BF.HHHHA.B.I. + ...BF.LFLFA.FB.. + .I.BF.LLLLA.FB.. + ...BF.ALLA.FB... + ..BF.LJAAJL.ABA. + .BF.LLJJJJLLAFB. + .BF.LAJKJJALAFB. + .BF.LAJJKJALAFB. + ..BF..LJJLAAABA. + ...BF.LLALAABA.. + ..BF.LLAALLAFB.. + ................ +} +# tile 250 (Angel,male) +{ + ................ + ................ + ......HHHH...... + ................ + .......CC....... + ......CLLC..AA.. + ......PLLP....A. + ......NPPPA.A... + .....BBLLPPAAA.. + .....NNLLPPAAA.. + ......BNNPAAAA.. + ......BNNPAAAA.. + .....BNNNPAA.A.. + .....BNNNNPA.... + ....BNNNNNNP.... + ................ +} +# tile 251 (Angel,female) +{ + ................ + ................ + ......HHHH...... + ................ + .......CC....... + ......CLLC..AA.. + ......PLLP....A. + ......NPPPA.A... + .....BBLLPPAAA.. + .....NNLLPPAAA.. + ......BNNPAAAA.. + ......BNNPAAAA.. + .....BNNNPAA.A.. + .....BNNNNPA.... + ....BNNNNNNP.... + ................ +} +# tile 252 (ki-rin,male) +{ + ................ + ................ + ..LP............ + ..PLO.C.C....... + ...PLCCD........ + ...KCIKD........ + ..KCCCCD........ + ..CKACCDA....... + ...ACCCCCC...A.. + ...KCCCKCCKAA... + ..CAKCKCKCAKA... + ..CAAKAKAKA..... + ...L.KALAK...... + .....LA..L...... + ................ + ................ +} +# tile 253 (ki-rin,female) +{ + ................ + ................ + ..LP............ + ..PLO.C.C....... + ...PLCCD........ + ...KCIKD........ + ..KCCCCD........ + ..CKACCDA....... + ...ACCCCCC...A.. + ...KCCCKCCKAA... + ..CAKCKCKCAKA... + ..CAAKAKAKA..... + ...L.KALAK...... + .....LA..L...... + ................ + ................ +} +# tile 254 (Archon,male) +{ + ................ + ......OOOO...... + .....OOOOOO..... + .....OJLLJO..... + .....OLLLLO..... + ....OOJLLJOO.... + ......AJJA...... + .....AAAAAAA.... + ....AAAAAAAAA... + ...OAAOAAAJLJ... + ..OOAOAAAACJC... + ....LAAAACCJCC.. + .....AAAAAJJJ... + ....AAAAAAAA.... + ................ + ................ +} +# tile 255 (Archon,female) +{ + ................ + ......OOOO...... + .....OOOOOO..... + .....OJLLJO..... + .....OLLLLO..... + ....OOKLLKOO.... + ......AKKA...... + .....AAAAAAA.... + ....AAAAAAAAA... + ...OAAOAAAJLJ... + ..OOAOAAAACJC... + ....LAAAACCJCC.. + .....AAAAAJJJ... + ....AAAAAAAA.... + ................ + ................ +} +# tile 256 (bat,male) +{ + ................ + ................ + ................ + ................ + ...JJJCACJJJ.... + ..JJAAHJHAAJJ... + ..JA...JA..AJ... + ................ + ................ + ......AAAA...... + ....AAAAAAAA.... + ...AAA.AA.AAA... + .......AA....... + ................ + ................ + ................ +} +# tile 257 (bat,female) +{ + ................ + ................ + ................ + ................ + ...JJJCACJJJ.... + ..JJAAHJHAAJJ... + ..JA...JA..AJ... + ................ + ................ + ......AAAA...... + ....AAAAAAAA.... + ...AAA.AA.AAA... + .......AA....... + ................ + ................ + ................ +} +# tile 258 (giant bat,male) +{ + ................ + ................ + ................ + ...JK.J.J.JK.... + ..KJJJCACJJKJ... + .JJJAAHJHAAJJK.. + .KJA...JA..AJJ.. + ..JA.......AJ... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 259 (giant bat,female) +{ + ................ + ................ + ................ + ...JK.J.J.JK.... + ..KJJJCACJJKJ... + .JJJAAHJHAAJJK.. + .KJA...JA..AJJ.. + ..JA.......AJ... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 260 (raven,male) +{ + ..AAAA...AAA.... + .AAAAAA.AAA..... + AAAAAAAAAAA.AA.. + A...AAAAAAAAAAA. + ......AAAAAAAAA. + .....AAAA.....AA + .....ADA.......A + .....PA......... + .....P.......... + .........P.P.P.. + ........P.P.P.P. + .......P.P.P.... + ........P.P.P... + ...........P.... + ................ + ................ +} +# tile 261 (raven,female) +{ + ..AAAA...AAA.... + .AAAAAA.AAA..... + AAAAAAAAAAA.AA.. + A...AAAAAAAAAAA. + ......AAAAAAAAA. + .....AAAA.....AA + .....ADA.......A + .....PA......... + .....P.......... + .........P.P.P.. + ........P.P.P.P. + .......P.P.P.... + ........P.P.P... + ...........P.... + ................ + ................ +} +# tile 262 (vampire bat,male) +{ + ................ + ................ + ................ + ...AA.A.A.AA.... + ..AAAAAAAAAAA... + .AAAA.DAD.AAAA.. + .AAA...A...AAA.. + ..A.........A... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 263 (vampire bat,female) +{ + ................ + ................ + ................ + ...AA.A.A.AA.... + ..AAAAAAAAAAA... + .AAAA.DAD.AAAA.. + .AAA...A...AAA.. + ..A.........A... + ................ + .....AAAAAA..... + ...AAAAAAAAAA... + ..AAAA.AA.AAAA.. + .......AA....... + ................ + ................ + ................ +} +# tile 264 (plains centaur,male) +{ + ................ + ...KKA.......... + ...LLAA......... + .AAKKAA......... + .LLAALLA........ + LALLLLALA....... + LALLLKALA.A..... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 265 (plains centaur,female) +{ + ................ + ...KKA.......... + ...LLAA......... + .AAKKAA......... + .LLAALLA........ + LALLLLALA....... + LALLLKALA.A..... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 266 (forest centaur,male) +{ + ................ + ................ + ................ + ...KKA.......... + LA.LLAALA....... + LAALLAALA....... + .LLAALLA........ + ..LLLLA.A....... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKA.A.. + .KAKJJJJKJAAAA.. + .KAAKAAJAKA..... + ..C.KAAKAK...... + ....CA...C...... + ................ +} +# tile 267 (forest centaur,female) +{ + ................ + ................ + ................ + ...KKA.......... + LA.LLAALA....... + LAALLAALA....... + .LLAALLA........ + ..LLLLA.A....... + ..LKLKAAAAA..... + ..KLKJKJJKAA.... + .KJKJKJKJAKA.A.. + .KAKJJJJKJAAAA.. + .KAAKAAJAKA..... + ..C.KAAKAK...... + ....CA...C...... + ................ +} +# tile 268 (mountain centaur,male) +{ + ................ + ................ + ...KKA.......... + ...LLAA......... + ..AKKAA......... + .LJJJJLA........ + LAJKKJALA.A..... + LAKKKKALAAA..... + ..JJJJKJJKAA.... + .KJJJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 269 (mountain centaur,female) +{ + ................ + ................ + ...KKA.......... + ...LLAA......... + ..AKKAA......... + .LJJJJLA........ + LAJKKJALA.A..... + LAKKKKALAAA..... + ..JJJJKJJKAA.... + .KJJJKJKJAKAAAA. + .KAKJJJJKJAAA.A. + .KAAKAAAAKAA.... + ..CAKAAJAKA..... + ....KAAKAK...... + ....CA...C...... + ................ +} +# tile 270 (baby gray dragon,male) +{ + ................ + ................ + ................ + .....BBBA....... + ....NPNPPA...... + ...BPPPPPA...... + ..CHHPABPA.AAA.. + .CHCDA.BPAAAAAA. + ..D..BPPAAAAAAA. + ....BBPPPPPAAAA. + ...BOOPPPPPPAAA. + ..BPOBPPPPPPPAA. + ..BPPBPPOBPAPPA. + ..BPABP.ABPAPPA. + .....BPAA..PPAA. + ...........PAA.. +} +# tile 271 (baby gray dragon,female) +{ + ................ + ................ + ................ + .....BBBA....... + ....NPNPPA...... + ...BPPPPPA...... + ..CHHPABPA.AAA.. + .CHCDA.BPAAAAAA. + ..D..BPPAAAAAAA. + ....BBPPPPPAAAA. + ...BOOPPPPPPAAA. + ..BPOBPPPPPPPAA. + ..BPPBPPOBPAPPA. + ..BPABP.ABPAPPA. + .....BPAA..PPAA. + ...........PAA.. +} +# tile 272 (baby silver dragon,male) +{ + ................ + ................ + ................ + .....PPPA....... + ....OBOBBA...... + ...PBBBBBA...... + ..CHHBAPBA.AAA.. + .CHCDA.PBAAAAAA. + ..D..PBBAAAAAAA. + ....PPBBBBBAAAA. + ...PNNBBBBBBAAA. + ..PBNPBBBBBBBAA. + ..PBBPBBNPBABBA. + ..PBAPB.APBABBA. + .....PBAA..BBAA. + ...........BAA.. +} +# tile 273 (baby silver dragon,female) +{ + ................ + ................ + ................ + .....PPPA....... + ....OBOBBA...... + ...PBBBBBA...... + ..CHHBAPBA.AAA.. + .CHCDA.PBAAAAAA. + ..D..PBBAAAAAAA. + ....PPBBBBBAAAA. + ...PNNBBBBBBAAA. + ..PBNPBBBBBBBAA. + ..PBBPBBNPBABBA. + ..PBAPB.APBABBA. + .....PBAA..BBAA. + ...........BAA.. +} +# tile 274 (baby shimmering dragon,male) +{ + .I.............. + ...BBBBBBB.I.... + ..BF.FFF.FB...I. + .BF..BBBA.FB.... + BF..NPNPPAFB.I.. + BF.BPPPPPA.B.... + B.CHHPABPAFBAAI. + BCHCDA.BPAAFBAA. + B.D..BPPAAAAFBA. + B...BBPPPPPAAFB. + BF.BOOPPPPPPAAAB + BFBPOBPPPPPPPAFB + BFBPPBPPOBPAPPFB + B.BPABP.ABPAPPFB + B....BPAA..PPAAB + .B.........PAAB. +} +# tile 275 (baby shimmering dragon,female) +{ + .I.............. + ...BBBBBBB.I.... + ..BF.FFF.FB...I. + .BF..BBBA.FB.... + BF..NPNPPAFB.I.. + BF.BPPPPPA.B.... + B.CHHPABPAFBAAI. + BCHCDA.BPAAFBAA. + B.D..BPPAAAAFBA. + B...BBPPPPPAAFB. + BF.BOOPPPPPPAAAB + BFBPOBPPPPPPPAFB + BFBPPBPPOBPAPPFB + B.BPABP.ABPAPPFB + B....BPAA..PPAAB + .B.........PAAB. +} +# tile 276 (baby red dragon,male) +{ + ................ + ................ + ................ + .....IIIA....... + ....NDNDDA...... + ...IDDDDDA...... + ..CHHDAIDA.AAA.. + .CHCDA.IDAAAAAA. + ..D..IDDAAAAAAA. + ....IIDDDDDAAAA. + ...IHHDDDDDDAAA. + ..IDHIDDDDDDDAA. + ..IDDIDDHIDADDA. + ..IDAID.AIDADDA. + .....IDAA..DDAA. + ...........DAA.. +} +# tile 277 (baby red dragon,female) +{ + ................ + ................ + ................ + .....IIIA....... + ....NDNDDA...... + ...IDDDDDA...... + ..CHHDAIDA.AAA.. + .CHCDA.IDAAAAAA. + ..D..IDDAAAAAAA. + ....IIDDDDDAAAA. + ...IHHDDDDDDAAA. + ..IDHIDDDDDDDAA. + ..IDDIDDHIDADDA. + ..IDAID.AIDADDA. + .....IDAA..DDAA. + ...........DAA.. +} +# tile 278 (baby white dragon,male) +{ + ................ + ................ + ................ + .....NNNA....... + ....IOIOOA...... + ...NOOOOOA...... + ..CHHOANOA.AAA.. + .CHCDA.NOAAAAAA. + ..D..NOOAAAAAAA. + ....NNOOOOOAAAA. + ...NOOOOOOOOAAA. + ..NOONOOOOOOOAA. + ..NOONOOONOAOOA. + ..NOANO.ANOAOOA. + .....NOAA..OOAA. + ...........OAA.. +} +# tile 279 (baby white dragon,female) +{ + ................ + ................ + ................ + .....NNNA....... + ....IOIOOA...... + ...NOOOOOA...... + ..CHHOANOA.AAA.. + .CHCDA.NOAAAAAA. + ..D..NOOAAAAAAA. + ....NNOOOOOAAAA. + ...NOOOOOOOOAAA. + ..NOONOOOOOOOAA. + ..NOONOOONOAOOA. + ..NOANO.ANOAOOA. + .....NOAA..OOAA. + ...........OAA.. +} +# tile 280 (baby orange dragon,male) +{ + ................ + ................ + ................ + .....LLLA....... + ....NCNCCA...... + ...LCCCCCA...... + ..CHHCALCA.AAA.. + .CHCDA.LCAAAAAA. + ..D..LCCAAAAAAA. + ....LLCCCCCAAAA. + ...LOOCCCCCCAAA. + ..LCOLCCCCCCCAA. + ..LCCLCCOLCACCA. + ..LCALC.ALCACCA. + .....LCAA..CCAA. + ...........CAA.. +} +# tile 281 (baby orange dragon,female) +{ + ................ + ................ + ................ + .....LLLA....... + ....NCNCCA...... + ...LCCCCCA...... + ..CHHCALCA.AAA.. + .CHCDA.LCAAAAAA. + ..D..LCCAAAAAAA. + ....LLCCCCCAAAA. + ...LOOCCCCCCAAA. + ..LCOLCCCCCCCAA. + ..LCCLCCOLCACCA. + ..LCALC.ALCACCA. + .....LCAA..CCAA. + ...........CAA.. +} +# tile 282 (baby black dragon,male) +{ + ................ + ................ + ................ + .....AAA........ + ....NANAA....... + ...AAAAAA....... + ..CHHA.AA..PPP.. + .CHCD..AA.PPPPP. + ..D..AAAPPP.PPP. + ....AAAAAAAPPPP. + ...AAAAAAAAAPPP. + ..AAAAAAAAAAAPP. + ..AAAAAAAAAPAAP. + ..AAPAA.PAAPAAP. + .....AAP...AAPP. + ...........APP.. +} +# tile 283 (baby black dragon,female) +{ + ................ + ................ + ................ + .....AAA........ + ....NANAA....... + ...AAAAAA....... + ..CHHA.AA..PPP.. + .CHCD..AA.PPPPP. + ..D..AAAPPP.PPP. + ....AAAAAAAPPPP. + ...AAAAAAAAAPPP. + ..AAAAAAAAAAAPP. + ..AAAAAAAAAPAAP. + ..AAPAA.PAAPAAP. + .....AAP...AAPP. + ...........APP.. +} +# tile 284 (baby blue dragon,male) +{ + ................ + ................ + ................ + .....BBBA....... + ....NENEEA...... + ...BEEEEEA...... + ..CHHEABEA.AAA.. + CCHCDA.BEAAAAAA. + ..D..BEEAAAAAAA. + ....BBEEEEEAAAA. + ...BOOEEEEEEAAA. + ..BEOBEEEEEEEAA. + ..BEEBEEOBEAEEA. + ..BEABE.ABEAEEA. + .....BEAA..EEAA. + ...........EAA.. +} +# tile 285 (baby blue dragon,female) +{ + ................ + ................ + ................ + .....BBBA....... + ....NENEEA...... + ...BEEEEEA...... + ..CHHEABEA.AAA.. + CCHCDA.BEAAAAAA. + ..D..BEEAAAAAAA. + ....BBEEEEEAAAA. + ...BOOEEEEEEAAA. + ..BEOBEEEEEEEAA. + ..BEEBEEOBEAEEA. + ..BEABE.ABEAEEA. + .....BEAA..EEAA. + ...........EAA.. +} +# tile 286 (baby green dragon,male) +{ + ................ + ................ + ................ + .....GGGA....... + ....NFNFFA...... + ...GFFFFFA...... + ..CHHFAGFA.AAA.. + .CHCDA.GFAAAAAA. + ..D..GFFAAAAAAA. + ....GGFFFFFAAAA. + ...GOOFFFFFFAAA. + ..GFOGFFFFFFFAA. + ..GFFGFFOGFAFFA. + ..GFAGF.AGFAFFA. + .....GFAA..FFAA. + ...........FAA.. +} +# tile 287 (baby green dragon,female) +{ + ................ + ................ + ................ + .....GGGA....... + ....NFNFFA...... + ...GFFFFFA...... + ..CHHFAGFA.AAA.. + .CHCDA.GFAAAAAA. + ..D..GFFAAAAAAA. + ....GGFFFFFAAAA. + ...GOOFFFFFFAAA. + ..GFOGFFFFFFFAA. + ..GFFGFFOGFAFFA. + ..GFAGF.AGFAFFA. + .....GFAA..FFAA. + ...........FAA.. +} +# tile 288 (baby yellow dragon,male) +{ + ................ + ................ + ................ + .....NNNA....... + ....DHDHHA...... + ...NHHHHHA...... + ..CHHHANHA.AAA.. + .CHCDA.NHAAAAAA. + ..D..NHHAAAAAAA. + ....NNHHHHHAAAA. + ...NOOHHHHHHAAA. + ..NHONHHHHHHHAA. + ..NHHNHHONHAHHA. + ..NHANH.ANHAHHA. + .....NHAA..HHAA. + ...........HAA.. +} +# tile 289 (baby yellow dragon,female) +{ + ................ + ................ + ................ + .....NNNA....... + ....DHDHHA...... + ...NHHHHHA...... + ..CHHHANHA.AAA.. + .CHCDA.NHAAAAAA. + ..D..NHHAAAAAAA. + ....NNHHHHHAAAA. + ...NOOHHHHHHAAA. + ..NHONHHHHHHHAA. + ..NHHNHHONHAHHA. + ..NHANH.ANHAHHA. + .....NHAA..HHAA. + ...........HAA.. +} +# tile 290 (gray dragon,male) +{ + ......BBBPA..... + .....NPNPPPA.... + ....BPPPPPPA.... + ..DCHHP..PPA.... + CHCHCD..BPPA.... + HD.D...BPPA..... + ......OBPAAAAAA. + ....BOBPAAAAAAAA + ..BOOBPA.PP.AAA. + .BOOOBPPPPPP.AA. + .BOOOBPPPPPPPAA. + PPOOBBPPPPPPPPA. + BP.OBPPOOPP.P.A. + BPAABP.AAPPAPPA. + ....BPAA...PP.A. + ........PPPP.A.. +} +# tile 291 (gray dragon,female) +{ + ......BBBPA..... + .....NPNPPPA.... + ....BPPPPPPA.... + ..DCHHP..PPA.... + CHCHCD..BPPA.... + HD.D...BPPA..... + ......OBPAAAAAA. + ....BOBPAAAAAAAA + ..BOOBPA.PP.AAA. + .BOOOBPPPPPP.AA. + .BOOOBPPPPPPPAA. + PPOOBBPPPPPPPPA. + BP.OBPPOOPP.P.A. + BPAABP.AAPPAPPA. + ....BPAA...PP.A. + ........PPPP.A.. +} +# tile 292 (silver dragon,male) +{ + ......PPPBA..... + .....OBOBBBA.... + ....PBBBBBBA.... + ..DCHHB..BBA.... + CHCHCD..PBBA.... + HD.D...PBBA..... + ......NPBAAAAAA. + ....PNPBAAAAAAAA + ..PNNPBA.BB.AAA. + .PNNNPBBBBBB.AA. + .PNNNPBBBBBBBAA. + BBNNPPBBBBBBBBA. + PB.NPBBNNBB.B.A. + PBAAPB.AABBABBA. + ....PBAA...BB.A. + ........BBBB.A.. +} +# tile 293 (silver dragon,female) +{ + ......PPPBA..... + .....OBOBBBA.... + ....PBBBBBBA.... + ..DCHHB..BBA.... + CHCHCD..PBBA.... + HD.D...PBBA..... + ......NPBAAAAAA. + ....PNPBAAAAAAAA + ..PNNPBA.BB.AAA. + .PNNNPBBBBBB.AA. + .PNNNPBBBBBBBAA. + BBNNPPBBBBBBBBA. + PB.NPBBNNBB.B.A. + PBAAPB.AABBABBA. + ....PBAA...BB.A. + ........BBBB.A.. +} +# tile 294 (shimmering dragon,male) +{ + .I.BF.BBBPAFB... + ..BF.NPNPPPAFB.I + .BF.BPPPPPPAFB.. + .BDCHHP..PPAFBI. + CBCHCD..BPPAFB.. + HDBB...BPPA.B..I + ..BF..OBPAAAABA. + .BF.BOBPAAAAAFBA + BFBOOBPA.PP.AAFB + .BOOOBPPPPPP.AFB + .BOOOBPPPPPPPAFB + PPOOBBPPPPPPPPFB + BP.OBPPOOPP.P.FB + BPAABP.AAPPAPPFB + ....BPAA...PP.AB + ........PPPP.AB. +} +# tile 295 (shimmering dragon,female) +{ + .I.BF.BBBPAFB... + ..BF.NPNPPPAFB.I + .BF.BPPPPPPAFB.. + .BDCHHP..PPAFBI. + CBCHCD..BPPAFB.. + HDBB...BPPA.B..I + ..BF..OBPAAAABA. + .BF.BOBPAAAAAFBA + BFBOOBPA.PP.AAFB + .BOOOBPPPPPP.AFB + .BOOOBPPPPPPPAFB + PPOOBBPPPPPPPPFB + BP.OBPPOOPP.P.FB + BPAABP.AAPPAPPFB + ....BPAA...PP.AB + ........PPPP.AB. +} +# tile 296 (red dragon,male) +{ + ......IIIDA..... + .....NDNDDDA.... + ....IDDDDDDA.... + ..DCHHD..DDA.... + CHCHCD..IDDA.... + HD.D...IDDA..... + ......HIDAAAAAA. + ....IHIDAAAAAAAA + ..IHHIDAJDDJAAA. + .IHHHIDDDDDDJAA. + .IHHHIDDDDDDDAA. + DDHHIIDDDDDDDDA. + ID.HIDDHHDDJDJA. + IDAAID.AADDADDA. + ....IDAAJJJDDJA. + ........DDDDJA.. +} +# tile 297 (red dragon,female) +{ + ......IIIDA..... + .....NDNDDDA.... + ....IDDDDDDA.... + ..DCHHD..DDA.... + CHCHCD..IDDA.... + HD.D...IDDA..... + ......HIDAAAAAA. + ....IHIDAAAAAAAA + ..IHHIDAJDDJAAA. + .IHHHIDDDDDDJAA. + .IHHHIDDDDDDDAA. + DDHHIIDDDDDDDDA. + ID.HIDDHHDDJDJA. + IDAAID.AADDADDA. + ....IDAAJJJDDJA. + ........DDDDJA.. +} +# tile 298 (white dragon,male) +{ + ......NNNOA..... + .....IOIOOOA.... + ....NOOOOOOA.... + ..DCHHO..OOA.... + CHCHCD..NOOA.... + HD.D...NOOA..... + ......ONOAAAAAA. + ....NONOAAAAAAAA + ..NOONOA.OO.AAA. + .NOOONOOOOOOJAA. + .NOOONOOOOOOOAA. + OOOONNOOOOOOOOA. + NO.ONOOOOOO.OJA. + NOAANO.AAOOAOOA. + ....NOAA...OOJA. + ........OOOOJA.. +} +# tile 299 (white dragon,female) +{ + ......NNNOA..... + .....IOIOOOA.... + ....NOOOOOOA.... + ..DCHHO..OOA.... + CHCHCD..NOOA.... + HD.D...NOOA..... + ......ONOAAAAAA. + ....NONOAAAAAAAA + ..NOONOA.OO.AAA. + .NOOONOOOOOOJAA. + .NOOONOOOOOOOAA. + OOOONNOOOOOOOOA. + NO.ONOOOOOO.OJA. + NOAANO.AAOOAOOA. + ....NOAA...OOJA. + ........OOOOJA.. +} +# tile 300 (orange dragon,male) +{ + ......LLLCA..... + .....NCNCCCA.... + ....LCCCCCCA.... + ..DCHHC..CCA.... + CHCHCD..LCCA.... + HD.D...LCCA..... + ......OLCAAAAAA. + ....LOLCAAAAAAAA + ..LOOLCA.CCKAAA. + .LOOOLCCCCCCJAA. + .LOOOLCCCCCCCAA. + CCOOLLCCCCCCCCA. + LC.OLCCOOCCKCJA. + LCAALC.AACCACCA. + ....LCAA.KKCCJA. + ........CCCCJA.. +} +# tile 301 (orange dragon,female) +{ + ......LLLCA..... + .....NCNCCCA.... + ....LCCCCCCA.... + ..DCHHC..CCA.... + CHCHCD..LCCA.... + HD.D...LCCA..... + ......OLCAAAAAA. + ....LOLCAAAAAAAA + ..LOOLCA.CCKAAA. + .LOOOLCCCCCCJAA. + .LOOOLCCCCCCCAA. + CCOOLLCCCCCCCCA. + LC.OLCCOOCCKCJA. + LCAALC.AACCACCA. + ....LCAA.KKCCJA. + ........CCCCJA.. +} +# tile 302 (black dragon,male) +{ + ......AAAA...... + .....NANAAA..... + ....AAAAAAA..... + ..DCHHA..AA..... + CHCHCD..AAA..... + HD.D...AAA...... + ......AAA..PPPP. + ....AAAAPPPPPPPP + ..AAAAAAAAA.PPP. + .AAAAAAAAAAAAPP. + .AAAAAAAAAAAAPP. + AAAAAAAAAAAAAAP. + AA.AAAAAAAA.AAP. + AAPPAA.PPAAPAAP. + ....AAPP...AAAP. + ........AAAAA... +} +# tile 303 (black dragon,female) +{ + ......AAAA...... + .....NANAAA..... + ....AAAAAAA..... + ..DCHHA..AA..... + CHCHCD..AAA..... + HD.D...AAA...... + ......AAA..PPPP. + ....AAAAPPPPPPPP + ..AAAAAAAAA.PPP. + .AAAAAAAAAAAAPP. + .AAAAAAAAAAAAPP. + AAAAAAAAAAAAAAP. + AA.AAAAAAAA.AAP. + AAPPAA.PPAAPAAP. + ....AAPP...AAAP. + ........AAAAA... +} +# tile 304 (blue dragon,male) +{ + ......BBBEA..... + .....NENEEEA.... + ....BEEEEEEA.... + ..DCHHE..EEA.... + CHCHCD..BEEA.... + HD.D...BEEA..... + ......OBEAAAAAA. + ....BOBEAAAAAAAA + ..BOOBEA.EE.AAA. + .BOOOBEEEEEEJAA. + .BOOOBEEEEEEEAA. + EEOOBBEEEEEEEEA. + BE.OBEEOOEE.EJA. + BEAABE.AAEEAEEA. + ....BEAA...EEJA. + ...P....EEEEJA.. +} +# tile 305 (blue dragon,female) +{ + ......BBBEA..... + .....NENEEEA.... + ....BEEEEEEA.... + ..DCHHE..EEA.... + CHCHCD..BEEA.... + HD.D...BEEA..... + ......OBEAAAAAA. + ....BOBEAAAAAAAA + ..BOOBEA.EE.AAA. + .BOOOBEEEEEEJAA. + .BOOOBEEEEEEEAA. + EEOOBBEEEEEEEEA. + BE.OBEEOOEE.EJA. + BEAABE.AAEEAEEA. + ....BEAA...EEJA. + ...P....EEEEJA.. +} +# tile 306 (green dragon,male) +{ + ......GGGFA..... + .....NFNFFFA.... + ....GFFFFFFA.... + ..DCHHF..FFA.... + CHCHCD..GFFA.... + HD.D...GFFA..... + ......OGFAAAAAA. + ....GOGFAAAAAAAA + ..GOOGFA.FF.AAA. + .GOOOGFFFFFFJAA. + .GOOOGFFFFFFFAA. + FFOOGGFFFFFFFFA. + GF.OGFFOOFF.FJA. + GFAAGF.AAFFAFFA. + ....GFAA...FFJA. + ........FFFFJA.. +} +# tile 307 (green dragon,female) +{ + ......GGGFA..... + .....NFNFFFA.... + ....GFFFFFFA.... + ..DCHHF..FFA.... + CHCHCD..GFFA.... + HD.D...GFFA..... + ......OGFAAAAAA. + ....GOGFAAAAAAAA + ..GOOGFA.FF.AAA. + .GOOOGFFFFFFJAA. + .GOOOGFFFFFFFAA. + FFOOGGFFFFFFFFA. + GF.OGFFOOFF.FJA. + GFAAGF.AAFFAFFA. + ....GFAA...FFJA. + ........FFFFJA.. +} +# tile 308 (yellow dragon,male) +{ + ......NNNHA..... + .....DHDHHHA.... + ....NHHHHHHA.... + ..DCHHH..HHA.... + CHCHCD..NHHA.... + HD.D...NHHA..... + ......ONHAAAAAA. + ....NONHAAAAAAAA + ..NOONHAJHHJAAA. + .NOOONHHHHHHJAA. + .NOOONHHHHHHHAA. + HHOONNHHHHHHHHA. + NH.ONHHOOHHJHJA. + NHAANH.AAHHAHHA. + ....NHAAJJJHHJA. + ........HHHHJA.. +} +# tile 309 (yellow dragon,female) +{ + ......NNNHA..... + .....DHDHHHA.... + ....NHHHHHHA.... + ..DCHHH..HHA.... + CHCHCD..NHHA.... + HD.D...NHHA..... + ......ONHAAAAAA. + ....NONHAAAAAAAA + ..NOONHAJHHJAAA. + .NOOONHHHHHHJAA. + .NOOONHHHHHHHAA. + HHOONNHHHHHHHHA. + NH.ONHHOOHHJHJA. + NHAANH.AAHHAHHA. + ....NHAAJJJHHJA. + ........HHHHJA.. +} +# tile 310 (stalker,male) +{ + ................ + .......PPP...... + ......P.P.P..... + .....PPPPPP..... + .....PP..PPP.... + ....PPPPPP.P.... + ....P.PPPP.P.... + ....P.PPP..P.... + ....P..PP..P.... + ....P.PPPP.P.... + ....P.P..P.P.... + ....P.P..P.P.... + ......P..P...... + ......P..P...... + .....PP..PP..... + ................ +} +# tile 311 (stalker,female) +{ + ................ + .......PPP...... + ......P.P.P..... + .....PPPPPP..... + .....PP..PPP.... + ....PPPPPP.P.... + ....P.PPPP.P.... + ....P.PPP..P.... + ....P..PP..P.... + ....P.PPPP.P.... + ....P.P..P.P.... + ....P.P..P.P.... + ......P..P...... + ......P..P...... + .....PP..PP..... + ................ +} +# tile 312 (air elemental,male) +{ + ................ + ...P.PPP..P..... + ..P.PAPA.P...... + P..PPPPPP..P.... + .P.PPAAPPP...P.. + ..PPPAAP.P.P.... + ..PAPAAPAP...... + P.PAPPP.AP.P.AA. + ..PA.PP.AP.AAAA. + ..PAPPPPAPAAAA.. + ..PAP.APAPAAAA.. + ..PAP.APAPAAAAA. + ....P.APAAAAAAA. + ..P.P.APPAAAAAA. + ...PP.APPPA..... + ................ +} +# tile 313 (air elemental,female) +{ + ................ + ...P.PPP..P..... + ..P.PAPA.P...... + P..PPPPPP..P.... + .P.PPAAPPP...P.. + ..PPPAAP.P.P.... + ..PAPAAPAP...... + P.PAPPP.AP.P.AA. + ..PA.PP.AP.AAAA. + ..PAPPPPAPAAAA.. + ..PAP.APAPAAAA.. + ..PAP.APAPAAAAA. + ....P.APAAAAAAA. + ..P.P.APPAAAAAA. + ...PP.APPPA..... + ................ +} +# tile 314 (fire elemental,male) +{ + ................ + .H..LDDD........ + ...LDADAC.H..... + H..DDDDDD..H.H.. + ..LDDAADDD...... + ..DDDAADCD.H.... + ..DADAACAD...... + H.DADDDCAD...AA. + ..DACDDCAD.AAAA. + ..DADDDDADAAAA.. + ..DADCADADAAAA.. + H.DADCADADAAAAA. + ....DCADAAAAAAA. + .H.LDCADDAAAAAA. + ..LDDCADDDA..... + ................ +} +# tile 315 (fire elemental,female) +{ + ................ + .H..LDDD........ + ...LDADAC.H..... + H..DDDDDD..H.H.. + ..LDDAADDD...... + ..DDDAADCD.H.... + ..DADAACAD...... + H.DADDDCAD...AA. + ..DACDDCAD.AAAA. + ..DADDDDADAAAA.. + ..DADCADADAAAA.. + H.DADCADADAAAAA. + ....DCADAAAAAAA. + .H.LDCADDAAAAAA. + ..LDDCADDDA..... + ................ +} +# tile 316 (earth elemental,male) +{ + ..F............. + ....CKKK..F..... + ...CKAKAJ....F.. + ...KKKKKK....... + ..CKKAAKKK.F..F. + .FKKKAAKJK...... + ..KAKAAJAK..F... + ..KAKJJJAK...AA. + F.KAJKKJAK.AAAA. + ..KAKKKKAKAAAA.. + ..KAKJAKAKAAAA.. + ..KAKJAKAKAAAAA. + ....KJAKAAAAAAA. + .F.CKJAKKAAAAAA. + ..CKKJAKKKA..... + ................ +} +# tile 317 (earth elemental,female) +{ + ..F............. + ....CKKK..F..... + ...CKAKAJ....F.. + ...KKKKKK....... + ..CKKAAKKK.F..F. + .FKKKAAKJK...... + ..KAKAAJAK..F... + ..KAKJJJAK...AA. + F.KAJKKJAK.AAAA. + ..KAKKKKAKAAAA.. + ..KAKJAKAKAAAA.. + ..KAKJAKAKAAAAA. + ....KJAKAAAAAAA. + .F.CKJAKKAAAAAA. + ..CKKJAKKKA..... + ................ +} +# tile 318 (water elemental,male) +{ + ................ + ....PBBB..E..... + .E.PBABAE...E... + ...BBBBBB....... + ..PBBAABBB.E..E. + E.BBBAABEB...... + ..BABAABEB.E.... + ..BABBBBEB...AA. + ..BAPBBEAB.AAAA. + E.BABBBBABAAAA.. + ..BABEABABAAAA.. + ..BABEABABAAAAA. + ....BEABAAAAAAA. + .E.PBEABBAAAAAA. + ..PBBEABBBA..... + ................ +} +# tile 319 (water elemental,female) +{ + ................ + ....PBBB..E..... + .E.PBABAE...E... + ...BBBBBB....... + ..PBBAABBB.E..E. + E.BBBAABEB...... + ..BABAABEB.E.... + ..BABBBBEB...AA. + ..BAPBBEAB.AAAA. + E.BABBBBABAAAA.. + ..BABEABABAAAA.. + ..BABEABABAAAAA. + ....BEABAAAAAAA. + .E.PBEABBAAAAAA. + ..PBBEABBBA..... + ................ +} +# tile 320 (lichen,male) +{ + ................ + ................ + ...FFF...FFF.... + ..FCFFFFFCCFA... + .FCOOFFFCOFFFA.. + .FCOOFFFCFFFFA.. + ..FFFFFFFFFFA... + ...AFFFCCFFFA... + ...FFFFCOFFAA... + ..FCCFFCOFCFA... + ..FCOFFCFFOCFA.. + ..FFCFFFCFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 321 (lichen,female) +{ + ................ + ................ + ...FFF...FFF.... + ..FCFFFFFCCFA... + .FCOOFFFCOFFFA.. + .FCOOFFFCFFFFA.. + ..FFFFFFFFFFA... + ...AFFFCCFFFA... + ...FFFFCOFFAA... + ..FCCFFCOFCFA... + ..FCOFFCFFOCFA.. + ..FFCFFFCFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 322 (brown mold,male) +{ + ................ + ................ + ...JJJ...JJJ.... + ..JKJJJJJKKJA... + .JKCCJJJKCJJJA.. + .JKCCJJJKJJJJA.. + ..JJJJJJJJJJA... + ...AJJJKKJJJA... + ...JJJJKCJJAA... + ..JKKJJKCJKJA... + ..JKCJJKJJCKJA.. + ..JJKJJJKJJJJA.. + ...JJJAAJJJJJA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 323 (brown mold,female) +{ + ................ + ................ + ...JJJ...JJJ.... + ..JKJJJJJKKJA... + .JKCCJJJKCJJJA.. + .JKCCJJJKJJJJA.. + ..JJJJJJJJJJA... + ...AJJJKKJJJA... + ...JJJJKCJJAA... + ..JKKJJKCJKJA... + ..JKCJJKJJCKJA.. + ..JJKJJJKJJJJA.. + ...JJJAAJJJJJA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 324 (yellow mold,male) +{ + ................ + ................ + ...HHH...HHH.... + ..HHHHHHHNHHA... + .HHNNOHHNNOHHA.. + .HHNNOOHHOOHHA.. + ..HHOOHHHHHHA... + ...AHHHHHHHHA... + ...HHHHNNOHAA... + ..HHHHHNNOHHA... + ..HNNOHHHONOHA.. + ..HHOHHHHHOOHA.. + ...HHHAAHHHHHA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 325 (yellow mold,female) +{ + ................ + ................ + ...HHH...HHH.... + ..HHHHHHHNHHA... + .HHNNOHHNNOHHA.. + .HHNNOOHHOOHHA.. + ..HHOOHHHHHHA... + ...AHHHHHHHHA... + ...HHHHNNOHAA... + ..HHHHHNNOHHA... + ..HNNOHHHONOHA.. + ..HHOHHHHHOOHA.. + ...HHHAAHHHHHA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 326 (green mold,male) +{ + ................ + ................ + ...FFF...FFF.... + ..FGFFFFFGGFA... + .FGOOFFFGOFFFA.. + .FGOOFFFGFFFFA.. + ..FFFFFFFFFFA... + ...AFFFGGFFFA... + ...FFFFGOFFAA... + ..FGGFFGOFGFA... + ..FGOFFGFFOGFA.. + ..FFGFFFGFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 327 (green mold,female) +{ + ................ + ................ + ...FFF...FFF.... + ..FGFFFFFGGFA... + .FGOOFFFGOFFFA.. + .FGOOFFFGFFFFA.. + ..FFFFFFFFFFA... + ...AFFFGGFFFA... + ...FFFFGOFFAA... + ..FGGFFGOFGFA... + ..FGOFFGFFOGFA.. + ..FFGFFFGFFFFA.. + ...FFFAAFFFFFA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 328 (red mold,male) +{ + ................ + ................ + ...DDD...DDD.... + ..DCDDDDDCCDA... + .DLLCDDDCLDDDA.. + .DCCCDDDCDDDDA.. + ..DDDDDDDDDDA... + ...ADDDCCDDDA... + ...DDDDCLDDAA... + ..DCCDDCLDCDA... + ..DCLDDCDDLCDA.. + ..DDCDDDCDDDDA.. + ...DDDAADDDDDA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 329 (red mold,female) +{ + ................ + ................ + ...DDD...DDD.... + ..DCDDDDDCCDA... + .DLLCDDDCLDDDA.. + .DCCCDDDCDDDDA.. + ..DDDDDDDDDDA... + ...ADDDCCDDDA... + ...DDDDCLDDAA... + ..DCCDDCLDCDA... + ..DCLDDCDDLCDA.. + ..DDCDDDCDDDDA.. + ...DDDAADDDDDA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 330 (shrieker,male) +{ + ................ + ................ + ................ + ................ + .....GGGGFF..... + ...GGGGIGIDFF... + .GGGIIGGGIIFFFF. + GIIGIIGGGGGGGDDF + GIIGGGGIIGIIGIDF + GGGGIGGIIGIIGGFF + ..GGGGGGGGGGG... + ......FFF..AAAAA + ....AGGGFFAAAAAA + ...AGGGGGGFAAAA. + ...AAAAAAAAAA... + ................ +} +# tile 331 (shrieker,female) +{ + ................ + ................ + ................ + ................ + .....GGGGFF..... + ...GGGGIGIDFF... + .GGGIIGGGIIFFFF. + GIIGIIGGGGGGGDDF + GIIGGGGIIGIIGIDF + GGGGIGGIIGIIGGFF + ..GGGGGGGGGGG... + ......FFF..AAAAA + ....AGGGFFAAAAAA + ...AGGGGGGFAAAA. + ...AAAAAAAAAA... + ................ +} +# tile 332 (violet fungus,male) +{ + ................ + ................ + ...III...III.... + ..ILIIIIILLIA... + .IOOLIIILOIIIA.. + .ILLLIIILIIIIA.. + ..IIIIIIIIIIA... + ...AIIILLIIIA... + ...IIIILOIIAA... + ..ILLIILOILIA... + ..ILOIILIIOLIA.. + ..IILIIILIIIIA.. + ...IIIAAIIIIIA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 333 (violet fungus,female) +{ + ................ + ................ + ...III...III.... + ..ILIIIIILLIA... + .IOOLIIILOIIIA.. + .ILLLIIILIIIIA.. + ..IIIIIIIIIIA... + ...AIIILLIIIA... + ...IIIILOIIAA... + ..ILLIILOILIA... + ..ILOIILIIOLIA.. + ..IILIIILIIIIA.. + ...IIIAAIIIIIA.. + .....AA.AAAAA... + ................ + ................ +} +# tile 334 (gnome,male) +{ + ................ + ................ + ................ + .....DF......... + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + .....OLO...AAA.. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 335 (gnome,female) +{ + ................ + ................ + ................ + .....DF......... + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + .....LLL...AAA.. + ...FGGGGFFAAAA.. + ...GAGFFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 336 (gnome leader,male) +{ + ................ + ................ + ......D......... + ......G......... + ......G......... + .....GFF........ + ....HHHHH....... + ....GLLLF.....A. + .....OLO...AAA.. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 337 (gnome leader,female) +{ + ................ + ................ + ......D......... + ......G......... + ......G......... + .....GFF........ + ....HHHHH....... + ....GLLLF.....A. + .....LLL...AAA.. + ...FGGGGFFAAAA.. + ...GAGGFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 338 (gnomish wizard,male) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + ...FFOLOFF.AAA.. + ...GFOOOFFAAAA.. + ...FAGOFAFAAAA.. + ...GLKNKFFAAA... + ...FFGFFFFA..... + ...GFFFFGFA..... + ................ + ................ +} +# tile 339 (gnomish wizard,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GLLLF....... + ...FFLLLFF.AAA.. + ...GFGFGFFAAAA.. + ...FAGGFAFAAAA.. + ...GLKNKFFAAA... + ...FFGFFFFA..... + ...GFFFFGFA..... + ................ + ................ +} +# tile 340 (gnome ruler,male) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....GLLLF...A... + .....OLO...AAAA. + ...FGOOOFFAAAA.. + ...GAGOFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 341 (gnome ruler,female) +{ + ................ + ................ + ................ + ................ + ....H.C.H....... + ....HCHCH....... + ....HHHHH....... + ....GLLLF...A... + .....LLL...AAAA. + ...FGGGGFFAAAA.. + ...GAGFFAFAAAA.. + ....LKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 342 (giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLKLKCKCLKLLLA + .LLAALLCCLLAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 343 (giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLKLKCKCLKLLLA + .LLAALLCCLLAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 344 (stone giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLAAKCKCLKLLLA + .LLPPPACCLLAALLA + .LLPPPPAKKJAALLA + .CLCPPPAJJKKCLAA + ..LLPPALACLJLLAA + .....ALJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 345 (stone giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCLLJJJJLLCCAA + .CLLLCCKCKCLLLCA + .LLLAAKCKCLKLLLA + .LLPPPACCLLAALLA + .LLPPPPAKKJAALLA + .CLCPPPAJJKKCLAA + ..LLPPALACLJLLAA + .....ALJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 346 (hill giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ...JJKJJJJJJJAA. + ..LJJCCKCKCJJLA. + ..JLKKKCKCKKLJA. + ..LAAKKCCKJAALAA + ..LAAJJJKKJAALAA + ..LC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 347 (hill giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ...JJKJJJJJJJAA. + ..LJJCCKCKCJJLA. + ..JLKKKCKCKKLJA. + ..LAAKKCCKJAALAA + ..LAAJJJKKJAALAA + ..LC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 348 (fire giant,male) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLJAAAA. + ...JPDJJJJJJJAA. + ..LDDHDKCKCJJLA. + ..JLHDDCKCKKLJA. + ..LAHDHCCKJAALAA + JLAADDHJKKJAALAA + JJLJDHHJJJKKCLAA + ..LLJJJJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 349 (fire giant,female) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLJAAAA. + ...JPDJJJJJJJAA. + ..LDDHDKCKCJJLA. + ..JLHDDCKCKKLJA. + ..LAHDHCCKJAALAA + JLAADDHJKKJAALAA + JJLJDHHJJJKKCLAA + ..LLJJJJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.LLLLKAA +} +# tile 350 (frost giant,male) +{ + .....KJJJJAA.... + ....KJJJJJJJA... + ....JJLLLLJJA... + ....JEELLEEJA... + ....JLLLLLLJA... + ....AKJJJJJAAA.. + .....KJAAJJAAAA. + ....KKJJJJAJAAAA + ...KJKJJJJAJJAAA + ..KJKKJJJJJKJJAA + ..KAAJKJJAJAAJAA + ..JAAJKKAKJAAJAA + ..LC.JJJJJKKCLAA + ..LL.CJJAJLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 351 (frost giant,female) +{ + .....KJJJJAA.... + ....KJJJJJJJA... + ....JJLLLLJJA... + ....JEELLEEJA... + ....JLLLLLLJA... + ....ALLLLLLAAA.. + .....LLAALLAAAA. + ....KKLLLLKKAAAA + ...KJKKKKKKJJAAA + ..KJKKJJJJKKJJAA + ..KAAJKJJKJAAJAA + ..JAAJKKKKJAAJAA + ..LC.JJJJJKKCLAA + ..LL.CJJAJLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 352 (ettin,male) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NPP..NPP..P... + ..ALPPLALPPLA... + ..APPPPAPPPPA... + ..APAAPAPAAPAA.. + ..APPPPAPPPPAAA. + ..BIIIIJJJIIIBAA + .BPPPIIIIIIPPPBA + .PPPFPIIIIPFPPPA + .PPAAPIIIIPAAPPA + .PPAAIIIIIIAAPPA + .BPB.IIFFIIABPAA + ..PP.BPAABPAPPAA + .....BPAABPAAAAA + ...PPPPA.BPPPFAA +} +# tile 353 (ettin,female) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NPP..NPP..P... + ..ALPPLALPPLA... + ..APPPPAPPPPA... + ..APAAPAPAAPAA.. + ..APPPPAPPPPAAA. + ..BIIIIJJJIIIBAA + .BPPPIIIIIIPPPBA + .PPPFPIIIIPFPPPA + .PPAAPIIIIPAAPPA + .PPAAIIIIIIAAPPA + .BPB.IIFFIIABPAA + ..PP.BPAABPAPPAA + .....BPAABPAAAAA + ...PPPPA.BPPPFAA +} +# tile 354 (storm giant,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAH.. + .....ALLLLJAHAA. + ...JJKJJJJJHHAA. + ..LJJCCKCKHHLAA. + ..JLKKKCKHHHHHH. + ..LAAKKCCKJAHHAA + ..LAAJJJKKJHHALA + ..LC.JJJJJKHAAAA + ..LL.CLJACHAAAAA + .....CLJACCJAAAA + ...LLLLJ.LLLLKAA +} +# tile 355 (storm giant,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJLLLLJJA... + ....JFFLLFFJA... + ....JLLLLLLJA... + ....ALLAALLAAH.. + .....ALLLLJAHAA. + ...JJKJJJJJHHAA. + ..LJJCCKCKHHLAA. + ..JLKKKCKHHHHHH. + ..LAAKKCCKJAHHAA + ..LAAJJJKKJHHALA + ..LC.JJJJJKHAAAA + ..LL.CLJACHAAAAA + .....CLJACCJAAAA + ...LLLLJ.LLLLKAA +} +# tile 356 (titan,male) +{ + .....AAAAAAA.... + ....AALLLLAAA... + ....A..LL..AA... + ....ALLLLLLAA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCJJJJJJJJCCA. + .CLLLCCKCKCLLLCA + .LLLKJKCKCJKLLLA + .LLAAJJCCJJAALLA + .LLAAJJCCJJAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 357 (titan,female) +{ + .....AAAAAAA.... + ....AALLLLAAA... + ....A..LL..AA... + ....ALLLLLLAA... + ....ALLAALLAAA.. + .....ALLLLJAAAA. + ..CCJJJJJJJJCCA. + .CLLLCCKCKCLLLCA + .LLLKJKCKCJKLLLA + .LLAAJJCCJJAALLA + .LLAAJJCCJJAALLA + .LLAAJJJKKJAALLA + .CLC.JJJJJKKCLAA + ..LL.CLJACLJLLAA + .....CLJACLJAAAA + ...LLLLJ.CLLLKAA +} +# tile 358 (minotaur,male) +{ + ................ + .O..........O... + .OOOJJJJJJOOO... + ..OOJJKJJJOO.... + ...JGAKJGAJA.... + ...JJJKJJJJA.... + ....JJKJJJAAA... + ....JKKKJAAAA... + ..CLJAJAKALCAA.A + .CLLJJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LL.JJJJJJJLLAAA + .LL.JJJJJJJLLAAA + ....CLCACLCAAAAA + ..LLLLL.LLLLLAA. +} +# tile 359 (minotaur,female) +{ + ................ + .O..........O... + .OOOJJJJJJOOO... + ..OOJJKJJJOO.... + ...JGAKJGAJA.... + ...JJJKJJJJA.... + ....JJKJJJAAA... + ....JKKKJAAAA... + ..CLJAJAKALCAA.A + .CLLJJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAAJLLLLJAALAA. + .LL.JJJJJJJLLAAA + .LL.JJJJJJJLLAAA + ....CLCACLCAAAAA + ..LLLLL.LLLLLAA. +} +# tile 360 (jabberwock,male) +{ + ................ + ...DP........... + ....DP.ADOO..... + ..DAIDADIPAD.... + ...DIAPIPA...... + ...DBDDDA....... + ..IBBDADDA..AA.. + .DDDDAODDIAAAA.. + ..OAOA.DDAIAAA.. + ..IOAODDAAADDAA. + ..DDDADDDDAIDA.. + ...AAADDIDIDDD.. + ....IDDAIDDDDA.. + ....IDAAIDAA.... + ...IDAA..ID..... + ................ +} +# tile 361 (jabberwock,female) +{ + ................ + ...DP........... + ....DP.ADOO..... + ..DAIDADIPAD.... + ...DIAPIPA...... + ...DBDDDA....... + ..IBBDADDA..AA.. + .DDDDAODDIAAAA.. + ..OAOA.DDAIAAA.. + ..IOAODDAAADDAA. + ..DDDADDDDAIDA.. + ...AAADDIDIDDD.. + ....IDDAIDDDDA.. + ....IDAAIDAA.... + ...IDAA..ID..... + ................ +} +# tile 362 (vorpal jabberwock,male) +{ + ................ + ...GP........... + ....GP.AGOO..... + ..GAFGAGFPAG.... + ...GFAPFPA...... + ...GHGGGA....... + ..FHHGAGGA..AA.. + .GGGGAOGGFAAAA.. + ..OAOA.GGAFAAA.. + ..FOAOGGAAAGGAA. + ..GGGAGGGGAFGA.. + ...AAAGGFGFGGG.. + ....FGGAFGGGGA.. + ....FGAAFGAA.... + ...FGAA..FG..... + ................ +} +# tile 363 (vorpal jabberwock,female) +{ + ................ + ...GP........... + ....GP.AGOO..... + ..GAFGAGFPAG.... + ...GFAPFPA...... + ...GHGGGA....... + ..FHHGAGGA..AA.. + .GGGGAOGGFAAAA.. + ..OAOA.GGAFAAA.. + ..FOAOGGAAAGGAA. + ..GGGAGGGGAFGA.. + ...AAAGGFGFGGG.. + ....FGGAFGGGGA.. + ....FGAAFGAA.... + ...FGAA..FG..... + ................ +} +# tile 364 (Keystone Kop,male) +{ + ................ + ....AA.......... + ...AAAA......... + ...AOAA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.PPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 365 (Keystone Kop,female) +{ + ................ + ....AA.......... + ...AAAA......... + ...AOAA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.PPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 366 (Kop Sergeant,male) +{ + ................ + ....AA.......... + ...AOOA......... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 367 (Kop Sergeant,female) +{ + ................ + ....AA.......... + ...AOOA......... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ...AAAA.AAA..... + ..AAAAAAAAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 368 (Kop Lieutenant,male) +{ + ................ + ....AA.......... + ...AOOA...C..... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ..OAAAO.AAA..... + .OAAAAA.AAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 369 (Kop Lieutenant,female) +{ + ................ + ....AA.......... + ...AOOA...C..... + ...AOOA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + ..OAAAO.AAA..... + .OAAAAA.AAC.P... + .AA.AAAAA.CPPP.. + ..AAAAAA.PPPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 370 (Kop Kaptain,male) +{ + ................ + ....AA....C..... + ...AHHA...C..... + ...AHHA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + .HHAAAAHHAA..... + .AAAAHAAAACCC... + .AA.AHAAA.CPPP.. + ..AAAHAA.PCPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 371 (Kop Kaptain,female) +{ + ................ + ....AA....C..... + ...AHHA...C..... + ...AHHA...C..... + ..AAAAAA..C..... + ...LLLL...C..... + ....LL....C..... + .HHAAAAHHAA..... + .AAAAHAAAACCC... + .AA.AHAAA.CPPP.. + ..AAAHAA.PCPPPP. + ....AAAAPPPAPP.. + .A.AAAAAAPAAA... + AAAAA.PAAAAA.... + ..AA....AA...... + ................ +} +# tile 372 (lich,male) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....O.PPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 373 (lich,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....O.PPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 374 (demilich,male) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....L.PPPAAAA.A. + ......LPPAAA.A.. + .....LLAL.A..... + ...LLLA.LA...... + ......LLL....... + ................ +} +# tile 375 (demilich,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...OOPPP....AAA. + ..O.PPPPPA..AAA. + .O...PPPP.AAAAA. + ....L.PPPAAAA.A. + ......LPPAAA.A.. + .....LLAL.A..... + ...LLLA.LA...... + ......LLL....... + ................ +} +# tile 376 (master lich,male) +{ + ...H............ + ...HCH.H........ + ...HHHCH........ + ..AOAOHH........ + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...PPPPP....AAA. + ..PPPPPPPA..AAA. + .O..PPPPP.AAAAA. + ....OPPPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 377 (master lich,female) +{ + ...H............ + ...HCH.H........ + ...HHHCH........ + ..AOAOHH........ + ..OOOOO......... + ..OO.O.......... + .....PPP........ + ...PPPPP....AAA. + ..PPPPPPPA..AAA. + .O..PPPPP.AAAAA. + ....OPPPPAAAA.A. + ......PPPAAA.A.. + .....OPAP.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 378 (arch-lich,male) +{ + ................ + ................ + ...OOO.......... + ..DODOO......... + ..OOOOO......... + H.OO.O.......... + A....PPP........ + A..OOPPP....AAA. + .AO.PPPPPA..AAA. + .O...PPPP.AAAAA. + .A..O.PPPAAAA.A. + ..A...PPPAAA.A.. + ..A..OPAP.A..... + ..AOOOA.OA...... + ......OOO....... + ................ +} +# tile 379 (arch-lich,female) +{ + ................ + ................ + ...OOO.......... + ..DODOO......... + ..OOOOO......... + H.OO.O.......... + A....PPP........ + A..OOPPP....AAA. + .AO.PPPPPA..AAA. + .O...PPPP.AAAAA. + .A..O.PPPAAAA.A. + ..A...PPPAAA.A.. + ..A..OPAP.A..... + ..AOOOA.OA...... + ......OOO....... + ................ +} +# tile 380 (kobold mummy,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NONONO....... + ...OAOAO.OP..... + ....ONN...A..... + ...ONODNA.AA.... + ..OLONNONAAA.A.. + ..NALONANAAAAA.. + ..NAOLOAOAAAAA.. + ....NOLAAAAAA... + ....NANAAAA..... + ...OOANOA....... + ................ + ................ +} +# tile 381 (kobold mummy,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NONONO....... + ...OAOAO.OP..... + ....ONN...A..... + ...ONODNA.AA.... + ..OLONNONAAA.A.. + ..NALONANAAAAA.. + ..NAOLOAOAAAAA.. + ....NOLAAAAAA... + ....NANAAAA..... + ...OOANOA....... + ................ + ................ +} +# tile 382 (gnome mummy,male) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GGFO....... + ....GGFFOOP..... + ....GDODF....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 383 (gnome mummy,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GGFO....... + ....GGFFOOP..... + ....GDODF....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 384 (orc mummy,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOOP........ + ....DODPOP...... + ....OOOA........ + ..OOOOOOOA.AA... + ..OOOOOOO.AAA... + ..OAOOOAACCC.... + ..OAOOOCCAAA.... + ....OCCOAAAAAA.. + ...CCAOOAAAA.... + ..OOOAOOOA...... + ................ + ................ +} +# tile 385 (orc mummy,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOOP........ + ....DODPOP...... + ....OOOA........ + ..OOOOOOOA.AA... + ..OOOOOOO.AAA... + ..OAOOOAACCC.... + ..OAOOOCCAAA.... + ....OCCOAAAAAA.. + ...CCAOOAAAA.... + ..OOOAOOOA...... + ................ + ................ +} +# tile 386 (dwarf mummy,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BBEO....... + ....BBEEEOP..... + ....BDODE....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 387 (dwarf mummy,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BBEO....... + ....BBEEEOP..... + ....BDODE....... + .....ONO...AAA.. + ...NONOONOAAAA.. + ...OANLOAOAAAA.. + ....NNOLOAAAA... + ....NOANDAA..... + ....NOAOO.A..... + ................ + ................ +} +# tile 388 (elf mummy,male) +{ + ................ + ................ + .........O...... + .......OOOP..... + ......OOOOP..... + ......OEOEAP.... + ......OOOOA..... + ......AOOA....A. + ......OAAO..AAA. + .....OOOOOOAAAA. + ....OALOOLAOAAA. + ....OADOOOAOAA.. + ......OOAOAA.A.. + .....OOA.OOA.... + ................ + ................ +} +# tile 389 (elf mummy,female) +{ + ................ + ................ + .........O...... + .......OOOP..... + ......OOOOP..... + ......OEOEAP.... + ......OOOOA..... + ......AOOA....A. + ......OAAO..AAA. + .....OOOOOOAAAA. + ....OALOOLAOAAA. + ....OADOOOAOAA.. + ......OOAOAA.A.. + .....OOA.OOA.... + ................ + ................ +} +# tile 390 (human mummy,male) +{ + ................ + ................ + ...ONNO......... + ...NNNNOP....... + ..PANAN.OPP..... + ..PNNNN......... + ..ONOONNP....... + .ONLNNOOO....... + .NJNOOOOO..AAA.. + .OJOOOODN.AAAA.. + .NJOLNOAOAAAAAA. + .OCNO.NKNAAAAA.. + .N.OO.OLAAAAAAA. + ...OOAOOAAA..... + ..NNN.NNNA...... + ................ +} +# tile 391 (human mummy,female) +{ + ................ + ................ + ...ONNO......... + ...NNNNOP....... + ..PANAN.OPP..... + ..PNNNN......... + ..ONOONNP....... + .ONLNNOOO....... + .NJNOOOOO..AAA.. + .OJOOOODN.AAAA.. + .NJOLNOAOAAAAAA. + .OCNO.NKNAAAAA.. + .N.OO.OLAAAAAAA. + ...OOAOOAAA..... + ..NNN.NNNA...... + ................ +} +# tile 392 (ettin mummy,male) +{ + .....NN..ONOO... + ...NNOOONNOOOO.. + ...NOOOONOOOOOO. + ...OFOFOLOFOFO.O + ...OOOOOLOOOOO.P + ...NOOOOLNNOOOA. + ...ONOOOLOOOOAAA + ..OOOONNNNNNNOAA + .ONNNNNNOONOOOOA + .ONODNNOOOOOOOOA + .NNAAONNONOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 393 (ettin mummy,female) +{ + .....NN..ONOO... + ...NNOOONNOOOO.. + ...NOOOONOOOOOO. + ...OFOFOLOFOFO.O + ...OOOOOLOOOOO.P + ...NOOOOLNNOOOA. + ...ONOOOLOOOOAAA + ..OOOONNNNNNNOAA + .ONNNNNNOONOOOOA + .ONODNNOOOOOOOOA + .NNAAONNONOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 394 (giant mummy,male) +{ + ......ONOOAA.... + ....ONNNOOOOA... + ....NNOOOOOOO... + ....NFFOOFFOOP.. + ....NONOOOOOAOP. + ....AONOOOOAAAP. + .....ANOOODAAAA. + ..OOOONOOONNNOAA + .ONNNNNOOOOOOOOA + .ONODNNLOOOOOOOA + .NNAAONOLNOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 395 (giant mummy,female) +{ + ......ONOOAA.... + ....ONNNOOOOA... + ....NNOOOOOOO... + ....NFFOOFFOOP.. + ....NONOOOOOAOP. + ....AONOOOOAAAP. + .....ANOOODAAAA. + ..OOOONOOONNNOAA + .ONNNNNOOOOOOOOA + .ONODNNLOOOOOOOA + .NNAAONOLNOAAOOA + .NOAAONOONLAAOOA + .OOO.ONOONOOOOAA + ..OO.NNOANOLOOAA + .....NOOANOOAAAA + ...OOOOO.OOOOKAA +} +# tile 396 (red naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LDLAA........ + ...IDDAAAAADA... + ...IDDDAAADDA... + ....IIDDDDDA.... + ................ +} +# tile 397 (red naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LDLAA........ + ...IDDAAAAADA... + ...IDDDAAADDA... + ....IIDDDDDA.... + ................ +} +# tile 398 (black naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLA......... + ...LALAA........ + ...AAAPA..PAA... + ...AAAAPPPAAA... + ....AAAAAAAA.... + ................ +} +# tile 399 (black naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLA......... + ...LALAA........ + ...AAAPA..PAA... + ...AAAAPPPAAA... + ....AAAAAAAA.... + ................ +} +# tile 400 (golden naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LHLAA........ + ...NHHAAAAAHA... + ...NHHHAAAHHA... + ....NNHHHHHA.... + ................ +} +# tile 401 (golden naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LHLAA........ + ...NHHAAAAAHA... + ...NHHHAAAHHA... + ....NNHHHHHA.... + ................ +} +# tile 402 (guardian naga hatchling,male) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LFLAA........ + ...GFFAAAAAFA... + ...GFFFAAAFFA... + ....GGFFFFFA.... + ................ +} +# tile 403 (guardian naga hatchling,female) +{ + ................ + ................ + ................ + ................ + ....K........... + ...KLK.......... + ...LLLA......... + ...ALAA......... + ...LALA......... + ...LLLA......... + ...LLLAA........ + ...LFLAA........ + ...GFFAAAAAFA... + ...GFFFAAAFFA... + ....GGFFFFFA.... + ................ +} +# tile 404 (red naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLDA..AA.... + ...LDLDA.AAAA... + ...IDDDAAAIIA... + ...IDDDAIDDDIDA. + ...IDDDIDDDDDDDA + ...IDDDDDDAA.DDA + ....DDDDDA..DDA. + .....DDAA..DDA.. + ..........DA.... +} +# tile 405 (red naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLDA..AA.... + ...LDLDA.AAAA... + ...IDDDAAAIIA... + ...IDDDAIDDDIDA. + ...IDDDIDDDDDDDA + ...IDDDDDDAA.DDA + ....DDDDDA..DDA. + .....DDAA..DDA.. + ..........DA.... +} +# tile 406 (black naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLAA........ + ...LALAA..PPP... + ...AAAAPPPAAP... + ...AAAAPAAAAAAP. + ...AAAAAAAAAAAAP + ...AAAAAAAPP.AAP + ....AAAAAP..AAP. + .....AAPP..AAP.. + ..........AP.... +} +# tile 407 (black naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLAA........ + ...LALAA..PPP... + ...AAAAPPPAAP... + ...AAAAPAAAAAAP. + ...AAAAAAAAAAAAP + ...AAAAAAAPP.AAP + ....AAAAAP..AAP. + .....AAPP..AAP.. + ..........AP.... +} +# tile 408 (golden naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLHA..AA.... + ...LHLHA.AAAA... + ...NHHHAAANNA... + ...NHHHANHHHNHA. + ...NHHHNHHHHHHHA + ...NHHHHHHAA.HHA + ....HHHHHA..HHA. + .....HHAA..HHA.. + ..........HA.... +} +# tile 409 (golden naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ...LAALA........ + ...LLLLA........ + ...LLLHA..AA.... + ...LHLHA.AAAA... + ...NHHHAAANNA... + ...NHHHANHHHNHA. + ...NHHHNHHHHHHHA + ...NHHHHHHAA.HHA + ....HHHHHA..HHA. + .....HHAA..HHA.. + ..........HA.... +} +# tile 410 (guardian naga,male) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ..CLAALC........ + ..LLLLLL........ + ..CLLCLC..AA.... + ...CLLCA.AAAA... + ...GLFCAAAGGA... + ...GFFFAAFFFGFA. + ...GFFFGFFFFFFFA + ...GFFFFFFAA.FFA + ....FFFFFA..FFA. + .....FFAA..FFA.. + ..........FA.... +} +# tile 411 (guardian naga,female) +{ + ................ + ....KK.......... + ...KLLK......... + ...LLLLA........ + ...ALLAA........ + ..CLAALC........ + ..LLLLLL........ + ..CLLCLC..AA.... + ...CLLCA.AAAA... + ...GLFCAAAGGA... + ...GFFFAAFFFGFA. + ...GFFFGFFFFFFFA + ...GFFFFFFAA.FFA + ....FFFFFA..FFA. + .....FFAA..FFA.. + ..........FA.... +} +# tile 412 (ogre,male) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CAAACJAAA... + ....LDDDLAAAA... + ..CLJLLLKALCAA.A + .CLLAJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 413 (ogre,female) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CAAACJAAA... + ....LDDDLAAAA... + ..CLJLLLKALCAA.A + .CLLAJJJJALLCAAA + .LLCLAAAALCLLAA. + .LAACLLLLCAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 414 (ogre leader,male) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 415 (ogre leader,female) +{ + ................ + ................ + ....CLLLC....... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 416 (ogre tyrant,male) +{ + ...H..C..H...... + ...HDCHCDH...... + ...HHHHHHH...... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CJKAJJJJAKJCAAA + .LJJKAAAAKJJLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 417 (ogre tyrant,female) +{ + ...HH.C.HH...... + ...HDCHCDH...... + ...HHHHHHH...... + ..LCKKLKKCL..... + ...LAALAALJA.... + ...CLLLLLCJA.... + ....CLLLCJAAA... + ....LAAALAAAA... + ..JKJLLLKAKJAA.A + .CJKAJJJJAKJCAAA + .LJJKAAAAKJJLAA. + .LAAJKKKKJAALAA. + .LC.HHHBHHACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 418 (gray ooze,male) +{ + ................ + ................ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAAA.. + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPBBPPAAA. + .PBBPPPBAAPPPAA. + ...PBBBAAAKPPJ.. + ........ACPPAK.. + .........KCCCJ.. + ................ +} +# tile 419 (gray ooze,female) +{ + ................ + ................ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAAA.. + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPBBPPAAA. + .PBBPPPBAAPPPAA. + ...PBBBAAAKPPJ.. + ........ACPPAK.. + .........KCCCJ.. + ................ +} +# tile 420 (brown pudding,male) +{ + ................ + ................ + ................ + ................ + ............J... + ....JKKJJJ..JJ.. + ...KKKCJJJJJ.... + ..KKNNJNNJJJ.... + ..KJANJANJJJA... + ..KKJJJJJCJJAA.. + ..JKJJCJJJJJAA.. + ...JJJJJJJJAAA.. + ....JJJJJJAAA... + .....AAAAAAA.... + ................ + ................ +} +# tile 421 (brown pudding,female) +{ + ................ + ................ + ................ + ................ + ............J... + ....JKKJJJ..JJ.. + ...KKKCJJJJJ.... + ..KKNNJNNJJJ.... + ..KJANJANJJJA... + ..KKJJJJJCJJAA.. + ..JKJJCJJJJJAA.. + ...JJJJJJJJAAA.. + ....JJJJJJAAA... + .....AAAAAAA.... + ................ + ................ +} +# tile 422 (green slime,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ............G... + .....G......G..G + .G....G..G.NGN.G + ..NG.NGGNGGGGGGG + ..GGNGGNGGGFGGF. + GGNGGGGGGGGGFF.G + .NGGGGGFGFG..... + NGGGGFGGFG.G..GF + NGGFGGF..GF..... + ..GGF..GGF..G... +} +# tile 423 (green slime,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ............G... + .....G......G..G + .G....G..G.NGN.G + ..NG.NGGNGGGGGGG + ..GGNGGNGGGFGGF. + GGNGGGGGGGGGFF.G + .NGGGGGFGFG..... + NGGGGFGGFG.G..GF + NGGFGGF..GF..... + ..GGF..GGF..G... +} +# tile 424 (black pudding,male) +{ + ........A....... + ........AA...... + .....AAA........ + ....AAAAA....... + ....CACAA....... + ....DADAA....... + ....AAAAA....... + ....AAAAA....... + ....AAAAA....... + .....AAAAA...... + .....AAAAA...... + ......AAAAA..... + ......AAAAAA.... + .......AAAAAA.A. + ........AAAAAAAA + ..........AAAA.. +} +# tile 425 (black pudding,female) +{ + ........A....... + ........AA...... + .....AAA........ + ....AAAAA....... + ....CACAA....... + ....DADAA....... + ....AAAAA....... + ....AAAAA....... + ....AAAAA....... + .....AAAAA...... + .....AAAAA...... + ......AAAAA..... + ......AAAAAA.... + .......AAAAAA.A. + ........AAAAAAAA + ..........AAAA.. +} +# tile 426 (quantum mechanic,male) +{ + ................ + ......LLLL...... + ...FGGCLCGGF.... + ...GNNGLGNNGL... + B.BGANGGGANGL... + B.BFGGCLCGGFL... + BIB..CLLLCCL.... + BILN.LLAALLAAAA. + BILNN.LLLLJAAAA. + BIB.NNJJJJNAAA.. + BIB.BNNNONNNAA.. + .B...NNNONNLAA.. + .....NBEBENA.A.. + .....NBEBENN.... + ....NAAEBAANN... + ................ +} +# tile 427 (quantum mechanic,female) +{ + ................ + ......JJJJJ..... + ...FGGCLCGGF.... + ...GNNGLGNNGJ... + B.BGANGGGANGL... + B.BFGGCLCGGFLJ.. + BIB.JCLLLCCLJJ.. + BILN.LLAALLAAAA. + BILNN.LLLLCAAAA. + BIB.NNCCCCNAAA.. + BIB.BNNNONNNAA.. + .B...NNNONNLAA.. + .....NBEBENA.A.. + .....NBEBENN.... + ....NAAEBAANN... + ................ +} +# tile 428 (genetic engineer,male) +{ + ................ + ......LLLL...... + ...LAALLLAAL.... + ...LNNLLLNNLL... + ...LANLLLANLL... + ...LLLLLLLLLL... + .....CLLLCCL.... + ..LN.LLAALL..... + ..LNN.LLLLJ..... + ..A.NNLLLLN..... + .A.ABNNNONNN.... + .AA..NNNONNL.... + .A.A.NPEPENA.... + .AA..NPEPENN.... + ..AANAAEPAANN... + ................ +} +# tile 429 (genetic engineer,female) +{ + ................ + ......LLLL...... + ...LAALLLAAL.... + ...LNNLLLNNLL... + ...LANLLLANLL... + ...LLLLLLLLLL... + .....CLLLCCL.... + ..LN.LLAALL..... + ..LNN.LLLLJ..... + ..A.NNLLLLN..... + .A.ABNNNONNN.... + .AA..NNNONNL.... + .A.A.NPEPENA.... + .AA..NPEPENN.... + ..AANAAEPAANN... + ................ +} +# tile 430 (rust monster,male) +{ + ................ + ....EEEE........ + ...EEHEHE....... + ...EEEAEE....... + ...EEPAPE....... + ...EPEAEP...E... + ....EEEE.AAEE... + ....EEEEEAAEEE.. + ...EEEEEEEAEAEE. + ..EEEEEEAAAAE... + ..EEAEEEEAEEEA.. + ..AAEEEEEEEEEAA. + ....AEEEEEEEAAA. + .....EEEEEAA..A. + ......AAAA...... + ................ +} +# tile 431 (rust monster,female) +{ + ................ + ....EEEE........ + ...EEHEHE....... + ...EEEAEE....... + ...EEPAPE....... + ...EPEAEP...E... + ....EEEE.AAEE... + ....EEEEEAAEEE.. + ...EEEEEEEAEAEE. + ..EEEEEEAAAAE... + ..EEAEEEEAEEEA.. + ..AAEEEEEEEEEAA. + ....AEEEEEEEAAA. + .....EEEEEAA..A. + ......AAAA...... + ................ +} +# tile 432 (disenchanter,male) +{ + ................ + ....PPPP........ + ...PPDPDP....... + ...PPPAPP....... + ...PPOAOP....... + ...POPAPO...P... + ....PPPP.AAPP... + ....PPPPPAAPPP.. + ...PPPPPPPAPAPP. + ..PPPPPPAAAAP... + ..PPAPPPPAPPPA.. + ..AAPPPPPPPPPAA. + ....APPPPPPPAAA. + .....PPPPPAA..A. + ......AAAA...... + ................ +} +# tile 433 (disenchanter,female) +{ + ................ + ....PPPP........ + ...PPDPDP....... + ...PPPAPP....... + ...PPOAOP....... + ...POPAPO...P... + ....PPPP.AAPP... + ....PPPPPAAPPP.. + ...PPPPPPPAPAPP. + ..PPPPPPAAAAP... + ..PPAPPPPAPPPA.. + ..AAPPPPPPPPPAA. + ....APPPPPPPAAA. + .....PPPPPAA..A. + ......AAAA...... + ................ +} +# tile 434 (garter snake,male) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOKA........ + ...KKAKA........ + ...KKAKA....KA.. + ....APKAP..KAPP. + .....PKAPP.KAP.. + .....KAAP..KAP.. + ....KAAP..KAAP.. + ....KAAPPKAAP... + ....KAAKKAAP.... + .....KAAAAP..... + ................ + ................ +} +# tile 435 (garter snake,female) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOKA........ + ...KKAKA........ + ...KKAKA....KA.. + ....APKAP..KAPP. + .....PKAPP.KAP.. + .....KAAP..KAP.. + ....KAAP..KAAP.. + ....KAAPPKAAP... + ....KAAKKAAP.... + .....KAAAAP..... + ................ + ................ +} +# tile 436 (snake,male) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOJA........ + ...KKJAJ........ + ...KKAAJ....KK.. + ...FAAKJ...KJAA. + ..FAFAKJAA.KJA.. + .....KJAA..KJA.. + ....KJAA..KJJA.. + ....KJAAAKJJA... + ....KJJJJJJA.... + .....KJJJJA..... + ................ + ................ +} +# tile 437 (snake,female) +{ + ................ + ................ + ................ + ....KKA......... + ...NAOJA........ + ...KKJAJ........ + ...KKAAJ....KK.. + ...FAAKJ...KJAA. + ..FAFAKJAA.KJA.. + .....KJAA..KJA.. + ....KJAA..KJJA.. + ....KJAAAKJJA... + ....KJJJJJJA.... + .....KJJJJA..... + ................ + ................ +} +# tile 438 (water moccasin,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AA... + ...OAOAAA.AA.... + ...AAA.AA.AA.... + ...DA..AA.AA.... + ..D.D.AAA..AA... + .....AAA...AA... + .....AAA...AA... + ....AAA...AAA... + ....AAAAAAAA.... + ....AAAAAAA..... + .....AAAAA...... + ................ +} +# tile 439 (water moccasin,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AA... + ...OAOAAA.AA.... + ...AAA.AA.AA.... + ...DA..AA.AA.... + ..D.D.AAA..AA... + .....AAA...AA... + .....AAA...AA... + ....AAA...AAA... + ....AAAAAAAA.... + ....AAAAAAA..... + .....AAAAA...... + ................ +} +# tile 440 (python,male) +{ + ................ + ................ + ................ + ...KKKA.....JJ.. + ...GAGJA...JJJ.. + ..JKKJAJ..KJJ... + ..KKKAJJ..KJJ.AA + ..KKAAKJA.KKJAA. + .....AKJAA.KJAA. + ....JKJAA..KJJA. + ...JJJAA..KJJJA. + ...JJJAAAKJJJA.. + ...JJJJJJJJJAA.. + ....JJJJJJJAA... + .....JJJJJAA.... + ................ +} +# tile 441 (python,female) +{ + ................ + ................ + ................ + ...KKKA.....JJ.. + ...GAGJA...JJJ.. + ..JKKJAJ..KJJ... + ..KKKAJJ..KJJ.AA + ..KKAAKJA.KKJAA. + .....AKJAA.KJAA. + ....JKJAA..KJJA. + ...JJJAA..KJJJA. + ...JJJAAAKJJJA.. + ...JJJJJJJJJAA.. + ....JJJJJJJAA... + .....JJJJJAA.... + ................ +} +# tile 442 (pit viper,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AAA.. + ...OAAAAA.AA.AA. + ...AA..AA.AA.AA. + ...D...AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA...AA... + .....AA...AAA... + .....AA..AAA.... + .....AAAAAA..... + ......AAAA...... + ................ +} +# tile 443 (pit viper,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAA...AAA.. + ...OAAAAA.AA.AA. + ...AA..AA.AA.AA. + ...D...AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA...AA... + .....AA...AAA... + .....AA..AAA.... + .....AAAAAA..... + ......AAAA...... + ................ +} +# tile 444 (cobra,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAAA....... + ..PA..AAAA...... + ..A..AAAAA..AA.. + ..D..AAAAA....A. + ......AAA.....A. + ......AA..AAAA.. + .....AA..AA..... + ....AA...AA..... + ....AA....AAAA.. + ....AAA......AA. + .....AAAAAAAAA.. + ................ +} +# tile 445 (cobra,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAAAAA....... + ..PA..AAAA...... + ..A..AAAAA..AA.. + ..D..AAAAA....A. + ......AAA.....A. + ......AA..AAAA.. + .....AA..AA..... + ....AA...AA..... + ....AA....AAAA.. + ....AAA......AA. + .....AAAAAAAAA.. + ................ +} +# tile 446 (troll,male) +{ + ................ + ..AAAAAA........ + AAAANANA........ + .AAKKKJJA....... + AAAKAAAKA....... + AKAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAFGFJJAAAA.. + ..KJA.PFJAAAA... + ...AFAGFAAAAAA.. + ...GFAGP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 447 (troll,female) +{ + ................ + ..AAAAAA........ + AAAANANA........ + .AAKKKJJA....... + AAAKAAAKA....... + AKAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAFGFJJAAAA.. + ..KJA.PFJAAAA... + ...AFAGFAAAAAA.. + ...GFAGP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 448 (ice troll,male) +{ + ................ + ..OONOOO........ + NONOAOAOO....... + .NOKKKJJO....... + NOJKAAAKOO...... + OKJKAAAKAO...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 449 (ice troll,female) +{ + ................ + ..OONOOO........ + NONOAOAOO....... + .NOKKKJJO....... + NOJKAAAKOO...... + OKJKAAAKAO...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 450 (rock troll,male) +{ + ................ + ...AAAAA........ + .AAANANAAAA..... + .AAKKKJJAA...... + AAAKAAAKAAAA.... + AKAKAAAKAAA..... + KJJAKKKAJKAA.... + KJAJAAAJJJA..... + KJAPAKJJKJA..... + PKJPPAGFJJAAAA.. + PPPPPAFFJAAAA... + .PPPAAGFAAAAAA.. + ...AFAGF.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 451 (rock troll,female) +{ + ................ + ...AAAAA........ + .AAANANAAAA..... + .AAKKKJJAA...... + AAAKAAAKAAAA.... + AKAKAAAKAAA..... + KJJAKKKAJKAA.... + KJAJAAAJJJA..... + KJAPAKJJKJA..... + PKJPPAGFJJAAAA.. + PPPPPAFFJAAAA... + .PPPAAGFAAAAAA.. + ...AFAGF.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 452 (water troll,male) +{ + ................ + ...AAAAA........ + ..AANANAA....... + .AAKKKJJAA...... + .AAKAAAKAA...... + .KAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 453 (water troll,female) +{ + ................ + ...AAAAA........ + ..AANANAA....... + .AAKKKJJAA...... + .AAKAAAKAA...... + .KAKAAAKAA...... + KJJAKKKAJKA..... + KJAJAAAJJJA..... + KJAJKKJJKJA..... + .KJJAEBEJJAAAA.. + ..KJA.PEJAAAA... + ...AEABEAAAAAA.. + ...BEABP.AA.AA.. + ..KJJAKJAA.AA... + ..KJA..KA....... + ................ +} +# tile 454 (Olog-hai,male) +{ + ...PPPPP........ + ..PPAAAPP....... + ..PANANAP....... + ..PAAAAAP....... + .PPAAAAAPP...... + PPPAAAAAPPP..... + AAPPAAAPPAA..... + AAAPPPPPAAA..... + AAAPPPPPAAA..... + .AAAAPPPAAAPPP.. + PONNNNNNAACPP... + ...APAPPAPPPPP.. + ...PPAPP.PP.PP.. + ..AAAAAAAP.PP... + ..AAA.AAA....... + ................ +} +# tile 455 (Olog-hai,female) +{ + ...PPPPP........ + ..PPAAAPP....... + ..PANANAP....... + ..PAAAAAP....... + .PPAAAAAPP...... + PPPAAAAAPPP..... + AAPPAAAPPAA..... + AAAPPPPPAAA..... + AAAPPPPPAAA..... + .AAAAPPPAAAPPP.. + PONNNNNNAACPP... + ...APAPPAPPPPP.. + ...PPAPP.PP.PP.. + ..AAAAAAAP.PP... + ..AAA.AAA....... + ................ +} +# tile 456 (umber hulk,male) +{ + ................ + ...AAAAA........ + ..AAAAAAA....... + .ADADADADA...... + .AAAAAAAAA.A.... + .AAAOAOAAA.AA... + .A.AOAOA.AAA.... + .A.AAAAAPAA..... + .AAAAAAAP....... + .A.AAAAA.PPPPPP. + ...AA.AA.PPPPP.. + ...AA.AAPPPPPPP. + ...AAPAAPPPP.... + ..AAAPAAAPP..... + .AAAP..AAP...... + ................ +} +# tile 457 (umber hulk,female) +{ + ................ + ...AAAAA........ + ..AAAAAAA....... + .ADADADADA...... + .AAAAAAAAA.A.... + .AAAOAOAAA.AA... + .A.AOAOA.AAA.... + .A.AAAAAPAA..... + .AAAAAAAP....... + .A.AAAAA.PPPPPP. + ...AA.AA.PPPPP.. + ...AA.AAPPPPPPP. + ...AAPAAPPPP.... + ..AAAPAAAPP..... + .AAAP..AAP...... + ................ +} +# tile 458 (vampire,male) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAAAAAAA...... + ..AAAAAAAA...... + ...AAAAAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 459 (vampire,female) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAAAAAAA...... + ..AAAAAAAA...... + ...AAAAAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 460 (vampire leader,male) +{ + ................ + .....AAAA....... + .N..AAOOAA...... + .NDDAGAAGADA.... + .NADALLLOAD..... + AAAAAAAAAAA..... + AAAAAAAAAAA..... + .AAAAAAAAAA..... + .NAAAAAAAAA..... + .N.AAAAAAAAPPPPP + .NADAAAAAAAPPPPP + .NADDAAAAAAPPPP. + .NAAAAAAAAAPPP.. + .N...AAAPAAPP... + .N..AAPP..AP.... + ................ +} +# tile 461 (vampire leader,female) +{ + ................ + .....AAAA....... + .N..AAOOAA...... + .NDDAGAAGADA.... + .NADALLLOAD..... + AAAAAAAAAAA..... + AAAAAAAAAAA..... + .AAAAAAAAAA..... + .NAAAAAAAAA..... + .N.AAAAAAAAPPPPP + .NADAAAAAAAPPPPP + .NADDAAAAAAPPPP. + .NAAAAAAAAAPPP.. + .N...AAAPAAPP... + .N..AAPP..AP.... + ................ +} +# tile 462 (vampire mage,male) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAA.A.AA...... + ..AAAACAAA...... + ...AAADAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 463 (vampire mage,female) +{ + ................ + ................ + .....AAA........ + ....AAOAA....... + .ADDAGAGADA..... + ..ADALLOAD...... + .AAAA.A.AA...... + ..AAAACAAA...... + ...AAADAAA...... + ..ADAAAAAAPPPPP. + ..ADDAAAAAPPPP.. + ..AAAAAAAAPPP... + .....AAPAAPP.... + ....AAP..AP..... + ................ + ................ +} +# tile 464 (Vlad the Impaler,male) +{ + ................ + ..N..AAAA....... + ADNDAAOOAADDDA.. + .ANDAGAAGADDA... + ..NDALLLOADA.... + ..NAAAAAAAAAAAAA + .HHHDAAAAADDDDDA + HEHEHJAAAADDDAA. + LLLLLJAAAADDAAPP + .LLLJAAAAADDAPPP + ..NJDAAAAADAPPPP + .ANDDAAAAAAAPPPP + .ANAAAAAAAAPPPP. + ..N..AAAPAAPPP.. + ..N.AAPP..AP.... + ................ +} +# tile 465 (Vlad the Impaler,female) +{ + ................ + ..N..AAAA....... + ADNDAAOOAADDDA.. + .ANDAGAAGADDA... + ..NDALLLOADA.... + ..NAAAAAAAAAAAAA + .HHHDAAAAADDDDDA + HEHEHJAAAADDDAA. + LLLLLJAAAADDAAPP + .LLLJAAAAADDAPPP + ..NJDAAAAADAPPPP + .ANDDAAAAAAAPPPP + .ANAAAAAAAAPPPP. + ..N..AAAPAAPPP.. + ..N.AAPP..AP.... + ................ +} +# tile 466 (barrow wight,male) +{ + ................ + ................ + ...LLO.......... + ..DLDLO......... + ..LLLLO......... + ..LJL..P........ + ..OOO.PP...AAAA. + ..POO.PP.AAAAAA. + .LPOO.PP.PAAAA.. + .JJOO.PP.PAAAA.. + .J.O..PL.PPAAA.. + .J.O.PPPPPPAAA.. + .J...PPPPPPPAA.. + .J..LLPPPPPPA... + .J.....LLAA..... + ................ +} +# tile 467 (barrow wight,female) +{ + ................ + .......OOOOO..... + ..OOOOOOO....... + .ODLDLOO.OOO.... + .OLLLLOOOOOOO... + .OLJLLOPOO...... + .OPLLL.POOOAAAA. + ..PPP.PP.AAAAAA. + .LPPPPPP.PAAAA.. + .JJ.PPPP.PAAAA.. + .J...PPL.PPAAA.. + .J...PPPPPPAAA.. + .J...PPPPPPPAA.. + .J..LLPPPPPPA... + .J.....LLAA..... + ................ +} +# tile 468 (wraith,male) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + ..AAPPPPAP..AAA. + ..PPPPPOLPAAAAA. + ...A.PPAAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ + ................ + ................ +} +# tile 469 (wraith,female) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + ..AAPPPPAP..AAA. + ..PPPPPOLPAAAAA. + ...A.PPAAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ + ................ + ................ +} +# tile 470 (Nazgul,male) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + .OPAPPPPAP..AAA. + ..PAPPPPAP..AAA. + ..PA.PPPLP..AAA. + ..PP.PPOLPAAAAA. + ...AAPPOAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ +} +# tile 471 (Nazgul,female) +{ + ................ + ................ + ...PPPPP........ + ...PAAPPP....... + ....PAAPP....... + ....PAAPP....... + ..PP.PPP.P...... + .OLAPPP.PP...... + .OPAPPPPAP..AAA. + ..PAPPPPAP..AAA. + ..PA.PPPLP..AAA. + ..PP.PPOLPAAAAA. + ...AAPPOAAAPPA.. + .....PPAPPPPA... + ......PPPPA..... + ................ +} +# tile 472 (xorn,male) +{ + ................ + ................ + ................ + ...OB.OP.BP..... + ...BBBBPPPP..... + ...B............ + ...DDBB.BDDA.A.. + ...DDBB.PDDAAAA. + ...B.......AAAA. + ...BOB.BPP.AAAA. + ...BBB.PPP.AAAA. + ...B.......AAA.. + ...BOBBPPBPAA... + ...BO.BP.PPA.... + ................ + ................ +} +# tile 473 (xorn,female) +{ + ................ + ................ + ................ + ...OB.OP.BP..... + ...BBBBPPPP..... + ...B............ + ...DDBB.BDDA.A.. + ...DDBB.PDDAAAA. + ...B.......AAAA. + ...BOB.BPP.AAAA. + ...BBB.PPP.AAAA. + ...B.......AAA.. + ...BOBBPPBPAA... + ...BO.BP.PPA.... + ................ + ................ +} +# tile 474 (monkey,male) +{ + ................ + ................ + ................ + ................ + ................ + .......KKA...... + ......KLLJA..... + ......KLLJA..... + .......KJA...... + .....KKKKKJAA... + ....KJKLLJJJAA.. + ....LAKLLJALAA.. + ......KJJJAAAA.. + ......JAAJAAA... + .....JJA.JJA.... + ................ +} +# tile 475 (monkey,female) +{ + ................ + ................ + ................ + ................ + ................ + .......KKA...... + ......KLLJA..... + ......KLLJA..... + .......KJA...... + .....KKKKKJAA... + ....KJKLLJJJAA.. + ....LAKLLJALAA.. + ......KJJJAAAA.. + ......JAAJAAA... + .....JJA.JJA.... + ................ +} +# tile 476 (ape,male) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCLACCAJJAAA + ..KKKKCCCAJKJJAA + ..KKAKJAAJJAJJAA + ..KAAKJJJJJAAJAA + ..LC.KJJJJJKCLAA + ..LL.CJJAKLJLLAA + .....CLJACLJAAAA + ...LLLLJACLLLKA. + ................ + ................ +} +# tile 477 (ape,female) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCLACCAJJAAA + ..KKKKCCCAJKJJAA + ..KKAKJAAJJAJJAA + ..KAAKJJJJJAAJAA + ..LC.KJJJJJKCLAA + ..LL.CJJAKLJLLAA + .....CLJACLJAAAA + ...LLLLJACLLLKA. + ................ + ................ +} +# tile 478 (owlbear,male) +{ + ................ + ....K.....K..... + ....CK...KK..... + ....CKKKKKK..... + ...KOOOKOOOK.... + ...KOOOKOOOKA..A + ...KOOAJAOOKAAAA + ..CKCJJHJJKAKAAA + .CKKKCKLKKAJJKAA + .KJJJJCKKJJJJJAA + .KJJJPAKJPJJJJAA + ..KJJJAKJJJJJAAA + ...JJPAKJPJJAAA. + ...JAAJAJAAJAA.. + ...PJPJAJPJPA... + ................ +} +# tile 479 (owlbear,female) +{ + ................ + ....K.....K..... + ....CK...KK..... + ....CKKKKKK..... + ...KOOOKOOOK.... + ...KOOOKOOOKA..A + ...KOOAJAOOKAAAA + ..CKCJJHJJKAKAAA + .CKKKCKLKKAJJKAA + .KJJJJCKKJJJJJAA + .KJJJPAKJPJJJJAA + ..KJJJAKJJJJJAAA + ...JJPAKJPJJAAA. + ...JAAJAJAAJAA.. + ...PJPJAJPJPA... + ................ +} +# tile 480 (yeti,male) +{ + ................ + ....BNNN........ + ...BNANAP....... + ..BNNNNNNP...... + ..NNNADANN...... + ..NNNNNNPN...... + ..N.NNBPPNP..... + ..N.NNNNANP..AA. + ..NNBNNNPN.AAAA. + ....NNNNP.KAAA.. + ....NN.NPAKKAA.. + ....NB.NPAACKAA. + ....NNANPAAKKJA. + ...BNNANNPAACKA. + ..BNNA..NNA..... + ................ +} +# tile 481 (yeti,female) +{ + ................ + ....BNNN........ + ...BNANAP....... + ..BNNNNNNP...... + ..NNNADANN...... + ..NNNNNNPN...... + ..N.NNBPPNP..... + ..N.NNNNANP..AA. + ..NNBNNNPN.AAAA. + ....NNNNP.KAAA.. + ....NN.NPAKKAA.. + ....NB.NPAACKAA. + ....NNANPAAKKJA. + ...BNNANNPAACKA. + ..BNNA..NNA..... + ................ +} +# tile 482 (carnivorous ape,male) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCAAACAJJAAA + ..KKKCDDDCAKJJAA + ..KKAKCCCAJAJJAA + ..KAAKJAAJJAAJAA + ..LC.AJJJJJKCLAA + ..LLDDAJAKLJLLAA + ...DDALJACLJAAAA + ..DDALLJACLLLKA. + ................ + ................ +} +# tile 483 (carnivorous ape,female) +{ + ................ + ................ + ......KKKJ...... + .....JJJJJJ..... + ....KCELECJJ.AA. + ....KLLLLCAJAAAA + ...KKCAAACAJJAAA + ..KKKCDDDCAKJJAA + ..KKAKCCCAJAJJAA + ..KAAKJAAJJAAJAA + ..LC.AJJJJJKCLAA + ..LLDDAJAKLJLLAA + ...DDALJACLJAAAA + ..DDALLJACLLLKA. + ................ + ................ +} +# tile 484 (sasquatch,male) +{ + ................ + ....CCCCC....... + ...CGAJGAJ...... + ..CKKKKJJJ...... + ..CKKAAAKJJ..... + .CKKKAAAKKJ..... + .CKJKKKKKKKJ.... + .CKAJJJJJAKJ.... + .CKAJKKKJAKJ.AA. + .CKJAJKJACKJAAAA + .CKJAJJJACKJAAA. + ..J.AJAKKAJAAAAA + ...CKJAKKJAAAAA. + .KCKJJACKJKJAA.. + .CJJJKACKJJKA... + ................ +} +# tile 485 (sasquatch,female) +{ + ................ + ....CCCCC....... + ...CGAJGAJ...... + ..CKKKKJJJ...... + ..CKKAAAKJJ..... + .CKKKAAAKKJ..... + .CKJKKKKKKKJ.... + .CKAJJJJJAKJ.... + .CKAJKKKJAKJ.AA. + .CKJAJKJACKJAAAA + .CKJAJJJACKJAAA. + ..J.AJAKKAJAAAAA + ...CKJAKKJAAAAA. + .KCKJJACKJKJAA.. + .CJJJKACKJJKA... + ................ +} +# tile 486 (kobold zombie,male) +{ + ................ + ................ + ................ + ...N...N........ + ...NGFBN........ + ...GABAB........ + ....GBFA..A..... + ...GBABFA.AA.... + ..GFBBBIKAAA.A.. + ..BAFBFFEAAAAA.. + ..BAFBFFAAAAAA.. + ....FBFAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 487 (kobold zombie,female) +{ + ................ + ................ + ................ + ...N...N........ + ...NGFBN........ + ...GABAB........ + ....GBFA..A..... + ...GBABFA.AA.... + ..GFBBBIKAAA.A.. + ..BAFBFFEAAAAA.. + ..BAFBFFAAAAAA.. + ....FBFAAAAAA... + ....BABAAAA..... + ...BBABBA....... + ................ + ................ +} +# tile 488 (gnome zombie,male) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GDFDF....... + .....PFP...AAA.. + ...FGFPFEGAAAA.. + ..GAAGFFFAGAAA.. + ....AKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 489 (gnome zombie,female) +{ + ................ + ................ + ................ + ................ + ......G......... + .....GFF........ + ....GGFFF....... + ....GDFDF....... + .....GFF...AAA.. + ...FGFFFEGAAAA.. + ..GAAGFFFAGAAA.. + ....AKNKFAAAA... + ....FGAFFAA..... + ....GFAFG.A..... + ................ + ................ +} +# tile 490 (orc zombie,male) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....GPGA........ + .....PFA........ + ..KCCAKKKA.AA... + .BBPCKJ.BBAAA... + BB.AGGFAABBA.... + B..AJJPAAABA.... + ....BAPPPAAAAA.. + ...BJAAEPAAA.... + ..BPPAAAPP...... + ................ + ................ +} +# tile 491 (orc zombie,female) +{ + ................ + ................ + ................ + .....OA......... + ....NOPA........ + ....GPGA........ + .....PFA........ + ..KCCAKKKA.AA... + .BBPCKJ.BBAAA... + BB.AGGFAABBA.... + B..AJJPAAABA.... + ....BAPPPAAAAA.. + ...BJAAEPAAA.... + ..BPPAAAPP...... + ................ + ................ +} +# tile 492 (dwarf zombie,male) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BFFFE....... + .....PFP...AAA.. + ...BBPPPEEAAAA.. + ..FBABPEAEAAAA.. + ..F.EBBEFAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 493 (dwarf zombie,female) +{ + ................ + ................ + ................ + ................ + ......B......... + .....BEE........ + ....BBEEE....... + ....BFFFE....... + .....PFP...AAA.. + ...BBPPPEEAAAA.. + ..FBABPEAEAAAA.. + ..F.EBBEFAAAA... + ....EBAEEAA..... + ....BEAEB.A..... + ................ + ................ +} +# tile 494 (elf zombie,male) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......FEFEA..... + ......FFFFA..... + ......AFDA....A. + ......GAAG..AAA. + ....FFGGGFFFAAA. + ...FAAAGFAAAFAA. + .....AGGGFAAAA.. + ......GFAFAA.A.. + .....KDA.FKA.... + ................ + ................ +} +# tile 495 (elf zombie,female) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......FEFEA..... + ......FFFFA..... + ......AFDA....A. + ......GAAG..AAA. + ....FFGGGFFFAAA. + ...FAAAGFAAAFAA. + .....AGGGFAAAA.. + ......GFAFAA.A.. + .....KDA.FKA.... + ................ + ................ +} +# tile 496 (human zombie,male) +{ + ......AAA....... + .....FFGAA...... + .....AGAFA...... + .....FFGFA...... + ....FKF..JJ..... + ....JJJFJKJ..... + ...FJ.KJJAKJ.... + ..FK..KFJFFJ.... + ..G...KKJG...... + .....BP.BPAAAAA. + .....FPAPFAAAA.. + .....BFABFAAAA.. + .....PFABPAA.... + .....BFABFA..... + ....GGAGGA...... + ................ +} +# tile 497 (human zombie,female) +{ + ......AAA....... + .....FFGAA...... + .....AGAFA...... + .....FFGFA...... + ....FKF..JJ..... + ....JJJFJKJ..... + ...FJ.KJJAKJ.... + ..FK..KFJFFJ.... + ..G...KKJG...... + .....BP.BPAAAAA. + .....FPAPFAAAA.. + .....BFABFAAAA.. + .....PFABPAA.... + .....BFABFA..... + ....GGAGGA...... + ................ +} +# tile 498 (ettin zombie,male) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NFF..NFF..P... + ..ADFFDADFFDA... + ..AFFFFAFFFFA... + ..AFAAFAFAAFAA.. + ..AFFFFAFFFFAAA. + ..GIIIIJJJIIIGAA + .GFFFIIIIIIFFFGA + .GFFFFIIIIFFFFFA + .FFAAFIIIIFAAFFA + .FFAAIIIIIIAAFFA + .FFF.IIFFIIAGFAA + ..FF.GFAAGFAFFAA + .....GFAAGFAAAAA + ...FFFFA.GFFFFAA +} +# tile 499 (ettin zombie,female) +{ + ....NN..ONOP.... + ..NNOOPNNOOPP... + ..NFF..NFF..P... + ..ADFFDADFFDA... + ..AFFFFAFFFFA... + ..AFAAFAFAAFAA.. + ..AFFFFAFFFFAAA. + ..GIIIIJJJIIIGAA + .GFFFIIIIIIFFFGA + .GFFFFIIIIFFFFFA + .FFAAFIIIIFAAFFA + .FFAAIIIIIIAAFFA + .FFF.IIFFIIAGFAA + ..FF.GFAAGFAFFAA + .....GFAAGFAAAAA + ...FFFFA.GFFFFAA +} +# tile 500 (ghoul,male) +{ + ......AAA....... + .....OOOAA...... + .....DODOA...... + .....OOOOA...... + ....PPOOOPP..... + ....PPPPPPP..... + ...PP.PPPAPP.... + ..PP..PPPOOP.... + ..O...PPPO...... + .....PP.PPAAAAA. + .....PPAPPAAAA.. + .....PPAPPAAAA.. + .....PPAPPAA.... + .....PPAPPA..... + ....OOAOOA...... + ................ +} +# tile 501 (ghoul,female) +{ + ......AAA....... + .....OOOAA...... + .....DODOA...... + .....OOOOA...... + ....PPOOOPP..... + ....PPPPPPP..... + ...PP.PPPAPP.... + ..PP..PPPOOP.... + ..O...PPPO...... + .....PP.PPAAAAA. + .....PPAPPAAAA.. + .....PPAPPAAAA.. + .....PPAPPAA.... + .....PPAPPA..... + ....OOAOOA...... + ................ +} +# tile 502 (giant zombie,male) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJFFFFJJA... + ....JDDFFDDJA... + ....JFFFFFFJA... + ....AFFAAFFAAA.. + .....AFFFFJAAAA. + ..GGFFJJJJFFGGAA + .GFFFGGFFFFFFFCA + .FFFKFFFFFFKFFFA + FFFAAFFFFFFAAFFA + FFAA.JJJKKJAAFFA + FFA..JJJJJKAGFAA + .....GFAGFFAFFAA + ....GFFAGFFAAAAA + ...GFFAAGFFFAAAA +} +# tile 503 (giant zombie,female) +{ + ......JJJJAA.... + ....JJJJJJJJA... + ....JJFFFFJJA... + ....JDDFFDDJA... + ....JFFFFFFJA... + ....AFFAAFFAAA.. + .....AFFFFJAAAA. + ..GGFFJJJJFFGGAA + .GFFFGGFFFFFFFCA + .FFFKFFFFFFKFFFA + FFFAAFFFFFFAAFFA + FFAA.JJJKKJAAFFA + FFA..JJJJJKAGFAA + .....GFAGFFAFFAA + ....GFFAGFFAAAAA + ...GFFAAGFFFAAAA +} +# tile 504 (skeleton,male) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + ......O......... + ....OOOOO...AAA. + ...OA.OOOA..AAA. + ..OA.OAAO.AAAAA. + ....OA.OOOAAA.A. + ......OOOAAA.A.. + .....O.AO.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 505 (skeleton,female) +{ + ................ + ................ + ...OOO.......... + ..AOAOO......... + ..OOOOO......... + ..OO.O.......... + ......O......... + ....OOOOO...AAA. + ...OA.OOOA..AAA. + ..OA.OAAO.AAAAA. + ....OA.OOOAAA.A. + ......OOOAAA.A.. + .....O.AO.A..... + ...OOOA.OA...... + ......OOO....... + ................ +} +# tile 506 (straw golem,male) +{ + ......LJ........ + ......LJHJ...... + ....HJLJH...A... + ....AAAAAL.....A + ....DAADAL.A.AA. + ....LJHJL..AAAA. + ....LLHJLHHCHHL. + ...HHLJL.AJLJL.A + .HHJJLLLLAAA.AA. + ..JL..LALHAAAAAA + .LL..CJLHJHAAAAA + .....HJLAHJHAAA. + .....HJAACALHAAA + ....CJLAAJHALHA. + ....HALA.AHAAL.. + ..........L..... +} +# tile 507 (straw golem,female) +{ + ......LJ........ + ......LJHJ...... + ....HJLJH...A... + ....AAAAAL.....A + ....DAADAL.A.AA. + ....LJHJL..AAAA. + ....LLHJLHHCHHL. + ...HHLJL.AJLJL.A + .HHJJLLLLAAA.AA. + ..JL..LALHAAAAAA + .LL..CJLHJHAAAAA + .....HJLAHJHAAA. + .....HJAACALHAAA + ....CJLAAJHALHA. + ....HALA.AHAAL.. + ..........L..... +} +# tile 508 (paper golem,male) +{ + ................ + .......OA....... + .....NNNOA...... + .....ONNNOA..... + ......ONNOA..... + .......NOA...... + ..NNOA.NOA...... + ..NONOAOAONNOA.. + ..OAOANNOAOOOA.. + ......NNNOAAAAA. + ......ONOAAAAAA. + .......OOAAAAAA. + .....NOAAOAAAAA. + .....NOA..NOAA.. + ....OOA...OOA... + ................ +} +# tile 509 (paper golem,female) +{ + ................ + .......OA....... + .....NNNOA...... + .....ONNNOA..... + ......ONNOA..... + .......NOA...... + ..NNOA.NOA...... + ..NONOAOAONNOA.. + ..OAOANNOAOOOA.. + ......NNNOAAAAA. + ......ONOAAAAAA. + .......OOAAAAAA. + .....NOAAOAAAAA. + .....NOA..NOAA.. + ....OOA...OOA... + ................ +} +# tile 510 (rope golem,male) +{ + ................ + ................ + ......OOO....... + .....O...O...... + .....O...O...AA. + .OO...O..O..A..A + O..O...LL..OO..A + ...O...LOOO.AOA. + ....OOOOOAAAAO.. + .......OO..AA.A. + .......LO.AA...A + ......O..OOAA..A + ....OO..A..O.A.. + ...O..AA...O.A.. + ...O.A....OAA... + ....OA.......... +} +# tile 511 (rope golem,female) +{ + ................ + ................ + ......OOO....... + .....O...O...... + .....O...O...AA. + .OO...O..O..A..A + O..O...LL..OO..A + ...O...LOOO.AOA. + ....OOOOOAAAAO.. + .......OO..AA.A. + .......LO.AA...A + ......O..OOAA..A + ....OO..A..O.A.. + ...O..AA...O.A.. + ...O.A....OAA... + ....OA.......... +} +# tile 512 (gold golem,male) +{ + ................ + ......HNH....... + ......DND...N... + ......HNH...JC.. + ......HNH...NC.. + ...HHHAAAAHANC.. + ..HNJNHNHNJNAC.A + ..HHHHHHHHHHHA.A + .NCACCCCCCCCA..A + .HH.AAAAAAAAA.AA + .NH.ANC.AHNC.AAA + .NJ.AHC.AHHC.AAA + ..H.ANC.AHNC.AAA + ....HJC.AHJC.AA. + H...HNC.AHNC.A.H + ..H............. +} +# tile 513 (gold golem,female) +{ + ................ + ......HNH....... + ......DND...N... + ......HNH...JC.. + ......HNH...NC.. + ...HHHAAAAHANC.. + ..HNJNHNHNJNAC.A + ..HHHHHHHHHHHA.A + .NCACCCCCCCCA..A + .HH.AAAAAAAAA.AA + .NH.ANC.AHNC.AAA + .NJ.AHC.AHHC.AAA + ..H.ANC.AHNC.AAA + ....HJC.AHJC.AA. + H...HNC.AHNC.A.H + ..H............. +} +# tile 514 (leather golem,male) +{ + ......KKKK...... + .....KHKHJ...... + ....KAKKJJA..... + ...KKAJJJJAJ.... + ..KKJJAJAAKJJ... + .KKKJJAAKKKJJJ.. + ..KKJJJAKKJJJJ.. + ...KKJJJA.AAA.A. + ....AAAA.KJAAAA. + ....KJAAAKKAAAAA + ...KJJAA.KJJAAA. + ...KKJA..KKJAAA. + ..KKJJJAKKJJJAA. + ..KKKJJAKKKJJA.. + ...KJJA..KJJA... + ....KA....KA.... +} +# tile 515 (leather golem,female) +{ + ......KKKK...... + .....KHKHJ...... + ....KAKKJJA..... + ...KKAJJJJAJ.... + ..KKJJAJAAKJJ... + .KKKJJAAKKKJJJ.. + ..KKJJJAKKJJJJ.. + ...KKJJJA.AAA.A. + ....AAAA.KJAAAA. + ....KJAAAKKAAAAA + ...KJJAA.KJJAAA. + ...KKJA..KKJAAA. + ..KKJJJAKKJJJAA. + ..KKKJJAKKKJJA.. + ...KJJA..KJJA... + ....KA....KA.... +} +# tile 516 (wood golem,male) +{ + ................ + ......KCKJ...... + ......HCHJ..C... + ......KCKJ..CK.. + ......KCKJ..CKJ. + ...KKKAAAAKACKJ. + ..KCCCCCCCCCAKJA + ..KKKKKKKKKKKAJA + .CJAJJJJJJJJA..A + .CKJAAAAAAAAA.AA + .CKJACKJAKCKJAAA + .CKJACKJAKCKJAAA + ..KJACKJAKCKJAAA + ....KCKJAKCKJAA. + ....KCKJAKCKJA.. + ................ +} +# tile 517 (wood golem,female) +{ + ................ + ......KCKJ...... + ......HCHJ..C... + ......KCKJ..CK.. + ......KCKJ..CKJ. + ...KKKAAAAKACKJ. + ..KCCCCCCCCCAKJA + ..KKKKKKKKKKKAJA + .CJAJJJJJJJJA..A + .CKJAAAAAAAAA.AA + .CKJACKJAKCKJAAA + .CKJACKJAKCKJAAA + ..KJACKJAKCKJAAA + ....KCKJAKCKJAA. + ....KCKJAKCKJA.. + ................ +} +# tile 518 (flesh golem,male) +{ + ................ + ................ + ...D..DDC....... + .....DLDDL...... + ..DD..LLLLC.D... + ...CDL.LLLLADL.. + ..CLDLA.CLLA.LL. + ..LLLAA.LLCA..L. + .CLLAA.CLLAA..CA + .LLA..CLLALLAAAA + ..LA.CLCAALCAAAA + ...A..LLCACLCAAA + ....LLALLAALLAAA + ..CLLLAAAADLLA.. + ..LLDDD..DDDDD.. + ................ +} +# tile 519 (flesh golem,female) +{ + ................ + ................ + ...D..DDC....... + .....DLDDL...... + ..DD..LLLLC.D... + ...CDL.LLLLADL.. + ..CLDLA.CLLA.LL. + ..LLLAA.LLCA..L. + .CLLAA.CLLAA..CA + .LLA..CLLALLAAAA + ..LA.CLCAALCAAAA + ...A..LLCACLCAAA + ....LLALLAALLAAA + ..CLLLAAAADLLA.. + ..LLDDD..DDDDD.. + ................ +} +# tile 520 (clay golem,male) +{ + ................ + ................ + ................ + ....LCCCCK...... + ...LKKKKKKK..... + ...CKAKKAKK..... + ...CKAKKAKK..... + .LCKKKKKKKKLC... + CKKJKKKKKKCKKJ.. + KKKJKKJJKKJKKJAA + .JJAKKJAKKAJJAAA + ..AKKKJAKKKAAAAA + ..CKKKKKKKKKAAAA + ..CKKKAACKKKAA.. + ..CKKKA.CKKKAA.. + ................ +} +# tile 521 (clay golem,female) +{ + ................ + ................ + ................ + ....LCCCCK...... + ...LKKKKKKK..... + ...CKAKKAKK..... + ...CKAKKAKK..... + .LCKKKKKKKKLC... + CKKJKKKKKKCKKJ.. + KKKJKKJJKKJKKJAA + .JJAKKJAKKAJJAAA + ..AKKKJAKKKAAAAA + ..CKKKKKKKKKAAAA + ..CKKKAACKKKAA.. + ..CKKKA.CKKKAA.. + ................ +} +# tile 522 (stone golem,male) +{ + ................ + ................ + ................ + ....BBBPP....... + ...BBPPPPP...... + ...BHAPHAP...... + ...PPPPPPP...... + .BBPPPPPP.BPA... + BPPPP....PPPPAA. + BPP.BPPPP.PPPAAA + .PP.BP.PP.PPPAAA + ...BPP.PPPAAAAAA + ..BPPPAPPPAAAAA. + ..PPPPAPPPPAAA.. + ...PPAA.PPPA.... + ................ +} +# tile 523 (stone golem,female) +{ + ................ + ................ + ................ + ....BBBPP....... + ...BBPPPPP...... + ...BHAPHAP...... + ...PPPPPPP...... + .BBPPPPPP.BPA... + BPPPP....PPPPAA. + BPP.BPPPP.PPPAAA + .PP.BP.PP.PPPAAA + ...BPP.PPPAAAAAA + ..BPPPAPPPAAAAA. + ..PPPPAPPPPAAA.. + ...PPAA.PPPA.... + ................ +} +# tile 524 (glass golem,male) +{ + ................ + .....BBBBBBA.... + .....BPNPPPA.... + .....BNPPPNA.... + .....NPPPNPA.... + .....BPPNPPA.... + .......BA...BA.. + .BNBBABPBA.BPNA. + .NPPNABPNBBANPBA + .....BPNPPPAABAA + .....BNPPPAAAAAA + ......BPPNAAAAAA + ....BNABNABPAAA. + ...BNPA...BNAAA. + ..BNPA....NPAA.. + ...BA.....BPA... +} +# tile 525 (glass golem,female) +{ + ................ + .....BBBBBBA.... + .....BPNPPPA.... + .....BNPPPNA.... + .....NPPPNPA.... + .....BPPNPPA.... + .......BA...BA.. + .BNBBABPBA.BPNA. + .NPPNABPNBBANPBA + .....BPNPPPAABAA + .....BNPPPAAAAAA + ......BPPNAAAAAA + ....BNABNABPAAA. + ...BNPA...BNAAA. + ..BNPA....NPAA.. + ...BA.....BPA... +} +# tile 526 (iron golem,male) +{ + ................ + ......PBP....... + ......HBH...B... + ......PBP...JP.. + ......PBP...BP.. + ...PPPAAAAPABP.. + ..PBJBBBBBJBAP.A + ..PPPPPPPPPPPA.A + .B.A........A..A + .BP.AAAAAAAAA.AA + .BP.ABP.APBP.AAA + .BJ.ABP.APBP.AAA + ..P.ABP.APBP.AAA + ....PJP.APJP.AA. + ....PBP.APBP.A.. + ................ +} +# tile 527 (iron golem,female) +{ + ................ + ......PBP....... + ......HBH...B... + ......PBP...JP.. + ......PBP...BP.. + ...PPPAAAAPABP.. + ..PBJBBBBBJBAP.A + ..PPPPPPPPPPPA.A + .B.A........A..A + .BP.AAAAAAAAA.AA + .BP.ABP.APBP.AAA + .BJ.ABP.APBP.AAA + ..P.ABP.APBP.AAA + ....PJP.APJP.AA. + ....PBP.APBP.A.. + ................ +} +# tile 528 (human,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......ELELA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 529 (human,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......ELELA..... + ......LLLLA..... + ......ALLA...... + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 530 (wererat,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......GJGJA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 531 (wererat,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......GJGJA..... + ......LLLLA..... + ......ALLA...... + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 532 (werejackal,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......IPIPA..... + ......LLLLA..... + ......ALLA...... + .....CLAALC.AAA. + ....CLLLLLLCAAA. + ....LACLLCALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 533 (werejackal,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + ......IPIPA..... + ......LLLLA..... + ......ALLA...... + .....CJAAJC.AAA. + ....CLJLLJLCAAA. + ....LAKJJJALAAA. + ....LAJJKJALAAA. + ......JJJKAAAA.. + ......JJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 534 (werewolf,male) +{ + ................ + ................ + ......JJA....... + .....JJJJA...... + .....NJNJA...... + .....LLLLA...... + .....ALLA....... + ....CLAALC.AAA.. + ...CLLLLLLCAAA.. + ...LACLLCALAAA.. + ...LAJJKJALAAA.. + .....JJJKAAAA... + .....JJAJAA.A... + ....KLA.LKA..... + ................ + ................ +} +# tile 535 (werewolf,female) +{ + ................ + ................ + ......JJA....... + .....JJJJA...... + .....NJNJA...... + .....LLLLA...... + .....ALLA....... + ....CJAAJC.AAA.. + ...CLJLLJLCAAA.. + ...LAKJJJALAAA.. + ...LAJJKJALAAA.. + .....JJJKAAAA... + .....JJAJAA.A... + ....KLA.LKA..... + ................ + ................ +} +# tile 536 (elf,male) +{ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 537 (elf,female) +{ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 538 (Woodland-elf,male) +{ + ................ + ................ + .........K...... + .......KKJ...... + ......KKKKA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......KAAK..AAA. + .....LKKKJLAAAA. + ....LAPPJAALAAA. + ..KKLKKKKJALAA.. + ......PPAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 539 (Woodland-elf,female) +{ + ................ + ................ + .........K...... + .......KKJ...... + ......KKKKA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......KAAK..AAA. + .....LKKKJLAAAA. + ....LAPPJAALAAA. + ..KKLKKKKJALAA.. + ......PPAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 540 (Green-elf,male) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 541 (Green-elf,female) +{ + ................ + ................ + .........G...... + .......GGF...... + ......GGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......GAAG..AAA. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LAGGGFALAA.. + ......GFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 542 (Grey-elf,male) +{ + ................ + ................ + .........P...... + .......PP....... + ......PPPPA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......PAAP..AAA. + .....LPPP.LAAAA. + ....LAAP.AALAAA. + ....LAPPP.ALAA.. + ......P.A.AA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 543 (Grey-elf,female) +{ + ................ + ................ + .........P...... + .......PP....... + ......PPPPA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......PAAP..AAA. + .....LPPP.LAAAA. + ....LAAP.AALAAA. + ....LAPPP.ALAA.. + ......P.A.AA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 544 (elf-leader,male) +{ + ................ + ................ + ........II...... + .......HGF...... + ......HGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......HAAH..AAA. + .....LHHHFLAAAA. + ....LAAIIAALAAA. + ....LAHGGFALAA.. + ......HFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 545 (elf-leader,female) +{ + ................ + ................ + ........II...... + .......HGF...... + ......HGGGA..... + ......LELEA..... + ......LLLLA..... + ......ALLA....A. + ......HAAH..AAA. + .....LHHHFLAAAA. + ....LAAIIAALAAA. + ....LAHGGFALAA.. + ......HFAFAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 546 (elven monarch,male) +{ + ................ + ................ + ......H..H...... + ......HCHH...... + ......HHHHA..... + ......LELEA..... + ......LLLLA..... + .....IALLAI...A. + ....IIIAAIDIAAA. + .....LIIGDLAAAAA + ....LADIFDALAAAA + ....LAIIGDALAAA. + .....IIFAFDAAA.. + ...IIKLAILKDI... + ................ + ................ +} +# tile 547 (elven monarch,female) +{ + ................ + ......H..H...... + ......H..H...... + ......HCHH...... + ......HHHHA..... + ......LELEA..... + ......LLLLA..... + .....IALLAI...A. + ....IIIAAIDIAAA. + .....LIIGDLAAAAA + ....LADIFDALAAAA + ....LAIIGDALAAA. + .....IIFAFDAAA.. + ...IIKLAILKDI... + ................ + ................ +} +# tile 548 (doppelganger,male) +{ + ................ + ......CCCC..I... + ..I..CD...C..... + ....CD.HHA.C.... + ...CD.HHHHA.C.I. + ...CD.LFLFA.DC.. + .I.CD.LLLLA.DC.. + ...CD.ALLA.DC... + ..CD.LLAALL.ACA. + .CD.LLLLLLLLADC. + .CD.LALLLLALADC. + .CD.LAJJKJALADC. + ..CD..LJJLAAACA. + ...CD.LLALAACA.. + ..CD.LLAALLADC.. + ................ +} +# tile 549 (doppelganger,female) +{ + ................ + ......CCCC..I... + ..I..CD...C..... + ....CD.HHA.C.... + ...CD.HHHHA.C.I. + ...CD.LFLFA.DC.. + .I.CD.LLLLA.DC.. + ...CD.ALLA.DC... + ..CD.LLAALL.ACA. + .CD.LLLLLLLLADC. + .CD.LALLLLALADC. + .CD.LAJJKJALADC. + ..CD..LJJLAAACA. + ...CD.LLALAACA.. + ..CD.LLAALLADC.. + ................ +} +# tile 550 (shopkeeper,male) +{ + ................ + ................ + ......AAAA...... + .....AAAAAA..... + ......JLJL...... + ......LLLL...... + ......ALLA...... + .....EBAABEA.AA. + ....EBBBBBBEAAA. + ....BAEBBEABAAA. + ....LAGFFFALAAA. + ......GFAFAAAA.. + ......GFAFAA.A.. + .....JJA.JJA.... + ................ + ................ +} +# tile 551 (shopkeeper,female) +{ + ................ + ................ + ......AAAA...... + .....AAAAAA..... + ......JLJL...... + ......LLLL...... + ......ALLA...... + .....EBAABEA.AA. + ....EBBBBBBEAAA. + ....BAEBBEABAAA. + ....LAGFFFALAAA. + ......GFAFAAAA.. + ......GFAFAA.A.. + .....JJA.JJA.... + ................ + ................ +} +# tile 552 (guard,male) +{ + ................ + .....BBPPPAA.... + ....BNPPPPPPA... + ....BPPBPPPPA... + ....BAABPAAPA... + ....BCLBPCLPA... + ....AKCPPCJAAA.. + ....BKJJJJAPAAAA + ...BPKJAAJAPPAAA + ..BPPKJJJJAPPPAA + ..PPABKJJAPPAPPA + ..PPABPKAPPPAPPA + ..LC.BPPPPPPCLAA + ..LL.BPPABPPLLAA + .....BPPABPPAAAA + ....BPPP.BPPPAAA +} +# tile 553 (guard,female) +{ + ................ + .....BBPPPAA.... + ....BNPPPPPPA... + ....BPPBPPPPA... + ....BAABPAAPA... + ....BCLBPCLPA... + ....JCLPPCLJAA.. + ....BPLLLLAPAAAA + ...BPPLAALAPPAAA + ..BPPPPLLPPPPPAA + ..PPABPPPPPPAPPA + ..PPABPPPPPPAPPA + ..LC.BPPPPPPCLAA + ..LL.BPPABPPLLAA + .....BPPABPPAAAA + ....BPPP.BPPPAAA +} +# tile 554 (prisoner,male) +{ + ................ + ................ + .......NOA...... + .......LLA...... + .......LLA...... + .......NOA...... + ......NOONA..... + .....NOOOONA.... + ....NANOOOANAA.. + ....PANOOOAPAAA. + ....LANOOOALAAA. + ......NOOOAAAA.. + ......NAANAAA... + ......PAAPAA.... + .....LLA.LLA.... + ................ +} +# tile 555 (prisoner,female) +{ + ................ + ................ + .......NOA...... + .......LLA...... + .......LLA...... + .......NOA...... + ......NOONA..... + .....NOOOONA.... + ....NANOOOANAA.. + ....PANOOOAPAAA. + ....LANOOOALAAA. + ......NOOOAAAA.. + ......NAANAAA... + ......PAAPAA.... + .....LLA.LLA.... + ................ +} +# tile 556 (Oracle,male) +{ + ................ + ................ + .......NN....... + LLL...GLLG...LLL + ..L..NLLLLN..L.. + ...L.NLAALN.L... + ....LNLLLLNL.... + .....LNLLNL..AA. + .....NBBEEN.AAAA + ......BBEEAAAAAA + .LLA..BBBEAAALL. + .LLLLBBBEBELLLLA + ..LLCLBLLELLCLAA + ...CLLLLLLLCLAA. + ....LELLLLELAA.. + ................ +} +# tile 557 (Oracle,female) +{ + ................ + ................ + .......NN....... + LLL...GLLG...LLL + ..L..NLLLLN..L.. + ...L.NLAALN.L... + ....LNLLLLNL.... + .....LNLLNL..AA. + .....NBBEEN.AAAA + ......BBEEAAAAAA + .LLA..BBBEAAALL. + .LLLLBBBEBELLLLA + ..LLCLBLLELLCLAA + ...CLLLLLLLCLAA. + ....LELLLLELAA.. + ................ +} +# tile 558 (aligned priest,male) +{ + ................ + INI............. + III..KCCK....... + .J..KCCCCK...... + .J..CAAKCC...... + .LC.CAAACC...... + CLLC.CAACJKC.... + CJLACCCCJKCCC... + .JAACCJJCKCCCK.. + .JKCCCJCCJCCK.AA + .J..CCJCCLJCAAAA + .J..CCJCLLCAAAA. + .J..KCJCCCJAAAA. + .J.ACCJCCCJAAA.. + .JACCCJJCCCAA... + ................ +} +# tile 559 (aligned priest,female) +{ + ................ + INI............. + III..KCCK....... + .J..KCCCCK...... + .J..CAAKCC...... + .LC.CAAACC...... + CLLC.CAACJKC.... + CJLACCCCJKCCC... + .JAACCJJCKCCCK.. + .JKCCCJCCJCCK.AA + .J..CCJCCLJCAAAA + .J..CCJCLLCAAAA. + .J..KCJCCCJAAAA. + .J.ACCJCCCJAAA.. + .JACCCJJCCCAA... + ................ +} +# tile 560 (high priest,male) +{ + .INI............ + IIIII.KCCK...... + .IHI.KCAACK..... + ..H..CGAGAC..... + ..LC.CAAAAC..... + .CLLC.CAACJCK... + .CHLACCCCJCCCK.. + ..HAACCJJCCCCCK. + ..HCCCCJCCJCCC.A + ..H..CCJCCLJCAAA + ..H..CCJCLLCAAAA + ..H..KCJCCCJAAAA + ..H..KCJCCCJAAAA + ..H.ACCJCCCJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 561 (high priest,female) +{ + .INI............ + IIIII.KCCK...... + .IHI.KCAACK..... + ..H..CGAGAC..... + ..LC.CAAAAC..... + .CLLC.CAACJCK... + .CHLACCCCJCCCK.. + ..HAACCJJCCCCCK. + ..HCCCCJCCJCCC.A + ..H..CCJCCLJCAAA + ..H..CCJCLLCAAAA + ..H..KCJCCCJAAAA + ..H..KCJCCCJAAAA + ..H.ACCJCCCJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 562 (soldier,male) +{ + .....J.......... + .....JAAA....... + .....ALLLA...... + .....LLLLC...... + .....JLLC....... + .....JF..F...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....JJ.JJ...... + ................ +} +# tile 563 (soldier,female) +{ + .....J.......... + .....JAAA....... + .....ALLLA...... + .....LLLLC...... + .....JLLC....... + .....JF..F...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....JJ.JJ...... + ................ +} +# tile 564 (sergeant,male) +{ + .....J.......... + .....JFFF....... + ....FFFFFF...... + .....LLLLC...... + .....JLLC....... + .....JF..G...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 565 (sergeant,female) +{ + .....J.......... + .....JFFF....... + ....FFFFFF...... + .....LLLLC...... + .....JLLC....... + .....JF..G...... + ....FJFFFFF..A.. + ....FJFFFAF.A... + ....FLFFFFFAAA.. + ....FJFFAAAAAAA. + .....LFAFFAAAA.. + .....FFAF.AAAA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 566 (nurse,male) +{ + ................ + .......NO....... + ......NDDO...... + ......NNOOA..... + .....DBLBLD..... + .....CLLLLDC.... + .....DALLACD.... + .....CNAAODCAAA. + .....NNNOOLAAAA. + ....LANNDOALAAA. + ....LANNOOALAAA. + ......NNOOAAAA.. + ......NNAOAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 567 (nurse,female) +{ + ................ + .......NO....... + ......NDDO...... + ......NNOOA..... + .....DBLBLD..... + .....CLLLLDC.... + .....DALLACD.... + .....CNAAODCAAA. + .....NNNOOLAAAA. + ....LANNDOALAAA. + ....LANNOOALAAA. + ......NNOOAAAA.. + ......NNAOAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 568 (lieutenant,male) +{ + ................ + .......FFF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....GF.FGA..... + ....FFFFFFFF.... + ....FAFFFFAFAAA. + ....FAFFFFAFAAAA + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 569 (lieutenant,female) +{ + ................ + .......FFF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....GF.FGA..... + ....FFFFFFFF.... + ....FAFFFFAFAAA. + ....FAFFFFAFAAAA + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.AA.... + .....FFAFFA..... + .....AA.AA...... + ................ +} +# tile 570 (captain,male) +{ + ................ + ......FHHF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....HF.FHF..... + ....FFFFFFFFAA.. + ....FAFFIFAFAAAA + ....FAFFFFAFAAA. + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.JJJA.. + .....FFAFFJJJA.. + .....AA.AAAAA... + ................ +} +# tile 571 (captain,female) +{ + ................ + ......FHHF...... + .....FFFFFF..... + ......LLLL...... + .......LLCA..... + .....HF.FHF..... + ....FFFFFFFFAA.. + ....FAFFIFAFAAAA + ....FAFFFFAFAAA. + ....FAFFFFAFAAA. + ....LFFAFFJLJA.. + .....FFAFFJJJA.. + ......FAF.JJJA.. + .....FFAFFJJJA.. + .....AA.AAAAA... + ................ +} +# tile 572 (watchman,male) +{ + ................ + ......PPP....... + ....PPPPPP...... + .....LLLLC...... + ......LLC....... + .....PP..P...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + ......PAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 573 (watchman,female) +{ + ................ + ......PPP....... + ....PPPPPP...... + .....LLLLC...... + ......LLC....... + .....PP..P...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + ......PAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 574 (watch captain,male) +{ + ......PPP....... + .....PHHHP...... + ....PPPPPPP..... + .....LLLLC...... + ......LLC....... + .....HP..H...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + .....JPAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 575 (watch captain,female) +{ + ......PPP....... + .....PHHHP...... + ....PPPPPPP..... + .....LLLLC...... + ......LLC....... + .....HP..H...... + ....PPPPPPP..... + ....PAPPHAPPA... + ....PAPPPANNAAA. + ....PJPPAPNNAAA. + ....JLPAPPAAAA.. + .....JPAP.AAAA.. + .....JPAP.AA.... + .....PPAPPA..... + ....JJJ.JJJ..... + ................ +} +# tile 576 (Medusa,male) +{ + ................ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....A.. + .GAFLLLLA..A..A. + ....JLLKA.A.A.A. + ...KBLLBKAAAAA.. + ..KIIBBIIIAAA.A. + ..IIIKKILLIAAA.. + ..KIILLIALIAA... + ...KIALKAAIAA... + ...IKAAKIIAAA... + ...IIKKIIIAA.... + ..IIKIKIKIA..... + ................ +} +# tile 577 (Medusa,female) +{ + ................ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....A.. + .GAFLLLLA..A..A. + ....JLLKA.A.A.A. + ...KBLLBKAAAAA.. + ..KIIBBIIIAAA.A. + ..IIIKKILLIAAA.. + ..KIILLIALIAA... + ...KIALKAAIAA... + ...IKAAKIIAAA... + ...IIKKIIIAA.... + ..IIKIKIKIA..... + ................ +} +# tile 578 (Wizard of Yendor,male) +{ + .EEE.......EEE.. + EFFAE..E..EAFFE. + EAAAE.EEE.EAAAE. + EAAAEEEAEEEAAAE. + EEAAEEDADEEAAEE. + .EEEEAAAAAEEEE.. + ..EEEEAAAEEEE... + ..EEEEEEEEEE.... + ...EEEEEEEE..... + ...EEEEEEEE....A + ....EEEEEE...AAA + ....EEEEEEAAAAAA + ...EEEEEEEEAAAAA + ..EEEEEEEEEAAAAA + .EEEEEEEEEEEAAA. + EEEEEEEEEEEEEEA. +} +# tile 579 (Wizard of Yendor,female) +{ + .EEE.......EEE.. + EFFAE..E..EAFFE. + EAAAE.EEE.EAAAE. + EAAAEEEAEEEAAAE. + EEAAEEDADEEAAEE. + .EEEEAAAAAEEEE.. + ..EEEEAAAEEEE... + ..EEEEEEEEEE.... + ...EEEEEEEE..... + ...EEEEEEEE....A + ....EEEEEE...AAA + ....EEEEEEAAAAAA + ...EEEEEEEEAAAAA + ..EEEEEEEEEAAAAA + .EEEEEEEEEEEAAA. + EEEEEEEEEEEEEEA. +} +# tile 580 (Croesus,male) +{ + ....H..H..H..... + ....HCHEHCH..... + ....HHHHHHH..... + ....ALLLLLA..... + ....LLALALL..... + .....LLLLL...... + ....HLLDLLH..... + ...HIALLLAIH.A.A + ...HIHAAAHIHAAAA + ..IIIEHHHIIIIAAA + ..IIIIEHIIIIIAA. + ..ILLIHHHILLIAAA + ...LIIKHIIILAAAA + ..GIIIKJIIIIGAA. + .GIIIKJJKKIIIGG. + ................ +} +# tile 581 (Croesus,female) +{ + ....H..H..H..... + ....HCHEHCH..... + ....HHHHHHH..... + ....ALLLLLA..... + ....LLALALL..... + .....LLLLL...... + ....HLLDLLH..... + ...HIALLLAIH.A.A + ...HIHAAAHIHAAAA + ..IIIEHHHIIIIAAA + ..IIIIEHIIIIIAA. + ..ILLIHHHILLIAAA + ...LIIKHIIILAAAA + ..GIIIKJIIIIGAA. + .GIIIKJJKKIIIGG. + ................ +} +# tile 582 (Charon,male) +{ + ................ + .......J........ + ......JJJ....... + ....JJJAJJJ..... + ....JJDADJJ..... + ...JJAAAAAJJ.... + ...JJJAAAJJJ.... + ..JJJJJJJJJJ.... + .JJJJJJJJJJJJ... + JJJJJJJJJJJJJJ.A + .OO.JJJJJJ.OOAAA + ....JJJJJJAAAAAA + ...JJJJJJJJAAAAA + ..JJJJJJJJJAAAAA + .JJJJJJJJJJJAAA. + JJJJJJJJJJJJJJA. +} +# tile 583 (Charon,female) +{ + ................ + .......J........ + ......JJJ....... + ....JJJAJJJ..... + ....JJDADJJ..... + ...JJAAAAAJJ.... + ...JJJAAAJJJ.... + ..JJJJJJJJJJ.... + .JJJJJJJJJJJJ... + JJJJJJJJJJJJJJ.A + .OO.JJJJJJ.OOAAA + ....JJJJJJAAAAAA + ...JJJJJJJJAAAAA + ..JJJJJJJJJAAAAA + .JJJJJJJJJJJAAA. + JJJJJJJJJJJJJJA. +} +# tile 584 (ghost,male) +{ + ................ + ................ + ...NNN.......... + ..NANANN........ + .NNNNNNNNN...... + .NNPAAPNNNNN.... + .NNAAAANNNOONO.. + .NNAAAANONNNPNNO + .NNPAAPNONNOOOP. + .NNNNNNONOPNPPO. + .NNONNOPNNOPOOP. + .NOPNNOOOPPOOP.. + .OOOPOPPOPPP.PP. + .PP.PPOPPP...P.. + .O...P....P..... + ........P....... +} +# tile 585 (ghost,female) +{ + ................ + ................ + ...NNN.......... + ..NANANN........ + .NNNNNNNNN...... + .NNPAAPNNNNN.... + .NNAAAANNNOONO.. + .NNAAAANONNNPNNO + .NNPAAPNONNOOOP. + .NNNNNNONOPNPPO. + .NNONNOPNNOPOOP. + .NOPNNOOOPPOOP.. + .OOOPOPPOPPP.PP. + .PP.PPOPPP...P.. + .O...P....P..... + ........P....... +} +# tile 586 (shade,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ........AAAAAAA. + ....AAAAAAAA.... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAA. + ..AAAAAAAAAAAAAA + .AAAAAAAAAAAAA.. + AAAA.AAAAJA..... + ................ +} +# tile 587 (shade,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ................ + ........AAAAAAA. + ....AAAAAAAA.... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAA. + ..AAAAAAAAAAAAAA + .AAAAAAAAAAAAA.. + AAAA.AAAAJA..... + ................ +} +# tile 588 (water demon,male) +{ + ................ + ................ + ................ + ................ + ..EE.....EE..... + .E.EE...EE.E.... + ....EEEEE....... + ....EBEBE..A.... + ...EEEEEEEAAAA.. + ..EEE...EEEAA.A. + ..EEEEEEEEEAAA.. + ..EEAEEEAEEAAA.. + ...AAEEEAAAAA... + ....EEAEEAA..... + ....EEAEEA...... + ................ +} +# tile 589 (water demon,female) +{ + ................ + ................ + ................ + ................ + ..EE.....EE..... + .E.EE...EE.E.... + ....EEEEE....... + ....EBEBE..A.... + ...EEEEEEEAAAA.. + ..EEE...EEEAA.A. + ..EEEEEEEEEAAA.. + ..EEAEEEAEEAAA.. + ...AAEEEAAAAA... + ....EEAEEAA..... + ....EEAEEA...... + ................ +} +# tile 590 (amorous demon,male) +{ + DD.OHHD......... + DDOHHDGD........ + DDOHDDDDD....... + DDHHDDDA........ + DDDHDJADDDD..... + DDDJDDDDDDDD.... + .DDDDDCDD.DDD... + .DDCDDDKK..DD... + ..DDKKDDDAADDA.. + ...DDDDDDAAAAA.. + ....DDDDDDDDDA.. + ....DDJDJJAAAAAA + ....JDJJADKAA... + ....DDKAADDKA... + ...DDKAA..DDAA.. + ..DDKAA...DDDA.. +} +# tile 595 (amorous demon,female) +{ + DD.OHHD......... + DDOHHDGD........ + DDOHDDDDD....... + DDHHDDDA........ + DHHHDJADDDD..... + .HHJJDDDJDDD.... + OHDDCDCDDJDD.... + HHHCDDCDLJ.DD... + HHHCDLJJJAADDA.. + HHHDJJDDDAADAA.. + HHHHDDAADAAAA... + HHHH.DKJDDAA.... + H.H..DDAADDAA... + ..H..DDAA.DAA... + ....DDAA..DDAA.. + ...DDJA...DDDA.. +} +# tile 592 (horned devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + ...LOCDCOL...... + ...CDDDDDC...... + ...DAADAADA..D.. + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + ..CDAKKKACDAAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + ...CDDADDKAA.... + ..CDDAA.DDK..... + ................ +} +# tile 593 (horned devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + ...LOCDCOL...... + ...CDDDDDC...... + ...DAADAADA..D.. + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + ..CDAKKKACDAAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + ...CDDADDKAA.... + ..CDDAA.DDK..... + ................ +} +# tile 596 (erinys,male) +{ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....... + .GAFDLDLA..A.A.. + ....LLLEA.A.A.A. + ...EBLLBEAAAA.A. + ..EBBBBBBBAAAA.. + ..BBBEBBLLBAA.A. + ..EBBLLBALBAAA.. + ...EBALBAABAA... + ...BEAABBBAAA... + ...BBBBBBBAAA... + ...BBBBBBBAA.... + ..BBEBEBEBA..... + ................ +} +# tile 597 (erinys,female) +{ + ..GA...GA....... + ...FA.FA..GA.... + ....FJFFFF...... + ..FAFLLFA....... + .GAFDLDLA..A.A.. + ....LLLEA.A.A.A. + ...EBLLBEAAAA.A. + ..EBBBBBBBAAAA.. + ..BBBEBBLLBAA.A. + ..EBBLLBALBAAA.. + ...EBALBAABAA... + ...BEAABBBAAA... + ...BBBBBBBAAA... + ...BBBBBBBAA.... + ..BBEBEBEBA..... + ................ +} +# tile 598 (barbed devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + .O.LOCDCOL.O.... + ...CDDDDDC....DD + ...DAADAADA..D.D + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + .C.DAKKKACDKAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + .K.CDDADDKAAK... + .CCDDAA.DDKK.... + ................ +} +# tile 599 (barbed devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..... + .O.LOCDCOL.O.... + ...CDDDDDC....DD + ...DAADAADA..D.D + ...DDDDDDDA.D... + ..CCDDFDDCCAD.A. + ..CDKDDDKCDADA.. + .C.DAKKKACDKAAA. + ..DDADDDADDAAAA. + ....CDDDKAAAAA.. + .K.CDDADDKAAK... + .CCDDAA.DDKK.... + ................ +} +# tile 600 (marilith,male) +{ + .D..HHH.....D... + DD.HHHHHA...DD.. + .DCHDDDHHAAD..A. + ..HDBDBDHDDAAAA. + .CHKDDDKHAAADD.. + CDDDKKKDHDDDDFF. + D..CDDCDKAAFFFAA + D.KDDKDDDDDDFAA. + D.DKDDKDKAFDFAA. + ..D.GDDFAAFDFFAA + .D.GGFFFAAAFFFFA + ...GFFFFFAAAFFFA + ..FGFFFFFFAFFFFA + ..FGFFFFFFFFFFA. + ..FGFFFFFFFFFA.. + ....GFFFFFFAA... +} +# tile 601 (marilith,female) +{ + .D..HHH.....D... + DD.HHHHHA...DD.. + .DCHDDDHHAAD..A. + ..HDBDBDHDDAAAA. + .CHKDDDKHAAADD.. + CDDDKKKDHDDDDFF. + D..CDDCDKAAFFFAA + D.KDDKDDDDDDFAA. + D.DKDDKDKAFDFAA. + ..D.GDDFAAFDFFAA + .D.GGFFFAAAFFFFA + ...GFFFFFAAAFFFA + ..FGFFFFFFAFFFFA + ..FGFFFFFFFFFFA. + ..FGFFFFFFFFFA.. + ....GFFFFFFAA... +} +# tile 602 (vrock,male) +{ + ................ + ......OPP.O..... + ......PPPP...... + .....CPPDP...... + ....CCCPPP...... + ....CCPPPP...... + ....C..PPA...... + .....DDAADD.AAA. + ....DDDDDDDDAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ......DAADAAAA.. + ......DAADAA.A.. + .....DDA.DDA.... + ................ +} +# tile 603 (vrock,female) +{ + ................ + ......OPP.O..... + ......PPPP...... + .....CPPDP...... + ....CCCPPP...... + ....CCPPPP...... + ....C..PPA...... + .....DDAADD.AAA. + ....DDDDDDDDAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ....DADDDDADAAA. + ......DAADAAAA.. + ......DAADAA.A.. + .....DDA.DDA.... + ................ +} +# tile 604 (hezrou,male) +{ + ................ + ................ + ....GGGFF....... + ..NGFFNNFFF..... + .DFFFDDNFF.F.... + .GFFFDNFF.FFFAA. + .AFAFFFFFFFFFFAA + .GFFFF.FFF.FGFAA + .GAAAFF..LFGFFAA + ..FFFF.FFLFGFFFA + ..LLA.FLLLJJG.FA + .LLAFFLLFJJGFFFA + ..LAFLLLAAGF.FAA + .....L.LAGFFFFAA + ...........FFFA. + ................ +} +# tile 605 (hezrou,female) +{ + ................ + ................ + ....GGGFF....... + ..NGFFNNFFF..... + .DFFFDDNFF.F.... + .GFFFDNFF.FFFAA. + .AFAFFFFFFFFFFAA + .GFFFF.FFF.FGFAA + .GAAAFF..LFGFFAA + ..FFFF.FFLFGFFFA + ..LLA.FLLLJJG.FA + .LLAFFLLFJJGFFFA + ..LAFLLLAAGF.FAA + .....L.LAGFFFFAA + ...........FFFA. + ................ +} +# tile 606 (bone devil,male) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..O.. + ...LNLOLOL....O. + ...LOOOOOL....O. + ...NAAOAAOA..O.. + ...NOOOOOOA.O... + ..NOOOFOOOOAO.A. + ..OOKNOOKOOALA.. + ..OOANOOAOOAKAA. + ..LLANOOALLAAAA. + ....NOOOLAAAAA.. + ...NOOAOOLAA.... + ..NOOAA.OOL..... + ................ +} +# tile 607 (bone devil,female) +{ + ................ + ................ + ..O.......O..... + ..OO.....OO..O.. + ...LNLOLOL....O. + ...LOOOOOL....O. + ...NAAOAAOA..O.. + ...NOOOOOOA.O... + ..NOOOFOOOOAO.A. + ..OOKNOOKOOALA.. + ..OOANOOAOOAKAA. + ..LLANOOALLAAAA. + ....NOOOLAAAAA.. + ...NOOAOOLAA.... + ..NOOAA.OOL..... + ................ +} +# tile 608 (ice devil,male) +{ + ................ + ................ + ..N.......N..... + ..NN.....NN..... + ...PBPNPNP..BNB. + ...PNNNNNP..N.N. + ...BAANAANA...N. + ...BNNNNNNA.BNB. + ..BNNNFNNNNAN.A. + ..NNKBNNKNNABA.. + ..NNABNNANNA.AA. + ..PPABNNAPPAAAA. + ....BNNNPAAAAA.. + ...BNNANNPAA.... + ..BNNAA.NNP..... + ................ +} +# tile 609 (ice devil,female) +{ + ................ + ................ + ..N.......N..... + ..NN.....NN..... + ...PBPNPNP..BNB. + ...PNNNNNP..N.N. + ...BAANAANA...N. + ...BNNNNNNA.BNB. + ..BNNNFNNNNAN.A. + ..NNKBNNKNNABA.. + ..NNABNNANNA.AA. + ..PPABNNAPPAAAA. + ....BNNNPAAAAA.. + ...BNNANNPAA.... + ..BNNAA.NNP..... + ................ +} +# tile 610 (nalfeshnee,male) +{ + ................ + ................ + ......BB...BB... + ..KKKKKBB.BB.... + .KADKADKKKB..... + .KKKKKKKDKK..... + .OKDKOKKDDKD.... + .OKDKOKKKDKDD... + .KAAAKKDKAKKD... + ..KKKDDLAKKKD.A. + ...KK.KKKKKDDA.. + ....L..KDAKDAA.. + ......LLAAKDA... + .........LLA.... + ................ + ................ +} +# tile 611 (nalfeshnee,female) +{ + ................ + ................ + ......BB...BB... + ..KKKKKBB.BB.... + .KADKADKKKB..... + .KKKKKKKDKK..... + .OKDKOKKDDKD.... + .OKDKOKKKDKDD... + .KAAAKKDKAKKD... + ..KKKDDLAKKKD.A. + ...KK.KKKKKDDA.. + ....L..KDAKDAA.. + ......LLAAKDA... + .........LLA.... + ................ + ................ +} +# tile 612 (pit fiend,male) +{ + ................ + .K.O.......O.K.. + .K.OO.....OO.KJ. + KJJ.LOCDCOL.KJJ. + KJJJKDDDDDKKJJJ. + KJJCKDNDNDKCJJJA + JJCCKDDDDDJCCJJA + JJCCCKDIDJDCCJJA + JACCDDKJJDDCDAJA + JACCKDDDDDKCDAJA + ...CDKDDDKCDDAAA + ....DKDDDKCDAAAA + .....CDDDKAAAA.. + ....CDDADDKA.... + ...CDDAA.DDK.... + ................ +} +# tile 613 (pit fiend,female) +{ + ................ + .K.O.......O.K.. + .K.OO.....OO.KJ. + KJJ.LOCDCOL.KJJ. + KJJJKDDDDDKKJJJ. + KJJCKDNDNDKCJJJA + JJCCKDDDDDJCCJJA + JJCCCKDIDJDCCJJA + JACCDDKJJDDCDAJA + JACCKDDDDDKCDAJA + ...CDKDDDKCDDAAA + ....DKDDDKCDAAAA + .....CDDDKAAAA.. + ....CDDADDKA.... + ...CDDAA.DDK.... + ................ +} +# tile 614 (sandestin,male) +{ + .....CCCCC..I... + .I..CD....C..... + ...CD.DDD..C..I. + ..CD.DDDDD..C... + ..CD.DNDNDA.DC.. + I.CD.DDDDDA.DC.. + ..CD.ADDDA.DC..A + .CD.DDAAADD.DCAA + CD.DDDDDDDDDADCA + CD.DADDDDDADADCA + CD.DADDDDDADADCA + CD.DADDDDDADADC. + .CD..DDJDDAADCA. + ..CD.DDADDADCA.. + .CD.DDAADDDADC.. + ................ +} +# tile 615 (sandestin,female) +{ + .....CCCCC..I... + .I..CD....C..... + ...CD.DDD..C..I. + ..CD.DDDDD..C... + ..CD.DNDNDA.DC.. + I.CD.DDDDDA.DC.. + ..CD.ADDDA.DC..A + .CD.DDAAADD.DCAA + CD.DDDDDDDDDADCA + CD.DADDDDDADADCA + CD.DADDDDDADADCA + CD.DADDDDDADADC. + .CD..DDJDDAADCA. + ..CD.DDADDADCA.. + .CD.DDAADDDADC.. + ................ +} +# tile 616 (balrog,male) +{ + ................ + .K..O.....O..K.. + .KJ.O.....O.KJ.. + KJJLOOCDCOOLJJJ. + JJJDDDDDDDDDDKJ. + JCCDDDNDNDDDCCJA + CCDKDDDDDDDJCCCA + CDDKKKDIDJJDCCDA + CDDKDDKJJDDDCDDA + CCDKDDDDDDDKCDDA + JCCDKKDDDKKCDDDA + JJCDKKDDDKKCDDJA + JJ..CCDDDKKAAJJA + J..CDDDADDDKAAJA + ..CDDDAA.DDDK.AA + ................ +} +# tile 617 (balrog,female) +{ + ................ + .K..O.....O..K.. + .KJ.O.....O.KJ.. + KJJLOOCDCOOLJJJ. + JJJDDDDDDDDDDKJ. + JCCDDDNDNDDDCCJA + CCDKDDDDDDDJCCCA + CDDKKKDIDJJDCCDA + CDDKDDKJJDDDCDDA + CCDKDDDDDDDKCDDA + JCCDKKDDDKKCDDDA + JJCDKKDDDKKCDDJA + JJ..CCDDDKKAAJJA + J..CDDDADDDKAAJA + ..CDDDAA.DDDK.AA + ................ +} +# tile 618 (Juiblex,male) +{ + ................ + DD.........DD... + NDC.KKKKJ.CND... + .CCKCCCKKCCAA... + ..KCCCCKCCJAA... + ..KCCCCCK.JJAA.. + ..KCCFCCK..JAA.. + ..FKCFCCKK.JAAA. + .FKKFCCKFK..JAA. + .FKCFCCFKFK.JAA. + .FCFCCKFCFK.JAA. + FKCFCFCFCKK.JAA. + CKFCCFCCKKFKJJA. + CCKKCFCKFFKKKKA. + .CCCCCCCCCCCKA.. + ................ +} +# tile 619 (Juiblex,female) +{ + ................ + DD.........DD... + NDC.KKKKJ.CND... + .CCKCCCKKCCAA... + ..KCCCCKCCJAA... + ..KCCCCCK.JJAA.. + ..KCCFCCK..JAA.. + ..FKCFCCKK.JAAA. + .FKKFCCKFK..JAA. + .FKCFCCFKFK.JAA. + .FCFCCKFCFK.JAA. + FKCFCFCFCKK.JAA. + CKFCCFCCKKFKJJA. + CCKKCFCKFFKKKKA. + .CCCCCCCCCCCKA.. + ................ +} +# tile 620 (Yeenoghu,male) +{ + ....B.HHP....... + ....BPPPP....... + ...BPLCPPH...... + .KBPPCCPPH...... + .PPPPPPP.H...... + .PP...P.PH...... + ....BPPPPPAAA... + ..BPPPPPPPPAAAA. + .BP.PPPPPAPPAAAA + .B...BPP.AAPAAAA + .B...BPP.AAPAAA. + .....BPPAAAAA.A. + ....BP.PPAA...A. + ...BP.AAPPA..A.. + ...BPAA.PPA..... + ................ +} +# tile 621 (Yeenoghu,female) +{ + ....B.HHP....... + ....BPPPP....... + ...BPLCPPH...... + .KBPPCCPPH...... + .PPPPPPP.H...... + .PP...P.PH...... + ....BPPPPPAAA... + ..BPPPPPPPPAAAA. + .BP.PPPPPAPPAAAA + .B...BPP.AAPAAAA + .B...BPP.AAPAAA. + .....BPPAAAAA.A. + ....BP.PPAA...A. + ...BP.AAPPA..A.. + ...BPAA.PPA..... + ................ +} +# tile 622 (Orcus,male) +{ + ................ + .K..O.....O..K.. + KJJO..BBB..O.KJ. + KJJLOBPPPPOLKJJ. + JKJJ.PGPGP.JJKJA + JJKJKPPPPPJJKJJJ + JBPPB.BPPABBPPJJ + PJJPP.BPPAPPJJPA + PJBPPP.AAPPPPJPA + .JBP.PPPP.P.PJAA + .JBPPPP.PPPPPJAA + ..PPP.PPP.PPPAAA + ...P.PPPPPPP.P.A + ...BPPPAPPPPAAPA + ...OOPPAOOPPAGA. + ................ +} +# tile 623 (Orcus,female) +{ + ................ + .K..O.....O..K.. + KJJO..BBB..O.KJ. + KJJLOBPPPPOLKJJ. + JKJJ.PGPGP.JJKJA + JJKJKPPPPPJJKJJJ + JBPPB.BPPABBPPJJ + PJJPP.BPPAPPJJPA + PJBPPP.AAPPPPJPA + .JBP.PPPP.P.PJAA + .JBPPPP.PPPPPJAA + ..PPP.PPP.PPPAAA + ...P.PPPPPPP.P.A + ...BPPPAPPPPAAPA + ...OOPPAOOPPAGA. + ................ +} +# tile 624 (Geryon,male) +{ + .K...........K.. + .K....JJJ....KJ. + KJJ..JJJJJ..KJJ. + KJJJKLLLLLKKJJJ. + KJJJKLBLBLKJJJJA + JJJJKLLLLLJJJJJA + JJALLKLLLJLLAJJA + JA.LLLKJJLLLAAJA + ...LJLLLLLKLAAAA + ...LCKLLLKCLAFGF + ...LLGLLFALLFFFA + .....GFFFAAAFFAA + ....GGGGFFAAFFAA + ....GFFFFFAAFGFA + ....FGGGFFFFFFFA + .....FFFFFFFFFA. +} +# tile 625 (Geryon,female) +{ + .K...........K.. + .K....JJJ....KJ. + KJJ..JJJJJ..KJJ. + KJJJKLLLLLKKJJJ. + KJJJKLBLBLKJJJJA + JJJJKLLLLLJJJJJA + JJALLKLLLJLLAJJA + JA.LLLKJJLLLAAJA + ...LJLLLLLKLAAAA + ...LCKLLLKCLAFGF + ...LLGLLFALLFFFA + .....GFFFAAAFFAA + ....GGGGFFAAFFAA + ....GFFFFFAAFGFA + ....FGGGFFFFFFFA + .....FFFFFFFFFA. +} +# tile 626 (Dispater,male) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ....KACKKJAKAAA. + ....KACKKJAKAAJA + ....KACKKJAKAAJA + ....LACKKJJLAJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 627 (Dispater,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ....KACKKJAKAAA. + ....KACKKJAKAAJA + ....KACKKJAKAAJA + ....LACKKJJLAJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 628 (Baalzebub,male) +{ + ......F...F..... + .......F.F...... + ......BFFFB..... + .....BPPFBPP.... + .....PPPFPPP.... + ......PPFPP..... + .....CAFFFAK.... + ....CKKAFAKKKAA. + ....CAKJFAKAKAA. + ....FACJDAJAFAA. + ....FACKJJJAFAA. + ....FACKKKJAFAA. + ......CKKKJAAA.. + ......CKAKJA.A.. + .....FFA..FF.... + ................ +} +# tile 629 (Baalzebub,female) +{ + ......F...F..... + .......F.F...... + ......BFFFB..... + .....BPPFBPP.... + .....PPPFPPP.... + ......PPFPP..... + .....CAFFFAK.... + ....CKKAFAKKKAA. + ....CAKJFAKAKAA. + ....FACJDAJAFAA. + ....FACKJJJAFAA. + ....FACKKKJAFAA. + ......CKKKJAAA.. + ......CKAKJA.A.. + .....FFA..FF.... + ................ +} +# tile 630 (Asmodeus,male) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKJAKKAJA + ...KA.CKKJAAKAJA + ...LA.CKKJJALJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 631 (Asmodeus,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKJAKKAJA + ...KA.CKKJAAKAJA + ...LA.CKKJJALJA. + ......CKAJAJJA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 632 (Demogorgon,male) +{ + ...KKK..KKK..... + ..KBKBK.BKBK.... + ..KDKKK.KKDK.... + ..DKKFA.GKKD.... + ....GFAAGFAAA... + ...GFFFJFFFA.AAA + ..GFAGFFFAFFAAAA + .GJFAGJFJAFFFAA. + .GFAAGFFFAAFJA.. + .GJA.GFJFAAFFAA. + .GFA.GFFFA.FJAA. + .GJA.GJFJA.FFAA. + .GFAGFAAFFAFFA.. + ..GAGJAAJFAFAA.. + ..GAGFAFFFAFA... + ................ +} +# tile 633 (Demogorgon,female) +{ + ...KKK..KKK..... + ..KBKBK.BKBK.... + ..KDKKK.KKDK.... + ..DKKFA.GKKD.... + ....GFAAGFAAA... + ...GFFFJFFFA.AAA + ..GFAGFFFAFFAAAA + .GJFAGJFJAFFFAA. + .GFAAGFFFAAFJA.. + .GJA.GFJFAAFFAA. + .GFA.GFFFA.FJAA. + .GJA.GJFJA.FFAA. + .GFAGFAAFFAFFA.. + ..GAGJAAJFAFAA.. + ..GAGFAFFFAFA... + ................ +} +# tile 634 (Death,male) +{ + .BBBB....JJJ.... + .BPPPP.JJJJ..... + .C....JJJJJ..... + .C....JAAAJ..... + .C...JADADAJ.AAA + OOJ..JAAAAAJAAA. + OOOJJJAAAAAJJJA. + OOJJJJAAAAJOOJJA + .CJJJJAAAJOOOOJA + .C.JJAAAAJAOAAJA + .C..JAAAAJAOAAJA + .C..JAAAAAJOAJAA + .C..JAAAAAJJJAAA + .C.JAAAAAAAJJAA. + .CJJAAAAAAAAJJA. + ACJAAAAAAAAAAAJ. +} +# tile 635 (Death,female) +{ + .BBBB....JJJ.... + .BPPPP.JJJJ..... + .C....JJJJJ..... + .C....JAAAJ..... + .C...JADADAJ.AAA + OOJ..JAAAAAJAAA. + OOOJJJAAAAAJJJA. + OOJJJJAAAAJOOJJA + .CJJJJAAAJOOOOJA + .C.JJAAAAJAOAAJA + .C..JAAAAJAOAAJA + .C..JAAAAAJOAJAA + .C..JAAAAAJJJAAA + .C.JAAAAAAAJJAA. + .CJJAAAAAAAAJJA. + ACJAAAAAAAAAAAJ. +} +# tile 636 (Pestilence,male) +{ + F........JJJ.... + ..F....JJJJ..... + B...F.JJJJJ..... + ...B..JAAAJ..... + .F...JADADAJ.... + ...F.JAAAAAJ.AA. + .B..JFAAAAFJAA.. + ...FJJAFABJJAA.. + ..F.JFFBAJJJAAA. + ....FAFFJJJJAAA. + ....JABAJJJJAAA. + ...FJFFJJJJJJAA. + ...JJBFJJJJJJAA. + ...JAABFBJJJJAA. + ..JJFBFAFFAJJJA. + .JJAAFAFAAAAAAJ. +} +# tile 637 (Pestilence,female) +{ + F........JJJ.... + ..F....JJJJ..... + B...F.JJJJJ..... + ...B..JAAAJ..... + .F...JADADAJ.... + ...F.JAAAAAJ.AA. + .B..JFAAAAFJAA.. + ...FJJAFABJJAA.. + ..F.JFFBAJJJAAA. + ....FAFFJJJJAAA. + ....JABAJJJJAAA. + ...FJFFJJJJJJAA. + ...JJBFJJJJJJAA. + ...JAABFBJJJJAA. + ..JJFBFAFFAJJJA. + .JJAAFAFAAAAAAJ. +} +# tile 638 (Famine,male) +{ + .........JJJ.... + .......JJJ...... + K.....JJJJJ..... + K.....JAAAJ..... + K....JADADAJ.... + K....JAAAAAJ...A + K.....JAAAJJ..AA + OOJJJJJJAAJAJ.AA + K...JJJAAJJAJAAA + K.....JAJJJOJAA. + K.....JAOOOAAA.. + K.....JAJJAAA... + K.....JAJJAA.... + K.....JAAJAA.... + K...JJAAAJJAA... + K..JJAAAAAJJJA.. +} +# tile 639 (Famine,female) +{ + .........JJJ.... + .......JJJ...... + K.....JJJJJ..... + K.....JAAAJ..... + K....JADADAJ.... + K....JAAAAAJ...A + K.....JAAAJJ..AA + OOJJJJJJAAJAJ.AA + K...JJJAAJJAJAAA + K.....JAJJJOJAA. + K.....JAOOOAAA.. + K.....JAJJAAA... + K.....JAJJAA.... + K.....JAAJAA.... + K...JJAAAJJAA... + K..JJAAAAAJJJA.. +} +# tile 640 (mail daemon,male) +{ + ...OP.BEEE.PO... + ...OOEBEEEEOOD.. + ..DLOBEEEEOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDK.KDAADJJECDD + CCDKEEKKKJEEKCDD + .CCDK.EEEE..CDDD + .CCDAE.EENNNCDD. + .DDDAEEEENDNDDD. + ....BBEEENNNNN.. + ...BEEEAANNNNNA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 641 (mail daemon,female) +{ + ...OP.BEEE.PO... + ...OOEBEEEEOOD.. + ..DLOBEEEEOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDK.KDAADJJECDD + CCDKEEKKKJEEKCDD + .CCDK.EEEE..CDDD + .CCDAE.EENNNCDD. + .DDDAEEEENDNDDD. + ....BBEEENNNNN.. + ...BEEEAANNNNNA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 642 (djinni,male) +{ + .LL..NNN..LL.... + ..L..NGNA.L..... + ..LAALLLAALA.... + ..LAAKKKAALA.... + ...LCKKKCLA..... + ....LCKCLA...... + ....LICLIA..A... + ....IIIIEA.AA..A + ....EIEEIA.AAAAA + ....IEFEAAAAAAAA + .....DEAIAAAAA.. + .....IGIFAAAA... + .......FEDAAA... + .......I.GEA.A.. + .........IFED... + ................ +} +# tile 643 (djinni,female) +{ + .LL..NNN..LL.... + ..L..NGNA.L..... + ..LAALLLAALA.... + ..LAAKKKAALA.... + ...LCKKKCLA..... + ....LCKCLA...... + ....LICLIA..A... + ....IIIIEA.AA..A + ....EIEEIA.AAAAA + ....IEFEAAAAAAAA + .....DEAIAAAAA.. + .....IGIFAAAA... + .......FEDAAA... + .......I.GEA.A.. + .........IFED... + ................ +} +# tile 644 (jellyfish,male) +{ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAA... + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPPEPEEE.. + .PBBPPPEPEPPEE.. + .PEPBBEEPEEPEE.. + .PEEEPEEPEEPE... + ..PEEPE..PE.P... + ..P.EP.EEP..P... + ..PEE.P.E..E.... + .P..E.P..E...... +} +# tile 645 (jellyfish,female) +{ + ................ + .....PBPA....... + ...PBBBPBA...... + ..BBNNBPPBAA.... + .BBNNPPPBBPAA... + PBBBPPPBPBBAAA.. + BBBPBPPPPPBPAAA. + BBPBPPPPPPPBAAA. + PBPPBPPPPEPEEE.. + .PBBPPPEPEPPEE.. + .PEPBBEEPEEPEE.. + .PEEEPEEPEEPE... + ..PEEPE..PE.P... + ..P.EP.EEP..P... + ..PEE.P.E..E.... + .P..E.P..E...... +} +# tile 646 (piranha,male) +{ + ................ + ................ + ................ + ................ + ................ + ....OPP......... + .....OPP........ + ..O..PPAP.....E. + ..POPPPPPA...EEE + ..PPPPP.PPA.E... + ...PP..PPPAAAEE. + ..E.PPPPPPPPPE.. + ..E...PPPPPAA.E. + .....E..PPAE.... + .....E..P....... + ....E..E...E.... +} +# tile 647 (piranha,female) +{ + ................ + ................ + ................ + ................ + ................ + ....OPP......... + .....OPP........ + ..O..PPAP.....E. + ..POPPPPPA...EEE + ..PPPPP.PPA.E... + ...PP..PPPAAAEE. + ..E.PPPPPPPPPE.. + ..E...PPPPPAA.E. + .....E..PPAE.... + .....E..P....... + ....E..E...E.... +} +# tile 648 (shark,male) +{ + ................ + ................ + ................ + ...............P + ........P.....PP + ....E..PP....PP. + ...E...PPA..PPP. + ..EEEEPPPA.PPPPP + .E.EEPPP.PPPPPPE + ...EP.P.PPPPPEEE + ..PPPPPPPPPPEEE. + .APPPPPPPPEEEE.E + PPPPPPP..EE..... + NDPPAPEPPP.E..EE + PDNPPEE..EE..... + .PPPE..EEE..E... +} +# tile 649 (shark,female) +{ + ................ + ................ + ................ + ...............P + ........P.....PP + ....E..PP....PP. + ...E...PPA..PPP. + ..EEEEPPPA.PPPPP + .E.EEPPP.PPPPPPE + ...EP.P.PPPPPEEE + ..PPPPPPPPPPEEE. + .APPPPPPPPEEEE.E + PPPPPPP..EE..... + NDPPAPEPPP.E..EE + PDNPPEE..EE..... + .PPPE..EEE..E... +} +# tile 650 (giant eel,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA...AAA.. + ..AAAAAAA.AA.AA. + ..AAAA.AA.AA.AA. + ...AA..AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA.E.AA.E. + ...E.AAEE.AAAE.. + ...E.AAEEAAAEE.. + ..E..AAAAAAE.E.. + ...EE.AAAAE.E... + ..E...EE.E...E.. +} +# tile 651 (giant eel,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA...AAA.. + ..AAAAAAA.AA.AA. + ..AAAA.AA.AA.AA. + ...AA..AA.AA..A. + ......AAA..AA.A. + ......AA...AA... + .....AAA.E.AA.E. + ...E.AAEE.AAAE.. + ...E.AAEEAAAEE.. + ..E..AAAAAAE.E.. + ...EE.AAAAE.E... + ..E...EE.E...E.. +} +# tile 652 (electric eel,male) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA........ + ..AAAAAAA....... + ..AAAA.AA....... + ...AA..AA...DD.. + ......AAA..DD... + ......AA...DD... + .....AAA.E.DD.E. + ...E.AAEE.DD.E.. + ...E.AAEEDD.EE.. + ..E..AAADDDE.E.. + ...EE.AAADE.E... + ..E...EE.E...E.. +} +# tile 653 (electric eel,female) +{ + ................ + ................ + ................ + ....AAA......... + ...AAOAA........ + ..AAAAAAA....... + ..AAAA.AA....... + ...AA..AA...DD.. + ......AAA..DD... + ......AA...DD... + .....AAA.E.DD.E. + ...E.AAEE.DD.E.. + ...E.AAEEDD.EE.. + ..E..AAADDDE.E.. + ...EE.AAADE.E... + ..E...EE.E...E.. +} +# tile 654 (kraken,male) +{ + ................ + ................ + ..FF..FF........ + ..DDFDDF........ + ..FFFFF.....GG.. + ..NCNFF......GFA + ..CC.FF.....EGFA + ....GFAA.GFAEGFE + ...GFFAGFFFFAGFE + ...GFAAFFAGFAEEE + ..GFFAGFFAGFEEE. + EEGFFAGFFAEEEE.E + .EGFFAGFFEE..... + EEGFFEEEEE.E..EE + EEEEEEE..EE..... + ..EEE..EEE..E... +} +# tile 655 (kraken,female) +{ + ................ + ................ + ..FF..FF........ + ..DDFDDF........ + ..FFFFF.....GG.. + ..NCNFF......GFA + ..CC.FF.....EGFA + ....GFAA.GFAEGFE + ...GFFAGFFFFAGFE + ...GFAAFFAGFAEEE + ..GFFAGFFAGFEEE. + EEGFFAGFFAEEEE.E + .EGFFAGFFEE..... + EEGFFEEEEE.E..EE + EEEEEEE..EE..... + ..EEE..EEE..E... +} +# tile 656 (newt,male) +{ + ................ + ................ + ................ + ................ + ................ + ......JKKJ...... + .....CLCCLLC.... + ....LAAAACCLCA.. + .......LCCLLLCA. + ....LCCCLLLAALA. + ....CALLLLAAAA.. + ...LLLLCLAAA.... + ...LLAAALLA..... + ................ + ................ + ................ +} +# tile 657 (newt,female) +{ + ................ + ................ + ................ + ................ + ................ + ......JKKJ...... + .....CLCCLLC.... + ....LAAAACCLCA.. + .......LCCLLLCA. + ....LCCCLLLAALA. + ....CALLLLAAAA.. + ...LLLLCLAAA.... + ...LLAAALLA..... + ................ + ................ + ................ +} +# tile 658 (gecko,male) +{ + ................ + ................ + ...........LLP.. + ..........LLOOA. + ......PO.LLOOOA. + ......OOALOOOA.. + .......LLOOOA... + ...POALOOOAA.... + ...OOLOOOOOOA... + ....ALOOOAOPA... + ...DOOOOA.AA.... + ...OOOAOOA...... + ...OODAOPA...... + ..F.AA.AA....... + ................ + ................ +} +# tile 659 (gecko,female) +{ + ................ + ................ + ...........LLP.. + ..........LLOOA. + ......PO.LLOOOA. + ......OOALOOOA.. + .......LLOOOA... + ...POALOOOAA.... + ...OOLOOOOOOA... + ....ALOOOAOPA... + ...DOOOOA.AA.... + ...OOOAOOA...... + ...OODAOPA...... + ..F.AA.AA....... + ................ + ................ +} +# tile 660 (iguana,male) +{ + ................ + ................ + ................ + ................ + ................ + ....GPGPGGPF.... + ..GPAAAAFFGPF... + .GPAA.PFFGPPPAA. + ......FGGPPFPPAA + .PFGGGGPPPFAAPPA + .FGPAPPPPFAAAAA. + .GPPPPFPFAAA.A.. + .PPFFAFPPAA..... + D.AAAAAAPPA..... + ................ + ................ +} +# tile 661 (iguana,female) +{ + ................ + ................ + ................ + ................ + ................ + ....GPGPGGPF.... + ..GPAAAAFFGPF... + .GPAA.PFFGPPPAA. + ......FGGPPFPPAA + .PFGGGGPPPFAAPPA + .FGPAPPPPFAAAAA. + .GPPPPFPFAAA.A.. + .PPFFAFPPAA..... + D.AAAAAAPPA..... + ................ + ................ +} +# tile 662 (baby crocodile,male) +{ + ................ + ................ + ................ + ................ + ................ + .....FFOFOFA.... + ....FOGFGGOFF... + ....GAAAAFOGFA.. + ...FAA.GFOGGGFA. + ...GFOOOGGGFAGA. + ...FGAGGGGFAAA.. + ..FGGGGFGFAA.... + ..GGDFAFGGA..... + ...D............ + ................ + ................ +} +# tile 663 (baby crocodile,female) +{ + ................ + ................ + ................ + ................ + ................ + .....FFOFOFA.... + ....FOGFGGOFF... + ....GAAAAFOGFA.. + ...FAA.GFOGGGFA. + ...GFOOOGGGFAGA. + ...FGAGGGGFAAA.. + ..FGGGGFGFAA.... + ..GGDFAFGGA..... + ...D............ + ................ + ................ +} +# tile 664 (lizard,male) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ....FFFFGFJ..... + ..FFAAAJJGFJ.... + ......JGFFJFAA.. + ...JGGGFFJAAFA.. + ..JFAFFFJAAAA... + ..FFFFJJAAA..... + .JFAAAAFAA...... + .D.............. + ................ + ................ +} +# tile 665 (lizard,female) +{ + ................ + ................ + ................ + ................ + ................ + ................ + ....FFFFGFJ..... + ..FFAAAJJGFJ.... + ......JGFFJFAA.. + ...JGGGFFJAAFA.. + ..JFAFFFJAAAA... + ..FFFFJJAAA..... + .JFAAAAFAA...... + .D.............. + ................ + ................ +} +# tile 666 (chameleon,male) +{ + ................ + ................ + ................ + .....GGGG....... + ...GGGGGGGG..... + ...GGFFFFGGFA... + ..GPAAAGFFGGFA.. + .GPAA.PFFGGGGAA. + ...GGGGGGGGFGGAA + .PGGBBGGGGFAAGGA + .FGGABGGGFAAAAA. + .GGGGGFGFAAA.A.. + .DGFFAFGGAA..... + D.AAAAAAGGA..... + .DD............. + ................ +} +# tile 667 (chameleon,female) +{ + ................ + ................ + ................ + .....GGGG....... + ...GGGGGGGG..... + ...GGFFFFGGFA... + ..GPAAAGFFGGFA.. + .GPAA.PFFGGGGAA. + ...GGGGGGGGFGGAA + .PGGBBGGGGFAAGGA + .FGGABGGGFAAAAA. + .GGGGGFGFAAA.A.. + .DGFFAFGGAA..... + D.AAAAAAGGA..... + .DD............. + ................ +} +# tile 668 (crocodile,male) +{ + ................ + ................ + ................ + ................ + ....FFOFOOFA.... + ...FOGFGFGOFFA.. + ..FGAAAAFFOGFFA. + .FFAA.GFFOGGGGFA + ......FOOGGGGGGA + .G.OOOOGGGGFAGGA + .FOGAGGGGGFAAAA. + FGGGGGFGGFAA.... + GGDDFAFGGGA..... + GDDFAAAAGGA..... + .DF............. + ................ +} +# tile 669 (crocodile,female) +{ + ................ + ................ + ................ + ................ + ....FFOFOOFA.... + ...FOGFGFGOFFA.. + ..FGAAAAFFOGFFA. + .FFAA.GFFOGGGGFA + ......FOOGGGGGGA + .G.OOOOGGGGFAGGA + .FOGAGGGGGFAAAA. + FGGGGGFGGFAA.... + GGDDFAFGGGA..... + GDDFAAAAGGA..... + .DF............. + ................ +} +# tile 670 (salamander,male) +{ + ................ + ................ + ................ + ......CCC....... + ....CCCCCCC..... + ...CCDDDDCCDA... + ....AAAADDCCDA.. + ......KDDCCCCAA. + ..LLLCCCCCCDCCAA + .KLCCCLLLCDAACCA + .DCEECLKKDAAAAA. + DCCAECDKDAAA.A.. + CCCCCCDCCAA..... + .DAADAAACCA..... + ..ACCA.......... + ...AAA.......... +} +# tile 671 (salamander,female) +{ + ................ + ................ + ................ + ......CCC....... + ....CCCCCCC..... + ...CCDDDDCCDA... + ....AAAADDCCDA.. + ......KDDCCCCAA. + ..LLLCCCCCCDCCAA + .KLCCCLLLCDAACCA + .DCEECLKKDAAAAA. + DCCAECDKDAAA.A.. + CCCCCCDCCAA..... + .DAADAAACCA..... + ..ACCA.......... + ...AAA.......... +} +# tile 672 (long worm tail,male) +{ + ........ILLLL... + ......IILLAA.... + .....ILLAA...... + .....ILA........ + .....ILA........ + ......LLA...II.. + .......LLIIILLLL + ........ILLAAA.L + ...IIIILLALL.... + .ILLLLLAA..LL... + ILLAAAA.....LA.. + ILA.........LA.. + LLA........LLA.. + LILA......LLA... + .LLLIIIILLLA.... + ...LLLLLAAA..... +} +# tile 673 (long worm tail,female) +{ + ........ILLLL... + ......IILLAA.... + .....ILLAA...... + .....ILA........ + .....ILA........ + ......LLA...II.. + .......LLIIILLLL + ........ILLAAA.L + ...IIIILLALL.... + .ILLLLLAA..LL... + ILLAAAA.....LA.. + ILA.........LA.. + LLA........LLA.. + LILA......LLA... + .LLLIIIILLLA.... + ...LLLLLAAA..... +} +# tile 674 (archeologist,male) +{ + ................ + ................ + ......KJ.J...... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + ......CJJKAAAA.. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 675 (archeologist,female) +{ + ................ + ................ + ................ + ......KJJJ...... + ......KKLJ...... + .....KLELE...... + ....KJLLLL...... + ....JJALLA...... + ...JJLBAAPL.AAA. + ...JLLBBBPLLAAA. + ....LABPPPALAAA. + ....LALLLLALAAA. + .....AOJJOAAAA.. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 676 (barbarian,male) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + ......ALLA...... + .....LLAALL.AAA. + ....LLLLLLLLAAA. + ....LALLLLALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 677 (barbarian,female) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + ......ALLA...... + .....LLAALL.AAA. + ....LLLLLLLLAAA. + ....LALLLLALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 678 (cave dweller,male) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LLAJJALLAAA. + ...LLLLAALLLLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 679 (cave dweller,female) +{ + ................ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JLDDLAJ.... + ....LJALLAJLAAA. + ...LLJCAAJJLLAA. + ...LLACKKJALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 680 (healer,male) +{ + ................ + .......NN....... + ......NDDO...... + ......NNNN...... + ......ELEP...... + ......LLLP...... + .......LLP...... + ......O..PA.AAA. + .....NNOOPPAAAA. + ....OOONOPPPAA.. + ....LANOOPALAA.. + ......NOOPAAAA.. + .....NOOOPAA.A.. + ....NOOOOOPA.... + ................ + ................ +} +# tile 681 (healer,female) +{ + ................ + .......NN....... + ......NDDO...... + ......NNNN...... + ......ELEP...... + ......LLLP...... + .......LLP...... + ......O..PA.AAA. + .....NNOOPPAAAA. + ....OOONOPPPAA.. + ....LANOOPALAA.. + ......NOOPAAAA.. + .....NOOOPAA.A.. + ....NOOOOOPA.... + ................ + ................ +} +# tile 682 (knight,male) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + ......ALLAA..... + .....BBAABB.AAA. + ....BPPPPPPPAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... + ................ + ................ +} +# tile 683 (knight,female) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + ......ALLAA..... + .....BBAABB.AAA. + ....BPPPPPPPAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... + ................ + ................ +} +# tile 684 (monk,male) +{ + ................ + ................ + .......CCC...... + ......JCJJJA.... + ......CAAAJA.... + ......CAAAJA.... + ......CKLKCAAAA. + .....CDDDDDDAAAA + ....CDDLALDDDAAA + ....DALLALLADAA. + ....DDDDCDDDDAA. + .....AACCCDAAAA. + .....CDCCCDDA.A. + ....CCCCCCCDD... + ................ + ................ +} +# tile 685 (monk,female) +{ + ................ + ................ + .......CCC...... + ......JCJJJA.... + ......CAAAJA.... + ......CAAAJA.... + ......CKLKCAAAA. + .....CDDDDDDAAAA + ....CDDLALDDDAAA + ....DALLALLADAA. + ....DDDDCDDDDAA. + .....AACCCDAAAA. + .....CDCCCDDA.A. + ....CCCCCCCDD... + ................ + ................ +} +# tile 686 (cleric,male) +{ + ................ + ................ + ......JLLJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......IJJIAAAA.. + .....ODDDDDAAAA. + ....INNDDDDDAAA. + ...NLNNDDDALAA.. + ......DDDDAAAA.. + ......DIIDAAAA.. + .....DDIIDDA.A.. + ....DIIIIIDD.... + ................ + ................ +} +# tile 687 (cleric,female) +{ + ................ + .......JJ....... + ......JJJJ...... + ......JLLJA..... + ......JLLJJ..... + .....JJLLJJ..... + .....JEJJEJAAA.. + .....ODEEDDAAAA. + ....IDINNDDDAAA. + ....L.DNNDALAA.. + ......IDDDAAAA.. + ......IDDDAAAA.. + .....DDIIDDA.A.. + ....DIIIIIDD.... + ................ + ................ +} +# tile 688 (ranger,male) +{ + ................ + ................ + ........CJA..... + .......CJJJA.... + .......JEEJA.... + .......JLLJA.... + .......ALLAA.... + ......GGAAGG.AAA + .....BPFFFFPPAAA + .....PAGFFFAPAAA + .....LA.FF.ALAAA + .......BP.PAAAA. + .......BPAPAA.A. + ......PPA.PPA... + ................ + ................ +} +# tile 689 (ranger,female) +{ + ................ + ................ + ........CJA..... + .......CJJJA.... + .......JEEJA.... + .......JLLJA.... + .......ALLAA.... + ......GGAAGG.AAA + .....BPFFFFPPAAA + .....PAGFFFAPAAA + .....LA.FF.ALAAA + .......BP.PAAAA. + .......BPAPAA.A. + ......PPA.PPA... + ................ + ................ +} +# tile 690 (rogue,male) +{ + ................ + ................ + ................ + .....OA...OA.... + .....OOIDPPA.... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + ......BAABAA..A. + .....KEBBEJAAAA. + ....KAAEEAAKAA.. + ....LAJJHJALAA.. + ......KKJKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 691 (rogue,female) +{ + ................ + ................ + ................ + .....OA...OA.... + .....OOIDPPA.... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + ......BAABAA..A. + .....KEBBEJAAAA. + ....KAAEEAAKAA.. + ....LAJJHJALAA.. + ......KKJKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 692 (samurai,male) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LABBBBALAAA. + ....LABBBBALAAA. + ......IDDDAAAA.. + ......IDADAA.A.. + .....IIA.IIA.... + ................ +} +# tile 693 (samurai,female) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LABBBBALAAA. + ....LABBBBALAAA. + ......IDDDAAAA.. + ......IDADAA.A.. + .....IIA.IIA.... + ................ +} +# tile 694 (tourist,male) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ...JJJJJJJJJJ... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HGAAGH.AAA. + ....LLGHHGLLAAA. + ....LAHGHGALAAA. + ....LAHHGHALAAA. + ......JJJKAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 695 (tourist,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ...JJJJJJJJJJ... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HGAAGH.AAA. + ....LLGHHGLLAAA. + ....LAHGHGALAAA. + ....LAHHGHALAAA. + ......JJJKAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 696 (valkyrie,male) +{ + D..............D + .D............D. + ..D...LHHL...D.. + ...D.HHHHHL.D... + ....DHELELHD.... + ....HDLLLLD..... + ...HHHDLLD...... + ...HJKJDDKJJAAA. + ..HHLJJDDJJLAAA. + ..H.LADKDCALAAA. + ....LDAKKDALAAA. + ....D.KKJKDAAA.. + ...D..KJAJAD.A.. + ..D..KLA.LKAD... + .D...........D.. + D.............D. +} +# tile 697 (valkyrie,female) +{ + ................ + ................ + ......LHHL...... + .....HHHHHL..... + ....LHELELH..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 698 (wizard,male) +{ + ................ + .........BP..... + .......BBPE..... + ......BPPEA..... + ......BAAEA..... + ......BAAEA..... + ......PLLE...... + ......PAAEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 699 (wizard,female) +{ + ................ + .........BP..... + .......BBPE..... + ......BPPEA..... + ......BAAEA..... + ......BAAEA..... + ......PLLE...... + ......PAAEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 700 (Lord Carnarvon,male) +{ + .......JJ....... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CIAAIK.AAA. + ....CKKIIKKKAAA. + ...KKCKKHKJKKAA. + ...KKAKHKJAKKAA. + ...KAIHKKJIAKA.. + ...LAICKKJIALA.. + .....ICKAJIAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 701 (Lord Carnarvon,female) +{ + .......JJ....... + ......KJJJ...... + ....KCKKKJJJ.... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CIAAIK.AAA. + ....CKKIIKKKAAA. + ...KKCKKHKJKKAA. + ...KKAKHKJAKKAA. + ...KAIHKKJIAKA.. + ...LAICKKJIALA.. + .....ICKAJIAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 702 (Pelias,male) +{ + ................ + .......JJ....... + ......KKKJ...... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKKAKKAA. + ...KA.CKKJAAKA.. + ...LA.CKAJAALA.. + ......CKAJAAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 703 (Pelias,female) +{ + ................ + .......JJ....... + ......KKKJ...... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKK.AAA. + ....CKKKKKKKAAA. + ...KKCKKKKJKKAA. + ...KKAKKKKAKKAA. + ...KA.CKKJAAKA.. + ...LA.CKAJAALA.. + ......CKAJAAAA.. + ......CKAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 704 (Shaman Karnov,male) +{ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LHAJJAHLAA.. + ...LLLHAAHLLLAA. + ...LLLLHHLLLLAA. + ...LLALHHLALLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ +} +# tile 705 (Shaman Karnov,female) +{ + ................ + .......JJA...... + ......JJJJA..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....LHAJJAHLAA.. + ...LLLHAAHLLLAA. + ...LLLLHHLLLLAA. + ...LLALHHLALLAA. + ...LLALLLLALLAA. + ....LACKKJALAAA. + ......CKKJAAAA.. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ +} +# tile 706 (Earendil,male) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBPLELEABPB.. + ..BBBPLLLLABBB.. + ..PBPPALLAPPP... + ...PPBGAAGBBB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 707 (Earendil,female) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBPLELEABPB.. + ..BBBPLLLLABBB.. + ..PBPPALLAPPP... + ...PPBGAAGBBB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 708 (Elwing,male) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBHLELEHBPB.. + ..BBBHLLLLHBBB.. + ..PBHHALLAHHP... + ...PHHGAAGHHB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 709 (Elwing,female) +{ + .........G...... + ....B..GGF..B... + ...BB.GGGGABB... + ..BPBHLELEHBPB.. + ..BBBHLLLLHBBB.. + ..PBHHALLAHHP... + ...PHHGAAGHHB... + ...BBLGGGFLBBB.. + ..BBLAAGFAALBB.. + ...BLAGGGFALB... + ......GFAF...... + ......L..L.AAA.. + ......AAAAAAAA.. + ....AAAAAAAA.... + .....AAAAAA..... + ................ +} +# tile 710 (Hippocrates,male) +{ + ................ + ....LLLCCD...... + ...LLCCDDA...... + ...LAAAADA...... + ...LBABADA...... + ...LAAAADA...... + ...CCLLDD.B..... + ....CKKDDFBFAAA. + ..LLLCLDDDBFAAA. + .CCCCLDDDFBAAA.. + .LALLCCDDFBDAA.. + ...LCCCCDABFAA.. + ...LCCCCDABAAA.. + ..LLCCCCDAA.AA.. + .LCCCCCCCDA..... + ................ +} +# tile 711 (Hippocrates,female) +{ + ................ + ....LLLCCD...... + ...LLCCDDA...... + ...LAAAADA...... + ...LBABADA...... + ...LAAAADA...... + ...CCLLDD.B..... + ....CKKDDFBFAAA. + ..LLLCLDDDBFAAA. + .CCCCLDDDFBAAA.. + .LALLCCDDFBDAA.. + ...LCCCCDABFAA.. + ...LCCCCDABAAA.. + ..LLCCCCDAA.AA.. + .LCCCCCCCDA..... + ................ +} +# tile 712 (King Arthur,male) +{ + ................ + ................ + ......OHHA...... + .....OHHHHA..... + .....HBLBHA..... + .....HLLLHA..... + .....ALLLAA..... + ....BBAAABB.AAA. + ...BPPPPPPPPAAA. + ...PABPPPPACPAA. + ..NNNNNNNNNCLCA. + .....BPP.PACAA.. + .....BPAPPAA.A.. + .....BPAPPAA.A.. + ....PPAA.PPA.... + ................ +} +# tile 713 (King Arthur,female) +{ + ................ + ................ + ......OHHA...... + .....OHHHHA..... + .....HBLBHA..... + .....HLLLHA..... + .....ALLLAA..... + ....BBAAABB.AAA. + ...BPPPPPPPPAAA. + ...PABPPPPACPAA. + ..NNNNNNNNNCLCA. + .....BPP.PACAA.. + .....BPAPPAA.A.. + .....BPAPPAA.A.. + ....PPAA.PPA.... + ................ +} +# tile 714 (Grand Master,male) +{ + ................ + .......LL....... + ......LLLL...... + ......LLLL...... + ..LC.CALLAC..... + .CLLC.CAACCCC... + .CJLACCCCCCCCC.. + ..JAACCCCCCCCCC. + ..JCCCCCCCCCCC.A + ..J..PPPPPLCCAAA + ..J..CCCCLLCAAAA + ..J..CCCCCCCAAAA + ..J..CCCCCCCAAAA + ..J.ACCCCCCCAAA. + ..JACCCCCCCCAA.. + ................ +} +# tile 715 (Grand Master,female) +{ + ................ + .......LL....... + ......LLLL...... + ......LLLL...... + ..LC.CALLAC..... + .CLLC.CAACCCC... + .CJLACCCCCCCCC.. + ..JAACCCCCCCCCC. + ..JCCCCCCCCCCC.A + ..J..PPPPPLCCAAA + ..J..CCCCLLCAAAA + ..J..CCCCCCCAAAA + ..J..CCCCCCCAAAA + ..J.ACCCCCCCAAA. + ..JACCCCCCCCAA.. + ................ +} +# tile 716 (Arch Priest,male) +{ + ..N............. + .NNN..JLLJ...... + ..N...JLLJ...... + ..N...LLLL...... + ..LC.CALLAC..... + .CLLC.CAACJDK... + .CHLACCCCJCCDK.. + ..HAACCJJCCCCDK. + ..HCCCCJCCJCCC.A + ..H..DCJCCLJCAAA + ..H..DCJCLLCAAAA + ..H..KCJCCDJAAAA + ..H..KCJCCDJAAAA + ..H.ACCJCCDJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 717 (Arch Priest,female) +{ + ..N............. + .NNN..JLLJ...... + ..N...JLLJ...... + ..N...LLLL...... + ..LC.CALLAC..... + .CLLC.CAACJDK... + .CHLACCCCJCCDK.. + ..HAACCJJCCCCDK. + ..HCCCCJCCJCCC.A + ..H..DCJCCLJCAAA + ..H..DCJCLLCAAAA + ..H..KCJCCDJAAAA + ..H..KCJCCDJAAAA + ..H.ACCJCCDJAAA. + ..HACCCJJCCCAA.. + ................ +} +# tile 718 (Orion,male) +{ + ................ + ................ + .......CJA...... + ......CJJJA..... + ......JEEJA..... + ......JLLJA..... + ......ALLAA..... + .....GGAAGG..... + ....BGFFFFFP.... + ....BPFFFFPPAAA. + ....PAGFFFAPAAA. + ....LANNNNALAAA. + ......BP.PAAAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... +} +# tile 719 (Orion,female) +{ + ................ + ................ + .......CJA...... + ......CJJJA..... + ......JEEJA..... + ......JLLJA..... + ......ALLAA..... + .....GGAAGG..... + ....BGFFFFFP.... + ....BPFFFFPPAAA. + ....PAGFFFAPAAA. + ....LANNNNALAAA. + ......BP.PAAAAA. + ......BP.PAAAA.. + ......BPAPAA.A.. + .....PPA.PPA.... +} +# tile 720 (Master of Thieves,male) +{ + ................ + ...H.....H...... + ...HHIDKHH...... + ....IDDDD....... + ....LLLLLA...... + ....LBLBLA...... + ....LLLLLA...... + .....LLLA....... + ....B.AABAA..... + ...KEBBBEJAAA... + ..KAEEEEEAJAAA.. + ..LAJJHHJALAAA.. + ....JKKKJAAAAA.. + ....KJAJKAAAA... + ...JJA..JJA..... + ................ +} +# tile 721 (Master of Thieves,female) +{ + ................ + ...H.....H...... + ...HHIDKHH...... + ....IDDDD....... + ....LLLLLA...... + ....LBLBLA...... + ....LLLLLA...... + .....LLLA....... + ....B.AABAA..... + ...KEBBBEJAAA... + ..KAEEEEEAJAAA.. + ..LAJJHHJALAAA.. + ....JKKKJAAAAA.. + ....KJAJKAAAA... + ...JJA..JJA..... + ................ +} +# tile 722 (Lord Sato,male) +{ + .....AAA........ + .....AAA........ + ...AAAAAAA...... + ..AALLLLLAA..... + ..ALFFLFFLA..... + ..ALLLLLLLA..... + ...AALLLA....... + IIIIIAAAIIIIAAA. + LLDIIIIIIDLLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + ...IIDDDDAAAAAA. + ...IIAAIDAAA..A. + ..IIIA.IIIAA.... + ................ +} +# tile 723 (Lord Sato,female) +{ + .....AAA........ + .....AAA........ + ...AAAAAAA...... + ..AALLLLLAA..... + ..ALFFLFFLA..... + ..ALLLLLLLA..... + ...AALLLA....... + IIIIIAAAIIIIAAA. + LLDIIIIIIDLLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + LLABBBBBBALLAAA. + ...IIDDDDAAAAAA. + ...IIAAIDAAA..A. + ..IIIA.IIIAA.... + ................ +} +# tile 724 (Twoflower,male) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + .....NNLNNA..... + ....NALNALNA.... + .....NNANNAA.... + .....AAAAAA.AAA. + ....LLHGHGLLAAA. + ....LAGGGGALAAA. + ....LAHGHGALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 725 (Twoflower,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + .....NNLNNA..... + ....NALNALNA.... + .....NNANNAA.... + .....AAAAAA.AAA. + ....LLHGHGLLAAA. + ....LAGGGGALAAA. + ....LAHGHGALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 726 (Norn,male) +{ + ................ + ................ + ......NNN....... + .....NNNNN...... + .....NELELN..... + ....NNLLLLN..... + ...NNNALLA...... + ...NJKJAAKJJAAA. + ..NNLJJKKJJLAAA. + ..N.LACKJCALAAA. + ....LAKKKKALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 727 (Norn,female) +{ + ................ + ................ + ......NNN....... + .....NNNNN...... + .....NELELN..... + ....NNLLLLN..... + ...NNNALLA...... + ...NJKJAAKJJAAA. + ..NNLJJKKJJLAAA. + ..N.LACKJCALAAA. + ....LAKKKKALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ + ................ +} +# tile 728 (Neferet the Green,male) +{ + ................ + ................ + ......GGG....... + .....GFFFG...... + ....GFEFEG...... + ....GFFFFEG..... + .N.GPEFFFEE..... + .I..BBEAAEA.AA.. + .I.BBPPBBEEAAAA. + .IGBPPPPPEEEAA.. + .I.PP.EPEAAGAA.. + .I...BPPPAAAAA.. + .N...BPPPEAA.A.. + ....BPPPPPEA.... + ...BPPPPPPPE.... + ................ +} +# tile 729 (Neferet the Green,female) +{ + ................ + ................ + ......GGG....... + .....GFFFG...... + ....GFEFEG...... + ....GFFFFEG..... + .N.GPEFFFEE..... + .I..BBEAAEA.AA.. + .I.BBPPBBEEAAAA. + .IGBPPPPPEEEAA.. + .I.PP.EPEAAGAA.. + .I...BPPPAAAAA.. + .N...BPPPEAA.A.. + ....BPPPPPEA.... + ...BPPPPPPPE.... + ................ +} +# tile 730 (Minion of Huhetotl,male) +{ + ...OP......PO... + ...OODDDDDDOOD.. + ..DLOOCDDCOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDKKKDAADJJDCDD + CCDKDDKKKJDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 731 (Minion of Huhetotl,female) +{ + ...OP......PO... + ...OODDDDDDOOD.. + ..DLOOCDDCOOLDD. + .DDDLDDDDDDLDDD. + .CCDDDNDDNDDDCC. + CCDKDDDDDDDDJCCC + CDDKKDDIIDDJJCCD + CDDKKKDAADJJDCDD + CCDKDDKKKJDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 732 (Thoth Amon,male) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....BPAAPP.AAA. + ....BPPPPPPPAAA. + ...PPBPPPPJPPAA. + ...PPAPPP.APPA.A + ...PA.BPP.AAPA.A + ...LA.BPP..AL.A. + ......BPA.A..A.. + ......BPAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 733 (Thoth Amon,female) +{ + ................ + ......OJJO...... + ......JJJJA..... + ......BLBLA..... + ......LLLLA..... + ......ALLA...... + .....BPAAPP.AAA. + ....BPPPPPPPAAA. + ...PPBPPPPJPPAA. + ...PPAPPP.APPA.A + ...PA.BPP.AAPA.A + ...LA.BPP..AL.A. + ......BPA.A..A.. + ......BPAPAAAA.. + .....PPA.PPA.... + ................ +} +# tile 734 (Chromatic Dragon,male) +{ + ......GGGFA..... + .....NFNFEEA.... + ....GFFFEECA.... + ..DCHHF..CCA.... + CHCHCD..BCCA.... + HD.D...BFFA..... + ......OBFAAAAAA. + ....HOGFAAAAAAAA + ..HOOIEA.EF.AAA. + .HOOOIEEEEFFJAA. + .HOOOIEEFFFDDAA. + HBOOIIEFFFDDCCA. + HB.OIEFOODD.CJA. + HBAAGE.AADDACCA. + ....GFAA...CCJA. + ........FFFFJA.. +} +# tile 735 (Chromatic Dragon,female) +{ + ......GGGFA..... + .....NFNFEEA.... + ....GFFFEECA.... + ..DCHHF..CCA.... + CHCHCD..BCCA.... + HD.D...BFFA..... + ......OBFAAAAAA. + ....HOGFAAAAAAAA + ..HOOIEA.EF.AAA. + .HOOOIEEEEFFJAA. + .HOOOIEEFFFDDAA. + HBOOIIEFFFDDCCA. + HB.OIEFOODD.CJA. + HBAAGE.AADDACCA. + ....GFAA...CCJA. + ........FFFFJA.. +} +# tile 736 (Goblin King,male) +{ + ................ + ................ + .H..H...H....... + CLC.HCHCH....... + CLC.HHHHH....... + .H..IIIII....... + .HK.IHIHI.I..... + .HICKIIIJKK..... + .H.IIJJJK.AA.... + .H..JICJJAAAAA.. + .H..IIIIJAAAAA.. + ....JIIJJAA..... + ....IJKJJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 737 (Goblin King,female) +{ + ................ + ................ + .H..H...H....... + CLC.HCHCH....... + CLC.HHHHH....... + .H..IIIII....... + .HK.IHIHI.I..... + .HICKIIIJKK..... + .H.IIJJJK.AA.... + .H..JICJJAAAAA.. + .H..IIIIJAAAAA.. + ....JIIJJAA..... + ....IJKJJA...... + ...IKAA.IK...... + ................ + ................ +} +# tile 738 (Cyclops,male) +{ + ................ + ....LLLLL....... + ...CLLLLLC...... + ...LBABNNL...... + ...LBBBNNLJA.... + ...CLNNNLCJA.... + ....LLLLLJAAA... + ....LAALLAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.GGGHGGACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 739 (Cyclops,female) +{ + ................ + ....LLLLL....... + ...CLLLLLC...... + ...LBABNNL...... + ...LBBBNNLJA.... + ...CLNNNLCJA.... + ....LLLLLJAAA... + ....LAALLAAAA... + ..JKJLLLKAKJAA.A + .CLKAJJJJAKLCAAA + .LLJKAAAAKJLLAA. + .LAAJKKKKJAALAA. + .LC.GGGHGGACLAAA + .LL.JJJJJJALLAAA + ....CJJJCLAAAAAA + ..LLLLL.LLLLLAA. +} +# tile 740 (Ixoth,male) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDGDDGDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 741 (Ixoth,female) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDGDDGDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 742 (Master Kaen,male) +{ + ................ + .......KKA...... + ......KJJKA..... + ..KKA.KAAKA.KKA. + .KAAKAKDDKAKAAKA + .KOOJKKOOKKKOOJA + .KJJJJJJJJJKJJJA + ..KJJJJJJJJJJJA. + ....KJJJJJJJA... + ......KJJJAAAAAA + .....KJJJJKAAAAA + .....KJJJJJAAAAA + ....KJJJJJJKAAA. + ...KJJJJJJJJKAA. + ...KJJJJJJJJJA.. + ................ +} +# tile 743 (Master Kaen,female) +{ + ................ + .......KKA...... + ......KJJKA..... + ..KKA.KAAKA.KKA. + .KAAKAKDDKAKAAKA + .KOOJKKOOKKKOOJA + .KJJJJJJJJJKJJJA + ..KJJJJJJJJJJJA. + ....KJJJJJJJA... + ......KJJJAAAAAA + .....KJJJJKAAAAA + .....KJJJJJAAAAA + ....KJJJJJJKAAA. + ...KJJJJJJJJKAA. + ...KJJJJJJJJJA.. + ................ +} +# tile 744 (Nalzok,male) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDBDDBDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 745 (Nalzok,female) +{ + ....O......O.... + ....O......O.... + ...LOOCDDCOOL... + ...DDDDDDDDDDD.. + .CCDDDBDDBDDDCC. + CCDKDDDDDDDDJCCC + CDDKKKDIIDJJDCCD + CDDKDDKJJJDDDCDD + CCDKDDDDDDDDKCDD + .CCDKKDDDDKKCDDD + .CCDADKDDKDACDD. + .DDDADDDDDDADDD. + ....CCDDDDKKAA.. + ...CDDDAADDDKAA. + ..CDDDAAA.DDDK.. + ................ +} +# tile 746 (Scorpius,male) +{ + .....JLJLJAA.... + ....JA.JCJCKAA.. + ....AJ.....JJJA. + ....LA......LCKA + .JAKJA......JJJA + ..JJA......ALCJA + .......ALLAJCJKA + ....JJALCCAAJJA. + .JJALLAJCJJJAA.. + JA.LCCAJAJJAAAA. + ..JACJJJAAACCJAA + GGJJJJJAACCAAAJA + .JJGGAJACAAJJAAA + D.JJAAJAACA.JAA. + ...D...JAAJA.JJ. + ........JA.JA... +} +# tile 747 (Scorpius,female) +{ + .....JLJLJAA.... + ....JA.JCJCKAA.. + ....AJ.....JJJA. + ....LA......LCKA + .JAKJA......JJJA + ..JJA......ALCJA + .......ALLAJCJKA + ....JJALCCAAJJA. + .JJALLAJCJJJAA.. + JA.LCCAJAJJAAAA. + ..JACJJJAAACCJAA + GGJJJJJAACCAAAJA + .JJGGAJACAAJJAAA + D.JJAAJAACA.JAA. + ...D...JAAJA.JJ. + ........JA.JA... +} +# tile 748 (Master Assassin,male) +{ + ................ + ................ + ................ + .......AA....... + ......AAAA...... + .....ABLBLA..... + .....AAAAAA..... + ......AAAA...... + .....AAAAAA..PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 749 (Master Assassin,female) +{ + ................ + ................ + ................ + .......AA....... + ......AAAA...... + .....ABLBLA..... + .....AAAAAA..... + ......AAAA...... + .....AAAAAA..PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 750 (Ashikaga Takauji,male) +{ + ................ + ................ + ......AA........ + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LAIIIIALAAA. + ....LALHHLALAAA. + ......IIIIAAAA.. + ......IIAIAA.A.. + .....IIA.IIA.... + ................ +} +# tile 751 (Ashikaga Takauji,female) +{ + ................ + ................ + ......AA........ + .......AAA...... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....IIIAAIIIAAA. + ....LDIIIIDLAAA. + ....LAIIIIALAAA. + ....LALHHLALAAA. + ......IIIIAAAA.. + ......IIAIAA.A.. + .....IIA.IIA.... + ................ +} +# tile 752 (Lord Surtur,male) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLBAAAA. + ...PPDBBBBBBBAA. + ..BDDHDPBPPPPPA. + ..PPHDDPBPPPPPA. + ..LAHDHPBPPAALAA + JLAADDHBBBBAALAA + JJLJDHHPBPPPCLAA + ..LLJBPPABPPLLAA + .....BPPABPPAAAA + ...LLLLJ.BLLLKAA +} +# tile 753 (Lord Surtur,female) +{ + ....PPDDDDAA.... + ....PDDDDDDDA... + ...PPDLLLLDDA... + ...PDPFLLFFDA... + ...PPPLLLLLDA... + ....PLLAALLAAA.. + ...PPALLLLBAAAA. + ...PPDBBBBBBBAA. + ..BDDHDPBPPPPPA. + ..PPHDDPBPPPPPA. + ..LAHDHPBPPAALAA + JLAADDHBBBBAALAA + JJLJDHHPBPPPCLAA + ..LLJBPPABPPLLAA + .....BPPABPPAAAA + ...LLLLJ.BLLLKAA +} +# tile 754 (Dark One,male) +{ + ................ + ......AAA....... + .....AAAAA...... + .....ADADA...... + .....AAAAA...... + ....AAAAAAA..... + ....AAAAAAA..... + ...AAAAAAAAA.... + ...AAAAAAAAA.... + ..AAAAAAAAAAA... + ..AAAAAAAAAAA... + ...AAAAAAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAAA + ................ +} +# tile 755 (Dark One,female) +{ + ................ + ......AAA....... + .....AAAAA...... + .....ADADA...... + .....AAAAA...... + ....AAAAAAA..... + ....AAAAAAA..... + ...AAAAAAAAA.... + ...AAAAAAAAA.... + ..AAAAAAAAAAA... + ..AAAAAAAAAAA... + ...AAAAAAAAA.... + ...AAAAAAAAAA... + ..AAAAAAAAAAAA.. + AAAAAAAAAAAAAAAA + ................ +} +# tile 756 (student,male) +{ + ................ + ................ + .....GGFGG...... + .......G........ + ......NDND...... + ...DDDDDDDD..... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 757 (student,female) +{ + ................ + ................ + .....GGFGG...... + .......G........ + ......NDND...... + ...DDDDDDDD..... + ......LELEA..... + ......LLLLA..... + ......ALLA...... + .....CKAAKJ.AAA. + ....CKKKJJJJAAA. + ....KACKJJAJAAA. + ....LACJKJALAAA. + .....KCJAJJA.A.. + .....CJJ.JKJ.... + ................ +} +# tile 758 (chieftain,male) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + .....HALLAH..... + ....LLHAAHLLAAA. + ....LLLIILLLAAA. + ....LALIILALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 759 (chieftain,female) +{ + ................ + ................ + .......HHA...... + ......HHHHA..... + ......LFLFA..... + ......LLLLA..... + .....HALLAH..... + ....LLHAAHLLAAA. + ....LLLIILLLAAA. + ....LALIILALAAA. + ....LAALLAALAAA. + ....LAJJKJALAAA. + ......LJJLAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ +} +# tile 760 (neanderthal,male) +{ + ................ + ................ + ................ + ......JJJJ...... + .....JJJJJJ..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....JJAJJAJJ.AA. + ...JLLJAAJLLJAA. + ...LLALJJLALLAA. + ....LALCCLALAAA. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 761 (neanderthal,female) +{ + ................ + ................ + ................ + ......JJJJ...... + .....JJJJJJ..... + .....JFLFLJ..... + .....JLLLLJ..... + .....JJDDJA..... + ....JJAJJAJJ.AA. + ...JLLJAAJLLJAA. + ...LLALJJLALLAA. + ....LALCCLALAAA. + ......LA.LAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 762 (High-elf,male) +{ + .........G...... + .......GGF...... + ......GGGGA..... + ......LILIA..... + ......LLLLA..... + ......ALLA...... + ......GAAG..AA.. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LA.GFAALAA.. + ....LA.GFAALAA.. + ....LAGGGFAL.A.. + ......GFAFAA.A.. + ......GFAFAA.... + ......GFAFAA.... + .....KLA.LKA.... +} +# tile 763 (High-elf,female) +{ + .........G...... + .......GGF...... + ......GGGGA..... + ......LILIA..... + ......LLLLA..... + ......ALLA...... + ......GAAG..AA.. + .....LGGGFLAAAA. + ....LAAGFAALAAA. + ....LA.GFAALAA.. + ....LA.GFAALAA.. + ....LAGGGFAL.A.. + ......GFAFAA.A.. + ......GFAFAA.... + ......GFAFAA.... + .....KLA.LKA.... +} +# tile 764 (attendant,male) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......BLB....... + .....CLLLD...... + .....CCKKDA.AAA. + .....LLCLDDAAAA. + ....CCCLDDDDAA.. + ....LALCCDALAA.. + ......LCCDAAAA.. + .....LCCCDAA.A.. + ....LCCCCCDA.... + ................ + ................ +} +# tile 765 (attendant,female) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......BLB....... + .....CLLLD...... + .....CCKKDA.AAA. + .....LLCLDDAAAA. + ....CCCLDDDDAA.. + ....LALCCDALAA.. + ......LCCDAAAA.. + .....LCCCDAA.A.. + ....LCCCCCDA.... + ................ + ................ +} +# tile 766 (page,male) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + .......LLAA..... + ......BAABA.AAA. + .....BPPPPPAAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 767 (page,female) +{ + ................ + ................ + .......BPA...... + ......BPPPA..... + ......PEEPA..... + ......PLLPA..... + .......LLAA..... + ......BAABA.AAA. + .....BPPPPPAAAA. + ....PABPPPAPAAA. + ....LA.PP.ALAAA. + ......BP.PAAAA.. + ......LLALAA.A.. + .....LLA.LLA.... + ................ + ................ +} +# tile 768 (abbot,male) +{ + ................ + ................ + ................ + ................ + ................ + ......KLK....... + ......LLL....... + ....CCLLLJJ..... + ....KCKLKKJAAA.. + ....CDDDDDDAAAA. + ...CDDLALDDDAAA. + ...DALLALLADAA.. + ...DDDDCDDDDAA.. + ....AACCCDAAAA.. + ....CDCCCDDA.A.. + ...CCCCCCCDD.... +} +# tile 769 (abbot,female) +{ + ................ + ................ + ................ + ................ + ................ + ......KLK....... + ......LLL....... + ....CCLLLJJ..... + ....KCKLKKJAAA.. + ....CDDDDDDAAAA. + ...CDDLALDDDAAA. + ...DALLALLADAA.. + ...DDDDCDDDDAA.. + ....AACCCDAAAA.. + ....CDCCCDDA.A.. + ...CCCCCCCDD.... +} +# tile 770 (acolyte,male) +{ + ................ + ................ + ................ + ......JJJJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......CJJCAAAA.. + .....LDDDDDAAAA. + ....CDCCDDDDAAA. + ....L.LCCDALAA.. + ......LCCDAAAA.. + ......LCCDAAAA.. + .....LDCCDDA.A.. + ....LCCCCCDD.... + ................ +} +# tile 771 (acolyte,female) +{ + ................ + ................ + ................ + ......JJJJ...... + ......JLLJA..... + ......LLLLA..... + ......ALLJA..... + ......CJJCAAAA.. + .....LDDDDDAAAA. + ....CDCCDDDDAAA. + ....L.LCCDALAA.. + ......LCCDAAAA.. + ......LCCDAAAA.. + .....LDCCDDA.A.. + ....LCCCCCDD.... + ................ +} +# tile 772 (hunter,male) +{ + ................ + ................ + ................ + ....J..CJA...... + ...J..CJJJA..... + ...J..JEEJA..... + ..J...JLLJA..... + ..J...ALLAA..... + ..J..GGAAGG.AAA. + ..LPBPFFFFPPAAA. + ..J..AGFFFAPAAA. + ..J....FF.ALAAA. + ...J..BP.PAAAA.. + ...J..BPAPAA.A.. + ....JPPA.PPA.... + ................ +} +# tile 773 (hunter,female) +{ + ................ + ................ + ................ + ....J..CJA...... + ...J..CJJJA..... + ...J..JEEJA..... + ..J...JLLJA..... + ..J...ALLAA..... + ..J..GGAAGG.AAA. + ..LPBPFFFFPPAAA. + ..J..AGFFFAPAAA. + ..J....FF.ALAAA. + ...J..BP.PAAAA.. + ...J..BPAPAA.A.. + ....JPPA.PPA.... + ................ +} +# tile 774 (thug,male) +{ + ................ + ................ + ................ + .......ID....... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + .....KKAAKKA..A. + ....KKJKKJJKAAA. + ....KAAJJAAKAA.. + ....LAJJJJALAA.. + ......KKJKAAAA.. + ......KAAKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 775 (thug,female) +{ + ................ + ................ + ................ + .......ID....... + ......IDDDA..... + ......LKLKA..... + ......LLLLA..... + ......ALLA...... + .....KKAAKKA..A. + ....KKJKKJJKAAA. + ....KAAJJAAKAA.. + ....LAJJJJALAA.. + ......KKJKAAAA.. + ......KAAKAAAA.. + .....KKA.KKA.... + ................ +} +# tile 776 (ninja,male) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....AFLFLA..... + .....AAAAAA..... + ......AAAA...... + ....AAAAAAAA.PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 777 (ninja,female) +{ + ................ + ................ + .........AA..... + .......AAA...... + ......AAAAA..... + .....AFLFLA..... + .....AAAAAA..... + ......AAAA...... + ....AAAAAAAA.PP. + ....AAAAAAAAPPP. + ....AAAAAAAAPPP. + ....LAAAAAALPPP. + ......AAAAAPPP.. + ......AAAAAP.P.. + .....AAA.AAA.... + ................ +} +# tile 778 (roshi,male) +{ + ................ + ................ + ................ + .......AAAAA.... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....PPPAAPPPAAA. + ....L.PPPP.LAAA. + ....LAOOOOALAAA. + ....LAOOOOALAAA. + ......P...AAAA.. + ......P.A.AA.A.. + .....PPA.PPA.... + ................ +} +# tile 779 (roshi,female) +{ + ................ + ................ + ................ + .......AAAAA.... + ......AAAAA..... + .....ALFLFA..... + .....ALLLLA..... + ......ALLA...... + ....PPPAAPPPAAA. + ....L.PPPP.LAAA. + ....LAOOOOALAAA. + ....LAOOOOALAAA. + ......P...AAAA.. + ......P.A.AA.A.. + .....PPA.PPA.... + ................ +} +# tile 780 (guide,male) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HHAAHH.AAA. + ....LLHHHHLLAAA. + ....LAHHHHALAAA. + ....LAHHHHALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 781 (guide,female) +{ + ................ + ................ + ......JKJJA..... + ......KJJJA..... + ....JJJJJJJJ.... + ......LFLFAA.... + ......LLLLA..... + ......ALLA...... + .....HHAAHH.AAA. + ....LLHHHHLLAAA. + ....LAHHHHALAAA. + ....LAHHHHALAAA. + ......JJJKAAAA.. + ......JJAKAA.A.. + .....LLA.LLA.... + ................ +} +# tile 782 (warrior,male) +{ + .....O....O..... + .....NO..ON..... + ......NPPN...... + .....PPPPPP..... + .....PELELP..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ +} +# tile 783 (warrior,female) +{ + .....O....O..... + .....NO..ON..... + ......NPPN...... + .....PPPPPP..... + .....PELELP..... + ....HHLLLLH..... + ...HHHALLA...... + ...HJKJAAKJJAAA. + ..HHLJJKKJJLAAA. + ..H.LACKJCALAAA. + ....LAAKKAALAAA. + ......KKJKAAAA.. + ......KJAJAA.A.. + ......KJAJAA.A.. + .....KLA.LKA.... + ................ +} +# tile 784 (apprentice,male) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......GLG....... + .....BLLLE...... + .....BBEEEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 785 (apprentice,female) +{ + ................ + ................ + ................ + ......JJJ....... + .....JLLLJ...... + ......GLG....... + .....BLLLE...... + .....BBEEEA.AAA. + .....BBPBEEAAAA. + ....PPPBEEEEAA.. + ....LABPPEALAA.. + ......BPPEAAAA.. + .....BPPPEAA.A.. + .....BPPPPEA.... + ....BPPPPPPE.... + ................ +} +# tile 786 (invisible monster, nogender) +{ + ................ + ................ + .....NNNN....... + ....NNNNNN...... + ...NNAAAANN..... + ...NNA...NNA.... + ....AA...NNA.... + ........NNAA.... + .......NNAA..... + ......NNAA...... + ......NNA....... + .......AA....... + ......NN........ + ......NNA....... + .......AA....... + ................ +} diff --git a/win/share/tiletext.c b/win/share/tiletext.c index 0970e0e14..c07c96431 100644 --- a/win/share/tiletext.c +++ b/win/share/tiletext.c @@ -44,7 +44,9 @@ static int grayscale = 0; /* grayscale color mapping */ static const int graymappings[] = { /* . A B C D E F G H I J K L M N O P */ - 0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14 + 0, 1, 17, 18, 19, 20, 27, 22, 23, 24, 25, 26, 21, 15, 13, 14, 14, + /* Q R S T U V W */ + 1, 17, 18, 19, 20, 27, 22 }; void From 51e5e9c998e11b48bb43175d62f1d9138d6423d2 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 21:28:50 -0500 Subject: [PATCH 694/708] extraneous file --- win/share/monsters.txt.keep | 14944 ---------------------------------- 1 file changed, 14944 deletions(-) delete mode 100644 win/share/monsters.txt.keep diff --git a/win/share/monsters.txt.keep b/win/share/monsters.txt.keep deleted file mode 100644 index e80b56448..000000000 --- a/win/share/monsters.txt.keep +++ /dev/null @@ -1,14944 +0,0 @@ -. = (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) -# tile 0 (giant ant,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......JAJKKA... - .....JAAAKJJJA.. - .....AKJJAJJAA.. - ...KKAJJJAAA.... - ..BJJAAAAAJJA... - ..JBJAJAJAA..... - .....AJA.JA..... - ......JA.JA..... - ................ -} -# tile 1 (giant ant,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......J......... - ......AJAJKKA... - ....JJAAAKJJJA.. - ....AAKJJAJJAA.. - ...KKAJJJAAA.... - ..BJJAAAAAJJ.... - ..JBJAJAJAAAJ... - .....AJA.JA..... - ......JA.JA..... - ................ -} -# tile 2 (killer bee,male) -{ - ................ - ................ - .PPP.....PP..... - PPPPP...PBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAA.. - ABJBBJJJJAHAHH.. - .JJABJAJ.J.HH... - .......J.J...... - ................ - ...AAAAAAAAAAA.. - .....AAAAAA..... - ................ -} -# tile 3 (killer bee,female) -{ - ................ - ................ - .PPP.....PP..... - PPPPP...PBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAA.. - ABJBBJJJJAHAHH.. - .JJABJAJ.J.HH... - .......J.J...... - ................ - ...AAAAAAAAAAA.. - .....AAAAAA..... - ................ -} -# tile 4 (soldier ant,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......JAJKKA... - .....JAAAKJJJA.. - .....AKJJAJJAA.. - .JJKKAJJJAAA.... - JBJJJAAAAAJJA... - JJJBJAJAJAA..... - JAAJJAJA.JA..... - ..JJAAJA.JA..... - ................ -} -# tile 5 (soldier ant,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ......JJAJKKA... - ....JJAAAKJJJA.. - ....AAKJJAJJAA.. - .JJKKAJJJAAA.... - JBJJJAAAAAJJ.... - JJJBJAJAJAAAJ... - JAAJJAJA.JA..... - ..JJAAJA.JA..... - ................ -} -# tile 6 (fire ant,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......DACCCA... - .....DAAACDDDA.. - .....ACDDADDAA.. - ...CCADDDAAA.... - ..GDDAAAAADDA... - ..DGDADADAA..... - .....ADA.DA..... - ......DA.DA..... - ................ -} -# tile 7 (fire ant,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......D......... - ......ADACCCA... - ....DDAAACDDDA.. - ....AACDDADDAA.. - ...CCADDDAAA.... - ..GDDAAAAADD.... - ..DGDADADAAAD... - .....ADA.DA..... - ......DA.DA..... - ................ -} -# tile 8 (giant beetle,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......KKDKK..... - ....KACLCJJD.... - ...KCLCJJDDDK... - ...DCCJDADDAD... - ...ADJDDDDDDD... - ...BAKDDAADKAA.. - ...ABAKDDK...... - ......AA.AA..... - ................ - ................ -} -# tile 9 (giant beetle,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......KKDKK..... - ....KACLCJJD.... - ...KCLCJJDDDK... - ...DCCJDADDAD... - ...ADJDDDDDDD... - ...BAKDDAADKAA.. - ...ABAKDDK...... - ......AA.AA..... - ................ - ................ -} -# tile 10 (queen bee,male) -{ - ................ - .PPP.....PP..... - PPPPP...PPPP.... - PPPPP..PPBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAAH. - ABJBBJJJJAHAHHH. - .JJABJAJ.JHHHAA. - ...J...J.JAAAHH. - ..JJ..JJ.J.HHAH. - ..JAAAJAAJ..HH.. - .....AAAAAA..... - ................ -} -# tile 11 (queen bee,female) -{ - ................ - .PPP.....PP..... - PPPPP...PPPP.... - PPPPP..PPBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAAH. - ABJBBJJJJAHAHHH. - .JJABJAJ.JHHHAA. - ...J...J.JAAAHH. - ..JJ..JJ.J.HHAH. - ..JAAAJAAJ..HH.. - .....AAAAAA..... - ................ -} -# tile 12 (acid blob,male) -{ - ................ - ................ - ................ - .....KDDA....... - ...DDKDDKA...... - .DDDIIIDJDA..... - D.IIOOIIDAIA.... - .DKNNNODIDA..IA. - IDJNANOJDDJA.... - ADIDNOIDIDDDA... - ...JDIKIADKIA... - .IA.IDID.JDA.... - ...I.DDA....DA.. - .........IA..... - ..IA............ - ................ -} -# tile 13 (acid blob,female) -{ - ................ - ................ - ................ - .....KDDA....... - ...DDKDDKA...... - .DDDIIIDJDA..... - D.IIOOIIDAIA.... - .DKNNNODIDA..IA. - IDJNANOJDDJA.... - ADIDNOIDIDDDA... - ...JDIKIADKIA... - .IA.IDID.JDA.... - ...I.DDA....DA.. - .........IA..... - ..IA............ - ................ -} -# tile 14 (quivering blob,male) -{ - ................ - ................ - .....PPPP....... - .........P...... - .P.OOOPPE..AAA.. - P.OPBBBPOEAEAA.. - P.PBNNNP.OEAAEA. - P.PNNNNNPOEEAEA. - POPNAANNEO.OAEA. - .OPNAANNE..OAAA. - .OPBNNNEPP.OEAA. - BPOPEEEBBPO.EEA. - BBBPBBBBBBPPPPA. - ..BBBBBBBBBBPA.. - ................ - ................ -} -# tile 15 (quivering blob,female) -{ - ................ - ................ - .....PPPP....... - .........P...... - .P.OOOPPE..AAA.. - P.OPBBBPOEAEAA.. - P.PBNNNP.OEAAEA. - P.PNNNNNPOEEAEA. - POPNAANNEO.OAEA. - .OPNAANNE..OAAA. - .OPBNNNEPP.OEAA. - BPOPEEEBBPO.EEA. - BBBPBBBBBBPPPPA. - ..BBBBBBBBBBPA.. - ................ - ................ -} -# tile 16 (gelatinous cube,male) -{ - ................ - ................ - ................ - ................ - ................ - .......LLL...... - .....LLLLLLLL... - ...LLLLLLLLLD... - ...CLLLLLLLDDA.. - ...CGGCLLLDDDAA. - ...CAGCGGDDDDAAA - ...CCCCAGDDDAAAA - .....CCCCDDAAAA. - .......CCDAAA... - ................ - ................ -} -# tile 17 (gelatinous cube,female) -{ - ................ - ................ - ................ - ................ - ................ - .......LLL...... - .....LLLLLLLL... - ...LLLLLLLLLD... - ...CLLLLLLLDDA.. - ...CGGCLLLDDDAA. - ...CAGCGGDDDDAAA - ...CCCCAGDDDAAAA - .....CCCCDDAAAA. - .......CCDAAA... - ................ - ................ -} -# tile 18 (chickatrice,male) -{ - ................ - ................ - ................ - ................ - .......OO....... - ......HAOO...... - .....HHOOH.HHA.. - ........OOHOA... - ........OOFA.... - ........FGGFA... - ........AGFGAA.. - ...........GA... - .......F..FFA... - .......AFFAA.... - ........AA...... - ................ -} -# tile 19 (chickatrice,female) -{ - ................ - ................ - ................ - ................ - .......OO....... - ......HAOO...... - .....HHOOH.HHA.. - ........OOHOA... - ........OOFA.... - ........FGGFA... - ........AGFGAA.. - ...........GA... - .......F..FFA... - .......AFFAA.... - ........AA...... - ................ -} -# tile 20 (cockatrice,male) -{ - ................ - ...D.DD......... - ....DD.......... - ....NL..AA...... - ..HHAN.AAA...... - .HH.NO..AAAA.... - ...AOOLFFFAA.... - ...OOLKGGFFAA... - ...AOAGGFGFFAA.. - .......GFFGFAA.. - .........FGGAA.. - .....FA...FFA... - ....FA....FFA... - ....FA..FFFA.... - .....FFFFA...... - ................ -} -# tile 21 (cockatrice,female) -{ - ................ - ...D.DD......... - ....DD.......... - ....NL..AA...... - ..HHAN.AAA...... - .HH.NO..AAAA.... - ...AOOLFFFAA.... - ...OOLKGGFFAA... - ...AOAGGFGFFAA.. - .......GFFGFAA.. - .........FGGAA.. - .....FA...FFA... - ....FA....FFA... - ....FA..FFFA.... - .....FFFFA...... - ................ -} -# tile 22 (pyrolisk,male) -{ - ................ - ...D.DD......... - ....DD.......... - ....NB..AA...... - ..HHAN.AAA...... - .HH.NB..AAAA.... - ...APBBJJJAA.... - ...PPPKDDKJAA... - ...APADDKDKJAA.. - .......DJKDJAA.. - .........JDDAA.. - .....JA...JJA... - ....JA....JJA... - ....KA..KKKA.... - .....JKKKA...... - ................ -} -# tile 23 (pyrolisk,female) -{ - ................ - ...D.DD......... - ....DD.......... - ....NB..AA...... - ..HHAN.AAA...... - .HH.NB..AAAA.... - ...APBBJJJAA.... - ...PPPKDDKJAA... - ...APADDKDKJAA.. - .......DJKDJAA.. - .........JDDAA.. - .....JA...JJA... - ....JA....JJA... - ....KA..KKKA.... - .....JKKKA...... - ................ -} -# tile 24 (jackal,male) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOAOOOOOOOAA.. - ..AAOOOOOOOOAA.. - ....OJOOOOOLAA.. - ....OJOLKALKAA.. - ...OOAOAAAOAA... - .....OO..OOA.... - ................ -} -# tile 25 (jackal,female) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOAOOOOOOOAA.. - ..AAOOOOOOOOAA.. - ....OJOOOOOLAA.. - ....OJOLKALKAA.. - ...OOAOAAAOAA... - .....OO..OOA.... - ................ -} -# tile 26 (fox,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....C........... - ....C........... - ..CCAC...CCC.... - ..ACCCCCCACCC... - ...AACCCC.ACC... - ....ACAAC..AA... - ...AC.ACA....... - ................ -} -# tile 27 (fox,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....C........... - ....C........... - ..CCAC...CCC.... - ..ACCCCCCACCC... - ...AACCCC.ACC... - ....ACAAC..AA... - ...AC.ACA....... - ................ -} -# tile 28 (coyote,male) -{ - ................ - ................ - ................ - ...K..K......... - ...K.KK......KKK - ..KKKK......KKKA - ..NCNK.KKKKKAAA. - .KCCKKKKKKKKK... - KKCKAKKKKKKKK... - DKKKAKAKKKKAK... - ..AAKAAKAAAAK... - ....AKAKAAAAK... - ...AKKAKA.AKK... - .....AKK........ - ................ - ................ -} -# tile 29 (coyote,female) -{ - ................ - ................ - ................ - ...K..K......... - ...K.KK......KKK - ..KKKK......KKKA - ..NCNK.KKKKKAAA. - .KCCKKKKKKKKK... - KKCKAKKKKKKKK... - DKKKAKAKKKKAK... - ..AAKAAKAAAAK... - ....AKAKAAAAK... - ...AKKAKA.AKK... - .....AKK........ - ................ - ................ -} -# tile 30 (werejackal,male) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOALLOOOOOAA.. - ..AALLLLOOOOAA.. - ....LJLLLOOLAA.. - ....LJLLKALKAA.. - ..LLLALAAAOAA... - ...L.LL..OOA.... - ......L......... -} -# tile 31 (werejackal,female) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOALLOOOOOAA.. - ..AALLLLOOOOAA.. - ....LJLLLOOLAA.. - ....LJLLKALKAA.. - ..LLLALAAAOAA... - ...L.LL..OOA.... - ......L......... -} -# tile 32 (little dog,male) -{ - ................ - ................ - ................ - ................ - ...J..J......... - ...J.JJ...K..... - ..JJJJ.....K.... - ..NJNKK....K.A.. - .JJJCKK....K.A.. - .PJJAKCKKCKKAA.. - .DDAACKKCKKKAA.. - ....KJKJCJKJAA.. - ....KJKJJAJJAA.. - ...KKAKAAAKAA... - .....KK...KA.... - ................ -} -# tile 33 (little dog,female) -{ - ................ - ................ - ................ - ................ - ...J..J......... - ...J.JJ...K..... - ..JJJJ.....K.... - ..NJNKK....K.A.. - .JJJCKK....K.A.. - .PJJAKCKKCKKAA.. - .DDAACKKCKKKAA.. - ....KJKJCJKJAA.. - ....KJKJJAJJAA.. - ...KKAKAAAKAA... - .....KK...KA.... - ................ -} -# tile 34 (dingo,male) -{ - ................ - ................ - ................ - .............C.. - ...C..C.......C. - ...C.CC.......CA - ..CCCCK.......CA - ..ACACCKCCCCCCAA - ..LLCCCKCCCLCCCA - .KCCACKCLLLLACCA - ..AACAACLLAAACCA - ....ACACAAAAAACA - ....CCACAAA..CCA - .....ACCA....... - ................ - ................ -} -# tile 35 (dingo,female) -{ - ................ - ................ - ................ - .............C.. - ...C..C.......C. - ...C.CC.......CA - ..CCCCK.......CA - ..ACACCKCCCCCCAA - ..LLCCCKCCCLCCCA - .KCCACKCLLLLACCA - ..AACAACLLAAACCA - ....ACACAAAAAACA - ....CCACAAA..CCA - .....ACCA....... - ................ - ................ -} -# tile 36 (dog,male) -{ - ................ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKK......K.A - .JJJCKKKK....K.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ....KJKKJJJAJJAA - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 37 (dog,female) -{ - ................ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKK......K.A - .JJJCKKKK....K.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ....KJKKJJJAJJAA - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 38 (large dog,male) -{ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKKK.....K.A - .JJJCKKKKK..JK.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ...JKJKKJJJAJJAA - ....KAKJAAAAKJA. - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 39 (large dog,female) -{ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKKK.....K.A - .JJJCKKKKK..JK.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ...JKJKKJJJAJJAA - ....KAKJAAAAKJA. - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 40 (wolf,male) -{ - ................ - ................ - ................ - ...P..P.....P... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPAPPPPPPPPPAA - ..AAP.PP..P.P.AA - ....P.PP...A.PAA - ....PAP.AAAAP.A. - ...PPAPAAAAAPAA. - .....PPAA..PPA.. - ................ -} -# tile 41 (wolf,female) -{ - ................ - ................ - ................ - ...P..P......... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPAPPPPPPPPPAA - ..AAP.PP..P.P.AA - ....P.PP...A.PAA - ....PAP.AAAAP.A. - ...PPAPAAAAAPAA. - .....PPAA..PPA.. - ................ -} -# tile 42 (werewolf,male) -{ - ................ - ................ - ................ - ...P..P.....P... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPALPPPPPPPPAA - ..AALLPL..P.P.AA - ....L.LL...A.PAA - ....LAL.AAAAP.A. - ..LLLALAAAAAPPA. - ...L.LLAA..PP... - .....LL......... -} -# tile 43 (werewolf,female) -{ - ................ - ................ - ................ - ...P..P......... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPALPPPPPPPPAA - ..AALLPL..P.P.AA - ....L.LL...A.PAA - ....LAL.AAAAP.A. - ..LLLALAAAAAPPA. - ...L.LLAA..PP... - .....LL......... -} -# tile 44 (winter wolf cub,male) -{ - ................ - ................ - ................ - ................ - ...N..N......... - ...N.NB...N..... - ..NNNN.....N.... - ..DNDNB....N.A.. - ..NNNNB....N.A.. - .NNNNNNNNNNNAA.. - .DNBBNNNNNNBAA.. - ....NNNNNNNBAA.. - ....NNNBBANBAA.. - ...NBANAAANAA... - .....NB..NBA.... - ................ -} -# tile 45 (winter wolf cub,female) -{ - ................ - ................ - ................ - ................ - ...N..N......... - ...N.NB......... - ..NNNN.....N.... - ..DNDNB....N.A.. - ..NNNNB....N.A.. - .NNNNNNNNNNNAA.. - .DNBBNNNNNNBAA.. - ....NNNNNNNBAA.. - ....NNNBBANBAA.. - ...NBANAAANAA... - .....NB..NBA.... - ................ -} -# tile 46 (warg,male) -{ - ................ - ...P..P....PP... - ...P.PP......P.. - ..PPPP.......P.A - ..N.NPP......P.A - .P..PPPPP....P.A - PPPPDPPPPPPPPPAA - DPPNDPPPPPPPPPAA - ..DDDPPPPPPPPPAA - PNDNP.PPPPPPPPAA - .PPPPAPPPPAPP.A. - ...PAAPPAAAAPPAA - ...PAAP.AAAAP.A. - .PPPAAPAAAAAPAA. - ....PPPAA.PPPA.. - ................ -} -# tile 47 (warg,female) -{ - ................ - ...P..P.....P... - ...P.PP......P.. - ..PPPP.......P.A - ..N.NPP......P.A - .P..PPPPP....P.A - PPPPDPPPPPPPPPAA - DPPNDPPPPPPPPPAA - ..DDDPPPPPPPPPAA - PNDNP.PPPPPPPPAA - .PPPPAPPPPAPP.A. - ...PAAPPAAAAPPAA - ...PAAP.AAAAP.A. - .PPPAAPAAAAAPAA. - ....PPPAA.PPPA.. - ................ -} -# tile 48 (winter wolf,male) -{ - ................ - ................ - ................ - ...N..N.....N... - ...N.NN......N.. - ..NNNN.......N.. - ..DODNN......N.A - .NOONNNNN....N.A - NNONANNNNNNNNNAA - DNNBANNNNNNNNNAA - ..AANNNNNNNBNNAA - ....NBNNNBBANNAA - ....NANBAAAANBA. - ...NNANAAAAANAA. - .....NNAA..NNA.. - ................ -} -# tile 49 (winter wolf,female) -{ - ................ - ................ - ................ - ...N..N......... - ...N.NN......N.. - ..NNNN.......N.. - ..DODNN......N.A - .NOONNNNN....N.A - NNONANNNNNNNNNAA - DNNBANNNNNNNNNAA - ..AANNNNNNNBNNAA - ....NBNNNBBANNAA - ....NANBAAAANBA. - ...NNANAAAAANAA. - .....NNAA..NNA.. - ................ -} -# tile 50 (hell hound pup,male) -{ - ................ - ................ - ................ - ................ - ...C..C......... - ...C.CC...C..... - ..CCCC.....C.... - ..DCDCC....C.A.. - .CCCCCC....C.A.. - .PCCACCCCCCCAA.. - .CHAACCCCCCCAA.. - CHC.CCCCCCCCAA.. - .D..CCCCCACCAA.. - ...CCACAAACAA... - .....CC...CA.... - ................ -} -# tile 51 (hell hound pup,female) -{ - ................ - ................ - ................ - ................ - ...C..C......... - ...C.CC...C..... - ..CCCC.....C.... - ..DCDCC....C.A.. - .CCCCCC....C.A.. - .PCCACCCCCCCAA.. - .CHAACCCCCCCAA.. - CHC.CCCCCCCCAA.. - .D..CCCCCACCAA.. - ...CCACAAACAA... - .....CC...CA.... - ................ -} -# tile 52 (hell hound,male) -{ - ................ - ...C..C....CC... - ...C.CC......C.. - ..CCCC.......C.A - ..DJDCC......C.A - .CCCCCCCC....C.A - CCCCDCCCCCCCCCAA - .CHC.CCCCCCCCCAA - CHC..CCCCCCCCCAA - .D..CCCCCCCCCCAA - ...CCACCCCACC.A. - ...CAACCAAAACCAA - ...CAAC.AAAAC.A. - .CCCAACAAAAACAA. - ....CCCAA.CCCA.. - ................ -} -# tile 53 (hell hound,female) -{ - ................ - ...C..C....CC... - ...C.CC......C.. - ..CCCC.......C.A - ..DJDCC......C.A - .CCCCCCCC....C.A - CCCCDCCCCCCCCCAA - .CHC.CCCCCCCCCAA - CHC..CCCCCCCCCAA - .D..CCCCCCCCCCAA - ...CCACCCCACC.A. - ...CAACCAAAACCAA - ...CAAC.AAAAC.A. - .CCCAACAAAAACAA. - ....CCCAA.CCCA.. - ................ -} -# tile 54 (Cerberus,male) -{ - ................ - ..J..J.......... - ..JJJJ.J..J..... - .NJNJ..J.JJ..... - JJJJKAJJJJ....J. - PJJJJANJNKK...J. - DJKJAJJJKJJK..J. - ..AAJPJKAJKJKJJ. - ..JJJDDAJKJJJJJA - ..JJJAAJJJJJJJJA - .JKKKJJJKJJKJJAA - .JJAAKJJKJJJKJAA - JJAAAAJJAAAAJJA. - JAAAAAJAAAAAJAA. - .....JJAA...JA.. - ................ -} -# tile 55 (Cerberus,female) -{ - ................ - ..J..J.......... - ..JJJJ.J..J..... - .NJNJ..J.JJ..... - JJJJKAJJJJ....J. - PJJJJANJNKK...J. - DJKJAJJJKJJK..J. - ..AAJPJKAJKJKJJ. - ..JJJDDAJKJJJJJA - ..JJJAAJJJJJJJJA - .JKKKJJJKJJKJJAA - .JJAAKJJKJJJKJAA - JJAAAAJJAAAAJJA. - JAAAAAJAAAAAJAA. - .....JJAA...JA.. - ................ -} -# tile 56 (gas spore,male) -{ - ................ - ................ - ................ - .....PFGGFP..... - ....PGFFFFFP.... - ...PFFFFFGGFP... - ...FFGGFFGGFF... - ...GFGGFFFFFG... - ...GFFFFFFFFG... - ...FFFFGGFFFF... - ...PGGFGGFGGP... - ....PGFFFFGP.... - .....PFGGFP..... - ................ - ................ - ................ -} -# tile 57 (gas spore,female) -{ - ................ - ................ - ................ - .....PFGGFP..... - ....PGFFFFFP.... - ...PFFFFFGGFP... - ...FFGGFFGGFF... - ...GFGGFFFFFG... - ...GFFFFFFFFG... - ...FFFFGGFFFF... - ...PGGFGGFGGP... - ....PGFFFFGP.... - .....PFGGFP..... - ................ - ................ - ................ -} -# tile 58 (floating eye,male) -{ - ................ - ................ - ......ONNNO..... - ....PNNNNNNNP... - ....NNNNNNNNN... - ...ONNBBBBNNNO.. - ...NNBBEEBBNNN.. - ...NNBEAAEBNNN.. - ...ONBEAAEBNNO.. - ....NBBEEBBNN... - ....PNBBBBNNPAA. - ......ONNNOAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 59 (floating eye,female) -{ - ................ - ................ - ......ONNNO..... - ....PNNNNNNNP... - ....NNNNNNNNN... - ...ONNBBBBNNNO.. - ...NNBBEEBBNNN.. - ...NNBEAAEBNNN.. - ...ONBEAAEBNNO.. - ....NBBEEBBNN... - ....PNBBBBNNPAA. - ......ONNNOAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 60 (freezing sphere,male) -{ - ................ - ................ - ......PBBBP..... - ....PBBBBBBBP... - ....BBBBBBBBB... - ...PBPPPBBBBBP.. - ...BBNNBBPPPBB.. - ...BBANPBNNBBB.. - ...PBBPPBANPBP.. - ....BBBBBBPPB... - ....PBBBBBBBPAA. - ......PBBBPAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 61 (freezing sphere,female) -{ - ................ - ................ - ......PBBBP..... - ....PBBBBBBBP... - ....BBBBBBBBB... - ...PBPPPBBBBBP.. - ...BBNNBBPPPBB.. - ...BBANPBNNBBB.. - ...PBBPPBANPBP.. - ....BBBBBBPPB... - ....PBBBBBBBPAA. - ......PBBBPAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 62 (flaming sphere,male) -{ - ................ - ....C...H....... - ....C....O...C.. - ...C..H.CC...C.. - ...C..C.CC..CC.. - ...DCA.DDC.ACC.. - .AHCDCADDCAADC.. - .AACDCDDDDDADD.. - ..ACDDDJJJDDDD.. - ..ADDCAKDDACDD.. - ...ADAKDDCDAD... - ...ADADHCHCAD... - ....DADDDCDAD... - .....DADDDAD.... - ......JJJJJ..... - ................ -} -# tile 63 (flaming sphere,female) -{ - ................ - ....C...H....... - ....C....O...C.. - ...C..H.CC...C.. - ...C..C.CC..CC.. - ...DCA.DDC.ACC.. - .AHCDCADDCAADC.. - .AACDCDDDDDADD.. - ..ACDDDJJJDDDD.. - ..ADDCAKDDACDD.. - ...ADAKDDCDAD... - ...ADADHCHCAD... - ....DADDDCDAD... - .....DADDDAD.... - ......JJJJJ..... - ................ -} -# tile 64 (shocking sphere,male) -{ - ................ - .....PPPPPP..... - ...PPIAAADAPP... - ..PAAAIAAADDAP.. - ..PHAAAPBOAAAP.. - .PAHHAPBBBOAAAP. - .PHAAAPBBBBAHHP. - .PAAAAPPBBBAAAP. - .PAAAIAPPPAAAIP. - .PIIIAAAAAAIIAP. - ..PIAANAAPAAAIP. - ..PIAANAAAPAAP.. - ...PANANAPAPAP.. - ....PPAIAPAPP... - ......PPPPP..... - ................ -} -# tile 65 (shocking sphere,female) -{ - ................ - .....PPPPPP..... - ...PPIAAADAPP... - ..PAAAIAAADDAP.. - ..PHAAAPBOAAAP.. - .PAHHAPBBBOAAAP. - .PHAAAPBBBBAHHP. - .PAAAAPPBBBAAAP. - .PAAAIAPPPAAAIP. - .PIIIAAAAAAIIAP. - ..PIAANAAPAAAIP. - ..PIAANAAAPAAP.. - ...PANANAPAPAP.. - ....PPAIAPAPP... - ......PPPPP..... - ................ -} -# tile 66 (beholder,male) -{ - ....OA..OA...... - ..OA.DADA.OA.OA. - ...DA.DADADADD.. - ..OADDOOOODDADO. - ...DDHOAAOHDDA.. - ...JDHOAAOHDDJ.. - ...DDDOOOODDDD.. - ...DDDDDDDDDDD.. - ...JDAOAAAOADJ.. - ....DDAAOAADD... - ....PDDDDDDDPAA. - ......JDDDJAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 67 (beholder,female) -{ - ....OA..OA...... - ..OA.DADA.OA.OA. - ...DA.DADADADD.. - ..OADDOOOODDADO. - ...DDHOAAOHDDA.. - ...JDHOAAOHDDJ.. - ...DDDOOOODDDD.. - ...DDDDDDDDDDD.. - ...JDAOAAAOADJ.. - ....DDAAOAADD... - ....PDDDDDDDPAA. - ......JDDDJAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 68 (kitten,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ...........K.... - ............C... - ....C.C.....L.A. - ...CCCCJ....C.A. - ...NCNCJCCLCL.A. - ...CCCCJCCLCCAA. - ....IACCLLCCCAA. - .....CACCJCCJA.. - ......CCA..CA... - ................ -} -# tile 69 (kitten,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ...........N.... - ............N... - ....N.N.....C.A. - ...NNNNC....C.A. - ...ENENNNJJNC.A. - ...NNNNNJJJNNAA. - ....IANNJJNNNAA. - .....NANNWNNWA.. - ......NNA..NA... - ................ -} -# tile 70 (housecat,male) -{ - ................ - ................ - ................ - ................ - ................ - ...........K.... - ............C... - ...C.C......L.A. - ..CCCCJ.....C.A. - .CNCNCJCLCLCL.A. - .CCCCCJCLCLCCAA. - ..CICJCCLCLCLAA. - ...AACCLCLCCCAA. - ...CCACCJJCCJA.. - .....CCA...CA... - ................ -} -# tile 71 (housecat,female) -{ - ................ - ................ - ................ - ................ - ................ - ...........N.... - ............N... - ...N.N......C.A. - ..NNNNC.....C.A. - .NANANCNJJJNN.A. - .NNNNNNNJJNNNAA. - ..NINWNJJJNNNAA. - ...AANNNNNNNNAA. - ...NNANNWWNNWA.. - .....NNA...NA... - ................ -} -# tile 72 (jaguar,male) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - ..CC.CJ......C.A - .CCCCCJ......C.A - .GCGCCJCAACCJC.A - .CCCCCJCCCCCCCAA - .CDDDJCAACCAJCAA - ..CCACCAJCCAACAA - ....CACCJJJCCJA. - ....CACAAAAACJA. - ...CKACAAAAACAA. - .....CCAA...CA.. - ................ -} -# tile 73 (jaguar,female) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - ..CC.CJ......C.A - .CCCCCJ......C.A - .GCGCCJCAACCJC.A - .CCCCCJCCCCCCCAA - .CDDDJCAACCAJCAA - ..CCACCAJCCAACAA - ....CACCJJJCCJA. - ....CACAAAAACJA. - ...CKACAAAAACAA. - .....CCAA...CA.. - ................ -} -# tile 74 (lynx,male) -{ - ................ - ................ - ................ - ................ - O....O.......... - AC.CCA.......... - .CCCA........CA. - .GCGCOAKKKKK.LA. - .CKCCAJCCCCCKA.. - LLDDLLACLLLCCAA. - ..CC.AACLLLCCAA. - .......CAAAACAA. - ....CACAAAACCA.. - ................ - ................ - ................ -} -# tile 75 (lynx,female) -{ - ................ - ................ - ................ - ................ - O....O.......... - AC.CCA.......... - .CCCA........CA. - .GCGCOAKKKKK.LA. - .CKCCAJCCCCCKA.. - LLDDLLACLLLCCAA. - ..CC.AACLLLCCAA. - .......CAAAACAA. - ....CACAAAACCA.. - ................ - ................ - ................ -} -# tile 76 (panther,male) -{ - ................ - ................ - ............AA.. - ..............A. - ..............A. - .A...A........A. - .EA.AE........A. - .AAAAAEAAAAAAA.. - .AAAAAEAAAAAAA.. - .HAHAA.AAAAAAAA. - .AAAA.AAAAAEAAA. - .AAA..AAAAAEAAA. - .....AA....AAA.. - ..AAAA..AAAA.... - ................ - ................ -} -# tile 77 (panther,female) -{ - ................ - ................ - ............AA.. - ..............A. - ..............A. - .A...A........A. - .EA.AE........A. - .AAAAAEAAAAAAA.. - .AAAAAEAAAAAAA.. - .HAHAA.AAAAAAAA. - .AAAA.AAAAAEAAA. - .AAA..AAAAAEAAA. - .....AA....AAA.. - ..AAAA..AAAA.... - ................ - ................ -} -# tile 78 (large cat,male) -{ - ................ - ................ - ................ - ................ - ............K... - .............C.. - ...C.C.......L.A - ..CCCCJ......C.A - .CNCNCJCLCCLCL.A - .CCCCCJCLCCLCCAA - ..CDCJCCLCCLCLAA - ...AACCLCCLCCCAA - ....CACCJJJCCJA. - ...CKALAAAAACAA. - .....CCAA...CA.. - ................ -} -# tile 79 (large cat,female) -{ - ................ - ................ - ................ - ................ - ............N... - .............N.. - ...N.N.......C.A - ..NNNNC......C.A - .NANANCNJJJJNN.A - .NNNNNNNJJJNNNAA - ..NDNWNJJJNNNNAA - ...AANNNNNNNNNAA - ....NANNWWWNNWA. - ...NJANAAAAANAA. - .....NNAA...NA.. - ................ -} -# tile 80 (tiger,male) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - .CCJCC.......C.A - .CAACCJ......A.A - .GAGCCJACACAJC.A - .CCCCCACACACACAA - .ODOCACCACACACAA - .OCOACCJACACACAA - ....CACJAJAJCAA. - ....AACAAAAAAJA. - ...CKACAAAAACAA. - .....CCAA..CCA.. - ................ -} -# tile 81 (tiger,female) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - .CCJCC.......C.A - .CAACCJ......A.A - .GAGCCJACACAJC.A - .CCCCCACACACACAA - .ODOCACCACACACAA - .OCOACCJACACACAA - ....CACJAJAJCAA. - ....AACAAAAAAJA. - ...CKACAAAAACAA. - .....CCAA..CCA.. - ................ -} -# tile 82 (displacer beast,male) -{ - ................ - ........E....... - .......E.E..AA.. - DEEEA..A.E....A. - ....EA.E.D....A. - .A...A.E......A. - .EA.AEAAA.....A. - .AAAAAAAAAA..A.. - .AAAAEAAAAAAAA.. - .HAHAEAAAAAAAAA. - .AAAAEAAAAAAAAA. - .AAA.AAAAAAAAAA. - .....AE.AEEA.EA. - ....AE.AE.EA.EA. - ...AE.AE.EA.EA.. - ................ -} -# tile 83 (displacer beast,female) -{ - ................ - ........E....... - .......E.E..AA.. - DEEEA..A.E....A. - ....EA.E.D....A. - .A...A.E......A. - .EA.AEAAA.....A. - .AAAAAAAAAA..A.. - .AAAAEAAAAAAAA.. - .HAHAEAAAAAAAAA. - .AAAAEAAAAAAAAA. - .AAA.AAAAAAAAAA. - .....AE.AEEA.EA. - ....AE.AE.EA.EA. - ...AE.AE.EA.EA.. - ................ -} -# tile 84 (gremlin,male) -{ - ................ - ................ - ................ - GGGA....AGGG.... - .GGGFAAAGGG..... - ..FFFFFFFF...... - ...NDFFDNA...... - ...GNFFNGA...... - ...GFFFFGA..AA.. - ...AGFFFAFAAAAA. - ..GFAGFAFFFAAAA. - .GFGFAAFFAFAAAA. - .GF.GFAGAAFAAAA. - ....FFAGFAA.AA.. - ...GFA.FGA...... - ................ -} -# tile 85 (gremlin,female) -{ - ................ - ................ - ................ - GGGA....AGGG.... - .GGGFAAAGGG..... - ..FFFFFFFF...... - ...NDFFDNA...... - ...GNFFNGA...... - ...GFFFFGA..AA.. - ...AGFFFAFAAAAA. - ..GFAGFAFFFAAAA. - .GFGFAAFFAFAAAA. - .GF.GFAGAAFAAAA. - ....FFAGFAA.AA.. - ...GFA.FGA...... - ................ -} -# tile 86 (gargoyle,male) -{ - ................ - ................ - ...PAPPPPAP..... - ..PA......AP.... - ..P.DD..DDAP.... - ....PD..DPA..... - ....P....PA..AA. - ....AP...A.AAAAA - ...P.AP.A...AAAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 87 (gargoyle,female) -{ - ................ - ................ - ...PAPPPPAP..... - ..PA......AP.... - ..P.DD..DDAP.... - ....PD..DPA..... - ....P....PA..AA. - ....AP...A.AAAAA - ...P.AP.A...AAAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 88 (winged gargoyle,male) -{ - ...K......K..... - ...KJ....KJ..... - ..KJAPPPPAJJ.... - ..KJ......AJ.... - ..KJDD..DDAJ.... - .KJAPD..DPAJJ... - .KJAP....PAAJAA. - KJA.AP...A.AJJAA - J..P.AP.A...AJAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 89 (winged gargoyle,female) -{ - ...K......K..... - ...KJ....KJ..... - ..KJAPPPPAJJ.... - ..KJ......AJ.... - ..KJDD..DDAJ.... - .KJAPD..DPAJJ... - .KJAP....PAAJAA. - KJA.AP...A.AJJAA - J..P.AP.A...AJAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 90 (hobbit,male) -{ - ................ - ................ - ................ - ................ - ......JJA....... - .....JJJJA...... - ....JLFLFJ...... - ....JLLLLJ...... - ....JKLLKJJ.AA.. - ...CLLLLLLCAAA.. - ..CLALLLLALCA... - ..LLAJJKJALLA... - ...L.LKJLALAA... - .....LLALLA.A... - ....LLL.LLL..... - ................ -} -# tile 91 (hobbit,female) -{ - ................ - ................ - ................ - ................ - ......JJA....... - .....JJJJA...... - ....JLFLFJ...... - ....JLLLLJ...... - ....JKLLKJJ.AA.. - ...CLLLLLLCAAA.. - ..CLALJKJALCA... - ..LLAJJKJALLA... - ...L.LKJLALAA... - .....LLALLA.A... - ....LLL.LLL..... - ................ -} -# tile 92 (dwarf,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BLLLE....... - .....OLO...AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 93 (dwarf,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BLLLE....... - .....OLO...AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 94 (bugbear,male) -{ - ................ - ................ - ......K......... - .K..KKK......... - .KKKKKK......... - KADKADKKK....... - KKKKKKKJKK...... - KAPAPAKJJKJ..... - KAAAAAKKJKJJ.... - .KKKKKJKAKKJ.... - ..KAJJCAKKKJ.AA. - ..KK.KKKKKJJAA.. - ...C..KJAKJAA... - .....CCAAKJA.... - ........CCA..... - ................ -} -# tile 95 (bugbear,female) -{ - ................ - ................ - ......K......... - .K..KKK......... - .KKKKKK......... - KADKADKKK....... - KKKKKKKJKK...... - KAPAPAKJJKJ..... - KAAAAAKKJKJJ.... - .KKKKKJKAKKJ.... - ..KAJJCAKKKJ.AA. - ..KK.KKKKKJJAA.. - ...C..KJAKJAA... - .....CCAAKJA.... - ........CCA..... - ................ -} -# tile 96 (dwarf leader,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....HHHHH....... - ....BLLLE....... - ....BOLOE..AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 97 (dwarf leader,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....HHHHH....... - ....BLLLE....... - ....BOLOE..AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 98 (dwarf ruler,male) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....BLLLE...A... - .....OLO...AAAA. - ...EBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 99 (dwarf ruler,female) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....BLLLE...A... - .....OLO...AAAA. - ...EBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 100 (mind flayer,male) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - ....IIIIIC...... - ....IAIAIF...... - ....IAIAIF...... - ....IAIAIFI..... - .....FIFIFIC.AA. - ....CBIBBF.CAAA. - ...IIIBBFFACAAA. - ......BBFCAAAA.. - ......CFFCAA.... - ....IIC.IIA..... -} -# tile 101 (mind flayer,female) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - ....IIIIIC...... - ....IAIAIF...... - ....IAIAIF...... - ....IAIAIFI..... - .....FIFIFIC.AA. - ....CBIBBF.CAAA. - ...IIIBBFFACAAA. - ......BBFCAAAA.. - ......CFFCAA.... - ....IIC.IIA..... -} -# tile 102 (master mind flayer,male) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - .EEEIIIIICEEEE.. - ..EEIAIAIEEEE... - ...EIAIAIEEE.... - ....IAIAIEEE.... - ....EFIFIEEE.AA. - ....CBIBBEEEAAA. - ...IIIBBEEEEAAA. - ....EEBEEEEAAA.. - ...EEECEEEAA.... - ....IIC.IIA..... -} -# tile 103 (master mind flayer,female) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - .EEEIIIIICEEEE.. - ..EEIAIAIEEEE... - ...EIAIAIEEE.... - ....IAIAIEEE.... - ....EFIFIEEE.AA. - ....CBIBBEEEAAA. - ...IIIBBEEEEAAA. - ....EEBEEEEAAA.. - ...EEECEEEAA.... - ....IIC.IIA..... -} -# tile 104 (manes,male) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP......... - ..PPPPP.PPP.P... - ..P..PPPP....... - ..P..PPPPP...P.. - ..PPPPP.PPP..... - ..P.P.P.PP.P.... - .P...P.PPPP..... - .P....PPP.PP.... - ..P....P.P.P.P.. - ........P....... - ................ - ................ -} -# tile 105 (manes,female) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP......... - ..PPPPP.PPP.P... - ..P..PPPP....... - ..P..PPPPP...P.. - ..PPPPP.PPP..... - ..P.P.P.PP.P.... - .P...P.PPPP..... - .P....PPP.PP.... - ..P....P.P.P.P.. - ........P....... - ................ - ................ -} -# tile 106 (homunculus,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ......JJJ....... - ......LLC....... - ......LLC....... - .....BBPPPAA.... - ....L.BPPACAA... - ......BAPAAAA... - .....LLALCA..... - ................ - ................ -} -# tile 107 (homunculus,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ......JJJ....... - ......LLC....... - ......LLC....... - .....BBPPPAA.... - ....L.BPPACAA... - ......BAPAAAA... - .....LLALCA..... - ................ - ................ -} -# tile 108 (imp,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDO...... - ......CDD....... - .....GGFFFAA.... - ....C.GFFADAA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 109 (imp,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDO...... - ......CDD....... - .....GGFFFAA.... - ....C.GFFADAA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 110 (lemure,male) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP....P.... - ..PPPPP..PP.P... - ..P..PPPPPPPP... - ..P..PPPPPPP.... - ..PPPPPPPPP..... - ....PPPPPPPP.... - ..PPPPPPPPPP.... - ...PPPPPPPPPP... - ..P.P..PPPP.PP.. - ........P.PP.... - ................ - ................ -} -# tile 111 (lemure,female) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP....P.... - ..PPPPP..PP.P... - ..P..PPPPPPPP... - ..P..PPPPPPP.... - ..PPPPPPPPP..... - ....PPPPPPPP.... - ..PPPPPPPPPP.... - ...PPPPPPPPPP... - ..P.P..PPPP.PP.. - ........P.PP.... - ................ - ................ -} -# tile 112 (quasit,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDOD..... - ......CDD.D..... - .....GGFFFAA.... - ....C.GFFAAADA.. - ....C.GFFJJDA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 113 (quasit,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDOD..... - ......CDD.D..... - .....GGFFFAA.... - ....C.GFFAAADA.. - ....C.GFFJJDA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 114 (tengu,male) -{ - ................ - .......PP....... - ......PPPP...... - .....DPPNP...... - ....DDDPPP...... - ....DDPPPP...... - ....D..PPA...... - .....PIAAIP.AAA. - ....PPPIIPPPAAA. - ....PAPPPPAPAAA. - ....PAHHHHAPAAA. - ....LAPPPPALAAA. - ......PPPPAAAA.. - ......PPPPAA.A.. - .....LLA.LLA.... - ................ -} -# tile 115 (tengu,female) -{ - ................ - .......PP....... - ......PPPP...... - .....DPPNP...... - ....DDDPPP...... - ....DDPPPP...... - ....D..PPA...... - .....PIAAIP.AAA. - ....PPPIIPPPAAA. - ....PAPPPPAPAAA. - ....PAHHHHAPAAA. - ....LAPPPPALAAA. - ......PPPPAAAA.. - ......PPPPAA.A.. - .....LLA.LLA.... - ................ -} -# tile 116 (blue jelly,male) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OBEBOE.... - ..OBEOBBEOBBE... - ..OBEOBBEOBBE... - ..BBBGGBGGBEEE.. - ..BBBAGBAGEEEEA. - ..BBBBBBEBEEEEAA - ...BBBBBBBEEEAAA - ....BBBBBEEEAAA. - ......BBBEEAA... - ................ - ................ -} -# tile 117 (blue jelly,female) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OBEBOE.... - ..OBEOBBEOBBE... - ..OBEOBBEOBBE... - ..BBBGGBGGBEEE.. - ..BBBAGBAGEEEEA. - ..BBBBBBEBEEEEAA - ...BBBBBBBEEEAAA - ....BBBBBEEEAAA. - ......BBBEEAA... - ................ - ................ -} -# tile 118 (spotted jelly,male) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OCEBOE.... - ..OCEOCCEOBCE... - ..OCEOBCEOCBD... - ..BBBHHBHHBEDD.. - ..CCBAHBAHEEEEA. - ..BBCBBBEBEEDEAA - ...BBBCBBBEEDAAA - ....BCCCBEEDAAA. - ......CCBEEAA... - ................ - ................ -} -# tile 119 (spotted jelly,female) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OCEBOE.... - ..OCEOCCEOBCE... - ..OCEOBCEOCBD... - ..BBBHHBHHBEDD.. - ..CCBAHBAHEEEEA. - ..BBCBBBEBEEDEAA - ...BBBCBBBEEDAAA - ....BCCCBEEDAAA. - ......CCBEEAA... - ................ - ................ -} -# tile 120 (ochre jelly,male) -{ - ................ - ................ - ................ - .......D........ - ......LCD....... - ...CD.LCDCLD.... - ..LCDLCCDLCCD... - ..LCDLCCDLCCD... - ..CCCGGCGGCDDD.. - ..CCCAGCAGDDDDA. - ..CCCCCCDCDDDDAA - ...CCCCCCCDDDAAA - ....CCCCCDDDAAA. - ......CCCDDAA... - ................ - ................ -} -# tile 121 (ochre jelly,female) -{ - ................ - ................ - ................ - .......D........ - ......LCD....... - ...CD.LCDCLD.... - ..LCDLCCDLCCD... - ..LCDLCCDLCCD... - ..CCCGGCGGCDDD.. - ..CCCAGCAGDDDDA. - ..CCCCCCDCDDDDAA - ...CCCCCCCDDDAAA - ....CCCCCDDDAAA. - ......CCCDDAA... - ................ - ................ -} -# tile 122 (kobold,male) -{ - ................ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.A.. - ..BPBBBBPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 123 (kobold,female) -{ - ................ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.A.. - ..BPBBBBPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 124 (large kobold,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.... - ..BPBBBBPAAA.A.. - ..BAPBPAPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 125 (large kobold,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.... - ..BPBBBBPAAA.A.. - ..BAPBPAPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 126 (kobold leader,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NCCCN........ - ...CABAC........ - ...CBBPC..A..... - ..CCBABCC.AA.... - ..CCBBBCCAAA.A.. - ..BCCBCCPAAAAA.. - ..BACBCAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 127 (kobold leader,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NCCCN........ - ...CABAC........ - ...CBBPC..A..... - ..CCBABCC.AA.... - ..CCBBBCCAAA.A.. - ..BCCBCCPAAAAA.. - ..BACBCAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 128 (kobold shaman,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NHHHN........ - ...HABAH........ - ...HBBPH..A..... - ..HHBABHH.AA.... - .HHHBBBHHHAA.A.. - .HBHHBHHPHAAAA.. - ..BAHBHAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 129 (kobold shaman,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NHHHN........ - ...HABAH........ - ...HBBPH..A..... - ..HHBABHH.AA.... - .HHHBBBHHHAA.A.. - .HBHHBHHPHAAAA.. - ..BAHBHAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 130 (leprechaun,male) -{ - ................ - ................ - ................ - ................ - ......G......... - ......F....K.... - .....GFF..KLK... - ....GFFFF..K.... - .....KLKA.GLAA.. - ...FGFJFFFAKA.A. - ...GAGFFAAAK.AA. - ....LKHKKJAKAA.. - ....GFAGKJAKA... - ...GFAA.GFAK.... - ................ - ................ -} -# tile 131 (leprechaun,female) -{ - ................ - ................ - ................ - ................ - ......G......... - ......F....K.... - .....GFF..KLK... - ....GFFFF..K.... - .....KLKA.GLAA.. - ...FGFLFFFAKA.A. - ...GAGFFAAAK.AA. - ....LKHKKJAKAA.. - ....GFAGKJAKA... - ...GFAA.GFAK.... - ................ - ................ -} -# tile 132 (small mimic,male) -{ - ................ - ................ - ................ - ................ - ......POP....... - ......NNO....... - ......NNO....... - .......OA....... - .....NNNNN..AA.. - ....OONNNOO.AA.. - ....NANOOANAAA.. - ......NAOAAAA... - ......NAOAA.A... - .....NN.OOA..... - ................ - ................ -} -# tile 133 (small mimic,female) -{ - ................ - ................ - ................ - ................ - ......POP....... - ......NNO....... - ......NNO....... - .......OA....... - .....NNNNN..AA.. - ....OONNNOO.AA.. - ....NANOOANAAA.. - ......NAOAAAA... - ......NAOAA.A... - .....NN.OOA..... - ................ - ................ -} -# tile 134 (large mimic,male) -{ - ................ - ................ - ................ - ......LLOA...... - ......NNOA...... - ......NNOA...... - ......ONOA...... - .....NNNNO..AAA. - ....OONNNOO.AAA. - ...NOANNNAOOAAA. - ...NAONONOANAAA. - .....NO.NOAAAA.. - .....NO.NOAA.A.. - ....NNO.NOOA.... - ................ - ................ -} -# tile 135 (large mimic,female) -{ - ................ - ................ - ................ - ......LLOA...... - ......NNOA...... - ......NNOA...... - ......ONOA...... - .....NNNNO..AAA. - ....OONNNOO.AAA. - ...NOANNNAOOAAA. - ...NAONONOANAAA. - .....NO.NOAAAA.. - .....NO.NOAA.A.. - ....NNO.NOOA.... - ................ - ................ -} -# tile 136 (giant mimic,male) -{ - ................ - ......NNO....... - .....NNNNOA..... - .....NNNNOA..... - .....NNNNOA..... - .....ONNNOA..... - ..PONNOOONOOPAAA - .PONONNNNOONOPAA - .ONOANNNNOAONOAA - .NNOANNNNOAOOOAA - ...AANNONNAAAAAA - ....PNO.NNPAAAAA - ....ONO.NNOAA..A - ....NNO.NNOAA..A - ...NNNO.NNOOA... - ................ -} -# tile 137 (giant mimic,female) -{ - ................ - ......NNO....... - .....NNNNOA..... - .....NNNNOA..... - .....NNNNOA..... - .....ONNNOA..... - ..PONNOOONOOPAAA - .PONONNNNOONOPAA - .ONOANNNNOAONOAA - .NNOANNNNOAOOOAA - ...AANNONNAAAAAA - ....PNO.NNPAAAAA - ....ONO.NNOAA..A - ....NNO.NNOAA..A - ...NNNO.NNOOA... - ................ -} -# tile 138 (wood nymph,male) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLFKKKKLA.... - .HKFLFKKKKA..... - OHKJFKKJJK.A.... - HKKLJJGKAAAAAAA. - .JJAJGDKJAAAAA.. - ..JA.KKJJAAAA... - ...J.KKKKJAA.... - ....JKKKKKJA.... - ....KJKJKJKJ.... - ................ -} -# tile 139 (wood nymph,female) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLFKKKKLA.... - .HKFLFKKKKA..... - OHKJFKKJJK.A.... - HKKLJJGKAAAAAAA. - .JJAJGDKJAAAAA.. - ..JA.KKJJAAAA... - ...J.KKKKJAA.... - ....JKKKKKJA.... - ....KJKJKJKJ.... - ................ -} -# tile 140 (water nymph,male) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLJBBBBLA.... - .HBJLJBBBBA..... - OHBPJBBPPB.A.... - HBBLPPNBAAAAAAA. - .PPAPNDB.AAAAA.. - ..PA.BBPPAAAA... - ...P.BBBBPAA.... - ....PBBBBBPA.... - ....BPBPBPBP.... - ................ -} -# tile 141 (water nymph,female) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLJBBBBLA.... - .HBJLJBBBBA..... - OHBPJBBPPB.A.... - HBBLPPNBAAAAAAA. - .PPAPNDB.AAAAA.. - ..PA.BBPPAAAA... - ...P.BBBBPAA.... - ....PBBBBBPA.... - ....BPBPBPBP.... - ................ -} -# tile 142 (mountain nymph,male) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLCOOOOLA.... - .HOCLCOOOOA..... - OHOLCOOLLO.A.... - HOOKLLIOAAAAAAA. - .LLALIBOKAAAAA.. - ..LA.OOLLAAAA... - ...L.OOOOLAA.... - ....LOOOOOLA.... - ....OLOLOLOL.... - ................ -} -# tile 143 (mountain nymph,female) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLCOOOOLA.... - .HOCLCOOOOA..... - OHOLCOOLLO.A.... - HOOKLLIOAAAAAAA. - .LLALIBOKAAAAA.. - ..LA.OOLLAAAA... - ...L.OOOOLAA.... - ....LOOOOOLA.... - ....OLOLOLOL.... - ................ -} -# tile 144 (goblin,male) -{ - ................ - ................ - ................ - ....LK.......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IGIGIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICJAAAAA... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 145 (goblin,female) -{ - ................ - ................ - ................ - ....LK.......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IGIGIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICJAAAAA... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 146 (hobgoblin,male) -{ - ................ - .....LK......... - ....CKA......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IHIHIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICCAAAAA... - ....IIIIJA...... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 147 (hobgoblin,female) -{ - ................ - .....LK......... - ....CKA......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IHIHIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICCAAAAA... - ....IIIIJA...... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 148 (orc,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KCCAKKKA.AA... - ..BPCKJ.P.AAA... - ..BAGGFAAPNO.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BJACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 149 (orc,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KCCAKKKA.AA... - ..BPCKJ.P.AAA... - ..BAGGFAAPNO.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BJACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 150 (hill orc,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LKLA........ - .....K.A........ - ..KGGAFFKA.AA... - ..JKGFF.K.AAA... - ..JAHHFAAKNO.... - ..JAGFFNOAAA.... - ....GNNFAAAAAA.. - ...GGAGFAAAA.... - ..KJJAKJJA...... - ................ - ................ -} -# tile 151 (hill orc,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LKLA........ - .....K.A........ - ..KGGAFFKA.AA... - ..JKGFF.K.AAA... - ..JAHHFAAKNO.... - ..JAGFFNOAAA.... - ....GNNFAAAAAA.. - ...GGAGFAAAA.... - ..KJJAKJJA...... - ................ - ................ -} -# tile 152 (Mordor orc,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KIIAIIKA.AA... - ..BPIDD.P.AAA... - ..BAGGFAAP.O.... - ..BAIDDNOAAA.... - ....BNOJAAAAAA.. - ...BIAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 153 (Mordor orc,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KIIAIIKA.AA... - ..BPIDD.P.AAA... - ..BAGGFAAP.O.... - ..BAIDDNOAAA.... - ....BNOJAAAAAA.. - ...BIAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 154 (Uruk-hai,male) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..IIIAIIIA...... - ..BPIKI.BAAAA... - ..BIG.PPPPAAA... - .NBAD.PDDPAA.... - ..BNNJPDDPAA.... - ....INPPPPAAAA.. - ...BIAK.AAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 155 (Uruk-hai,female) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..IIIAIIIA...... - ..BPIKI.BAAAA... - ..BIG.PPPPAAA... - .NBAD.PDDPAA.... - ..BNNJPDDPAA.... - ....INPPPPAAAA.. - ...BIAK.AAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 156 (orc shaman,male) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..CCCACCCA...... - ..BPCKC.BAAAA... - ..BCGGFJBAAAA... - ..BAJJCJBAAA.... - ..BAJJCJBAAA.... - ....CACJAAAAAA.. - ...BCACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 157 (orc shaman,female) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..CCCACCCA...... - ..BPCKC.BAAAA... - ..BCGGFJBAAAA... - ..BAJJCJBAAA.... - ..BAJJCJBAAA.... - ....CACJAAAAAA.. - ...BCACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 158 (orc-captain,male) -{ - ................ - ................ - .....OA......... - ...NNOOPA....... - ....LPLA........ - ...IPPPA........ - ..DIIPADDA.AA... - ..BPIAD.P.AAA... - ..BAGGFAAP.O.... - ..BAGGFAAP.O.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BDAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 159 (orc-captain,female) -{ - ................ - ................ - .....OA......... - ...NNOOPA....... - ....LPLA........ - ...IPPPA........ - ..DIIPADDA.AA... - ..BPIAD.P.AAA... - ..BAGGFAAP.O.... - ..BAGGFAAP.O.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BDAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 160 (rock piercer,male) -{ - .JKKKKKKKKJAAA.. - ..JJGKGKJJAAAA.. - ...JKKKJJAAAA... - ...JJKKJJAAAA... - ....JKKJAAAA.... - ....JJKJ.AAA.... - ....JJKJ.AAA.... - ....JJJJ..A..... - .....JJ...A..... - .....JJ...A..... - .....JJ......... - .....JJ......... - .....J.......... - .....J.......... - ................ - ................ -} -# tile 161 (rock piercer,female) -{ - .JKKKKKKKKJAAA.. - ..JJGKGKJJAAAA.. - ...JKKKJJAAAA... - ...JJKKJJAAAA... - ....JKKJAAAA.... - ....JJKJ.AAA.... - ....JJKJ.AAA.... - ....JJJJ..A..... - .....JJ...A..... - .....JJ...A..... - .....JJ......... - .....JJ......... - .....J.......... - .....J.......... - ................ - ................ -} -# tile 162 (iron piercer,male) -{ - .BPPPPPPPP.AAA.. - ..BBDPDP..AAAA.. - ...BPPP..AAAA... - ...PBPP..AAAA... - ....BPP.AAAA.... - ....BBP.AAAA.... - ....PBP.AAAA.... - ....PBP...A..... - .....BP...A..... - .....BP...A..... - .....BP......... - .....BP......... - .....B.......... - .....P.......... - ................ - ................ -} -# tile 163 (iron piercer,female) -{ - .BPPPPPPPP.AAA.. - ..BBDPDP..AAAA.. - ...BPPP..AAAA... - ...PBPP..AAAA... - ....BPP.AAAA.... - ....BBP.AAAA.... - ....PBP.AAAA.... - ....PBP...A..... - .....BP...A..... - .....BP...A..... - .....BP......... - .....BP......... - .....B.......... - .....P.......... - ................ - ................ -} -# tile 164 (glass piercer,male) -{ - .NBBBBBBBBPAAA.. - ..NNDBDBPPAAAA.. - ...NBBBPPAAAA... - ...PNBBPPAAAA... - ....NBBPAAAA.... - ....NNBPAAAA.... - ....PNBPAAAA.... - ....PNBP..A..... - .....NB...A..... - .....NB...A..... - .....NB......... - .....NB......... - .....N.......... - .....P.......... - ................ - ................ -} -# tile 165 (glass piercer,female) -{ - .NBBBBBBBBPAAA.. - ..NNDBDBPPAAAA.. - ...NBBBPPAAAA... - ...PNBBPPAAAA... - ....NBBPAAAA.... - ....NNBPAAAA.... - ....PNBPAAAA.... - ....PNBP..A..... - .....NB...A..... - .....NB...A..... - .....NB......... - .....NB......... - .....N.......... - .....P.......... - ................ - ................ -} -# tile 166 (rothe,male) -{ - ................ - ...........K.... - ............K... - ............K... - .......JJJKKJ... - .....JKKKKKKK... - ..AAAKKKKKKKK... - .AAAAAKKKKKKKA.. - AAKKAAKKKKKAKA.. - .KEKKAKKKJAAKA.. - .KKKJAKKAJAAK... - ..KJAAAKAAA..... - ..AAKA.KA....... - ..A..A.K........ - ................ - ................ -} -# tile 167 (rothe,female) -{ - ................ - ...........K.... - ............K... - ............K... - .......JJJKKJ... - .....JKKKKKKK... - ..AAAKKKKKKKK... - .AAAAAKKKKKKKA.. - AAKKAAKKKKKAKA.. - .KEKKAKKKJAAKA.. - .KKKJAKKAJAAK... - ..KJAAAKAAA..... - ..AAKA.KA....... - ..A..A.K........ - ................ - ................ -} -# tile 168 (mumak,male) -{ - ................ - ...........P.... - .PP.........P... - PPP...PPPPP.P... - PPPPPPPPP.PP.... - PPPPBPPBBP.PP... - PPPBPPPPPP.PP... - .PDPPDDPP.PPP... - ..BPPDDP.PPPPA.. - ..PPPPPPPPPPPA.. - ..PPPPO..PAPPA.. - .OOPPOOAPPAPPA.. - OOPPOOAAPPA..... - .PPPAPA.PP...... - PPPA............ - .AA............. -} -# tile 169 (mumak,female) -{ - ................ - ...........P.... - .PP.........P... - PPP...PPPPP.P... - PPPPPPPPP.PP.... - PPPPBPPBBP.PP... - PPPBPPPPPP.PP... - .PDPPDDPP.PPP... - ..BPPDDP.PPPPA.. - ..PPPPPPPPPPPA.. - ..PPPPO..PAPPA.. - .OOPPOOAPPAPPA.. - OOPPOOAAPPA..... - .PPPAPA.PP...... - PPPA............ - .AA............. -} -# tile 170 (leocrotta,male) -{ - ................ - ..A..A.......... - ..AOOA....J..... - ..AOOAA....J.... - .APOAFA....J.... - .APOAAA.JJJJ.... - .AOPAAJKKKKKJ... - .AOAAKJJKKJKJA.. - ...JKKKKKJAKKA.. - ...JKJKKJAAKKA.. - ..JKJAKKAAPAPA.. - ..KKAAKKAAPAPA.. - .PAPAAPAPA...... - .PAPA.PAPA...... - ................ - ................ -} -# tile 171 (leocrotta,female) -{ - ................ - ..A..A.......... - ..AOOA....J..... - ..AOOAA....J.... - .APOAFA....J.... - .APOAAA.JJJJ.... - .AOPAAJKKKKKJ... - .AOAAKJJKKJKJA.. - ...JKKKKKJAKKA.. - ...JKJKKJAAKKA.. - ..JKJAKKAAPAPA.. - ..KKAAKKAAPAPA.. - .PAPAAPAPA...... - .PAPA.PAPA...... - ................ - ................ -} -# tile 172 (wumpus,male) -{ - ................ - ............B... - .............B.. - .......BBBBB.B.. - ....BBBPPBBBB... - ...BOOBBBPBBBB.. - ...OOBBBBBPBBB.. - ..DABBAABBPBBBA. - .BOOBBDABEBBEBAA - .BOBBBBBBEBEBBAA - .BBBBBBBEBBABBAA - .EBBBBBEABBABBAA - ..EEEEEAABBA.... - .....BBA.BB..... - ................ - ................ -} -# tile 173 (wumpus,female) -{ - ................ - ............B... - .............B.. - .......BBBBB.B.. - ....BBBPPBBBB... - ...BOOBBBPBBBB.. - ...OOBBBBBPBBB.. - ..DABBAABBPBBBA. - .BOOBBDABEBBEBAA - .BOBBBBBBEBEBBAA - .BBBBBBBEBBABBAA - .EBBBBBEABBABBAA - ..EEEEEAABBA.... - .....BBA.BB..... - ................ - ................ -} -# tile 174 (titanothere,male) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - .PPPPP.PPPPPPP.. - .PPEPP.PPPP.PPA. - PBPPP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 175 (titanothere,female) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - .PPPPP.PPPPPPP.. - .PPEPP.PPPP.PPA. - PBPPP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 176 (baluchitherium,male) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - BPPPPP.PPPPPPP.. - B.PEPP.PPPP.PPA. - PB.PP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 177 (baluchitherium,female) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - BPPPPP.PPPPPPP.. - B.PEPP.PPPP.PPA. - PB.PP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 178 (mastodon,male) -{ - ................ - ................ - ................ - ................ - ................ - ..O...O......... - .N..POP.P....... - N..PNPPPPP...... - O.PNPPPPPP.PP... - O.POPEPPP.PPPPP. - .OPOPOP..PPPPPAP - ..PPOPP.PPPPPPAA - ..PPAAAPPPPAPPA. - ..P...APPAAAPPA. - .......PPA...... - ................ -} -# tile 179 (mastodon,female) -{ - ................ - ................ - ................ - ................ - ................ - ..O...O......... - .N..POP.P....... - N..PNPPPPP...... - O.PNPPPPPP.PP... - O.POPEPPP.PPPPP. - .OPOPOP..PPPPPAP - ..PPOPP.PPPPPPAA - ..PPAAAPPPPAPPA. - ..P...APPAAAPPA. - .......PPA...... - ................ -} -# tile 180 (sewer rat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKK.... - ..KKKKJKKJKKK... - ..JAKAKJJJKKKJ.. - ..GKGKJKAKKAKKA. - .KKJJJJKAKAAKKA. - .PJJAAKKAJAJKA.. - ..AA.KKA..JKA... - .........JJA.... - ................ -} -# tile 181 (sewer rat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKK.... - ..KKKKJKKJKKK... - ..JAKAKJJJKKKJ.. - ..GKGKJKAKKAKKA. - .KKJJJJKAKAAKKA. - .PJJAAKKAJAJKA.. - ..AA.KKA..JKA... - .........JJA.... - ................ -} -# tile 182 (giant rat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 183 (giant rat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 184 (rabid rat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJOOOKAJKAAKKA - .PJOOAKKAJJAJKA. - ..AOOOKAA..JKA.. - .OOOOOOOO.JJA... - ................ -} -# tile 185 (rabid rat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJOOOKAJKAAKKA - .PJOOAKKAJJAJKA. - ..AOOOKAA..JKA.. - .OOOOOOOO.JJA... - ................ -} -# tile 186 (wererat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..LLLLKJKJJKKKJ. - ..FLFLLJKJJKKKK. - ..LLLLJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 187 (wererat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..LLLLKJKJJKKKJ. - ..FLFLLJKJJKKKK. - ..LLLLJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 188 (rock mole,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......AAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - ..JAJAAAAAAAAAA. - .AAAAAAAAAAAAAA. - AN.NAAAAAAAAAAA. - A...AAAA...AAA.. - AN.NAA.AA...AA.. - .AAAA........... -} -# tile 189 (rock mole,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......AAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - ..JAJAAAAAAAAAA. - .AAAAAAAAAAAAAA. - AN.NAAAAAAAAAAA. - A...AAAA...AAA.. - AN.NAA.AA...AA.. - .AAAA........... -} -# tile 190 (woodchuck,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .......KJA...... - ......NKKNA..... - ......KNOJA..... - ......KNOJA..... - .....KKKKKJA.... - ....JJKLLJJJAA.. - ......KLLJAAAAA. - ......KJJJAAAA.. - .....JJAAJJAA... - ................ -} -# tile 191 (woodchuck,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .......KJA...... - ......NKKNA..... - ......KNOJA..... - ......KNOJA..... - .....KKKKKJA.... - ....JJKLLJJJAA.. - ......KLLJAAAAA. - ......KJJJAAAA.. - .....JJAAJJAA... - ................ -} -# tile 192 (cave spider,male) -{ - ................ - ................ - ................ - ................ - ................ - ........PA...... - .......PA....... - ......PAPBBA.... - ...PA.APBPPPA... - ...ABBPPAPPAA.PA - ...GPPPPAAAPPPAA - ...PPGPAAPPAAAA. - ..D.PAPAPAAPPA.. - ....D.PAAPA.APA. - .....PAA.APA.... - ................ -} -# tile 193 (cave spider,female) -{ - ................ - ................ - ................ - ................ - ................ - ........PA...... - .......PA....... - ......PAPBBA.... - ...PA.APBPPPA... - ...ABBPPAPPAA.PA - ...GPPPPAAAPPPAA - ...PPGPAAPPAAAA. - ..D.PAPAPAAPPA.. - ....D.PAAPA.APA. - .....PAA.APA.... - ................ -} -# tile 194 (centipede,male) -{ - ................ - ................ - ......PBPP...... - ....BBPAAA...... - ..PPBAAA........ - .PAPBBBPPPP..... - ..PAAPPBBBA..... - ....PAAPAPBPP... - ......AABBPP.... - ......BB.PPAP... - ....PBBPPAP.A... - ...GPPPAP.AP.... - ...PPGPAAP...... - ..B.PAA......... - ...B............ - ................ -} -# tile 195 (centipede,female) -{ - ................ - ................ - ......PBPP...... - ....BBPAAA...... - ..PPBAAA........ - .PAPBBBPPPP..... - ..PAAPPBBBA..... - ....PAAPAPBPP... - ......AABBPP.... - ......BB.PPAP... - ....PBBPPAP.A... - ...GPPPAP.AP.... - ...PPGPAAP...... - ..B.PAA......... - ...B............ - ................ -} -# tile 196 (giant spider,male) -{ - ................ - ................ - ................ - ................ - ................ - ........JA...... - .......JA....... - ......JAJKKA.... - ...JA.AJKJJJA... - ...AKKJJAJJAA.JA - ...GJJJJAAAJJJAA - ...JJGJAAJJAAAA. - ..D.JAJAJAAJJA.. - ....D.JAAJA.AJA. - .....JAA.AJA.... - ................ -} -# tile 197 (giant spider,female) -{ - ................ - ................ - ................ - ................ - ................ - ........JA...... - .......JA....... - ......JAJKKA.... - ...JA.AJKJJJA... - ...AKKJJAJJAA.JA - ...GJJJJAAAJJJAA - ...JJGJAAJJAAAA. - ..D.JAJAJAAJJA.. - ....D.JAAJA.AJA. - .....JAA.AJA.... - ................ -} -# tile 198 (scorpion,male) -{ - ................ - ................ - .......JKJKJAA.. - ......JA.JKJKKA. - .......KA...JJJA - ......JA....KKJA - ...........JJJKA - .......AJKKAJJA. - .....AAJKJJJAA.. - ...AKKJJAJJAA... - ...GJJJJAAAJJJA. - ...JJGJAAJJAAAJ. - ..D.JAJAJAAJJA.. - ....D.JAAJA.JAA. - .......JAAJA.... - ................ -} -# tile 199 (scorpion,female) -{ - ................ - ................ - .......JKJKJAA.. - ......JA.JKJKKA. - .......KA...JJJA - ......JA....KKJA - ...........JJJKA - .......AJKKAJJA. - .....AAJKJJJAA.. - ...AKKJJAJJAA... - ...GJJJJAAAJJJA. - ...JJGJAAJJAAAJ. - ..D.JAJAJAAJJA.. - ....D.JAAJA.JAA. - .......JAAJA.... - ................ -} -# tile 200 (lurker above,male) -{ - .AAAAAAAAAAAAAAA - ...AAGFAAGFAAA.. - ...AAAAAAAAAAA.. - ....AODODODOA... - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ -} -# tile 201 (lurker above,female) -{ - .AAAAAAAAAAAAAAA - ...AAGFAAGFAAA.. - ...AAAAAAAAAAA.. - ....AODODODOA... - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ -} -# tile 202 (trapper,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....AODODODOA... - ...AAAAAAAAAAA.. - ...AAGFAAGFAAA.. - .AAAAAAAAAAAAAAA -} -# tile 203 (trapper,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....AODODODOA... - ...AAAAAAAAAAA.. - ...AAGFAAGFAAA.. - .AAAAAAAAAAAAAAA -} -# tile 204 (pony,male) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ...KKEKJ........ - ..KKJKKJ........ - ..JJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKJ..... - ...KKKKKKKJJAAA. - ...KJKJJJJJAJA.. - ...JAJAAAAJAA... - ...JAJAAJAJA.... - ...L.JAALAJ..... - .....LA...L..... - ................ -} -# tile 205 (pony,female) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ...KKEKJ........ - ..KKJKKJ........ - ..JJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKJ..... - ...KKKKKKKJJAAA. - ...KJKJJJJJAJA.. - ...JAJAAAAJAA... - ...JAJAAJAJA.... - ...L.JAALAJ..... - .....LA...L..... - ................ -} -# tile 206 (white unicorn,male) -{ - ................ - ..HP............ - ..PHO.NN........ - ...PHNNB........ - ...ONENB........ - ..ONNNNB........ - ..NOANNBAA...... - ...AONNBA....... - ...ONNNONNN..... - ..NONNNNONNOAAA. - ..N.ONONNONAOA.. - ..OAANAAAAOAA... - ...LAOAAOAOA.... - .....OAALAO..... - .....LA...L..... - ................ -} -# tile 207 (white unicorn,female) -{ - ................ - ..HP............ - ..PHO.NN........ - ...PHNNB........ - ...ONENB........ - ..ONNNNB........ - ..NOANNBAA...... - ...AONNBA....... - ...ONNNONNN..... - ..NONNNNONNOAAA. - ..N.ONONNONAOA.. - ..OAANAAAAOAA... - ...LAOAAOAOA.... - .....OAALAO..... - .....LA...L..... - ................ -} -# tile 208 (gray unicorn,male) -{ - ................ - ..HP............ - ..PHO.PP........ - ...PHPPN........ - ....PGPN........ - ...PPPPN........ - ..PPAPPNAA...... - ...APPPNA....... - ....PPP.PPP..... - ..P.PPPP.PP.AAA. - ..P..P.PP.PA.A.. - ..PAAPAAAA.AA... - ...LA.AA.A.A.... - ......AALA...... - .....LA...L..... - ................ -} -# tile 209 (gray unicorn,female) -{ - ................ - ..HP............ - ..PHO.PP........ - ...PHPPN........ - ....PGPN........ - ...PPPPN........ - ..PPAPPNAA...... - ...APPPNA....... - ....PPP.PPP..... - ..P.PPPP.PP.AAA. - ..P..P.PP.PA.A.. - ..PAAPAAAA.AA... - ...LA.AA.A.A.... - ......AALA...... - .....LA...L..... - ................ -} -# tile 210 (black unicorn,male) -{ - ................ - ..HP............ - ..PHO.AA........ - ...PHAAJ........ - ...AADAJ........ - ..AAAAAJ........ - ..AAPAAJPP...... - ...PAAAJP....... - ...AAAAAAAA..... - ..AAAAAAAAAAPPP. - ..A.AAAAAAAPAP.. - ..APPAPPAPAPP... - ...LPAPPAPAP.... - .....APPLPA..... - .....LP...L..... - ................ -} -# tile 211 (black unicorn,female) -{ - ................ - ..HP............ - ..PHO.AA........ - ...PHAAJ........ - ...AADAJ........ - ..AAAAAJ........ - ..AAPAAJPP...... - ...PAAAJP....... - ...AAAAAAAA..... - ..AAAAAAAAAAPPP. - ..A.AAAAAAAPAP.. - ..APPAPPAPAPP... - ...LPAPPAPAP.... - .....APPLPA..... - .....LP...L..... - ................ -} -# tile 212 (horse,male) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ..KKKEKJ........ - .KKKJKKJAA...... - .JJJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKKJA... - ..KKKKKKKKKKJA.. - ..KJJKJJJJJKAJA. - ..JAAJAAAAAJAJA. - ..JAAJAAAJAJAA.. - ..LA.JAA.L.JA... - .....LA....L.... - ................ -} -# tile 213 (horse,female) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ..KKKEKJ........ - .KKKJKKJAA...... - .JJJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKKJA... - ..KKKKKKKKKKJA.. - ..KJJKJJJJJKAJA. - ..JAAJAAAAAJAJA. - ..JAAJAAAJAJAA.. - ..LA.JAA.L.JA... - .....LA....L.... - ................ -} -# tile 214 (warhorse,male) -{ - ................ - .....JJJ........ - ...KKKKJJ....... - .KKKKEKJJ....... - KKKKKKKJJAA..... - JKKKJKKJJAA..... - .JJJAKKJJAA..... - ...AKKKJJA...... - ...KKKKKKKKKJA.. - ..KKKKKKKKKKKJA. - ..KKJKKJKKJKKJJA - ..KJAKJAKJAKJAJA - ..KJAKJAKJAKJA.. - ..LC.KJALC.KJ... - .....LC....LC... - ................ -} -# tile 215 (warhorse,female) -{ - ................ - .....JJJ........ - ...KKKKJJ....... - .KKKKEKJJ....... - KKKKKKKJJAA..... - JKKKJKKJJAA..... - .JJJAKKJJAA..... - ...AKKKJJA...... - ...KKKKKKKKKJA.. - ..KKKKKKKKKKKJA. - ..KKJKKJKKJKKJJA - ..KJAKJAKJAKJAJA - ..KJAKJAKJAKJA.. - ..LC.KJALC.KJ... - .....LC....LC... - ................ -} -# tile 216 (fog cloud,male) -{ - .......P........ - ....P..P........ - .....P.P...P.... - ...P.......P.... - ..P..P.P.P...... - ....PP.PP.P.P... - .P..APAPPP..P... - ...P.PPPP.PP.... - ......PPPPP.P.P. - ...P.PPPPP..P... - ....P..P.PP.P... - .P...P.P...PPP.. - ..P.P....PP..... - .......P....P... - ..P..P.P..P..... - ................ -} -# tile 217 (fog cloud,female) -{ - .......P........ - ....P..P........ - .....P.P...P.... - ...P.......P.... - ..P..P.P.P...... - ....PP.PP.P.P... - .P..APAPPP..P... - ...P.PPPP.PP.... - ......PPPPP.P.P. - ...P.PPPPP..P... - ....P..P.PP.P... - .P...P.P...PPP.. - ..P.P....PP..... - .......P....P... - ..P..P.P..P..... - ................ -} -# tile 218 (dust vortex,male) -{ - ................ - ................ - ....K..KKKK..... - ...K..KKJJJK.... - ..K..KJJJJ..K... - .KJ.KJJ.JKK..K.. - .KJJKJ.JJJJK.... - .KJJJJ....JJK... - .KKJ.J...J.JKK.. - ..KJJ....JJJJK.. - ...KJJJJ.JKJJK.. - .K..KKJ.JJK.JK.. - ..K..JJJJK..K... - ...KJJJKK..K.... - ....KKKK..K..... - ................ -} -# tile 219 (dust vortex,female) -{ - ................ - ................ - ....K..KKKK..... - ...K..KKJJJK.... - ..K..KJJJJ..K... - .KJ.KJJ.JKK..K.. - .KJJKJ.JJJJK.... - .KJJJJ....JJK... - .KKJ.J...J.JKK.. - ..KJJ....JJJJK.. - ...KJJJJ.JKJJK.. - .K..KKJ.JJK.JK.. - ..K..JJJJK..K... - ...KJJJKK..K.... - ....KKKK..K..... - ................ -} -# tile 220 (ice vortex,male) -{ - ................ - ................ - ....N..NNNN..... - ...N..NNOOON.... - ..N..NOOOO..N... - .NO.NOO.ONN..N.. - .NOONO.OOOON.... - .NOOOO....OON... - .NNO.O...O.ONN.. - ..NOO....OOOON.. - ...NOOOO.ONOON.. - .N..NNO.OON.ON.. - ..N..OOOON..N... - ...NOOONN..N.... - ....NNNN..N..... - ................ -} -# tile 221 (ice vortex,female) -{ - ................ - ................ - ....N..NNNN..... - ...N..NNOOON.... - ..N..NOOOO..N... - .NO.NOO.ONN..N.. - .NOONO.OOOON.... - .NOOOO....OON... - .NNO.O...O.ONN.. - ..NOO....OOOON.. - ...NOOOO.ONOON.. - .N..NNO.OON.ON.. - ..N..OOOON..N... - ...NOOONN..N.... - ....NNNN..N..... - ................ -} -# tile 222 (energy vortex,male) -{ - ................ - ................ - ....E..EEEE..... - ...E..EEAAAE.... - ..E..EAAAA..E... - .EA.EAAAAIE..E.. - .EAAIAAAAAAE.... - .EAAAAAAAAAAE... - .EEAAAAAAAAAEE.. - ..EAAAAAAAAAAE.. - ...EAAAAAAIAAE.. - .E..EIAAAAE.AE.. - ..E..AAAAE..E... - ...EAAAEE..E.... - ....EEEE..E..... - ................ -} -# tile 223 (energy vortex,female) -{ - ................ - ................ - ....E..EEEE..... - ...E..EEAAAE.... - ..E..EAAAA..E... - .EA.EAAAAIE..E.. - .EAAIAAAAAAE.... - .EAAAAAAAAAAE... - .EEAAAAAAAAAEE.. - ..EAAAAAAAAAAE.. - ...EAAAAAAIAAE.. - .E..EIAAAAE.AE.. - ..E..AAAAE..E... - ...EAAAEE..E.... - ....EEEE..E..... - ................ -} -# tile 224 (steam vortex,male) -{ - ................ - ................ - ....P..PPPP..... - ...P..PPBBBP.... - ..P..PBBBB..P... - .PB.PBBPBPP..P.. - .PBBPBPBBBBP.... - .PBBBBP.PPBBP... - .PPBPB...BPBPP.. - ..PBBPP.PBBBBP.. - ...PBBBBPBPBBP.. - .P..PPBPBBP.BP.. - ..P..BBBBP..P... - ...PBBBPP..P.... - ....PPPP..P..... - ................ -} -# tile 225 (steam vortex,female) -{ - ................ - ................ - ....P..PPPP..... - ...P..PPBBBP.... - ..P..PBBBB..P... - .PB.PBBPBPP..P.. - .PBBPBPBBBBP.... - .PBBBBP.PPBBP... - .PPBPB...BPBPP.. - ..PBBPP.PBBBBP.. - ...PBBBBPBPBBP.. - .P..PPBPBBP.BP.. - ..P..BBBBP..P... - ...PBBBPP..P.... - ....PPPP..P..... - ................ -} -# tile 226 (fire vortex,male) -{ - ................ - ................ - ....D..DDDD..... - ...D..DDCCCD.... - ..D..DCCCC..D... - .DC.DCCHCDD..D.. - .DCCDCHCCCCD.... - .DCCCCHHHHCCD... - .DDCHCHHHCHCDD.. - ..DCCHHHHCCCCD.. - ...DCCCCHCDCCD.. - .D..DDCHCCD.CD.. - ..D..CCCCD..D... - ...DCCCDD..D.... - ....DDDD..D..... - ................ -} -# tile 227 (fire vortex,female) -{ - ................ - ................ - ....D..DDDD..... - ...D..DDCCCD.... - ..D..DCCCC..D... - .DC.DCCHCDD..D.. - .DCCDCHCCCCD.... - .DCCCCHHHHCCD... - .DDCHCHHHCHCDD.. - ..DCCHHHHCCCCD.. - ...DCCCCHCDCCD.. - .D..DDCHCCD.CD.. - ..D..CCCCD..D... - ...DCCCDD..D.... - ....DDDD..D..... - ................ -} -# tile 228 (baby long worm,male) -{ - ................ - ................ - ................ - ................ - ......CLC....... - ......LLL....... - .....GGAGG.A.... - .....GGAGGAAA... - ......LLLAAA.C.. - ......LLLAA.CC.. - ......CLLCCCCA.. - .......LLLCCA... - ........CLL..... - ................ - ................ - ................ -} -# tile 229 (baby long worm,female) -{ - ................ - ................ - ................ - ................ - ......CLC....... - ......LLL....... - .....GGAGG.A.... - .....GGAGGAAA... - ......LLLAAA.C.. - ......LLLAA.CC.. - ......CLLCCCCA.. - .......LLLCCA... - ........CLL..... - ................ - ................ - ................ -} -# tile 230 (baby purple worm,male) -{ - ................ - ................ - ................ - .......I........ - ......III....... - ......III....... - .....GGAGG.A.... - .....GGAGGAAA... - ......IIIAAA.D.. - ......IIIAA.DD.. - ......IIIDDDDA.. - .......IIIDDA... - ........III..... - ................ - ................ - ................ -} -# tile 231 (baby purple worm,female) -{ - ................ - ................ - ................ - .......I........ - ......III....... - ......III....... - .....GGAGG.A.... - .....GGAGGAAA... - ......IIIAAA.D.. - ......IIIAA.DD.. - ......IIIDDDDA.. - .......IIIDDA... - ........III..... - ................ - ................ - ................ -} -# tile 232 (long worm,male) -{ - ................ - ................ - .....CLC........ - ....CLLLC....... - ....LLLLL....... - ...GGGLGGGAA.... - ...GAGLGAGAAA... - ...GGGLGGGAAA... - ....LLLLLAAACC.. - ....LLLLLAACCC.. - ....CLLLLCCCCA.. - .....LLLLLCCA... - ......CLLLL..... - ................ - ................ - ................ -} -# tile 233 (long worm,female) -{ - ................ - ................ - .....CLC........ - ....CLLLC....... - ....LLLLL....... - ...GGGLGGGAA.... - ...GAGLGAGAAA... - ...GGGLGGGAAA... - ....LLLLLAAACC.. - ....LLLLLAACCC.. - ....CLLLLCCCCA.. - .....LLLLLCCA... - ......CLLLL..... - ................ - ................ - ................ -} -# tile 234 (purple worm,male) -{ - ................ - ................ - .....DID........ - ....DIIID....... - ....IIIII....... - ...GGGIGGGAA.... - ...GAGIGAGAAA... - ...GGGIGGGAAA... - ....IIIIIAAADD.. - ....IIIIIAADDD.. - ....DIIIIDDDDA.. - .....IIIIIDDA... - ......DIIII..... - ................ - ................ - ................ -} -# tile 235 (purple worm,female) -{ - ................ - ................ - .....DID........ - ....DIIID....... - ....IIIII....... - ...GGGIGGGAA.... - ...GAGIGAGAAA... - ...GGGIGGGAAA... - ....IIIIIAAADD.. - ....IIIIIAADDD.. - ....DIIIIDDDDA.. - .....IIIIIDDA... - ......DIIII..... - ................ - ................ - ................ -} -# tile 236 (grid bug,male) -{ - ................ - ................ - ................ - ................ - ..D....NHCN..D.. - .D.D..NHDNCNDED. - D.D.D.NNHCND.DED - .D...D.NNHDND... - .DDD..ENNG.D.DE. - ..DDDDEEEEGD..DE - D.....DEHEE.D... - .D.......H...... - ................ - ................ - ................ - ................ -} -# tile 237 (grid bug,female) -{ - ................ - ................ - ................ - ................ - ..D....NHCN..D.. - .D.D..NHDNCNDED. - D.D.D.NNHCND.DED - .D...D.NNHDND... - .DDD..ENNG.D.DE. - ..DDDDEEEEGD..DE - D.....DEHEE.D... - .D.......H...... - ................ - ................ - ................ - ................ -} -# tile 238 (xan,male) -{ - ................ - ................ - ..........GG.... - ...HHH...GOGG... - .....HH..GGGG... - ...HHHHH.GGG.... - .......GG...AAA. - .....GOGGHHAAAA. - ....GOGG..HHAAA. - NNNGOGG.AAHHHA.. - NANGGGG.AAHAH... - NNNGGNNNAAAAAA.. - ..GGGNANAA.AAA.. - .GGGANNNAA.A.A.. - ..G..AAAAAA..... - ......AA.AA..... -} -# tile 239 (xan,female) -{ - ................ - ................ - ..........GG.... - ...HHH...GOGG... - .....HH..GGGG... - ...HHHHH.GGG.... - .......GG...AAA. - .....GOGGHHAAAA. - ....GOGG..HHAAA. - NNNGOGG.AAHHHA.. - NANGGGG.AAHAH... - NNNGGNNNAAAAAA.. - ..GGGNANAA.AAA.. - .GGGANNNAA.A.A.. - ..G..AAAAAA..... - ......AA.AA..... -} -# tile 240 (yellow light,male) -{ - ................ - ......NA........ - ......HA........ - ..NA.NHNA.NA.... - ...LALHLALA..... - ....NHHHNA...... - ..NLHHHHHLNA.... - NHHHHHHHHHHHNA.. - ..NLHHHHHLNA.... - ....NHHHNA...... - ...LALHLALA..... - ..NA.NNNA.NA.... - ......HA........ - ......NA........ - ................ - ................ -} -# tile 241 (yellow light,female) -{ - ................ - ......NA........ - ......HA........ - ..NA.NHNA.NA.... - ...LALHLALA..... - ....NHHHNA...... - ..NLHHHHHLNA.... - NHHHHHHHHHHHNA.. - ..NLHHHHHLNA.... - ....NHHHNA...... - ...LALHLALA..... - ..NA.NNNA.NA.... - ......HA........ - ......NA........ - ................ - ................ -} -# tile 242 (black light,male) -{ - ................ - ......AA........ - ......AA........ - ..AA.AAAA.AA.... - ...AAAAAAAA..... - ....AAAAAA...... - ..AAAAAAAAAA.... - AAAAAAAAAAAAAA.. - ..AAAAAAAAAA.... - ....AAAAAA...... - ...AAAAAAAA..... - ..AA.AAAA.AA.... - ......AA........ - ......AA........ - ................ - ................ -} -# tile 243 (black light,female) -{ - ................ - ......AA........ - ......AA........ - ..AA.AAAA.AA.... - ...AAAAAAAA..... - ....AAAAAA...... - ..AAAAAAAAAA.... - AAAAAAAAAAAAAA.. - ..AAAAAAAAAA.... - ....AAAAAA...... - ...AAAAAAAA..... - ..AA.AAAA.AA.... - ......AA........ - ......AA........ - ................ - ................ -} -# tile 244 (zruty,male) -{ - ................ - ......FFGF...... - ....OOFGFFFF.... - ...AOFGFOOKFF... - ...FFGFAOAJKKF.. - ..FFFFFFJAAJKK.. - ..ODOFFJAJJKKJA. - ..DDDDJAJJKJJAA. - ..JODOAJJJAJJAAA - .KKJAJJJKJAJJAAA - .KKAAJKKKKJAAAAA - ...AJJKKKKJJAAAA - ...KJJAAAAKJAAA. - ..JKJJJAAJJJJ... - ................ - ................ -} -# tile 245 (zruty,female) -{ - ................ - ......FFGF...... - ....OOFGFFFF.... - ...AOFGFOOKFF... - ...FFGFAOAJKKF.. - ..FFFFFFJAAJKK.. - ..ODOFFJAJJKKJA. - ..DDDDJAJJKJJAA. - ..JODOAJJJAJJAAA - .KKJAJJJKJAJJAAA - .KKAAJKKKKJAAAAA - ...AJJKKKKJJAAAA - ...KJJAAAAKJAAA. - ..JKJJJAAJJJJ... - ................ - ................ -} -# tile 246 (couatl,male) -{ - ................ - ................ - ........I....I.. - ....KKAIII..III. - ...NAOJAKI.IIIII - ...KKJAJJKKK..II - ...KKAAIJJJJJ..I - ...FAA.I...KJ..I - ..FAFA..AAAKJAA. - .......AAAJJAAA. - ......AKKJJAAA.. - ......KJAAAAAJA. - .....JJAA...JA.. - ......JJJJJJA... - ................ - ................ -} -# tile 247 (couatl,female) -{ - ................ - ................ - ........I....I.. - ....KKAIII..III. - ...NAOJAKI.IIIII - ...KKJAJJKKK..II - ...KKAAIJJJJJ..I - ...FAA.I...KJ..I - ..FAFA..AAAKJAA. - .......AAAJJAAA. - ......AKKJJAAA.. - ......KJAAAAAJA. - .....JJAA...JA.. - ......JJJJJJA... - ................ - ................ -} -# tile 248 (Aleax,male) -{ - ................ - ......BBBB..I... - ..I..BF...B..... - ....BF.HHA.B.... - ...BF.HHHHA.B.I. - ...BF.LFLFA.FB.. - .I.BF.LLLLA.FB.. - ...BF.ALLA.FB... - ..BF.LLAALL.ABA. - .BF.LLLLLLLLAFB. - .BF.LALLLLALAFB. - .BF.LAJJKJALAFB. - ..BF..LJJLAAABA. - ...BF.LLALAABA.. - ..BF.LLAALLAFB.. - ................ -} -# tile 249 (Aleax,female) -{ - ................ - ......BBBB..I... - ..I..BF...B..... - ....BF.HHA.B.... - ...BF.HHHHA.B.I. - ...BF.LFLFA.FB.. - .I.BF.LLLLA.FB.. - ...BF.ALLA.FB... - ..BF.LJAAJL.ABA. - .BF.LLJJJJLLAFB. - .BF.LAJKJJALAFB. - .BF.LAJJKJALAFB. - ..BF..LJJLAAABA. - ...BF.LLALAABA.. - ..BF.LLAALLAFB.. - ................ -} -# tile 250 (Angel,male) -{ - ................ - ................ - ......HHHH...... - ................ - .......CC....... - ......CLLC..AA.. - ......PLLP....A. - ......NPPPA.A... - .....BBLLPPAAA.. - .....NNLLPPAAA.. - ......BNNPAAAA.. - ......BNNPAAAA.. - .....BNNNPAA.A.. - .....BNNNNPA.... - ....BNNNNNNP.... - ................ -} -# tile 251 (Angel,female) -{ - ................ - ................ - ......HHHH...... - ................ - .......CC....... - ......CLLC..AA.. - ......PLLP....A. - ......NPPPA.A... - .....BBLLPPAAA.. - .....NNLLPPAAA.. - ......BNNPAAAA.. - ......BNNPAAAA.. - .....BNNNPAA.A.. - .....BNNNNPA.... - ....BNNNNNNP.... - ................ -} -# tile 252 (ki-rin,male) -{ - ................ - ................ - ..LP............ - ..PLO.C.C....... - ...PLCCD........ - ...KCIKD........ - ..KCCCCD........ - ..CKACCDA....... - ...ACCCCCC...A.. - ...KCCCKCCKAA... - ..CAKCKCKCAKA... - ..CAAKAKAKA..... - ...L.KALAK...... - .....LA..L...... - ................ - ................ -} -# tile 253 (ki-rin,female) -{ - ................ - ................ - ..LP............ - ..PLO.C.C....... - ...PLCCD........ - ...KCIKD........ - ..KCCCCD........ - ..CKACCDA....... - ...ACCCCCC...A.. - ...KCCCKCCKAA... - ..CAKCKCKCAKA... - ..CAAKAKAKA..... - ...L.KALAK...... - .....LA..L...... - ................ - ................ -} -# tile 254 (Archon,male) -{ - ................ - ......OOOO...... - .....OOOOOO..... - .....OJLLJO..... - .....OLLLLO..... - ....OOJLLJOO.... - ......AJJA...... - .....AAAAAAA.... - ....AAAAAAAAA... - ...OAAOAAAJLJ... - ..OOAOAAAACJC... - ....LAAAACCJCC.. - .....AAAAAJJJ... - ....AAAAAAAA.... - ................ - ................ -} -# tile 255 (Archon,female) -{ - ................ - ......OOOO...... - .....OOOOOO..... - .....OJLLJO..... - .....OLLLLO..... - ....OOKLLKOO.... - ......AKKA...... - .....AAAAAAA.... - ....AAAAAAAAA... - ...OAAOAAAJLJ... - ..OOAOAAAACJC... - ....LAAAACCJCC.. - .....AAAAAJJJ... - ....AAAAAAAA.... - ................ - ................ -} -# tile 256 (bat,male) -{ - ................ - ................ - ................ - ................ - ...JJJCACJJJ.... - ..JJAAHJHAAJJ... - ..JA...JA..AJ... - ................ - ................ - ......AAAA...... - ....AAAAAAAA.... - ...AAA.AA.AAA... - .......AA....... - ................ - ................ - ................ -} -# tile 257 (bat,female) -{ - ................ - ................ - ................ - ................ - ...JJJCACJJJ.... - ..JJAAHJHAAJJ... - ..JA...JA..AJ... - ................ - ................ - ......AAAA...... - ....AAAAAAAA.... - ...AAA.AA.AAA... - .......AA....... - ................ - ................ - ................ -} -# tile 258 (giant bat,male) -{ - ................ - ................ - ................ - ...JK.J.J.JK.... - ..KJJJCACJJKJ... - .JJJAAHJHAAJJK.. - .KJA...JA..AJJ.. - ..JA.......AJ... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 259 (giant bat,female) -{ - ................ - ................ - ................ - ...JK.J.J.JK.... - ..KJJJCACJJKJ... - .JJJAAHJHAAJJK.. - .KJA...JA..AJJ.. - ..JA.......AJ... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 260 (raven,male) -{ - ..AAAA...AAA.... - .AAAAAA.AAA..... - AAAAAAAAAAA.AA.. - A...AAAAAAAAAAA. - ......AAAAAAAAA. - .....AAAA.....AA - .....ADA.......A - .....PA......... - .....P.......... - .........P.P.P.. - ........P.P.P.P. - .......P.P.P.... - ........P.P.P... - ...........P.... - ................ - ................ -} -# tile 261 (raven,female) -{ - ..AAAA...AAA.... - .AAAAAA.AAA..... - AAAAAAAAAAA.AA.. - A...AAAAAAAAAAA. - ......AAAAAAAAA. - .....AAAA.....AA - .....ADA.......A - .....PA......... - .....P.......... - .........P.P.P.. - ........P.P.P.P. - .......P.P.P.... - ........P.P.P... - ...........P.... - ................ - ................ -} -# tile 262 (vampire bat,male) -{ - ................ - ................ - ................ - ...AA.A.A.AA.... - ..AAAAAAAAAAA... - .AAAA.DAD.AAAA.. - .AAA...A...AAA.. - ..A.........A... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 263 (vampire bat,female) -{ - ................ - ................ - ................ - ...AA.A.A.AA.... - ..AAAAAAAAAAA... - .AAAA.DAD.AAAA.. - .AAA...A...AAA.. - ..A.........A... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 264 (plains centaur,male) -{ - ................ - ...KKA.......... - ...LLAA......... - .AAKKAA......... - .LLAALLA........ - LALLLLALA....... - LALLLKALA.A..... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 265 (plains centaur,female) -{ - ................ - ...KKA.......... - ...LLAA......... - .AAKKAA......... - .LLAALLA........ - LALLLLALA....... - LALLLKALA.A..... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 266 (forest centaur,male) -{ - ................ - ................ - ................ - ...KKA.......... - LA.LLAALA....... - LAALLAALA....... - .LLAALLA........ - ..LLLLA.A....... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKA.A.. - .KAKJJJJKJAAAA.. - .KAAKAAJAKA..... - ..C.KAAKAK...... - ....CA...C...... - ................ -} -# tile 267 (forest centaur,female) -{ - ................ - ................ - ................ - ...KKA.......... - LA.LLAALA....... - LAALLAALA....... - .LLAALLA........ - ..LLLLA.A....... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKA.A.. - .KAKJJJJKJAAAA.. - .KAAKAAJAKA..... - ..C.KAAKAK...... - ....CA...C...... - ................ -} -# tile 268 (mountain centaur,male) -{ - ................ - ................ - ...KKA.......... - ...LLAA......... - ..AKKAA......... - .LJJJJLA........ - LAJKKJALA.A..... - LAKKKKALAAA..... - ..JJJJKJJKAA.... - .KJJJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 269 (mountain centaur,female) -{ - ................ - ................ - ...KKA.......... - ...LLAA......... - ..AKKAA......... - .LJJJJLA........ - LAJKKJALA.A..... - LAKKKKALAAA..... - ..JJJJKJJKAA.... - .KJJJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 270 (baby gray dragon,male) -{ - ................ - ................ - ................ - .....BBBA....... - ....NPNPPA...... - ...BPPPPPA...... - ..CHHPABPA.AAA.. - .CHCDA.BPAAAAAA. - ..D..BPPAAAAAAA. - ....BBPPPPPAAAA. - ...BOOPPPPPPAAA. - ..BPOBPPPPPPPAA. - ..BPPBPPOBPAPPA. - ..BPABP.ABPAPPA. - .....BPAA..PPAA. - ...........PAA.. -} -# tile 271 (baby gray dragon,female) -{ - ................ - ................ - ................ - .....BBBA....... - ....NPNPPA...... - ...BPPPPPA...... - ..CHHPABPA.AAA.. - .CHCDA.BPAAAAAA. - ..D..BPPAAAAAAA. - ....BBPPPPPAAAA. - ...BOOPPPPPPAAA. - ..BPOBPPPPPPPAA. - ..BPPBPPOBPAPPA. - ..BPABP.ABPAPPA. - .....BPAA..PPAA. - ...........PAA.. -} -# tile 272 (baby silver dragon,male) -{ - ................ - ................ - ................ - .....PPPA....... - ....OBOBBA...... - ...PBBBBBA...... - ..CHHBAPBA.AAA.. - .CHCDA.PBAAAAAA. - ..D..PBBAAAAAAA. - ....PPBBBBBAAAA. - ...PNNBBBBBBAAA. - ..PBNPBBBBBBBAA. - ..PBBPBBNPBABBA. - ..PBAPB.APBABBA. - .....PBAA..BBAA. - ...........BAA.. -} -# tile 273 (baby silver dragon,female) -{ - ................ - ................ - ................ - .....PPPA....... - ....OBOBBA...... - ...PBBBBBA...... - ..CHHBAPBA.AAA.. - .CHCDA.PBAAAAAA. - ..D..PBBAAAAAAA. - ....PPBBBBBAAAA. - ...PNNBBBBBBAAA. - ..PBNPBBBBBBBAA. - ..PBBPBBNPBABBA. - ..PBAPB.APBABBA. - .....PBAA..BBAA. - ...........BAA.. -} -# tile 274 (baby shimmering dragon,male) -{ - .I.............. - ...BBBBBBB.I.... - ..BF.FFF.FB...I. - .BF..BBBA.FB.... - BF..NPNPPAFB.I.. - BF.BPPPPPA.B.... - B.CHHPABPAFBAAI. - BCHCDA.BPAAFBAA. - B.D..BPPAAAAFBA. - B...BBPPPPPAAFB. - BF.BOOPPPPPPAAAB - BFBPOBPPPPPPPAFB - BFBPPBPPOBPAPPFB - B.BPABP.ABPAPPFB - B....BPAA..PPAAB - .B.........PAAB. -} -# tile 275 (baby shimmering dragon,female) -{ - .I.............. - ...BBBBBBB.I.... - ..BF.FFF.FB...I. - .BF..BBBA.FB.... - BF..NPNPPAFB.I.. - BF.BPPPPPA.B.... - B.CHHPABPAFBAAI. - BCHCDA.BPAAFBAA. - B.D..BPPAAAAFBA. - B...BBPPPPPAAFB. - BF.BOOPPPPPPAAAB - BFBPOBPPPPPPPAFB - BFBPPBPPOBPAPPFB - B.BPABP.ABPAPPFB - B....BPAA..PPAAB - .B.........PAAB. -} -# tile 276 (baby red dragon,male) -{ - ................ - ................ - ................ - .....IIIA....... - ....NDNDDA...... - ...IDDDDDA...... - ..CHHDAIDA.AAA.. - .CHCDA.IDAAAAAA. - ..D..IDDAAAAAAA. - ....IIDDDDDAAAA. - ...IHHDDDDDDAAA. - ..IDHIDDDDDDDAA. - ..IDDIDDHIDADDA. - ..IDAID.AIDADDA. - .....IDAA..DDAA. - ...........DAA.. -} -# tile 277 (baby red dragon,female) -{ - ................ - ................ - ................ - .....IIIA....... - ....NDNDDA...... - ...IDDDDDA...... - ..CHHDAIDA.AAA.. - .CHCDA.IDAAAAAA. - ..D..IDDAAAAAAA. - ....IIDDDDDAAAA. - ...IHHDDDDDDAAA. - ..IDHIDDDDDDDAA. - ..IDDIDDHIDADDA. - ..IDAID.AIDADDA. - .....IDAA..DDAA. - ...........DAA.. -} -# tile 278 (baby white dragon,male) -{ - ................ - ................ - ................ - .....NNNA....... - ....IOIOOA...... - ...NOOOOOA...... - ..CHHOANOA.AAA.. - .CHCDA.NOAAAAAA. - ..D..NOOAAAAAAA. - ....NNOOOOOAAAA. - ...NOOOOOOOOAAA. - ..NOONOOOOOOOAA. - ..NOONOOONOAOOA. - ..NOANO.ANOAOOA. - .....NOAA..OOAA. - ...........OAA.. -} -# tile 279 (baby white dragon,female) -{ - ................ - ................ - ................ - .....NNNA....... - ....IOIOOA...... - ...NOOOOOA...... - ..CHHOANOA.AAA.. - .CHCDA.NOAAAAAA. - ..D..NOOAAAAAAA. - ....NNOOOOOAAAA. - ...NOOOOOOOOAAA. - ..NOONOOOOOOOAA. - ..NOONOOONOAOOA. - ..NOANO.ANOAOOA. - .....NOAA..OOAA. - ...........OAA.. -} -# tile 280 (baby orange dragon,male) -{ - ................ - ................ - ................ - .....LLLA....... - ....NCNCCA...... - ...LCCCCCA...... - ..CHHCALCA.AAA.. - .CHCDA.LCAAAAAA. - ..D..LCCAAAAAAA. - ....LLCCCCCAAAA. - ...LOOCCCCCCAAA. - ..LCOLCCCCCCCAA. - ..LCCLCCOLCACCA. - ..LCALC.ALCACCA. - .....LCAA..CCAA. - ...........CAA.. -} -# tile 281 (baby orange dragon,female) -{ - ................ - ................ - ................ - .....LLLA....... - ....NCNCCA...... - ...LCCCCCA...... - ..CHHCALCA.AAA.. - .CHCDA.LCAAAAAA. - ..D..LCCAAAAAAA. - ....LLCCCCCAAAA. - ...LOOCCCCCCAAA. - ..LCOLCCCCCCCAA. - ..LCCLCCOLCACCA. - ..LCALC.ALCACCA. - .....LCAA..CCAA. - ...........CAA.. -} -# tile 282 (baby black dragon,male) -{ - ................ - ................ - ................ - .....AAA........ - ....NANAA....... - ...AAAAAA....... - ..CHHA.AA..PPP.. - .CHCD..AA.PPPPP. - ..D..AAAPPP.PPP. - ....AAAAAAAPPPP. - ...AAAAAAAAAPPP. - ..AAAAAAAAAAAPP. - ..AAAAAAAAAPAAP. - ..AAPAA.PAAPAAP. - .....AAP...AAPP. - ...........APP.. -} -# tile 283 (baby black dragon,female) -{ - ................ - ................ - ................ - .....AAA........ - ....NANAA....... - ...AAAAAA....... - ..CHHA.AA..PPP.. - .CHCD..AA.PPPPP. - ..D..AAAPPP.PPP. - ....AAAAAAAPPPP. - ...AAAAAAAAAPPP. - ..AAAAAAAAAAAPP. - ..AAAAAAAAAPAAP. - ..AAPAA.PAAPAAP. - .....AAP...AAPP. - ...........APP.. -} -# tile 284 (baby blue dragon,male) -{ - ................ - ................ - ................ - .....BBBA....... - ....NENEEA...... - ...BEEEEEA...... - ..CHHEABEA.AAA.. - CCHCDA.BEAAAAAA. - ..D..BEEAAAAAAA. - ....BBEEEEEAAAA. - ...BOOEEEEEEAAA. - ..BEOBEEEEEEEAA. - ..BEEBEEOBEAEEA. - ..BEABE.ABEAEEA. - .....BEAA..EEAA. - ...........EAA.. -} -# tile 285 (baby blue dragon,female) -{ - ................ - ................ - ................ - .....BBBA....... - ....NENEEA...... - ...BEEEEEA...... - ..CHHEABEA.AAA.. - CCHCDA.BEAAAAAA. - ..D..BEEAAAAAAA. - ....BBEEEEEAAAA. - ...BOOEEEEEEAAA. - ..BEOBEEEEEEEAA. - ..BEEBEEOBEAEEA. - ..BEABE.ABEAEEA. - .....BEAA..EEAA. - ...........EAA.. -} -# tile 286 (baby green dragon,male) -{ - ................ - ................ - ................ - .....GGGA....... - ....NFNFFA...... - ...GFFFFFA...... - ..CHHFAGFA.AAA.. - .CHCDA.GFAAAAAA. - ..D..GFFAAAAAAA. - ....GGFFFFFAAAA. - ...GOOFFFFFFAAA. - ..GFOGFFFFFFFAA. - ..GFFGFFOGFAFFA. - ..GFAGF.AGFAFFA. - .....GFAA..FFAA. - ...........FAA.. -} -# tile 287 (baby green dragon,female) -{ - ................ - ................ - ................ - .....GGGA....... - ....NFNFFA...... - ...GFFFFFA...... - ..CHHFAGFA.AAA.. - .CHCDA.GFAAAAAA. - ..D..GFFAAAAAAA. - ....GGFFFFFAAAA. - ...GOOFFFFFFAAA. - ..GFOGFFFFFFFAA. - ..GFFGFFOGFAFFA. - ..GFAGF.AGFAFFA. - .....GFAA..FFAA. - ...........FAA.. -} -# tile 288 (baby yellow dragon,male) -{ - ................ - ................ - ................ - .....NNNA....... - ....DHDHHA...... - ...NHHHHHA...... - ..CHHHANHA.AAA.. - .CHCDA.NHAAAAAA. - ..D..NHHAAAAAAA. - ....NNHHHHHAAAA. - ...NOOHHHHHHAAA. - ..NHONHHHHHHHAA. - ..NHHNHHONHAHHA. - ..NHANH.ANHAHHA. - .....NHAA..HHAA. - ...........HAA.. -} -# tile 289 (baby yellow dragon,female) -{ - ................ - ................ - ................ - .....NNNA....... - ....DHDHHA...... - ...NHHHHHA...... - ..CHHHANHA.AAA.. - .CHCDA.NHAAAAAA. - ..D..NHHAAAAAAA. - ....NNHHHHHAAAA. - ...NOOHHHHHHAAA. - ..NHONHHHHHHHAA. - ..NHHNHHONHAHHA. - ..NHANH.ANHAHHA. - .....NHAA..HHAA. - ...........HAA.. -} -# tile 290 (gray dragon,male) -{ - ......BBBPA..... - .....NPNPPPA.... - ....BPPPPPPA.... - ..DCHHP..PPA.... - CHCHCD..BPPA.... - HD.D...BPPA..... - ......OBPAAAAAA. - ....BOBPAAAAAAAA - ..BOOBPA.PP.AAA. - .BOOOBPPPPPP.AA. - .BOOOBPPPPPPPAA. - PPOOBBPPPPPPPPA. - BP.OBPPOOPP.P.A. - BPAABP.AAPPAPPA. - ....BPAA...PP.A. - ........PPPP.A.. -} -# tile 291 (gray dragon,female) -{ - ......BBBPA..... - .....NPNPPPA.... - ....BPPPPPPA.... - ..DCHHP..PPA.... - CHCHCD..BPPA.... - HD.D...BPPA..... - ......OBPAAAAAA. - ....BOBPAAAAAAAA - ..BOOBPA.PP.AAA. - .BOOOBPPPPPP.AA. - .BOOOBPPPPPPPAA. - PPOOBBPPPPPPPPA. - BP.OBPPOOPP.P.A. - BPAABP.AAPPAPPA. - ....BPAA...PP.A. - ........PPPP.A.. -} -# tile 292 (silver dragon,male) -{ - ......PPPBA..... - .....OBOBBBA.... - ....PBBBBBBA.... - ..DCHHB..BBA.... - CHCHCD..PBBA.... - HD.D...PBBA..... - ......NPBAAAAAA. - ....PNPBAAAAAAAA - ..PNNPBA.BB.AAA. - .PNNNPBBBBBB.AA. - .PNNNPBBBBBBBAA. - BBNNPPBBBBBBBBA. - PB.NPBBNNBB.B.A. - PBAAPB.AABBABBA. - ....PBAA...BB.A. - ........BBBB.A.. -} -# tile 293 (silver dragon,female) -{ - ......PPPBA..... - .....OBOBBBA.... - ....PBBBBBBA.... - ..DCHHB..BBA.... - CHCHCD..PBBA.... - HD.D...PBBA..... - ......NPBAAAAAA. - ....PNPBAAAAAAAA - ..PNNPBA.BB.AAA. - .PNNNPBBBBBB.AA. - .PNNNPBBBBBBBAA. - BBNNPPBBBBBBBBA. - PB.NPBBNNBB.B.A. - PBAAPB.AABBABBA. - ....PBAA...BB.A. - ........BBBB.A.. -} -# tile 294 (shimmering dragon,male) -{ - .I.BF.BBBPAFB... - ..BF.NPNPPPAFB.I - .BF.BPPPPPPAFB.. - .BDCHHP..PPAFBI. - CBCHCD..BPPAFB.. - HDBB...BPPA.B..I - ..BF..OBPAAAABA. - .BF.BOBPAAAAAFBA - BFBOOBPA.PP.AAFB - .BOOOBPPPPPP.AFB - .BOOOBPPPPPPPAFB - PPOOBBPPPPPPPPFB - BP.OBPPOOPP.P.FB - BPAABP.AAPPAPPFB - ....BPAA...PP.AB - ........PPPP.AB. -} -# tile 295 (shimmering dragon,female) -{ - .I.BF.BBBPAFB... - ..BF.NPNPPPAFB.I - .BF.BPPPPPPAFB.. - .BDCHHP..PPAFBI. - CBCHCD..BPPAFB.. - HDBB...BPPA.B..I - ..BF..OBPAAAABA. - .BF.BOBPAAAAAFBA - BFBOOBPA.PP.AAFB - .BOOOBPPPPPP.AFB - .BOOOBPPPPPPPAFB - PPOOBBPPPPPPPPFB - BP.OBPPOOPP.P.FB - BPAABP.AAPPAPPFB - ....BPAA...PP.AB - ........PPPP.AB. -} -# tile 296 (red dragon,male) -{ - ......IIIDA..... - .....NDNDDDA.... - ....IDDDDDDA.... - ..DCHHD..DDA.... - CHCHCD..IDDA.... - HD.D...IDDA..... - ......HIDAAAAAA. - ....IHIDAAAAAAAA - ..IHHIDAJDDJAAA. - .IHHHIDDDDDDJAA. - .IHHHIDDDDDDDAA. - DDHHIIDDDDDDDDA. - ID.HIDDHHDDJDJA. - IDAAID.AADDADDA. - ....IDAAJJJDDJA. - ........DDDDJA.. -} -# tile 297 (red dragon,female) -{ - ......IIIDA..... - .....NDNDDDA.... - ....IDDDDDDA.... - ..DCHHD..DDA.... - CHCHCD..IDDA.... - HD.D...IDDA..... - ......HIDAAAAAA. - ....IHIDAAAAAAAA - ..IHHIDAJDDJAAA. - .IHHHIDDDDDDJAA. - .IHHHIDDDDDDDAA. - DDHHIIDDDDDDDDA. - ID.HIDDHHDDJDJA. - IDAAID.AADDADDA. - ....IDAAJJJDDJA. - ........DDDDJA.. -} -# tile 298 (white dragon,male) -{ - ......NNNOA..... - .....IOIOOOA.... - ....NOOOOOOA.... - ..DCHHO..OOA.... - CHCHCD..NOOA.... - HD.D...NOOA..... - ......ONOAAAAAA. - ....NONOAAAAAAAA - ..NOONOA.OO.AAA. - .NOOONOOOOOOJAA. - .NOOONOOOOOOOAA. - OOOONNOOOOOOOOA. - NO.ONOOOOOO.OJA. - NOAANO.AAOOAOOA. - ....NOAA...OOJA. - ........OOOOJA.. -} -# tile 299 (white dragon,female) -{ - ......NNNOA..... - .....IOIOOOA.... - ....NOOOOOOA.... - ..DCHHO..OOA.... - CHCHCD..NOOA.... - HD.D...NOOA..... - ......ONOAAAAAA. - ....NONOAAAAAAAA - ..NOONOA.OO.AAA. - .NOOONOOOOOOJAA. - .NOOONOOOOOOOAA. - OOOONNOOOOOOOOA. - NO.ONOOOOOO.OJA. - NOAANO.AAOOAOOA. - ....NOAA...OOJA. - ........OOOOJA.. -} -# tile 300 (orange dragon,male) -{ - ......LLLCA..... - .....NCNCCCA.... - ....LCCCCCCA.... - ..DCHHC..CCA.... - CHCHCD..LCCA.... - HD.D...LCCA..... - ......OLCAAAAAA. - ....LOLCAAAAAAAA - ..LOOLCA.CCKAAA. - .LOOOLCCCCCCJAA. - .LOOOLCCCCCCCAA. - CCOOLLCCCCCCCCA. - LC.OLCCOOCCKCJA. - LCAALC.AACCACCA. - ....LCAA.KKCCJA. - ........CCCCJA.. -} -# tile 301 (orange dragon,female) -{ - ......LLLCA..... - .....NCNCCCA.... - ....LCCCCCCA.... - ..DCHHC..CCA.... - CHCHCD..LCCA.... - HD.D...LCCA..... - ......OLCAAAAAA. - ....LOLCAAAAAAAA - ..LOOLCA.CCKAAA. - .LOOOLCCCCCCJAA. - .LOOOLCCCCCCCAA. - CCOOLLCCCCCCCCA. - LC.OLCCOOCCKCJA. - LCAALC.AACCACCA. - ....LCAA.KKCCJA. - ........CCCCJA.. -} -# tile 302 (black dragon,male) -{ - ......AAAA...... - .....NANAAA..... - ....AAAAAAA..... - ..DCHHA..AA..... - CHCHCD..AAA..... - HD.D...AAA...... - ......AAA..PPPP. - ....AAAAPPPPPPPP - ..AAAAAAAAA.PPP. - .AAAAAAAAAAAAPP. - .AAAAAAAAAAAAPP. - AAAAAAAAAAAAAAP. - AA.AAAAAAAA.AAP. - AAPPAA.PPAAPAAP. - ....AAPP...AAAP. - ........AAAAA... -} -# tile 303 (black dragon,female) -{ - ......AAAA...... - .....NANAAA..... - ....AAAAAAA..... - ..DCHHA..AA..... - CHCHCD..AAA..... - HD.D...AAA...... - ......AAA..PPPP. - ....AAAAPPPPPPPP - ..AAAAAAAAA.PPP. - .AAAAAAAAAAAAPP. - .AAAAAAAAAAAAPP. - AAAAAAAAAAAAAAP. - AA.AAAAAAAA.AAP. - AAPPAA.PPAAPAAP. - ....AAPP...AAAP. - ........AAAAA... -} -# tile 304 (blue dragon,male) -{ - ......BBBEA..... - .....NENEEEA.... - ....BEEEEEEA.... - ..DCHHE..EEA.... - CHCHCD..BEEA.... - HD.D...BEEA..... - ......OBEAAAAAA. - ....BOBEAAAAAAAA - ..BOOBEA.EE.AAA. - .BOOOBEEEEEEJAA. - .BOOOBEEEEEEEAA. - EEOOBBEEEEEEEEA. - BE.OBEEOOEE.EJA. - BEAABE.AAEEAEEA. - ....BEAA...EEJA. - ...P....EEEEJA.. -} -# tile 305 (blue dragon,female) -{ - ......BBBEA..... - .....NENEEEA.... - ....BEEEEEEA.... - ..DCHHE..EEA.... - CHCHCD..BEEA.... - HD.D...BEEA..... - ......OBEAAAAAA. - ....BOBEAAAAAAAA - ..BOOBEA.EE.AAA. - .BOOOBEEEEEEJAA. - .BOOOBEEEEEEEAA. - EEOOBBEEEEEEEEA. - BE.OBEEOOEE.EJA. - BEAABE.AAEEAEEA. - ....BEAA...EEJA. - ...P....EEEEJA.. -} -# tile 306 (green dragon,male) -{ - ......GGGFA..... - .....NFNFFFA.... - ....GFFFFFFA.... - ..DCHHF..FFA.... - CHCHCD..GFFA.... - HD.D...GFFA..... - ......OGFAAAAAA. - ....GOGFAAAAAAAA - ..GOOGFA.FF.AAA. - .GOOOGFFFFFFJAA. - .GOOOGFFFFFFFAA. - FFOOGGFFFFFFFFA. - GF.OGFFOOFF.FJA. - GFAAGF.AAFFAFFA. - ....GFAA...FFJA. - ........FFFFJA.. -} -# tile 307 (green dragon,female) -{ - ......GGGFA..... - .....NFNFFFA.... - ....GFFFFFFA.... - ..DCHHF..FFA.... - CHCHCD..GFFA.... - HD.D...GFFA..... - ......OGFAAAAAA. - ....GOGFAAAAAAAA - ..GOOGFA.FF.AAA. - .GOOOGFFFFFFJAA. - .GOOOGFFFFFFFAA. - FFOOGGFFFFFFFFA. - GF.OGFFOOFF.FJA. - GFAAGF.AAFFAFFA. - ....GFAA...FFJA. - ........FFFFJA.. -} -# tile 308 (yellow dragon,male) -{ - ......NNNHA..... - .....DHDHHHA.... - ....NHHHHHHA.... - ..DCHHH..HHA.... - CHCHCD..NHHA.... - HD.D...NHHA..... - ......ONHAAAAAA. - ....NONHAAAAAAAA - ..NOONHAJHHJAAA. - .NOOONHHHHHHJAA. - .NOOONHHHHHHHAA. - HHOONNHHHHHHHHA. - NH.ONHHOOHHJHJA. - NHAANH.AAHHAHHA. - ....NHAAJJJHHJA. - ........HHHHJA.. -} -# tile 309 (yellow dragon,female) -{ - ......NNNHA..... - .....DHDHHHA.... - ....NHHHHHHA.... - ..DCHHH..HHA.... - CHCHCD..NHHA.... - HD.D...NHHA..... - ......ONHAAAAAA. - ....NONHAAAAAAAA - ..NOONHAJHHJAAA. - .NOOONHHHHHHJAA. - .NOOONHHHHHHHAA. - HHOONNHHHHHHHHA. - NH.ONHHOOHHJHJA. - NHAANH.AAHHAHHA. - ....NHAAJJJHHJA. - ........HHHHJA.. -} -# tile 310 (stalker,male) -{ - ................ - .......PPP...... - ......P.P.P..... - .....PPPPPP..... - .....PP..PPP.... - ....PPPPPP.P.... - ....P.PPPP.P.... - ....P.PPP..P.... - ....P..PP..P.... - ....P.PPPP.P.... - ....P.P..P.P.... - ....P.P..P.P.... - ......P..P...... - ......P..P...... - .....PP..PP..... - ................ -} -# tile 311 (stalker,female) -{ - ................ - .......PPP...... - ......P.P.P..... - .....PPPPPP..... - .....PP..PPP.... - ....PPPPPP.P.... - ....P.PPPP.P.... - ....P.PPP..P.... - ....P..PP..P.... - ....P.PPPP.P.... - ....P.P..P.P.... - ....P.P..P.P.... - ......P..P...... - ......P..P...... - .....PP..PP..... - ................ -} -# tile 312 (air elemental,male) -{ - ................ - ...P.PPP..P..... - ..P.PAPA.P...... - P..PPPPPP..P.... - .P.PPAAPPP...P.. - ..PPPAAP.P.P.... - ..PAPAAPAP...... - P.PAPPP.AP.P.AA. - ..PA.PP.AP.AAAA. - ..PAPPPPAPAAAA.. - ..PAP.APAPAAAA.. - ..PAP.APAPAAAAA. - ....P.APAAAAAAA. - ..P.P.APPAAAAAA. - ...PP.APPPA..... - ................ -} -# tile 313 (air elemental,female) -{ - ................ - ...P.PPP..P..... - ..P.PAPA.P...... - P..PPPPPP..P.... - .P.PPAAPPP...P.. - ..PPPAAP.P.P.... - ..PAPAAPAP...... - P.PAPPP.AP.P.AA. - ..PA.PP.AP.AAAA. - ..PAPPPPAPAAAA.. - ..PAP.APAPAAAA.. - ..PAP.APAPAAAAA. - ....P.APAAAAAAA. - ..P.P.APPAAAAAA. - ...PP.APPPA..... - ................ -} -# tile 314 (fire elemental,male) -{ - ................ - .H..LDDD........ - ...LDADAC.H..... - H..DDDDDD..H.H.. - ..LDDAADDD...... - ..DDDAADCD.H.... - ..DADAACAD...... - H.DADDDCAD...AA. - ..DACDDCAD.AAAA. - ..DADDDDADAAAA.. - ..DADCADADAAAA.. - H.DADCADADAAAAA. - ....DCADAAAAAAA. - .H.LDCADDAAAAAA. - ..LDDCADDDA..... - ................ -} -# tile 315 (fire elemental,female) -{ - ................ - .H..LDDD........ - ...LDADAC.H..... - H..DDDDDD..H.H.. - ..LDDAADDD...... - ..DDDAADCD.H.... - ..DADAACAD...... - H.DADDDCAD...AA. - ..DACDDCAD.AAAA. - ..DADDDDADAAAA.. - ..DADCADADAAAA.. - H.DADCADADAAAAA. - ....DCADAAAAAAA. - .H.LDCADDAAAAAA. - ..LDDCADDDA..... - ................ -} -# tile 316 (earth elemental,male) -{ - ..F............. - ....CKKK..F..... - ...CKAKAJ....F.. - ...KKKKKK....... - ..CKKAAKKK.F..F. - .FKKKAAKJK...... - ..KAKAAJAK..F... - ..KAKJJJAK...AA. - F.KAJKKJAK.AAAA. - ..KAKKKKAKAAAA.. - ..KAKJAKAKAAAA.. - ..KAKJAKAKAAAAA. - ....KJAKAAAAAAA. - .F.CKJAKKAAAAAA. - ..CKKJAKKKA..... - ................ -} -# tile 317 (earth elemental,female) -{ - ..F............. - ....CKKK..F..... - ...CKAKAJ....F.. - ...KKKKKK....... - ..CKKAAKKK.F..F. - .FKKKAAKJK...... - ..KAKAAJAK..F... - ..KAKJJJAK...AA. - F.KAJKKJAK.AAAA. - ..KAKKKKAKAAAA.. - ..KAKJAKAKAAAA.. - ..KAKJAKAKAAAAA. - ....KJAKAAAAAAA. - .F.CKJAKKAAAAAA. - ..CKKJAKKKA..... - ................ -} -# tile 318 (water elemental,male) -{ - ................ - ....PBBB..E..... - .E.PBABAE...E... - ...BBBBBB....... - ..PBBAABBB.E..E. - E.BBBAABEB...... - ..BABAABEB.E.... - ..BABBBBEB...AA. - ..BAPBBEAB.AAAA. - E.BABBBBABAAAA.. - ..BABEABABAAAA.. - ..BABEABABAAAAA. - ....BEABAAAAAAA. - .E.PBEABBAAAAAA. - ..PBBEABBBA..... - ................ -} -# tile 319 (water elemental,female) -{ - ................ - ....PBBB..E..... - .E.PBABAE...E... - ...BBBBBB....... - ..PBBAABBB.E..E. - E.BBBAABEB...... - ..BABAABEB.E.... - ..BABBBBEB...AA. - ..BAPBBEAB.AAAA. - E.BABBBBABAAAA.. - ..BABEABABAAAA.. - ..BABEABABAAAAA. - ....BEABAAAAAAA. - .E.PBEABBAAAAAA. - ..PBBEABBBA..... - ................ -} -# tile 320 (lichen,male) -{ - ................ - ................ - ...FFF...FFF.... - ..FCFFFFFCCFA... - .FCOOFFFCOFFFA.. - .FCOOFFFCFFFFA.. - ..FFFFFFFFFFA... - ...AFFFCCFFFA... - ...FFFFCOFFAA... - ..FCCFFCOFCFA... - ..FCOFFCFFOCFA.. - ..FFCFFFCFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 321 (lichen,female) -{ - ................ - ................ - ...FFF...FFF.... - ..FCFFFFFCCFA... - .FCOOFFFCOFFFA.. - .FCOOFFFCFFFFA.. - ..FFFFFFFFFFA... - ...AFFFCCFFFA... - ...FFFFCOFFAA... - ..FCCFFCOFCFA... - ..FCOFFCFFOCFA.. - ..FFCFFFCFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 322 (brown mold,male) -{ - ................ - ................ - ...JJJ...JJJ.... - ..JKJJJJJKKJA... - .JKCCJJJKCJJJA.. - .JKCCJJJKJJJJA.. - ..JJJJJJJJJJA... - ...AJJJKKJJJA... - ...JJJJKCJJAA... - ..JKKJJKCJKJA... - ..JKCJJKJJCKJA.. - ..JJKJJJKJJJJA.. - ...JJJAAJJJJJA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 323 (brown mold,female) -{ - ................ - ................ - ...JJJ...JJJ.... - ..JKJJJJJKKJA... - .JKCCJJJKCJJJA.. - .JKCCJJJKJJJJA.. - ..JJJJJJJJJJA... - ...AJJJKKJJJA... - ...JJJJKCJJAA... - ..JKKJJKCJKJA... - ..JKCJJKJJCKJA.. - ..JJKJJJKJJJJA.. - ...JJJAAJJJJJA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 324 (yellow mold,male) -{ - ................ - ................ - ...HHH...HHH.... - ..HHHHHHHNHHA... - .HHNNOHHNNOHHA.. - .HHNNOOHHOOHHA.. - ..HHOOHHHHHHA... - ...AHHHHHHHHA... - ...HHHHNNOHAA... - ..HHHHHNNOHHA... - ..HNNOHHHONOHA.. - ..HHOHHHHHOOHA.. - ...HHHAAHHHHHA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 325 (yellow mold,female) -{ - ................ - ................ - ...HHH...HHH.... - ..HHHHHHHNHHA... - .HHNNOHHNNOHHA.. - .HHNNOOHHOOHHA.. - ..HHOOHHHHHHA... - ...AHHHHHHHHA... - ...HHHHNNOHAA... - ..HHHHHNNOHHA... - ..HNNOHHHONOHA.. - ..HHOHHHHHOOHA.. - ...HHHAAHHHHHA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 326 (green mold,male) -{ - ................ - ................ - ...FFF...FFF.... - ..FGFFFFFGGFA... - .FGOOFFFGOFFFA.. - .FGOOFFFGFFFFA.. - ..FFFFFFFFFFA... - ...AFFFGGFFFA... - ...FFFFGOFFAA... - ..FGGFFGOFGFA... - ..FGOFFGFFOGFA.. - ..FFGFFFGFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 327 (green mold,female) -{ - ................ - ................ - ...FFF...FFF.... - ..FGFFFFFGGFA... - .FGOOFFFGOFFFA.. - .FGOOFFFGFFFFA.. - ..FFFFFFFFFFA... - ...AFFFGGFFFA... - ...FFFFGOFFAA... - ..FGGFFGOFGFA... - ..FGOFFGFFOGFA.. - ..FFGFFFGFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 328 (red mold,male) -{ - ................ - ................ - ...DDD...DDD.... - ..DCDDDDDCCDA... - .DLLCDDDCLDDDA.. - .DCCCDDDCDDDDA.. - ..DDDDDDDDDDA... - ...ADDDCCDDDA... - ...DDDDCLDDAA... - ..DCCDDCLDCDA... - ..DCLDDCDDLCDA.. - ..DDCDDDCDDDDA.. - ...DDDAADDDDDA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 329 (red mold,female) -{ - ................ - ................ - ...DDD...DDD.... - ..DCDDDDDCCDA... - .DLLCDDDCLDDDA.. - .DCCCDDDCDDDDA.. - ..DDDDDDDDDDA... - ...ADDDCCDDDA... - ...DDDDCLDDAA... - ..DCCDDCLDCDA... - ..DCLDDCDDLCDA.. - ..DDCDDDCDDDDA.. - ...DDDAADDDDDA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 330 (shrieker,male) -{ - ................ - ................ - ................ - ................ - .....GGGGFF..... - ...GGGGIGIDFF... - .GGGIIGGGIIFFFF. - GIIGIIGGGGGGGDDF - GIIGGGGIIGIIGIDF - GGGGIGGIIGIIGGFF - ..GGGGGGGGGGG... - ......FFF..AAAAA - ....AGGGFFAAAAAA - ...AGGGGGGFAAAA. - ...AAAAAAAAAA... - ................ -} -# tile 331 (shrieker,female) -{ - ................ - ................ - ................ - ................ - .....GGGGFF..... - ...GGGGIGIDFF... - .GGGIIGGGIIFFFF. - GIIGIIGGGGGGGDDF - GIIGGGGIIGIIGIDF - GGGGIGGIIGIIGGFF - ..GGGGGGGGGGG... - ......FFF..AAAAA - ....AGGGFFAAAAAA - ...AGGGGGGFAAAA. - ...AAAAAAAAAA... - ................ -} -# tile 332 (violet fungus,male) -{ - ................ - ................ - ...III...III.... - ..ILIIIIILLIA... - .IOOLIIILOIIIA.. - .ILLLIIILIIIIA.. - ..IIIIIIIIIIA... - ...AIIILLIIIA... - ...IIIILOIIAA... - ..ILLIILOILIA... - ..ILOIILIIOLIA.. - ..IILIIILIIIIA.. - ...IIIAAIIIIIA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 333 (violet fungus,female) -{ - ................ - ................ - ...III...III.... - ..ILIIIIILLIA... - .IOOLIIILOIIIA.. - .ILLLIIILIIIIA.. - ..IIIIIIIIIIA... - ...AIIILLIIIA... - ...IIIILOIIAA... - ..ILLIILOILIA... - ..ILOIILIIOLIA.. - ..IILIIILIIIIA.. - ...IIIAAIIIIIA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 334 (gnome,male) -{ - ................ - ................ - ................ - .....DF......... - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - .....OLO...AAA.. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 335 (gnome,female) -{ - ................ - ................ - ................ - .....DF......... - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - .....LLL...AAA.. - ...FGGGGFFAAAA.. - ...GAGFFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 336 (gnome leader,male) -{ - ................ - ................ - ......D......... - ......G......... - ......G......... - .....GFF........ - ....HHHHH....... - ....GLLLF.....A. - .....OLO...AAA.. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 337 (gnome leader,female) -{ - ................ - ................ - ......D......... - ......G......... - ......G......... - .....GFF........ - ....HHHHH....... - ....GLLLF.....A. - .....LLL...AAA.. - ...FGGGGFFAAAA.. - ...GAGGFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 338 (gnomish wizard,male) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - ...FFOLOFF.AAA.. - ...GFOOOFFAAAA.. - ...FAGOFAFAAAA.. - ...GLKNKFFAAA... - ...FFGFFFFA..... - ...GFFFFGFA..... - ................ - ................ -} -# tile 339 (gnomish wizard,female) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - ...FFLLLFF.AAA.. - ...GFGFGFFAAAA.. - ...FAGGFAFAAAA.. - ...GLKNKFFAAA... - ...FFGFFFFA..... - ...GFFFFGFA..... - ................ - ................ -} -# tile 340 (gnome ruler,male) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....GLLLF...A... - .....OLO...AAAA. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 341 (gnome ruler,female) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....GLLLF...A... - .....LLL...AAAA. - ...FGGGGFFAAAA.. - ...GAGFFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 342 (giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLKLKCKCLKLLLA - .LLAALLCCLLAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 343 (giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLKLKCKCLKLLLA - .LLAALLCCLLAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 344 (stone giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLAAKCKCLKLLLA - .LLPPPACCLLAALLA - .LLPPPPAKKJAALLA - .CLCPPPAJJKKCLAA - ..LLPPALACLJLLAA - .....ALJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 345 (stone giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLAAKCKCLKLLLA - .LLPPPACCLLAALLA - .LLPPPPAKKJAALLA - .CLCPPPAJJKKCLAA - ..LLPPALACLJLLAA - .....ALJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 346 (hill giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ...JJKJJJJJJJAA. - ..LJJCCKCKCJJLA. - ..JLKKKCKCKKLJA. - ..LAAKKCCKJAALAA - ..LAAJJJKKJAALAA - ..LC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 347 (hill giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ...JJKJJJJJJJAA. - ..LJJCCKCKCJJLA. - ..JLKKKCKCKKLJA. - ..LAAKKCCKJAALAA - ..LAAJJJKKJAALAA - ..LC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 348 (fire giant,male) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLJAAAA. - ...JPDJJJJJJJAA. - ..LDDHDKCKCJJLA. - ..JLHDDCKCKKLJA. - ..LAHDHCCKJAALAA - JLAADDHJKKJAALAA - JJLJDHHJJJKKCLAA - ..LLJJJJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 349 (fire giant,female) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLJAAAA. - ...JPDJJJJJJJAA. - ..LDDHDKCKCJJLA. - ..JLHDDCKCKKLJA. - ..LAHDHCCKJAALAA - JLAADDHJKKJAALAA - JJLJDHHJJJKKCLAA - ..LLJJJJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 350 (frost giant,male) -{ - .....KJJJJAA.... - ....KJJJJJJJA... - ....JJLLLLJJA... - ....JEELLEEJA... - ....JLLLLLLJA... - ....AKJJJJJAAA.. - .....KJAAJJAAAA. - ....KKJJJJAJAAAA - ...KJKJJJJAJJAAA - ..KJKKJJJJJKJJAA - ..KAAJKJJAJAAJAA - ..JAAJKKAKJAAJAA - ..LC.JJJJJKKCLAA - ..LL.CJJAJLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 351 (frost giant,female) -{ - .....KJJJJAA.... - ....KJJJJJJJA... - ....JJLLLLJJA... - ....JEELLEEJA... - ....JLLLLLLJA... - ....ALLLLLLAAA.. - .....LLAALLAAAA. - ....KKLLLLKKAAAA - ...KJKKKKKKJJAAA - ..KJKKJJJJKKJJAA - ..KAAJKJJKJAAJAA - ..JAAJKKKKJAAJAA - ..LC.JJJJJKKCLAA - ..LL.CJJAJLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 352 (ettin,male) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NPP..NPP..P... - ..ALPPLALPPLA... - ..APPPPAPPPPA... - ..APAAPAPAAPAA.. - ..APPPPAPPPPAAA. - ..BIIIIJJJIIIBAA - .BPPPIIIIIIPPPBA - .PPPFPIIIIPFPPPA - .PPAAPIIIIPAAPPA - .PPAAIIIIIIAAPPA - .BPB.IIFFIIABPAA - ..PP.BPAABPAPPAA - .....BPAABPAAAAA - ...PPPPA.BPPPFAA -} -# tile 353 (ettin,female) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NPP..NPP..P... - ..ALPPLALPPLA... - ..APPPPAPPPPA... - ..APAAPAPAAPAA.. - ..APPPPAPPPPAAA. - ..BIIIIJJJIIIBAA - .BPPPIIIIIIPPPBA - .PPPFPIIIIPFPPPA - .PPAAPIIIIPAAPPA - .PPAAIIIIIIAAPPA - .BPB.IIFFIIABPAA - ..PP.BPAABPAPPAA - .....BPAABPAAAAA - ...PPPPA.BPPPFAA -} -# tile 354 (storm giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAH.. - .....ALLLLJAHAA. - ...JJKJJJJJHHAA. - ..LJJCCKCKHHLAA. - ..JLKKKCKHHHHHH. - ..LAAKKCCKJAHHAA - ..LAAJJJKKJHHALA - ..LC.JJJJJKHAAAA - ..LL.CLJACHAAAAA - .....CLJACCJAAAA - ...LLLLJ.LLLLKAA -} -# tile 355 (storm giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAH.. - .....ALLLLJAHAA. - ...JJKJJJJJHHAA. - ..LJJCCKCKHHLAA. - ..JLKKKCKHHHHHH. - ..LAAKKCCKJAHHAA - ..LAAJJJKKJHHALA - ..LC.JJJJJKHAAAA - ..LL.CLJACHAAAAA - .....CLJACCJAAAA - ...LLLLJ.LLLLKAA -} -# tile 356 (titan,male) -{ - .....AAAAAAA.... - ....AALLLLAAA... - ....A..LL..AA... - ....ALLLLLLAA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCJJJJJJJJCCA. - .CLLLCCKCKCLLLCA - .LLLKJKCKCJKLLLA - .LLAAJJCCJJAALLA - .LLAAJJCCJJAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 357 (titan,female) -{ - .....AAAAAAA.... - ....AALLLLAAA... - ....A..LL..AA... - ....ALLLLLLAA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCJJJJJJJJCCA. - .CLLLCCKCKCLLLCA - .LLLKJKCKCJKLLLA - .LLAAJJCCJJAALLA - .LLAAJJCCJJAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 358 (minotaur,male) -{ - ................ - .O..........O... - .OOOJJJJJJOOO... - ..OOJJKJJJOO.... - ...JGAKJGAJA.... - ...JJJKJJJJA.... - ....JJKJJJAAA... - ....JKKKJAAAA... - ..CLJAJAKALCAA.A - .CLLJJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. - .LL.JJJJJJJLLAAA - .LL.JJJJJJJLLAAA - ....CLCACLCAAAAA - ..LLLLL.LLLLLAA. -} -# tile 359 (minotaur,female) -{ - ................ - .O..........O... - .OOOJJJJJJOOO... - ..OOJJKJJJOO.... - ...JGAKJGAJA.... - ...JJJKJJJJA.... - ....JJKJJJAAA... - ....JKKKJAAAA... - ..CLJAJAKALCAA.A - .CLLJJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAAJLLLLJAALAA. - .LL.JJJJJJJLLAAA - .LL.JJJJJJJLLAAA - ....CLCACLCAAAAA - ..LLLLL.LLLLLAA. -} -# tile 360 (jabberwock,male) -{ - ................ - ...DP........... - ....DP.ADOO..... - ..DAIDADIPAD.... - ...DIAPIPA...... - ...DBDDDA....... - ..IBBDADDA..AA.. - .DDDDAODDIAAAA.. - ..OAOA.DDAIAAA.. - ..IOAODDAAADDAA. - ..DDDADDDDAIDA.. - ...AAADDIDIDDD.. - ....IDDAIDDDDA.. - ....IDAAIDAA.... - ...IDAA..ID..... - ................ -} -# tile 361 (jabberwock,female) -{ - ................ - ...DP........... - ....DP.ADOO..... - ..DAIDADIPAD.... - ...DIAPIPA...... - ...DBDDDA....... - ..IBBDADDA..AA.. - .DDDDAODDIAAAA.. - ..OAOA.DDAIAAA.. - ..IOAODDAAADDAA. - ..DDDADDDDAIDA.. - ...AAADDIDIDDD.. - ....IDDAIDDDDA.. - ....IDAAIDAA.... - ...IDAA..ID..... - ................ -} -# tile 362 (vorpal jabberwock,male) -{ - ................ - ...GP........... - ....GP.AGOO..... - ..GAFGAGFPAG.... - ...GFAPFPA...... - ...GHGGGA....... - ..FHHGAGGA..AA.. - .GGGGAOGGFAAAA.. - ..OAOA.GGAFAAA.. - ..FOAOGGAAAGGAA. - ..GGGAGGGGAFGA.. - ...AAAGGFGFGGG.. - ....FGGAFGGGGA.. - ....FGAAFGAA.... - ...FGAA..FG..... - ................ -} -# tile 363 (vorpal jabberwock,female) -{ - ................ - ...GP........... - ....GP.AGOO..... - ..GAFGAGFPAG.... - ...GFAPFPA...... - ...GHGGGA....... - ..FHHGAGGA..AA.. - .GGGGAOGGFAAAA.. - ..OAOA.GGAFAAA.. - ..FOAOGGAAAGGAA. - ..GGGAGGGGAFGA.. - ...AAAGGFGFGGG.. - ....FGGAFGGGGA.. - ....FGAAFGAA.... - ...FGAA..FG..... - ................ -} -# tile 364 (Keystone Kop,male) -{ - ................ - ....AA.......... - ...AAAA......... - ...AOAA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.PPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 365 (Keystone Kop,female) -{ - ................ - ....AA.......... - ...AAAA......... - ...AOAA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.PPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 366 (Kop Sergeant,male) -{ - ................ - ....AA.......... - ...AOOA......... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 367 (Kop Sergeant,female) -{ - ................ - ....AA.......... - ...AOOA......... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 368 (Kop Lieutenant,male) -{ - ................ - ....AA.......... - ...AOOA...C..... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ..OAAAO.AAA..... - .OAAAAA.AAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 369 (Kop Lieutenant,female) -{ - ................ - ....AA.......... - ...AOOA...C..... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ..OAAAO.AAA..... - .OAAAAA.AAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 370 (Kop Kaptain,male) -{ - ................ - ....AA....C..... - ...AHHA...C..... - ...AHHA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - .HHAAAAHHAA..... - .AAAAHAAAACCC... - .AA.AHAAA.CPPP.. - ..AAAHAA.PCPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 371 (Kop Kaptain,female) -{ - ................ - ....AA....C..... - ...AHHA...C..... - ...AHHA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - .HHAAAAHHAA..... - .AAAAHAAAACCC... - .AA.AHAAA.CPPP.. - ..AAAHAA.PCPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 372 (lich,male) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....O.PPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 373 (lich,female) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....O.PPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 374 (demilich,male) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....L.PPPAAAA.A. - ......LPPAAA.A.. - .....LLAL.A..... - ...LLLA.LA...... - ......LLL....... - ................ -} -# tile 375 (demilich,female) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....L.PPPAAAA.A. - ......LPPAAA.A.. - .....LLAL.A..... - ...LLLA.LA...... - ......LLL....... - ................ -} -# tile 376 (master lich,male) -{ - ...H............ - ...HCH.H........ - ...HHHCH........ - ..AOAOHH........ - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...PPPPP....AAA. - ..PPPPPPPA..AAA. - .O..PPPPP.AAAAA. - ....OPPPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 377 (master lich,female) -{ - ...H............ - ...HCH.H........ - ...HHHCH........ - ..AOAOHH........ - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...PPPPP....AAA. - ..PPPPPPPA..AAA. - .O..PPPPP.AAAAA. - ....OPPPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 378 (arch-lich,male) -{ - ................ - ................ - ...OOO.......... - ..DODOO......... - ..OOOOO......... - H.OO.O.......... - A....PPP........ - A..OOPPP....AAA. - .AO.PPPPPA..AAA. - .O...PPPP.AAAAA. - .A..O.PPPAAAA.A. - ..A...PPPAAA.A.. - ..A..OPAP.A..... - ..AOOOA.OA...... - ......OOO....... - ................ -} -# tile 379 (arch-lich,female) -{ - ................ - ................ - ...OOO.......... - ..DODOO......... - ..OOOOO......... - H.OO.O.......... - A....PPP........ - A..OOPPP....AAA. - .AO.PPPPPA..AAA. - .O...PPPP.AAAAA. - .A..O.PPPAAAA.A. - ..A...PPPAAA.A.. - ..A..OPAP.A..... - ..AOOOA.OA...... - ......OOO....... - ................ -} -# tile 380 (kobold mummy,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NONONO....... - ...OAOAO.OP..... - ....ONN...A..... - ...ONODNA.AA.... - ..OLONNONAAA.A.. - ..NALONANAAAAA.. - ..NAOLOAOAAAAA.. - ....NOLAAAAAA... - ....NANAAAA..... - ...OOANOA....... - ................ - ................ -} -# tile 381 (kobold mummy,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NONONO....... - ...OAOAO.OP..... - ....ONN...A..... - ...ONODNA.AA.... - ..OLONNONAAA.A.. - ..NALONANAAAAA.. - ..NAOLOAOAAAAA.. - ....NOLAAAAAA... - ....NANAAAA..... - ...OOANOA....... - ................ - ................ -} -# tile 382 (gnome mummy,male) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GGFO....... - ....GGFFOOP..... - ....GDODF....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 383 (gnome mummy,female) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GGFO....... - ....GGFFOOP..... - ....GDODF....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 384 (orc mummy,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOOP........ - ....DODPOP...... - ....OOOA........ - ..OOOOOOOA.AA... - ..OOOOOOO.AAA... - ..OAOOOAACCC.... - ..OAOOOCCAAA.... - ....OCCOAAAAAA.. - ...CCAOOAAAA.... - ..OOOAOOOA...... - ................ - ................ -} -# tile 385 (orc mummy,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOOP........ - ....DODPOP...... - ....OOOA........ - ..OOOOOOOA.AA... - ..OOOOOOO.AAA... - ..OAOOOAACCC.... - ..OAOOOCCAAA.... - ....OCCOAAAAAA.. - ...CCAOOAAAA.... - ..OOOAOOOA...... - ................ - ................ -} -# tile 386 (dwarf mummy,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BBEO....... - ....BBEEEOP..... - ....BDODE....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 387 (dwarf mummy,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BBEO....... - ....BBEEEOP..... - ....BDODE....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 388 (elf mummy,male) -{ - ................ - ................ - .........O...... - .......OOOP..... - ......OOOOP..... - ......OEOEAP.... - ......OOOOA..... - ......AOOA....A. - ......OAAO..AAA. - .....OOOOOOAAAA. - ....OALOOLAOAAA. - ....OADOOOAOAA.. - ......OOAOAA.A.. - .....OOA.OOA.... - ................ - ................ -} -# tile 389 (elf mummy,female) -{ - ................ - ................ - .........O...... - .......OOOP..... - ......OOOOP..... - ......OEOEAP.... - ......OOOOA..... - ......AOOA....A. - ......OAAO..AAA. - .....OOOOOOAAAA. - ....OALOOLAOAAA. - ....OADOOOAOAA.. - ......OOAOAA.A.. - .....OOA.OOA.... - ................ - ................ -} -# tile 390 (human mummy,male) -{ - ................ - ................ - ...ONNO......... - ...NNNNOP....... - ..PANAN.OPP..... - ..PNNNN......... - ..ONOONNP....... - .ONLNNOOO....... - .NJNOOOOO..AAA.. - .OJOOOODN.AAAA.. - .NJOLNOAOAAAAAA. - .OCNO.NKNAAAAA.. - .N.OO.OLAAAAAAA. - ...OOAOOAAA..... - ..NNN.NNNA...... - ................ -} -# tile 391 (human mummy,female) -{ - ................ - ................ - ...ONNO......... - ...NNNNOP....... - ..PANAN.OPP..... - ..PNNNN......... - ..ONOONNP....... - .ONLNNOOO....... - .NJNOOOOO..AAA.. - .OJOOOODN.AAAA.. - .NJOLNOAOAAAAAA. - .OCNO.NKNAAAAA.. - .N.OO.OLAAAAAAA. - ...OOAOOAAA..... - ..NNN.NNNA...... - ................ -} -# tile 392 (ettin mummy,male) -{ - .....NN..ONOO... - ...NNOOONNOOOO.. - ...NOOOONOOOOOO. - ...OFOFOLOFOFO.O - ...OOOOOLOOOOO.P - ...NOOOOLNNOOOA. - ...ONOOOLOOOOAAA - ..OOOONNNNNNNOAA - .ONNNNNNOONOOOOA - .ONODNNOOOOOOOOA - .NNAAONNONOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 393 (ettin mummy,female) -{ - .....NN..ONOO... - ...NNOOONNOOOO.. - ...NOOOONOOOOOO. - ...OFOFOLOFOFO.O - ...OOOOOLOOOOO.P - ...NOOOOLNNOOOA. - ...ONOOOLOOOOAAA - ..OOOONNNNNNNOAA - .ONNNNNNOONOOOOA - .ONODNNOOOOOOOOA - .NNAAONNONOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 394 (giant mummy,male) -{ - ......ONOOAA.... - ....ONNNOOOOA... - ....NNOOOOOOO... - ....NFFOOFFOOP.. - ....NONOOOOOAOP. - ....AONOOOOAAAP. - .....ANOOODAAAA. - ..OOOONOOONNNOAA - .ONNNNNOOOOOOOOA - .ONODNNLOOOOOOOA - .NNAAONOLNOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 395 (giant mummy,female) -{ - ......ONOOAA.... - ....ONNNOOOOA... - ....NNOOOOOOO... - ....NFFOOFFOOP.. - ....NONOOOOOAOP. - ....AONOOOOAAAP. - .....ANOOODAAAA. - ..OOOONOOONNNOAA - .ONNNNNOOOOOOOOA - .ONODNNLOOOOOOOA - .NNAAONOLNOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 396 (red naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LDLAA........ - ...IDDAAAAADA... - ...IDDDAAADDA... - ....IIDDDDDA.... - ................ -} -# tile 397 (red naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LDLAA........ - ...IDDAAAAADA... - ...IDDDAAADDA... - ....IIDDDDDA.... - ................ -} -# tile 398 (black naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLA......... - ...LALAA........ - ...AAAPA..PAA... - ...AAAAPPPAAA... - ....AAAAAAAA.... - ................ -} -# tile 399 (black naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLA......... - ...LALAA........ - ...AAAPA..PAA... - ...AAAAPPPAAA... - ....AAAAAAAA.... - ................ -} -# tile 400 (golden naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LHLAA........ - ...NHHAAAAAHA... - ...NHHHAAAHHA... - ....NNHHHHHA.... - ................ -} -# tile 401 (golden naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LHLAA........ - ...NHHAAAAAHA... - ...NHHHAAAHHA... - ....NNHHHHHA.... - ................ -} -# tile 402 (guardian naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LFLAA........ - ...GFFAAAAAFA... - ...GFFFAAAFFA... - ....GGFFFFFA.... - ................ -} -# tile 403 (guardian naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LFLAA........ - ...GFFAAAAAFA... - ...GFFFAAAFFA... - ....GGFFFFFA.... - ................ -} -# tile 404 (red naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLDA..AA.... - ...LDLDA.AAAA... - ...IDDDAAAIIA... - ...IDDDAIDDDIDA. - ...IDDDIDDDDDDDA - ...IDDDDDDAA.DDA - ....DDDDDA..DDA. - .....DDAA..DDA.. - ..........DA.... -} -# tile 405 (red naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLDA..AA.... - ...LDLDA.AAAA... - ...IDDDAAAIIA... - ...IDDDAIDDDIDA. - ...IDDDIDDDDDDDA - ...IDDDDDDAA.DDA - ....DDDDDA..DDA. - .....DDAA..DDA.. - ..........DA.... -} -# tile 406 (black naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLAA........ - ...LALAA..PPP... - ...AAAAPPPAAP... - ...AAAAPAAAAAAP. - ...AAAAAAAAAAAAP - ...AAAAAAAPP.AAP - ....AAAAAP..AAP. - .....AAPP..AAP.. - ..........AP.... -} -# tile 407 (black naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLAA........ - ...LALAA..PPP... - ...AAAAPPPAAP... - ...AAAAPAAAAAAP. - ...AAAAAAAAAAAAP - ...AAAAAAAPP.AAP - ....AAAAAP..AAP. - .....AAPP..AAP.. - ..........AP.... -} -# tile 408 (golden naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLHA..AA.... - ...LHLHA.AAAA... - ...NHHHAAANNA... - ...NHHHANHHHNHA. - ...NHHHNHHHHHHHA - ...NHHHHHHAA.HHA - ....HHHHHA..HHA. - .....HHAA..HHA.. - ..........HA.... -} -# tile 409 (golden naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLHA..AA.... - ...LHLHA.AAAA... - ...NHHHAAANNA... - ...NHHHANHHHNHA. - ...NHHHNHHHHHHHA - ...NHHHHHHAA.HHA - ....HHHHHA..HHA. - .....HHAA..HHA.. - ..........HA.... -} -# tile 410 (guardian naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ..CLAALC........ - ..LLLLLL........ - ..CLLCLC..AA.... - ...CLLCA.AAAA... - ...GLFCAAAGGA... - ...GFFFAAFFFGFA. - ...GFFFGFFFFFFFA - ...GFFFFFFAA.FFA - ....FFFFFA..FFA. - .....FFAA..FFA.. - ..........FA.... -} -# tile 411 (guardian naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ..CLAALC........ - ..LLLLLL........ - ..CLLCLC..AA.... - ...CLLCA.AAAA... - ...GLFCAAAGGA... - ...GFFFAAFFFGFA. - ...GFFFGFFFFFFFA - ...GFFFFFFAA.FFA - ....FFFFFA..FFA. - .....FFAA..FFA.. - ..........FA.... -} -# tile 412 (ogre,male) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CAAACJAAA... - ....LDDDLAAAA... - ..CLJLLLKALCAA.A - .CLLAJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 413 (ogre,female) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CAAACJAAA... - ....LDDDLAAAA... - ..CLJLLLKALCAA.A - .CLLAJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 414 (ogre leader,male) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 415 (ogre leader,female) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 416 (ogre tyrant,male) -{ - ...H..C..H...... - ...HDCHCDH...... - ...HHHHHHH...... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CJKAJJJJAKJCAAA - .LJJKAAAAKJJLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 417 (ogre tyrant,female) -{ - ...HH.C.HH...... - ...HDCHCDH...... - ...HHHHHHH...... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CJKAJJJJAKJCAAA - .LJJKAAAAKJJLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 418 (gray ooze,male) -{ - ................ - ................ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAAA.. - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPBBPPAAA. - .PBBPPPBAAPPPAA. - ...PBBBAAAKPPJ.. - ........ACPPAK.. - .........KCCCJ.. - ................ -} -# tile 419 (gray ooze,female) -{ - ................ - ................ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAAA.. - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPBBPPAAA. - .PBBPPPBAAPPPAA. - ...PBBBAAAKPPJ.. - ........ACPPAK.. - .........KCCCJ.. - ................ -} -# tile 420 (brown pudding,male) -{ - ................ - ................ - ................ - ................ - ............J... - ....JKKJJJ..JJ.. - ...KKKCJJJJJ.... - ..KKNNJNNJJJ.... - ..KJANJANJJJA... - ..KKJJJJJCJJAA.. - ..JKJJCJJJJJAA.. - ...JJJJJJJJAAA.. - ....JJJJJJAAA... - .....AAAAAAA.... - ................ - ................ -} -# tile 421 (brown pudding,female) -{ - ................ - ................ - ................ - ................ - ............J... - ....JKKJJJ..JJ.. - ...KKKCJJJJJ.... - ..KKNNJNNJJJ.... - ..KJANJANJJJA... - ..KKJJJJJCJJAA.. - ..JKJJCJJJJJAA.. - ...JJJJJJJJAAA.. - ....JJJJJJAAA... - .....AAAAAAA.... - ................ - ................ -} -# tile 422 (green slime,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ............G... - .....G......G..G - .G....G..G.NGN.G - ..NG.NGGNGGGGGGG - ..GGNGGNGGGFGGF. - GGNGGGGGGGGGFF.G - .NGGGGGFGFG..... - NGGGGFGGFG.G..GF - NGGFGGF..GF..... - ..GGF..GGF..G... -} -# tile 423 (green slime,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ............G... - .....G......G..G - .G....G..G.NGN.G - ..NG.NGGNGGGGGGG - ..GGNGGNGGGFGGF. - GGNGGGGGGGGGFF.G - .NGGGGGFGFG..... - NGGGGFGGFG.G..GF - NGGFGGF..GF..... - ..GGF..GGF..G... -} -# tile 424 (black pudding,male) -{ - ........A....... - ........AA...... - .....AAA........ - ....AAAAA....... - ....CACAA....... - ....DADAA....... - ....AAAAA....... - ....AAAAA....... - ....AAAAA....... - .....AAAAA...... - .....AAAAA...... - ......AAAAA..... - ......AAAAAA.... - .......AAAAAA.A. - ........AAAAAAAA - ..........AAAA.. -} -# tile 425 (black pudding,female) -{ - ........A....... - ........AA...... - .....AAA........ - ....AAAAA....... - ....CACAA....... - ....DADAA....... - ....AAAAA....... - ....AAAAA....... - ....AAAAA....... - .....AAAAA...... - .....AAAAA...... - ......AAAAA..... - ......AAAAAA.... - .......AAAAAA.A. - ........AAAAAAAA - ..........AAAA.. -} -# tile 426 (quantum mechanic,male) -{ - ................ - ......LLLL...... - ...FGGCLCGGF.... - ...GNNGLGNNGL... - B.BGANGGGANGL... - B.BFGGCLCGGFL... - BIB..CLLLCCL.... - BILN.LLAALLAAAA. - BILNN.LLLLJAAAA. - BIB.NNJJJJNAAA.. - BIB.BNNNONNNAA.. - .B...NNNONNLAA.. - .....NBEBENA.A.. - .....NBEBENN.... - ....NAAEBAANN... - ................ -} -# tile 427 (quantum mechanic,female) -{ - ................ - ......JJJJJ..... - ...FGGCLCGGF.... - ...GNNGLGNNGJ... - B.BGANGGGANGL... - B.BFGGCLCGGFLJ.. - BIB.JCLLLCCLJJ.. - BILN.LLAALLAAAA. - BILNN.LLLLCAAAA. - BIB.NNCCCCNAAA.. - BIB.BNNNONNNAA.. - .B...NNNONNLAA.. - .....NBEBENA.A.. - .....NBEBENN.... - ....NAAEBAANN... - ................ -} -# tile 428 (genetic engineer,male) -{ - ................ - ......LLLL...... - ...LAALLLAAL.... - ...LNNLLLNNLL... - ...LANLLLANLL... - ...LLLLLLLLLL... - .....CLLLCCL.... - ..LN.LLAALL..... - ..LNN.LLLLJ..... - ..A.NNLLLLN..... - .A.ABNNNONNN.... - .AA..NNNONNL.... - .A.A.NPEPENA.... - .AA..NPEPENN.... - ..AANAAEPAANN... - ................ -} -# tile 429 (genetic engineer,female) -{ - ................ - ......LLLL...... - ...LAALLLAAL.... - ...LNNLLLNNLL... - ...LANLLLANLL... - ...LLLLLLLLLL... - .....CLLLCCL.... - ..LN.LLAALL..... - ..LNN.LLLLJ..... - ..A.NNLLLLN..... - .A.ABNNNONNN.... - .AA..NNNONNL.... - .A.A.NPEPENA.... - .AA..NPEPENN.... - ..AANAAEPAANN... - ................ -} -# tile 430 (rust monster,male) -{ - ................ - ....EEEE........ - ...EEHEHE....... - ...EEEAEE....... - ...EEPAPE....... - ...EPEAEP...E... - ....EEEE.AAEE... - ....EEEEEAAEEE.. - ...EEEEEEEAEAEE. - ..EEEEEEAAAAE... - ..EEAEEEEAEEEA.. - ..AAEEEEEEEEEAA. - ....AEEEEEEEAAA. - .....EEEEEAA..A. - ......AAAA...... - ................ -} -# tile 431 (rust monster,female) -{ - ................ - ....EEEE........ - ...EEHEHE....... - ...EEEAEE....... - ...EEPAPE....... - ...EPEAEP...E... - ....EEEE.AAEE... - ....EEEEEAAEEE.. - ...EEEEEEEAEAEE. - ..EEEEEEAAAAE... - ..EEAEEEEAEEEA.. - ..AAEEEEEEEEEAA. - ....AEEEEEEEAAA. - .....EEEEEAA..A. - ......AAAA...... - ................ -} -# tile 432 (disenchanter,male) -{ - ................ - ....PPPP........ - ...PPDPDP....... - ...PPPAPP....... - ...PPOAOP....... - ...POPAPO...P... - ....PPPP.AAPP... - ....PPPPPAAPPP.. - ...PPPPPPPAPAPP. - ..PPPPPPAAAAP... - ..PPAPPPPAPPPA.. - ..AAPPPPPPPPPAA. - ....APPPPPPPAAA. - .....PPPPPAA..A. - ......AAAA...... - ................ -} -# tile 433 (disenchanter,female) -{ - ................ - ....PPPP........ - ...PPDPDP....... - ...PPPAPP....... - ...PPOAOP....... - ...POPAPO...P... - ....PPPP.AAPP... - ....PPPPPAAPPP.. - ...PPPPPPPAPAPP. - ..PPPPPPAAAAP... - ..PPAPPPPAPPPA.. - ..AAPPPPPPPPPAA. - ....APPPPPPPAAA. - .....PPPPPAA..A. - ......AAAA...... - ................ -} -# tile 434 (garter snake,male) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOKA........ - ...KKAKA........ - ...KKAKA....KA.. - ....APKAP..KAPP. - .....PKAPP.KAP.. - .....KAAP..KAP.. - ....KAAP..KAAP.. - ....KAAPPKAAP... - ....KAAKKAAP.... - .....KAAAAP..... - ................ - ................ -} -# tile 435 (garter snake,female) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOKA........ - ...KKAKA........ - ...KKAKA....KA.. - ....APKAP..KAPP. - .....PKAPP.KAP.. - .....KAAP..KAP.. - ....KAAP..KAAP.. - ....KAAPPKAAP... - ....KAAKKAAP.... - .....KAAAAP..... - ................ - ................ -} -# tile 436 (snake,male) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOJA........ - ...KKJAJ........ - ...KKAAJ....KK.. - ...FAAKJ...KJAA. - ..FAFAKJAA.KJA.. - .....KJAA..KJA.. - ....KJAA..KJJA.. - ....KJAAAKJJA... - ....KJJJJJJA.... - .....KJJJJA..... - ................ - ................ -} -# tile 437 (snake,female) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOJA........ - ...KKJAJ........ - ...KKAAJ....KK.. - ...FAAKJ...KJAA. - ..FAFAKJAA.KJA.. - .....KJAA..KJA.. - ....KJAA..KJJA.. - ....KJAAAKJJA... - ....KJJJJJJA.... - .....KJJJJA..... - ................ - ................ -} -# tile 438 (water moccasin,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AA... - ...OAOAAA.AA.... - ...AAA.AA.AA.... - ...DA..AA.AA.... - ..D.D.AAA..AA... - .....AAA...AA... - .....AAA...AA... - ....AAA...AAA... - ....AAAAAAAA.... - ....AAAAAAA..... - .....AAAAA...... - ................ -} -# tile 439 (water moccasin,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AA... - ...OAOAAA.AA.... - ...AAA.AA.AA.... - ...DA..AA.AA.... - ..D.D.AAA..AA... - .....AAA...AA... - .....AAA...AA... - ....AAA...AAA... - ....AAAAAAAA.... - ....AAAAAAA..... - .....AAAAA...... - ................ -} -# tile 440 (python,male) -{ - ................ - ................ - ................ - ...KKKA.....JJ.. - ...GAGJA...JJJ.. - ..JKKJAJ..KJJ... - ..KKKAJJ..KJJ.AA - ..KKAAKJA.KKJAA. - .....AKJAA.KJAA. - ....JKJAA..KJJA. - ...JJJAA..KJJJA. - ...JJJAAAKJJJA.. - ...JJJJJJJJJAA.. - ....JJJJJJJAA... - .....JJJJJAA.... - ................ -} -# tile 441 (python,female) -{ - ................ - ................ - ................ - ...KKKA.....JJ.. - ...GAGJA...JJJ.. - ..JKKJAJ..KJJ... - ..KKKAJJ..KJJ.AA - ..KKAAKJA.KKJAA. - .....AKJAA.KJAA. - ....JKJAA..KJJA. - ...JJJAA..KJJJA. - ...JJJAAAKJJJA.. - ...JJJJJJJJJAA.. - ....JJJJJJJAA... - .....JJJJJAA.... - ................ -} -# tile 442 (pit viper,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AAA.. - ...OAAAAA.AA.AA. - ...AA..AA.AA.AA. - ...D...AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA...AA... - .....AA...AAA... - .....AA..AAA.... - .....AAAAAA..... - ......AAAA...... - ................ -} -# tile 443 (pit viper,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AAA.. - ...OAAAAA.AA.AA. - ...AA..AA.AA.AA. - ...D...AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA...AA... - .....AA...AAA... - .....AA..AAA.... - .....AAAAAA..... - ......AAAA...... - ................ -} -# tile 444 (cobra,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAAA....... - ..PA..AAAA...... - ..A..AAAAA..AA.. - ..D..AAAAA....A. - ......AAA.....A. - ......AA..AAAA.. - .....AA..AA..... - ....AA...AA..... - ....AA....AAAA.. - ....AAA......AA. - .....AAAAAAAAA.. - ................ -} -# tile 445 (cobra,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAAA....... - ..PA..AAAA...... - ..A..AAAAA..AA.. - ..D..AAAAA....A. - ......AAA.....A. - ......AA..AAAA.. - .....AA..AA..... - ....AA...AA..... - ....AA....AAAA.. - ....AAA......AA. - .....AAAAAAAAA.. - ................ -} -# tile 446 (troll,male) -{ - ................ - ..AAAAAA........ - AAAANANA........ - .AAKKKJJA....... - AAAKAAAKA....... - AKAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAFGFJJAAAA.. - ..KJA.PFJAAAA... - ...AFAGFAAAAAA.. - ...GFAGP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 447 (troll,female) -{ - ................ - ..AAAAAA........ - AAAANANA........ - .AAKKKJJA....... - AAAKAAAKA....... - AKAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAFGFJJAAAA.. - ..KJA.PFJAAAA... - ...AFAGFAAAAAA.. - ...GFAGP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 448 (ice troll,male) -{ - ................ - ..OONOOO........ - NONOAOAOO....... - .NOKKKJJO....... - NOJKAAAKOO...... - OKJKAAAKAO...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 449 (ice troll,female) -{ - ................ - ..OONOOO........ - NONOAOAOO....... - .NOKKKJJO....... - NOJKAAAKOO...... - OKJKAAAKAO...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 450 (rock troll,male) -{ - ................ - ...AAAAA........ - .AAANANAAAA..... - .AAKKKJJAA...... - AAAKAAAKAAAA.... - AKAKAAAKAAA..... - KJJAKKKAJKAA.... - KJAJAAAJJJA..... - KJAPAKJJKJA..... - PKJPPAGFJJAAAA.. - PPPPPAFFJAAAA... - .PPPAAGFAAAAAA.. - ...AFAGF.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 451 (rock troll,female) -{ - ................ - ...AAAAA........ - .AAANANAAAA..... - .AAKKKJJAA...... - AAAKAAAKAAAA.... - AKAKAAAKAAA..... - KJJAKKKAJKAA.... - KJAJAAAJJJA..... - KJAPAKJJKJA..... - PKJPPAGFJJAAAA.. - PPPPPAFFJAAAA... - .PPPAAGFAAAAAA.. - ...AFAGF.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 452 (water troll,male) -{ - ................ - ...AAAAA........ - ..AANANAA....... - .AAKKKJJAA...... - .AAKAAAKAA...... - .KAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 453 (water troll,female) -{ - ................ - ...AAAAA........ - ..AANANAA....... - .AAKKKJJAA...... - .AAKAAAKAA...... - .KAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 454 (Olog-hai,male) -{ - ...PPPPP........ - ..PPAAAPP....... - ..PANANAP....... - ..PAAAAAP....... - .PPAAAAAPP...... - PPPAAAAAPPP..... - AAPPAAAPPAA..... - AAAPPPPPAAA..... - AAAPPPPPAAA..... - .AAAAPPPAAAPPP.. - PONNNNNNAACPP... - ...APAPPAPPPPP.. - ...PPAPP.PP.PP.. - ..AAAAAAAP.PP... - ..AAA.AAA....... - ................ -} -# tile 455 (Olog-hai,female) -{ - ...PPPPP........ - ..PPAAAPP....... - ..PANANAP....... - ..PAAAAAP....... - .PPAAAAAPP...... - PPPAAAAAPPP..... - AAPPAAAPPAA..... - AAAPPPPPAAA..... - AAAPPPPPAAA..... - .AAAAPPPAAAPPP.. - PONNNNNNAACPP... - ...APAPPAPPPPP.. - ...PPAPP.PP.PP.. - ..AAAAAAAP.PP... - ..AAA.AAA....... - ................ -} -# tile 456 (umber hulk,male) -{ - ................ - ...AAAAA........ - ..AAAAAAA....... - .ADADADADA...... - .AAAAAAAAA.A.... - .AAAOAOAAA.AA... - .A.AOAOA.AAA.... - .A.AAAAAPAA..... - .AAAAAAAP....... - .A.AAAAA.PPPPPP. - ...AA.AA.PPPPP.. - ...AA.AAPPPPPPP. - ...AAPAAPPPP.... - ..AAAPAAAPP..... - .AAAP..AAP...... - ................ -} -# tile 457 (umber hulk,female) -{ - ................ - ...AAAAA........ - ..AAAAAAA....... - .ADADADADA...... - .AAAAAAAAA.A.... - .AAAOAOAAA.AA... - .A.AOAOA.AAA.... - .A.AAAAAPAA..... - .AAAAAAAP....... - .A.AAAAA.PPPPPP. - ...AA.AA.PPPPP.. - ...AA.AAPPPPPPP. - ...AAPAAPPPP.... - ..AAAPAAAPP..... - .AAAP..AAP...... - ................ -} -# tile 458 (vampire,male) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAAAAAAA...... - ..AAAAAAAA...... - ...AAAAAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 459 (vampire,female) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAAAAAAA...... - ..AAAAAAAA...... - ...AAAAAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 460 (vampire leader,male) -{ - ................ - .....AAAA....... - .N..AAOOAA...... - .NDDAGAAGADA.... - .NADALLLOAD..... - AAAAAAAAAAA..... - AAAAAAAAAAA..... - .AAAAAAAAAA..... - .NAAAAAAAAA..... - .N.AAAAAAAAPPPPP - .NADAAAAAAAPPPPP - .NADDAAAAAAPPPP. - .NAAAAAAAAAPPP.. - .N...AAAPAAPP... - .N..AAPP..AP.... - ................ -} -# tile 461 (vampire leader,female) -{ - ................ - .....AAAA....... - .N..AAOOAA...... - .NDDAGAAGADA.... - .NADALLLOAD..... - AAAAAAAAAAA..... - AAAAAAAAAAA..... - .AAAAAAAAAA..... - .NAAAAAAAAA..... - .N.AAAAAAAAPPPPP - .NADAAAAAAAPPPPP - .NADDAAAAAAPPPP. - .NAAAAAAAAAPPP.. - .N...AAAPAAPP... - .N..AAPP..AP.... - ................ -} -# tile 462 (vampire mage,male) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAA.A.AA...... - ..AAAACAAA...... - ...AAADAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 463 (vampire mage,female) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAA.A.AA...... - ..AAAACAAA...... - ...AAADAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 464 (Vlad the Impaler,male) -{ - ................ - ..N..AAAA....... - ADNDAAOOAADDDA.. - .ANDAGAAGADDA... - ..NDALLLOADA.... - ..NAAAAAAAAAAAAA - .HHHDAAAAADDDDDA - HEHEHJAAAADDDAA. - LLLLLJAAAADDAAPP - .LLLJAAAAADDAPPP - ..NJDAAAAADAPPPP - .ANDDAAAAAAAPPPP - .ANAAAAAAAAPPPP. - ..N..AAAPAAPPP.. - ..N.AAPP..AP.... - ................ -} -# tile 465 (Vlad the Impaler,female) -{ - ................ - ..N..AAAA....... - ADNDAAOOAADDDA.. - .ANDAGAAGADDA... - ..NDALLLOADA.... - ..NAAAAAAAAAAAAA - .HHHDAAAAADDDDDA - HEHEHJAAAADDDAA. - LLLLLJAAAADDAAPP - .LLLJAAAAADDAPPP - ..NJDAAAAADAPPPP - .ANDDAAAAAAAPPPP - .ANAAAAAAAAPPPP. - ..N..AAAPAAPPP.. - ..N.AAPP..AP.... - ................ -} -# tile 466 (barrow wight,male) -{ - ................ - ................ - ...LLO.......... - ..DLDLO......... - ..LLLLO......... - ..LJL..P........ - ..OOO.PP...AAAA. - ..POO.PP.AAAAAA. - .LPOO.PP.PAAAA.. - .JJOO.PP.PAAAA.. - .J.O..PL.PPAAA.. - .J.O.PPPPPPAAA.. - .J...PPPPPPPAA.. - .J..LLPPPPPPA... - .J.....LLAA..... - ................ -} -# tile 467 (barrow wight,female) -{ - ................ - .......OOOOO..... - ..OOOOOOO....... - .ODLDLOO.OOO.... - .OLLLLOOOOOOO... - .OLJLLOPOO...... - .OPLLL.POOOAAAA. - ..PPP.PP.AAAAAA. - .LPPPPPP.PAAAA.. - .JJ.PPPP.PAAAA.. - .J...PPL.PPAAA.. - .J...PPPPPPAAA.. - .J...PPPPPPPAA.. - .J..LLPPPPPPA... - .J.....LLAA..... - ................ -} -# tile 468 (wraith,male) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - ..AAPPPPAP..AAA. - ..PPPPPOLPAAAAA. - ...A.PPAAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ - ................ - ................ -} -# tile 469 (wraith,female) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - ..AAPPPPAP..AAA. - ..PPPPPOLPAAAAA. - ...A.PPAAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ - ................ - ................ -} -# tile 470 (Nazgul,male) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - .OPAPPPPAP..AAA. - ..PAPPPPAP..AAA. - ..PA.PPPLP..AAA. - ..PP.PPOLPAAAAA. - ...AAPPOAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ -} -# tile 471 (Nazgul,female) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - .OPAPPPPAP..AAA. - ..PAPPPPAP..AAA. - ..PA.PPPLP..AAA. - ..PP.PPOLPAAAAA. - ...AAPPOAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ -} -# tile 472 (xorn,male) -{ - ................ - ................ - ................ - ...OB.OP.BP..... - ...BBBBPPPP..... - ...B............ - ...DDBB.BDDA.A.. - ...DDBB.PDDAAAA. - ...B.......AAAA. - ...BOB.BPP.AAAA. - ...BBB.PPP.AAAA. - ...B.......AAA.. - ...BOBBPPBPAA... - ...BO.BP.PPA.... - ................ - ................ -} -# tile 473 (xorn,female) -{ - ................ - ................ - ................ - ...OB.OP.BP..... - ...BBBBPPPP..... - ...B............ - ...DDBB.BDDA.A.. - ...DDBB.PDDAAAA. - ...B.......AAAA. - ...BOB.BPP.AAAA. - ...BBB.PPP.AAAA. - ...B.......AAA.. - ...BOBBPPBPAA... - ...BO.BP.PPA.... - ................ - ................ -} -# tile 474 (monkey,male) -{ - ................ - ................ - ................ - ................ - ................ - .......KKA...... - ......KLLJA..... - ......KLLJA..... - .......KJA...... - .....KKKKKJAA... - ....KJKLLJJJAA.. - ....LAKLLJALAA.. - ......KJJJAAAA.. - ......JAAJAAA... - .....JJA.JJA.... - ................ -} -# tile 475 (monkey,female) -{ - ................ - ................ - ................ - ................ - ................ - .......KKA...... - ......KLLJA..... - ......KLLJA..... - .......KJA...... - .....KKKKKJAA... - ....KJKLLJJJAA.. - ....LAKLLJALAA.. - ......KJJJAAAA.. - ......JAAJAAA... - .....JJA.JJA.... - ................ -} -# tile 476 (ape,male) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCLACCAJJAAA - ..KKKKCCCAJKJJAA - ..KKAKJAAJJAJJAA - ..KAAKJJJJJAAJAA - ..LC.KJJJJJKCLAA - ..LL.CJJAKLJLLAA - .....CLJACLJAAAA - ...LLLLJACLLLKA. - ................ - ................ -} -# tile 477 (ape,female) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCLACCAJJAAA - ..KKKKCCCAJKJJAA - ..KKAKJAAJJAJJAA - ..KAAKJJJJJAAJAA - ..LC.KJJJJJKCLAA - ..LL.CJJAKLJLLAA - .....CLJACLJAAAA - ...LLLLJACLLLKA. - ................ - ................ -} -# tile 478 (owlbear,male) -{ - ................ - ....K.....K..... - ....CK...KK..... - ....CKKKKKK..... - ...KOOOKOOOK.... - ...KOOOKOOOKA..A - ...KOOAJAOOKAAAA - ..CKCJJHJJKAKAAA - .CKKKCKLKKAJJKAA - .KJJJJCKKJJJJJAA - .KJJJPAKJPJJJJAA - ..KJJJAKJJJJJAAA - ...JJPAKJPJJAAA. - ...JAAJAJAAJAA.. - ...PJPJAJPJPA... - ................ -} -# tile 479 (owlbear,female) -{ - ................ - ....K.....K..... - ....CK...KK..... - ....CKKKKKK..... - ...KOOOKOOOK.... - ...KOOOKOOOKA..A - ...KOOAJAOOKAAAA - ..CKCJJHJJKAKAAA - .CKKKCKLKKAJJKAA - .KJJJJCKKJJJJJAA - .KJJJPAKJPJJJJAA - ..KJJJAKJJJJJAAA - ...JJPAKJPJJAAA. - ...JAAJAJAAJAA.. - ...PJPJAJPJPA... - ................ -} -# tile 480 (yeti,male) -{ - ................ - ....BNNN........ - ...BNANAP....... - ..BNNNNNNP...... - ..NNNADANN...... - ..NNNNNNPN...... - ..N.NNBPPNP..... - ..N.NNNNANP..AA. - ..NNBNNNPN.AAAA. - ....NNNNP.KAAA.. - ....NN.NPAKKAA.. - ....NB.NPAACKAA. - ....NNANPAAKKJA. - ...BNNANNPAACKA. - ..BNNA..NNA..... - ................ -} -# tile 481 (yeti,female) -{ - ................ - ....BNNN........ - ...BNANAP....... - ..BNNNNNNP...... - ..NNNADANN...... - ..NNNNNNPN...... - ..N.NNBPPNP..... - ..N.NNNNANP..AA. - ..NNBNNNPN.AAAA. - ....NNNNP.KAAA.. - ....NN.NPAKKAA.. - ....NB.NPAACKAA. - ....NNANPAAKKJA. - ...BNNANNPAACKA. - ..BNNA..NNA..... - ................ -} -# tile 482 (carnivorous ape,male) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCAAACAJJAAA - ..KKKCDDDCAKJJAA - ..KKAKCCCAJAJJAA - ..KAAKJAAJJAAJAA - ..LC.AJJJJJKCLAA - ..LLDDAJAKLJLLAA - ...DDALJACLJAAAA - ..DDALLJACLLLKA. - ................ - ................ -} -# tile 483 (carnivorous ape,female) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCAAACAJJAAA - ..KKKCDDDCAKJJAA - ..KKAKCCCAJAJJAA - ..KAAKJAAJJAAJAA - ..LC.AJJJJJKCLAA - ..LLDDAJAKLJLLAA - ...DDALJACLJAAAA - ..DDALLJACLLLKA. - ................ - ................ -} -# tile 484 (sasquatch,male) -{ - ................ - ....CCCCC....... - ...CGAJGAJ...... - ..CKKKKJJJ...... - ..CKKAAAKJJ..... - .CKKKAAAKKJ..... - .CKJKKKKKKKJ.... - .CKAJJJJJAKJ.... - .CKAJKKKJAKJ.AA. - .CKJAJKJACKJAAAA - .CKJAJJJACKJAAA. - ..J.AJAKKAJAAAAA - ...CKJAKKJAAAAA. - .KCKJJACKJKJAA.. - .CJJJKACKJJKA... - ................ -} -# tile 485 (sasquatch,female) -{ - ................ - ....CCCCC....... - ...CGAJGAJ...... - ..CKKKKJJJ...... - ..CKKAAAKJJ..... - .CKKKAAAKKJ..... - .CKJKKKKKKKJ.... - .CKAJJJJJAKJ.... - .CKAJKKKJAKJ.AA. - .CKJAJKJACKJAAAA - .CKJAJJJACKJAAA. - ..J.AJAKKAJAAAAA - ...CKJAKKJAAAAA. - .KCKJJACKJKJAA.. - .CJJJKACKJJKA... - ................ -} -# tile 486 (kobold zombie,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NGFBN........ - ...GABAB........ - ....GBFA..A..... - ...GBABFA.AA.... - ..GFBBBIKAAA.A.. - ..BAFBFFEAAAAA.. - ..BAFBFFAAAAAA.. - ....FBFAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 487 (kobold zombie,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NGFBN........ - ...GABAB........ - ....GBFA..A..... - ...GBABFA.AA.... - ..GFBBBIKAAA.A.. - ..BAFBFFEAAAAA.. - ..BAFBFFAAAAAA.. - ....FBFAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 488 (gnome zombie,male) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GDFDF....... - .....PFP...AAA.. - ...FGFPFEGAAAA.. - ..GAAGFFFAGAAA.. - ....AKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 489 (gnome zombie,female) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GDFDF....... - .....GFF...AAA.. - ...FGFFFEGAAAA.. - ..GAAGFFFAGAAA.. - ....AKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 490 (orc zombie,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....GPGA........ - .....PFA........ - ..KCCAKKKA.AA... - .BBPCKJ.BBAAA... - BB.AGGFAABBA.... - B..AJJPAAABA.... - ....BAPPPAAAAA.. - ...BJAAEPAAA.... - ..BPPAAAPP...... - ................ - ................ -} -# tile 491 (orc zombie,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....GPGA........ - .....PFA........ - ..KCCAKKKA.AA... - .BBPCKJ.BBAAA... - BB.AGGFAABBA.... - B..AJJPAAABA.... - ....BAPPPAAAAA.. - ...BJAAEPAAA.... - ..BPPAAAPP...... - ................ - ................ -} -# tile 492 (dwarf zombie,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BFFFE....... - .....PFP...AAA.. - ...BBPPPEEAAAA.. - ..FBABPEAEAAAA.. - ..F.EBBEFAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 493 (dwarf zombie,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BFFFE....... - .....PFP...AAA.. - ...BBPPPEEAAAA.. - ..FBABPEAEAAAA.. - ..F.EBBEFAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 494 (elf zombie,male) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......FEFEA..... - ......FFFFA..... - ......AFDA....A. - ......GAAG..AAA. - ....FFGGGFFFAAA. - ...FAAAGFAAAFAA. - .....AGGGFAAAA.. - ......GFAFAA.A.. - .....KDA.FKA.... - ................ - ................ -} -# tile 495 (elf zombie,female) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......FEFEA..... - ......FFFFA..... - ......AFDA....A. - ......GAAG..AAA. - ....FFGGGFFFAAA. - ...FAAAGFAAAFAA. - .....AGGGFAAAA.. - ......GFAFAA.A.. - .....KDA.FKA.... - ................ - ................ -} -# tile 496 (human zombie,male) -{ - ......AAA....... - .....FFGAA...... - .....AGAFA...... - .....FFGFA...... - ....FKF..JJ..... - ....JJJFJKJ..... - ...FJ.KJJAKJ.... - ..FK..KFJFFJ.... - ..G...KKJG...... - .....BP.BPAAAAA. - .....FPAPFAAAA.. - .....BFABFAAAA.. - .....PFABPAA.... - .....BFABFA..... - ....GGAGGA...... - ................ -} -# tile 497 (human zombie,female) -{ - ......AAA....... - .....FFGAA...... - .....AGAFA...... - .....FFGFA...... - ....FKF..JJ..... - ....JJJFJKJ..... - ...FJ.KJJAKJ.... - ..FK..KFJFFJ.... - ..G...KKJG...... - .....BP.BPAAAAA. - .....FPAPFAAAA.. - .....BFABFAAAA.. - .....PFABPAA.... - .....BFABFA..... - ....GGAGGA...... - ................ -} -# tile 498 (ettin zombie,male) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NFF..NFF..P... - ..ADFFDADFFDA... - ..AFFFFAFFFFA... - ..AFAAFAFAAFAA.. - ..AFFFFAFFFFAAA. - ..GIIIIJJJIIIGAA - .GFFFIIIIIIFFFGA - .GFFFFIIIIFFFFFA - .FFAAFIIIIFAAFFA - .FFAAIIIIIIAAFFA - .FFF.IIFFIIAGFAA - ..FF.GFAAGFAFFAA - .....GFAAGFAAAAA - ...FFFFA.GFFFFAA -} -# tile 499 (ettin zombie,female) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NFF..NFF..P... - ..ADFFDADFFDA... - ..AFFFFAFFFFA... - ..AFAAFAFAAFAA.. - ..AFFFFAFFFFAAA. - ..GIIIIJJJIIIGAA - .GFFFIIIIIIFFFGA - .GFFFFIIIIFFFFFA - .FFAAFIIIIFAAFFA - .FFAAIIIIIIAAFFA - .FFF.IIFFIIAGFAA - ..FF.GFAAGFAFFAA - .....GFAAGFAAAAA - ...FFFFA.GFFFFAA -} -# tile 500 (ghoul,male) -{ - ......AAA....... - .....OOOAA...... - .....DODOA...... - .....OOOOA...... - ....PPOOOPP..... - ....PPPPPPP..... - ...PP.PPPAPP.... - ..PP..PPPOOP.... - ..O...PPPO...... - .....PP.PPAAAAA. - .....PPAPPAAAA.. - .....PPAPPAAAA.. - .....PPAPPAA.... - .....PPAPPA..... - ....OOAOOA...... - ................ -} -# tile 501 (ghoul,female) -{ - ......AAA....... - .....OOOAA...... - .....DODOA...... - .....OOOOA...... - ....PPOOOPP..... - ....PPPPPPP..... - ...PP.PPPAPP.... - ..PP..PPPOOP.... - ..O...PPPO...... - .....PP.PPAAAAA. - .....PPAPPAAAA.. - .....PPAPPAAAA.. - .....PPAPPAA.... - .....PPAPPA..... - ....OOAOOA...... - ................ -} -# tile 502 (giant zombie,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJFFFFJJA... - ....JDDFFDDJA... - ....JFFFFFFJA... - ....AFFAAFFAAA.. - .....AFFFFJAAAA. - ..GGFFJJJJFFGGAA - .GFFFGGFFFFFFFCA - .FFFKFFFFFFKFFFA - FFFAAFFFFFFAAFFA - FFAA.JJJKKJAAFFA - FFA..JJJJJKAGFAA - .....GFAGFFAFFAA - ....GFFAGFFAAAAA - ...GFFAAGFFFAAAA -} -# tile 503 (giant zombie,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJFFFFJJA... - ....JDDFFDDJA... - ....JFFFFFFJA... - ....AFFAAFFAAA.. - .....AFFFFJAAAA. - ..GGFFJJJJFFGGAA - .GFFFGGFFFFFFFCA - .FFFKFFFFFFKFFFA - FFFAAFFFFFFAAFFA - FFAA.JJJKKJAAFFA - FFA..JJJJJKAGFAA - .....GFAGFFAFFAA - ....GFFAGFFAAAAA - ...GFFAAGFFFAAAA -} -# tile 504 (skeleton,male) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - ......O......... - ....OOOOO...AAA. - ...OA.OOOA..AAA. - ..OA.OAAO.AAAAA. - ....OA.OOOAAA.A. - ......OOOAAA.A.. - .....O.AO.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 505 (skeleton,female) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - ......O......... - ....OOOOO...AAA. - ...OA.OOOA..AAA. - ..OA.OAAO.AAAAA. - ....OA.OOOAAA.A. - ......OOOAAA.A.. - .....O.AO.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 506 (straw golem,male) -{ - ......LJ........ - ......LJHJ...... - ....HJLJH...A... - ....AAAAAL.....A - ....DAADAL.A.AA. - ....LJHJL..AAAA. - ....LLHJLHHCHHL. - ...HHLJL.AJLJL.A - .HHJJLLLLAAA.AA. - ..JL..LALHAAAAAA - .LL..CJLHJHAAAAA - .....HJLAHJHAAA. - .....HJAACALHAAA - ....CJLAAJHALHA. - ....HALA.AHAAL.. - ..........L..... -} -# tile 507 (straw golem,female) -{ - ......LJ........ - ......LJHJ...... - ....HJLJH...A... - ....AAAAAL.....A - ....DAADAL.A.AA. - ....LJHJL..AAAA. - ....LLHJLHHCHHL. - ...HHLJL.AJLJL.A - .HHJJLLLLAAA.AA. - ..JL..LALHAAAAAA - .LL..CJLHJHAAAAA - .....HJLAHJHAAA. - .....HJAACALHAAA - ....CJLAAJHALHA. - ....HALA.AHAAL.. - ..........L..... -} -# tile 508 (paper golem,male) -{ - ................ - .......OA....... - .....NNNOA...... - .....ONNNOA..... - ......ONNOA..... - .......NOA...... - ..NNOA.NOA...... - ..NONOAOAONNOA.. - ..OAOANNOAOOOA.. - ......NNNOAAAAA. - ......ONOAAAAAA. - .......OOAAAAAA. - .....NOAAOAAAAA. - .....NOA..NOAA.. - ....OOA...OOA... - ................ -} -# tile 509 (paper golem,female) -{ - ................ - .......OA....... - .....NNNOA...... - .....ONNNOA..... - ......ONNOA..... - .......NOA...... - ..NNOA.NOA...... - ..NONOAOAONNOA.. - ..OAOANNOAOOOA.. - ......NNNOAAAAA. - ......ONOAAAAAA. - .......OOAAAAAA. - .....NOAAOAAAAA. - .....NOA..NOAA.. - ....OOA...OOA... - ................ -} -# tile 510 (rope golem,male) -{ - ................ - ................ - ......OOO....... - .....O...O...... - .....O...O...AA. - .OO...O..O..A..A - O..O...LL..OO..A - ...O...LOOO.AOA. - ....OOOOOAAAAO.. - .......OO..AA.A. - .......LO.AA...A - ......O..OOAA..A - ....OO..A..O.A.. - ...O..AA...O.A.. - ...O.A....OAA... - ....OA.......... -} -# tile 511 (rope golem,female) -{ - ................ - ................ - ......OOO....... - .....O...O...... - .....O...O...AA. - .OO...O..O..A..A - O..O...LL..OO..A - ...O...LOOO.AOA. - ....OOOOOAAAAO.. - .......OO..AA.A. - .......LO.AA...A - ......O..OOAA..A - ....OO..A..O.A.. - ...O..AA...O.A.. - ...O.A....OAA... - ....OA.......... -} -# tile 512 (gold golem,male) -{ - ................ - ......HNH....... - ......DND...N... - ......HNH...JC.. - ......HNH...NC.. - ...HHHAAAAHANC.. - ..HNJNHNHNJNAC.A - ..HHHHHHHHHHHA.A - .NCACCCCCCCCA..A - .HH.AAAAAAAAA.AA - .NH.ANC.AHNC.AAA - .NJ.AHC.AHHC.AAA - ..H.ANC.AHNC.AAA - ....HJC.AHJC.AA. - H...HNC.AHNC.A.H - ..H............. -} -# tile 513 (gold golem,female) -{ - ................ - ......HNH....... - ......DND...N... - ......HNH...JC.. - ......HNH...NC.. - ...HHHAAAAHANC.. - ..HNJNHNHNJNAC.A - ..HHHHHHHHHHHA.A - .NCACCCCCCCCA..A - .HH.AAAAAAAAA.AA - .NH.ANC.AHNC.AAA - .NJ.AHC.AHHC.AAA - ..H.ANC.AHNC.AAA - ....HJC.AHJC.AA. - H...HNC.AHNC.A.H - ..H............. -} -# tile 514 (leather golem,male) -{ - ......KKKK...... - .....KHKHJ...... - ....KAKKJJA..... - ...KKAJJJJAJ.... - ..KKJJAJAAKJJ... - .KKKJJAAKKKJJJ.. - ..KKJJJAKKJJJJ.. - ...KKJJJA.AAA.A. - ....AAAA.KJAAAA. - ....KJAAAKKAAAAA - ...KJJAA.KJJAAA. - ...KKJA..KKJAAA. - ..KKJJJAKKJJJAA. - ..KKKJJAKKKJJA.. - ...KJJA..KJJA... - ....KA....KA.... -} -# tile 515 (leather golem,female) -{ - ......KKKK...... - .....KHKHJ...... - ....KAKKJJA..... - ...KKAJJJJAJ.... - ..KKJJAJAAKJJ... - .KKKJJAAKKKJJJ.. - ..KKJJJAKKJJJJ.. - ...KKJJJA.AAA.A. - ....AAAA.KJAAAA. - ....KJAAAKKAAAAA - ...KJJAA.KJJAAA. - ...KKJA..KKJAAA. - ..KKJJJAKKJJJAA. - ..KKKJJAKKKJJA.. - ...KJJA..KJJA... - ....KA....KA.... -} -# tile 516 (wood golem,male) -{ - ................ - ......KCKJ...... - ......HCHJ..C... - ......KCKJ..CK.. - ......KCKJ..CKJ. - ...KKKAAAAKACKJ. - ..KCCCCCCCCCAKJA - ..KKKKKKKKKKKAJA - .CJAJJJJJJJJA..A - .CKJAAAAAAAAA.AA - .CKJACKJAKCKJAAA - .CKJACKJAKCKJAAA - ..KJACKJAKCKJAAA - ....KCKJAKCKJAA. - ....KCKJAKCKJA.. - ................ -} -# tile 517 (wood golem,female) -{ - ................ - ......KCKJ...... - ......HCHJ..C... - ......KCKJ..CK.. - ......KCKJ..CKJ. - ...KKKAAAAKACKJ. - ..KCCCCCCCCCAKJA - ..KKKKKKKKKKKAJA - .CJAJJJJJJJJA..A - .CKJAAAAAAAAA.AA - .CKJACKJAKCKJAAA - .CKJACKJAKCKJAAA - ..KJACKJAKCKJAAA - ....KCKJAKCKJAA. - ....KCKJAKCKJA.. - ................ -} -# tile 518 (flesh golem,male) -{ - ................ - ................ - ...D..DDC....... - .....DLDDL...... - ..DD..LLLLC.D... - ...CDL.LLLLADL.. - ..CLDLA.CLLA.LL. - ..LLLAA.LLCA..L. - .CLLAA.CLLAA..CA - .LLA..CLLALLAAAA - ..LA.CLCAALCAAAA - ...A..LLCACLCAAA - ....LLALLAALLAAA - ..CLLLAAAADLLA.. - ..LLDDD..DDDDD.. - ................ -} -# tile 519 (flesh golem,female) -{ - ................ - ................ - ...D..DDC....... - .....DLDDL...... - ..DD..LLLLC.D... - ...CDL.LLLLADL.. - ..CLDLA.CLLA.LL. - ..LLLAA.LLCA..L. - .CLLAA.CLLAA..CA - .LLA..CLLALLAAAA - ..LA.CLCAALCAAAA - ...A..LLCACLCAAA - ....LLALLAALLAAA - ..CLLLAAAADLLA.. - ..LLDDD..DDDDD.. - ................ -} -# tile 520 (clay golem,male) -{ - ................ - ................ - ................ - ....LCCCCK...... - ...LKKKKKKK..... - ...CKAKKAKK..... - ...CKAKKAKK..... - .LCKKKKKKKKLC... - CKKJKKKKKKCKKJ.. - KKKJKKJJKKJKKJAA - .JJAKKJAKKAJJAAA - ..AKKKJAKKKAAAAA - ..CKKKKKKKKKAAAA - ..CKKKAACKKKAA.. - ..CKKKA.CKKKAA.. - ................ -} -# tile 521 (clay golem,female) -{ - ................ - ................ - ................ - ....LCCCCK...... - ...LKKKKKKK..... - ...CKAKKAKK..... - ...CKAKKAKK..... - .LCKKKKKKKKLC... - CKKJKKKKKKCKKJ.. - KKKJKKJJKKJKKJAA - .JJAKKJAKKAJJAAA - ..AKKKJAKKKAAAAA - ..CKKKKKKKKKAAAA - ..CKKKAACKKKAA.. - ..CKKKA.CKKKAA.. - ................ -} -# tile 522 (stone golem,male) -{ - ................ - ................ - ................ - ....BBBPP....... - ...BBPPPPP...... - ...BHAPHAP...... - ...PPPPPPP...... - .BBPPPPPP.BPA... - BPPPP....PPPPAA. - BPP.BPPPP.PPPAAA - .PP.BP.PP.PPPAAA - ...BPP.PPPAAAAAA - ..BPPPAPPPAAAAA. - ..PPPPAPPPPAAA.. - ...PPAA.PPPA.... - ................ -} -# tile 523 (stone golem,female) -{ - ................ - ................ - ................ - ....BBBPP....... - ...BBPPPPP...... - ...BHAPHAP...... - ...PPPPPPP...... - .BBPPPPPP.BPA... - BPPPP....PPPPAA. - BPP.BPPPP.PPPAAA - .PP.BP.PP.PPPAAA - ...BPP.PPPAAAAAA - ..BPPPAPPPAAAAA. - ..PPPPAPPPPAAA.. - ...PPAA.PPPA.... - ................ -} -# tile 524 (glass golem,male) -{ - ................ - .....BBBBBBA.... - .....BPNPPPA.... - .....BNPPPNA.... - .....NPPPNPA.... - .....BPPNPPA.... - .......BA...BA.. - .BNBBABPBA.BPNA. - .NPPNABPNBBANPBA - .....BPNPPPAABAA - .....BNPPPAAAAAA - ......BPPNAAAAAA - ....BNABNABPAAA. - ...BNPA...BNAAA. - ..BNPA....NPAA.. - ...BA.....BPA... -} -# tile 525 (glass golem,female) -{ - ................ - .....BBBBBBA.... - .....BPNPPPA.... - .....BNPPPNA.... - .....NPPPNPA.... - .....BPPNPPA.... - .......BA...BA.. - .BNBBABPBA.BPNA. - .NPPNABPNBBANPBA - .....BPNPPPAABAA - .....BNPPPAAAAAA - ......BPPNAAAAAA - ....BNABNABPAAA. - ...BNPA...BNAAA. - ..BNPA....NPAA.. - ...BA.....BPA... -} -# tile 526 (iron golem,male) -{ - ................ - ......PBP....... - ......HBH...B... - ......PBP...JP.. - ......PBP...BP.. - ...PPPAAAAPABP.. - ..PBJBBBBBJBAP.A - ..PPPPPPPPPPPA.A - .B.A........A..A - .BP.AAAAAAAAA.AA - .BP.ABP.APBP.AAA - .BJ.ABP.APBP.AAA - ..P.ABP.APBP.AAA - ....PJP.APJP.AA. - ....PBP.APBP.A.. - ................ -} -# tile 527 (iron golem,female) -{ - ................ - ......PBP....... - ......HBH...B... - ......PBP...JP.. - ......PBP...BP.. - ...PPPAAAAPABP.. - ..PBJBBBBBJBAP.A - ..PPPPPPPPPPPA.A - .B.A........A..A - .BP.AAAAAAAAA.AA - .BP.ABP.APBP.AAA - .BJ.ABP.APBP.AAA - ..P.ABP.APBP.AAA - ....PJP.APJP.AA. - ....PBP.APBP.A.. - ................ -} -# tile 528 (human,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......ELELA..... - ......LLLLA..... - ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 529 (human,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......ELELA..... - ......LLLLA..... - ......ALLA...... - .....CJAAJC.AAA. - ....CLJLLJLCAAA. - ....LAKJJJALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 530 (wererat,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......GJGJA..... - ......LLLLA..... - ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 531 (wererat,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......GJGJA..... - ......LLLLA..... - ......ALLA...... - .....CJAAJC.AAA. - ....CLJLLJLCAAA. - ....LAKJJJALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 532 (werejackal,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......IPIPA..... - ......LLLLA..... - ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 533 (werejackal,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......IPIPA..... - ......LLLLA..... - ......ALLA...... - .....CJAAJC.AAA. - ....CLJLLJLCAAA. - ....LAKJJJALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 534 (werewolf,male) -{ - ................ - ................ - ......JJA....... - .....JJJJA...... - .....NJNJA...... - .....LLLLA...... - .....ALLA....... - ....CLAALC.AAA.. - ...CLLLLLLCAAA.. - ...LACLLCALAAA.. - ...LAJJKJALAAA.. - .....JJJKAAAA... - .....JJAJAA.A... - ....KLA.LKA..... - ................ - ................ -} -# tile 535 (werewolf,female) -{ - ................ - ................ - ......JJA....... - .....JJJJA...... - .....NJNJA...... - .....LLLLA...... - .....ALLA....... - ....CJAAJC.AAA.. - ...CLJLLJLCAAA.. - ...LAKJJJALAAA.. - ...LAJJKJALAAA.. - .....JJJKAAAA... - .....JJAJAA.A... - ....KLA.LKA..... - ................ - ................ -} -# tile 536 (elf,male) -{ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 537 (elf,female) -{ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 538 (Woodland-elf,male) -{ - ................ - ................ - .........K...... - .......KKJ...... - ......KKKKA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......KAAK..AAA. - .....LKKKJLAAAA. - ....LAPPJAALAAA. - ..KKLKKKKJALAA.. - ......PPAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 539 (Woodland-elf,female) -{ - ................ - ................ - .........K...... - .......KKJ...... - ......KKKKA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......KAAK..AAA. - .....LKKKJLAAAA. - ....LAPPJAALAAA. - ..KKLKKKKJALAA.. - ......PPAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 540 (Green-elf,male) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 541 (Green-elf,female) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 542 (Grey-elf,male) -{ - ................ - ................ - .........P...... - .......PP....... - ......PPPPA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......PAAP..AAA. - .....LPPP.LAAAA. - ....LAAP.AALAAA. - ....LAPPP.ALAA.. - ......P.A.AA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 543 (Grey-elf,female) -{ - ................ - ................ - .........P...... - .......PP....... - ......PPPPA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......PAAP..AAA. - .....LPPP.LAAAA. - ....LAAP.AALAAA. - ....LAPPP.ALAA.. - ......P.A.AA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 544 (elf-leader,male) -{ - ................ - ................ - ........II...... - .......HGF...... - ......HGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......HAAH..AAA. - .....LHHHFLAAAA. - ....LAAIIAALAAA. - ....LAHGGFALAA.. - ......HFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 545 (elf-leader,female) -{ - ................ - ................ - ........II...... - .......HGF...... - ......HGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......HAAH..AAA. - .....LHHHFLAAAA. - ....LAAIIAALAAA. - ....LAHGGFALAA.. - ......HFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 546 (elven monarch,male) -{ - ................ - ................ - ......H..H...... - ......HCHH...... - ......HHHHA..... - ......LELEA..... - ......LLLLA..... - .....IALLAI...A. - ....IIIAAIDIAAA. - .....LIIGDLAAAAA - ....LADIFDALAAAA - ....LAIIGDALAAA. - .....IIFAFDAAA.. - ...IIKLAILKDI... - ................ - ................ -} -# tile 547 (elven monarch,female) -{ - ................ - ......H..H...... - ......H..H...... - ......HCHH...... - ......HHHHA..... - ......LELEA..... - ......LLLLA..... - .....IALLAI...A. - ....IIIAAIDIAAA. - .....LIIGDLAAAAA - ....LADIFDALAAAA - ....LAIIGDALAAA. - .....IIFAFDAAA.. - ...IIKLAILKDI... - ................ - ................ -} -# tile 548 (doppelganger,male) -{ - ................ - ......CCCC..I... - ..I..CD...C..... - ....CD.HHA.C.... - ...CD.HHHHA.C.I. - ...CD.LFLFA.DC.. - .I.CD.LLLLA.DC.. - ...CD.ALLA.DC... - ..CD.LLAALL.ACA. - .CD.LLLLLLLLADC. - .CD.LALLLLALADC. - .CD.LAJJKJALADC. - ..CD..LJJLAAACA. - ...CD.LLALAACA.. - ..CD.LLAALLADC.. - ................ -} -# tile 549 (doppelganger,female) -{ - ................ - ......CCCC..I... - ..I..CD...C..... - ....CD.HHA.C.... - ...CD.HHHHA.C.I. - ...CD.LFLFA.DC.. - .I.CD.LLLLA.DC.. - ...CD.ALLA.DC... - ..CD.LLAALL.ACA. - .CD.LLLLLLLLADC. - .CD.LALLLLALADC. - .CD.LAJJKJALADC. - ..CD..LJJLAAACA. - ...CD.LLALAACA.. - ..CD.LLAALLADC.. - ................ -} -# tile 550 (shopkeeper,male) -{ - ................ - ................ - ......AAAA...... - .....AAAAAA..... - ......JLJL...... - ......LLLL...... - ......ALLA...... - .....EBAABEA.AA. - ....EBBBBBBEAAA. - ....BAEBBEABAAA. - ....LAGFFFALAAA. - ......GFAFAAAA.. - ......GFAFAA.A.. - .....JJA.JJA.... - ................ - ................ -} -# tile 551 (shopkeeper,female) -{ - ................ - ................ - ......AAAA...... - .....AAAAAA..... - ......JLJL...... - ......LLLL...... - ......ALLA...... - .....EBAABEA.AA. - ....EBBBBBBEAAA. - ....BAEBBEABAAA. - ....LAGFFFALAAA. - ......GFAFAAAA.. - ......GFAFAA.A.. - .....JJA.JJA.... - ................ - ................ -} -# tile 552 (guard,male) -{ - ................ - .....BBPPPAA.... - ....BNPPPPPPA... - ....BPPBPPPPA... - ....BAABPAAPA... - ....BCLBPCLPA... - ....AKCPPCJAAA.. - ....BKJJJJAPAAAA - ...BPKJAAJAPPAAA - ..BPPKJJJJAPPPAA - ..PPABKJJAPPAPPA - ..PPABPKAPPPAPPA - ..LC.BPPPPPPCLAA - ..LL.BPPABPPLLAA - .....BPPABPPAAAA - ....BPPP.BPPPAAA -} -# tile 553 (guard,female) -{ - ................ - .....BBPPPAA.... - ....BNPPPPPPA... - ....BPPBPPPPA... - ....BAABPAAPA... - ....BCLBPCLPA... - ....JCLPPCLJAA.. - ....BPLLLLAPAAAA - ...BPPLAALAPPAAA - ..BPPPPLLPPPPPAA - ..PPABPPPPPPAPPA - ..PPABPPPPPPAPPA - ..LC.BPPPPPPCLAA - ..LL.BPPABPPLLAA - .....BPPABPPAAAA - ....BPPP.BPPPAAA -} -# tile 554 (prisoner,male) -{ - ................ - ................ - .......NOA...... - .......LLA...... - .......LLA...... - .......NOA...... - ......NOONA..... - .....NOOOONA.... - ....NANOOOANAA.. - ....PANOOOAPAAA. - ....LANOOOALAAA. - ......NOOOAAAA.. - ......NAANAAA... - ......PAAPAA.... - .....LLA.LLA.... - ................ -} -# tile 555 (prisoner,female) -{ - ................ - ................ - .......NOA...... - .......LLA...... - .......LLA...... - .......NOA...... - ......NOONA..... - .....NOOOONA.... - ....NANOOOANAA.. - ....PANOOOAPAAA. - ....LANOOOALAAA. - ......NOOOAAAA.. - ......NAANAAA... - ......PAAPAA.... - .....LLA.LLA.... - ................ -} -# tile 556 (Oracle,male) -{ - ................ - ................ - .......NN....... - LLL...GLLG...LLL - ..L..NLLLLN..L.. - ...L.NLAALN.L... - ....LNLLLLNL.... - .....LNLLNL..AA. - .....NBBEEN.AAAA - ......BBEEAAAAAA - .LLA..BBBEAAALL. - .LLLLBBBEBELLLLA - ..LLCLBLLELLCLAA - ...CLLLLLLLCLAA. - ....LELLLLELAA.. - ................ -} -# tile 557 (Oracle,female) -{ - ................ - ................ - .......NN....... - LLL...GLLG...LLL - ..L..NLLLLN..L.. - ...L.NLAALN.L... - ....LNLLLLNL.... - .....LNLLNL..AA. - .....NBBEEN.AAAA - ......BBEEAAAAAA - .LLA..BBBEAAALL. - .LLLLBBBEBELLLLA - ..LLCLBLLELLCLAA - ...CLLLLLLLCLAA. - ....LELLLLELAA.. - ................ -} -# tile 558 (aligned priest,male) -{ - ................ - INI............. - III..KCCK....... - .J..KCCCCK...... - .J..CAAKCC...... - .LC.CAAACC...... - CLLC.CAACJKC.... - CJLACCCCJKCCC... - .JAACCJJCKCCCK.. - .JKCCCJCCJCCK.AA - .J..CCJCCLJCAAAA - .J..CCJCLLCAAAA. - .J..KCJCCCJAAAA. - .J.ACCJCCCJAAA.. - .JACCCJJCCCAA... - ................ -} -# tile 559 (aligned priest,female) -{ - ................ - INI............. - III..KCCK....... - .J..KCCCCK...... - .J..CAAKCC...... - .LC.CAAACC...... - CLLC.CAACJKC.... - CJLACCCCJKCCC... - .JAACCJJCKCCCK.. - .JKCCCJCCJCCK.AA - .J..CCJCCLJCAAAA - .J..CCJCLLCAAAA. - .J..KCJCCCJAAAA. - .J.ACCJCCCJAAA.. - .JACCCJJCCCAA... - ................ -} -# tile 560 (high priest,male) -{ - .INI............ - IIIII.KCCK...... - .IHI.KCAACK..... - ..H..CGAGAC..... - ..LC.CAAAAC..... - .CLLC.CAACJCK... - .CHLACCCCJCCCK.. - ..HAACCJJCCCCCK. - ..HCCCCJCCJCCC.A - ..H..CCJCCLJCAAA - ..H..CCJCLLCAAAA - ..H..KCJCCCJAAAA - ..H..KCJCCCJAAAA - ..H.ACCJCCCJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 561 (high priest,female) -{ - .INI............ - IIIII.KCCK...... - .IHI.KCAACK..... - ..H..CGAGAC..... - ..LC.CAAAAC..... - .CLLC.CAACJCK... - .CHLACCCCJCCCK.. - ..HAACCJJCCCCCK. - ..HCCCCJCCJCCC.A - ..H..CCJCCLJCAAA - ..H..CCJCLLCAAAA - ..H..KCJCCCJAAAA - ..H..KCJCCCJAAAA - ..H.ACCJCCCJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 562 (soldier,male) -{ - .....J.......... - .....JAAA....... - .....ALLLA...... - .....LLLLC...... - .....JLLC....... - .....JF..F...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....JJ.JJ...... - ................ -} -# tile 563 (soldier,female) -{ - .....J.......... - .....JAAA....... - .....ALLLA...... - .....LLLLC...... - .....JLLC....... - .....JF..F...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....JJ.JJ...... - ................ -} -# tile 564 (sergeant,male) -{ - .....J.......... - .....JFFF....... - ....FFFFFF...... - .....LLLLC...... - .....JLLC....... - .....JF..G...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 565 (sergeant,female) -{ - .....J.......... - .....JFFF....... - ....FFFFFF...... - .....LLLLC...... - .....JLLC....... - .....JF..G...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 566 (nurse,male) -{ - ................ - .......NO....... - ......NDDO...... - ......NNOOA..... - .....DBLBLD..... - .....CLLLLDC.... - .....DALLACD.... - .....CNAAODCAAA. - .....NNNOOLAAAA. - ....LANNDOALAAA. - ....LANNOOALAAA. - ......NNOOAAAA.. - ......NNAOAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 567 (nurse,female) -{ - ................ - .......NO....... - ......NDDO...... - ......NNOOA..... - .....DBLBLD..... - .....CLLLLDC.... - .....DALLACD.... - .....CNAAODCAAA. - .....NNNOOLAAAA. - ....LANNDOALAAA. - ....LANNOOALAAA. - ......NNOOAAAA.. - ......NNAOAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 568 (lieutenant,male) -{ - ................ - .......FFF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....GF.FGA..... - ....FFFFFFFF.... - ....FAFFFFAFAAA. - ....FAFFFFAFAAAA - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 569 (lieutenant,female) -{ - ................ - .......FFF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....GF.FGA..... - ....FFFFFFFF.... - ....FAFFFFAFAAA. - ....FAFFFFAFAAAA - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 570 (captain,male) -{ - ................ - ......FHHF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....HF.FHF..... - ....FFFFFFFFAA.. - ....FAFFIFAFAAAA - ....FAFFFFAFAAA. - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.JJJA.. - .....FFAFFJJJA.. - .....AA.AAAAA... - ................ -} -# tile 571 (captain,female) -{ - ................ - ......FHHF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....HF.FHF..... - ....FFFFFFFFAA.. - ....FAFFIFAFAAAA - ....FAFFFFAFAAA. - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.JJJA.. - .....FFAFFJJJA.. - .....AA.AAAAA... - ................ -} -# tile 572 (watchman,male) -{ - ................ - ......PPP....... - ....PPPPPP...... - .....LLLLC...... - ......LLC....... - .....PP..P...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - ......PAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 573 (watchman,female) -{ - ................ - ......PPP....... - ....PPPPPP...... - .....LLLLC...... - ......LLC....... - .....PP..P...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - ......PAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 574 (watch captain,male) -{ - ......PPP....... - .....PHHHP...... - ....PPPPPPP..... - .....LLLLC...... - ......LLC....... - .....HP..H...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - .....JPAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 575 (watch captain,female) -{ - ......PPP....... - .....PHHHP...... - ....PPPPPPP..... - .....LLLLC...... - ......LLC....... - .....HP..H...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - .....JPAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 576 (Medusa,male) -{ - ................ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....A.. - .GAFLLLLA..A..A. - ....JLLKA.A.A.A. - ...KBLLBKAAAAA.. - ..KIIBBIIIAAA.A. - ..IIIKKILLIAAA.. - ..KIILLIALIAA... - ...KIALKAAIAA... - ...IKAAKIIAAA... - ...IIKKIIIAA.... - ..IIKIKIKIA..... - ................ -} -# tile 577 (Medusa,female) -{ - ................ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....A.. - .GAFLLLLA..A..A. - ....JLLKA.A.A.A. - ...KBLLBKAAAAA.. - ..KIIBBIIIAAA.A. - ..IIIKKILLIAAA.. - ..KIILLIALIAA... - ...KIALKAAIAA... - ...IKAAKIIAAA... - ...IIKKIIIAA.... - ..IIKIKIKIA..... - ................ -} -# tile 578 (Wizard of Yendor,male) -{ - .EEE.......EEE.. - EFFAE..E..EAFFE. - EAAAE.EEE.EAAAE. - EAAAEEEAEEEAAAE. - EEAAEEDADEEAAEE. - .EEEEAAAAAEEEE.. - ..EEEEAAAEEEE... - ..EEEEEEEEEE.... - ...EEEEEEEE..... - ...EEEEEEEE....A - ....EEEEEE...AAA - ....EEEEEEAAAAAA - ...EEEEEEEEAAAAA - ..EEEEEEEEEAAAAA - .EEEEEEEEEEEAAA. - EEEEEEEEEEEEEEA. -} -# tile 579 (Wizard of Yendor,female) -{ - .EEE.......EEE.. - EFFAE..E..EAFFE. - EAAAE.EEE.EAAAE. - EAAAEEEAEEEAAAE. - EEAAEEDADEEAAEE. - .EEEEAAAAAEEEE.. - ..EEEEAAAEEEE... - ..EEEEEEEEEE.... - ...EEEEEEEE..... - ...EEEEEEEE....A - ....EEEEEE...AAA - ....EEEEEEAAAAAA - ...EEEEEEEEAAAAA - ..EEEEEEEEEAAAAA - .EEEEEEEEEEEAAA. - EEEEEEEEEEEEEEA. -} -# tile 580 (Croesus,male) -{ - ....H..H..H..... - ....HCHEHCH..... - ....HHHHHHH..... - ....ALLLLLA..... - ....LLALALL..... - .....LLLLL...... - ....HLLDLLH..... - ...HIALLLAIH.A.A - ...HIHAAAHIHAAAA - ..IIIEHHHIIIIAAA - ..IIIIEHIIIIIAA. - ..ILLIHHHILLIAAA - ...LIIKHIIILAAAA - ..GIIIKJIIIIGAA. - .GIIIKJJKKIIIGG. - ................ -} -# tile 581 (Croesus,female) -{ - ....H..H..H..... - ....HCHEHCH..... - ....HHHHHHH..... - ....ALLLLLA..... - ....LLALALL..... - .....LLLLL...... - ....HLLDLLH..... - ...HIALLLAIH.A.A - ...HIHAAAHIHAAAA - ..IIIEHHHIIIIAAA - ..IIIIEHIIIIIAA. - ..ILLIHHHILLIAAA - ...LIIKHIIILAAAA - ..GIIIKJIIIIGAA. - .GIIIKJJKKIIIGG. - ................ -} -# tile 582 (Charon,male) -{ - ................ - .......J........ - ......JJJ....... - ....JJJAJJJ..... - ....JJDADJJ..... - ...JJAAAAAJJ.... - ...JJJAAAJJJ.... - ..JJJJJJJJJJ.... - .JJJJJJJJJJJJ... - JJJJJJJJJJJJJJ.A - .OO.JJJJJJ.OOAAA - ....JJJJJJAAAAAA - ...JJJJJJJJAAAAA - ..JJJJJJJJJAAAAA - .JJJJJJJJJJJAAA. - JJJJJJJJJJJJJJA. -} -# tile 583 (Charon,female) -{ - ................ - .......J........ - ......JJJ....... - ....JJJAJJJ..... - ....JJDADJJ..... - ...JJAAAAAJJ.... - ...JJJAAAJJJ.... - ..JJJJJJJJJJ.... - .JJJJJJJJJJJJ... - JJJJJJJJJJJJJJ.A - .OO.JJJJJJ.OOAAA - ....JJJJJJAAAAAA - ...JJJJJJJJAAAAA - ..JJJJJJJJJAAAAA - .JJJJJJJJJJJAAA. - JJJJJJJJJJJJJJA. -} -# tile 584 (ghost,male) -{ - ................ - ................ - ...NNN.......... - ..NANANN........ - .NNNNNNNNN...... - .NNPAAPNNNNN.... - .NNAAAANNNOONO.. - .NNAAAANONNNPNNO - .NNPAAPNONNOOOP. - .NNNNNNONOPNPPO. - .NNONNOPNNOPOOP. - .NOPNNOOOPPOOP.. - .OOOPOPPOPPP.PP. - .PP.PPOPPP...P.. - .O...P....P..... - ........P....... -} -# tile 585 (ghost,female) -{ - ................ - ................ - ...NNN.......... - ..NANANN........ - .NNNNNNNNN...... - .NNPAAPNNNNN.... - .NNAAAANNNOONO.. - .NNAAAANONNNPNNO - .NNPAAPNONNOOOP. - .NNNNNNONOPNPPO. - .NNONNOPNNOPOOP. - .NOPNNOOOPPOOP.. - .OOOPOPPOPPP.PP. - .PP.PPOPPP...P.. - .O...P....P..... - ........P....... -} -# tile 586 (shade,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ........AAAAAAA. - ....AAAAAAAA.... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAA. - ..AAAAAAAAAAAAAA - .AAAAAAAAAAAAA.. - AAAA.AAAAJA..... - ................ -} -# tile 587 (shade,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ........AAAAAAA. - ....AAAAAAAA.... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAA. - ..AAAAAAAAAAAAAA - .AAAAAAAAAAAAA.. - AAAA.AAAAJA..... - ................ -} -# tile 588 (water demon,male) -{ - ................ - ................ - ................ - ................ - ..EE.....EE..... - .E.EE...EE.E.... - ....EEEEE....... - ....EBEBE..A.... - ...EEEEEEEAAAA.. - ..EEE...EEEAA.A. - ..EEEEEEEEEAAA.. - ..EEAEEEAEEAAA.. - ...AAEEEAAAAA... - ....EEAEEAA..... - ....EEAEEA...... - ................ -} -# tile 589 (water demon,female) -{ - ................ - ................ - ................ - ................ - ..EE.....EE..... - .E.EE...EE.E.... - ....EEEEE....... - ....EBEBE..A.... - ...EEEEEEEAAAA.. - ..EEE...EEEAA.A. - ..EEEEEEEEEAAA.. - ..EEAEEEAEEAAA.. - ...AAEEEAAAAA... - ....EEAEEAA..... - ....EEAEEA...... - ................ -} -# tile 590 (amorous demon,male) -{ - DD.OHHD......... - DDOHHDGD........ - DDOHDDDDD....... - DDHHDDDA........ - DDDHDJADDDD..... - DDDJDDDDDDDD.... - .DDDDDCDD.DDD... - .DDCDDDKK..DD... - ..DDKKDDDAADDA.. - ...DDDDDDAAAAA.. - ....DDDDDDDDDA.. - ....DDJDJJAAAAAA - ....JDJJADKAA... - ....DDKAADDKA... - ...DDKAA..DDAA.. - ..DDKAA...DDDA.. -} -# tile 595 (amorous demon,female) -{ - DD.OHHD......... - DDOHHDGD........ - DDOHDDDDD....... - DDHHDDDA........ - DHHHDJADDDD..... - .HHJJDDDJDDD.... - OHDDCDCDDJDD.... - HHHCDDCDLJ.DD... - HHHCDLJJJAADDA.. - HHHDJJDDDAADAA.. - HHHHDDAADAAAA... - HHHH.DKJDDAA.... - H.H..DDAADDAA... - ..H..DDAA.DAA... - ....DDAA..DDAA.. - ...DDJA...DDDA.. -} -# tile 592 (horned devil,male) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - ...LOCDCOL...... - ...CDDDDDC...... - ...DAADAADA..D.. - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - ..CDAKKKACDAAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - ...CDDADDKAA.... - ..CDDAA.DDK..... - ................ -} -# tile 593 (horned devil,female) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - ...LOCDCOL...... - ...CDDDDDC...... - ...DAADAADA..D.. - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - ..CDAKKKACDAAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - ...CDDADDKAA.... - ..CDDAA.DDK..... - ................ -} -# tile 596 (erinys,male) -{ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....... - .GAFDLDLA..A.A.. - ....LLLEA.A.A.A. - ...EBLLBEAAAA.A. - ..EBBBBBBBAAAA.. - ..BBBEBBLLBAA.A. - ..EBBLLBALBAAA.. - ...EBALBAABAA... - ...BEAABBBAAA... - ...BBBBBBBAAA... - ...BBBBBBBAA.... - ..BBEBEBEBA..... - ................ -} -# tile 597 (erinys,female) -{ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....... - .GAFDLDLA..A.A.. - ....LLLEA.A.A.A. - ...EBLLBEAAAA.A. - ..EBBBBBBBAAAA.. - ..BBBEBBLLBAA.A. - ..EBBLLBALBAAA.. - ...EBALBAABAA... - ...BEAABBBAAA... - ...BBBBBBBAAA... - ...BBBBBBBAA.... - ..BBEBEBEBA..... - ................ -} -# tile 598 (barbed devil,male) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - .O.LOCDCOL.O.... - ...CDDDDDC....DD - ...DAADAADA..D.D - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - .C.DAKKKACDKAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - .K.CDDADDKAAK... - .CCDDAA.DDKK.... - ................ -} -# tile 599 (barbed devil,female) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - .O.LOCDCOL.O.... - ...CDDDDDC....DD - ...DAADAADA..D.D - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - .C.DAKKKACDKAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - .K.CDDADDKAAK... - .CCDDAA.DDKK.... - ................ -} -# tile 600 (marilith,male) -{ - .D..HHH.....D... - DD.HHHHHA...DD.. - .DCHDDDHHAAD..A. - ..HDBDBDHDDAAAA. - .CHKDDDKHAAADD.. - CDDDKKKDHDDDDFF. - D..CDDCDKAAFFFAA - D.KDDKDDDDDDFAA. - D.DKDDKDKAFDFAA. - ..D.GDDFAAFDFFAA - .D.GGFFFAAAFFFFA - ...GFFFFFAAAFFFA - ..FGFFFFFFAFFFFA - ..FGFFFFFFFFFFA. - ..FGFFFFFFFFFA.. - ....GFFFFFFAA... -} -# tile 601 (marilith,female) -{ - .D..HHH.....D... - DD.HHHHHA...DD.. - .DCHDDDHHAAD..A. - ..HDBDBDHDDAAAA. - .CHKDDDKHAAADD.. - CDDDKKKDHDDDDFF. - D..CDDCDKAAFFFAA - D.KDDKDDDDDDFAA. - D.DKDDKDKAFDFAA. - ..D.GDDFAAFDFFAA - .D.GGFFFAAAFFFFA - ...GFFFFFAAAFFFA - ..FGFFFFFFAFFFFA - ..FGFFFFFFFFFFA. - ..FGFFFFFFFFFA.. - ....GFFFFFFAA... -} -# tile 602 (vrock,male) -{ - ................ - ......OPP.O..... - ......PPPP...... - .....CPPDP...... - ....CCCPPP...... - ....CCPPPP...... - ....C..PPA...... - .....DDAADD.AAA. - ....DDDDDDDDAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ......DAADAAAA.. - ......DAADAA.A.. - .....DDA.DDA.... - ................ -} -# tile 603 (vrock,female) -{ - ................ - ......OPP.O..... - ......PPPP...... - .....CPPDP...... - ....CCCPPP...... - ....CCPPPP...... - ....C..PPA...... - .....DDAADD.AAA. - ....DDDDDDDDAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ......DAADAAAA.. - ......DAADAA.A.. - .....DDA.DDA.... - ................ -} -# tile 604 (hezrou,male) -{ - ................ - ................ - ....GGGFF....... - ..NGFFNNFFF..... - .DFFFDDNFF.F.... - .GFFFDNFF.FFFAA. - .AFAFFFFFFFFFFAA - .GFFFF.FFF.FGFAA - .GAAAFF..LFGFFAA - ..FFFF.FFLFGFFFA - ..LLA.FLLLJJG.FA - .LLAFFLLFJJGFFFA - ..LAFLLLAAGF.FAA - .....L.LAGFFFFAA - ...........FFFA. - ................ -} -# tile 605 (hezrou,female) -{ - ................ - ................ - ....GGGFF....... - ..NGFFNNFFF..... - .DFFFDDNFF.F.... - .GFFFDNFF.FFFAA. - .AFAFFFFFFFFFFAA - .GFFFF.FFF.FGFAA - .GAAAFF..LFGFFAA - ..FFFF.FFLFGFFFA - ..LLA.FLLLJJG.FA - .LLAFFLLFJJGFFFA - ..LAFLLLAAGF.FAA - .....L.LAGFFFFAA - ...........FFFA. - ................ -} -# tile 606 (bone devil,male) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..O.. - ...LNLOLOL....O. - ...LOOOOOL....O. - ...NAAOAAOA..O.. - ...NOOOOOOA.O... - ..NOOOFOOOOAO.A. - ..OOKNOOKOOALA.. - ..OOANOOAOOAKAA. - ..LLANOOALLAAAA. - ....NOOOLAAAAA.. - ...NOOAOOLAA.... - ..NOOAA.OOL..... - ................ -} -# tile 607 (bone devil,female) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..O.. - ...LNLOLOL....O. - ...LOOOOOL....O. - ...NAAOAAOA..O.. - ...NOOOOOOA.O... - ..NOOOFOOOOAO.A. - ..OOKNOOKOOALA.. - ..OOANOOAOOAKAA. - ..LLANOOALLAAAA. - ....NOOOLAAAAA.. - ...NOOAOOLAA.... - ..NOOAA.OOL..... - ................ -} -# tile 608 (ice devil,male) -{ - ................ - ................ - ..N.......N..... - ..NN.....NN..... - ...PBPNPNP..BNB. - ...PNNNNNP..N.N. - ...BAANAANA...N. - ...BNNNNNNA.BNB. - ..BNNNFNNNNAN.A. - ..NNKBNNKNNABA.. - ..NNABNNANNA.AA. - ..PPABNNAPPAAAA. - ....BNNNPAAAAA.. - ...BNNANNPAA.... - ..BNNAA.NNP..... - ................ -} -# tile 609 (ice devil,female) -{ - ................ - ................ - ..N.......N..... - ..NN.....NN..... - ...PBPNPNP..BNB. - ...PNNNNNP..N.N. - ...BAANAANA...N. - ...BNNNNNNA.BNB. - ..BNNNFNNNNAN.A. - ..NNKBNNKNNABA.. - ..NNABNNANNA.AA. - ..PPABNNAPPAAAA. - ....BNNNPAAAAA.. - ...BNNANNPAA.... - ..BNNAA.NNP..... - ................ -} -# tile 610 (nalfeshnee,male) -{ - ................ - ................ - ......BB...BB... - ..KKKKKBB.BB.... - .KADKADKKKB..... - .KKKKKKKDKK..... - .OKDKOKKDDKD.... - .OKDKOKKKDKDD... - .KAAAKKDKAKKD... - ..KKKDDLAKKKD.A. - ...KK.KKKKKDDA.. - ....L..KDAKDAA.. - ......LLAAKDA... - .........LLA.... - ................ - ................ -} -# tile 611 (nalfeshnee,female) -{ - ................ - ................ - ......BB...BB... - ..KKKKKBB.BB.... - .KADKADKKKB..... - .KKKKKKKDKK..... - .OKDKOKKDDKD.... - .OKDKOKKKDKDD... - .KAAAKKDKAKKD... - ..KKKDDLAKKKD.A. - ...KK.KKKKKDDA.. - ....L..KDAKDAA.. - ......LLAAKDA... - .........LLA.... - ................ - ................ -} -# tile 612 (pit fiend,male) -{ - ................ - .K.O.......O.K.. - .K.OO.....OO.KJ. - KJJ.LOCDCOL.KJJ. - KJJJKDDDDDKKJJJ. - KJJCKDNDNDKCJJJA - JJCCKDDDDDJCCJJA - JJCCCKDIDJDCCJJA - JACCDDKJJDDCDAJA - JACCKDDDDDKCDAJA - ...CDKDDDKCDDAAA - ....DKDDDKCDAAAA - .....CDDDKAAAA.. - ....CDDADDKA.... - ...CDDAA.DDK.... - ................ -} -# tile 613 (pit fiend,female) -{ - ................ - .K.O.......O.K.. - .K.OO.....OO.KJ. - KJJ.LOCDCOL.KJJ. - KJJJKDDDDDKKJJJ. - KJJCKDNDNDKCJJJA - JJCCKDDDDDJCCJJA - JJCCCKDIDJDCCJJA - JACCDDKJJDDCDAJA - JACCKDDDDDKCDAJA - ...CDKDDDKCDDAAA - ....DKDDDKCDAAAA - .....CDDDKAAAA.. - ....CDDADDKA.... - ...CDDAA.DDK.... - ................ -} -# tile 614 (sandestin,male) -{ - .....CCCCC..I... - .I..CD....C..... - ...CD.DDD..C..I. - ..CD.DDDDD..C... - ..CD.DNDNDA.DC.. - I.CD.DDDDDA.DC.. - ..CD.ADDDA.DC..A - .CD.DDAAADD.DCAA - CD.DDDDDDDDDADCA - CD.DADDDDDADADCA - CD.DADDDDDADADCA - CD.DADDDDDADADC. - .CD..DDJDDAADCA. - ..CD.DDADDADCA.. - .CD.DDAADDDADC.. - ................ -} -# tile 615 (sandestin,female) -{ - .....CCCCC..I... - .I..CD....C..... - ...CD.DDD..C..I. - ..CD.DDDDD..C... - ..CD.DNDNDA.DC.. - I.CD.DDDDDA.DC.. - ..CD.ADDDA.DC..A - .CD.DDAAADD.DCAA - CD.DDDDDDDDDADCA - CD.DADDDDDADADCA - CD.DADDDDDADADCA - CD.DADDDDDADADC. - .CD..DDJDDAADCA. - ..CD.DDADDADCA.. - .CD.DDAADDDADC.. - ................ -} -# tile 616 (balrog,male) -{ - ................ - .K..O.....O..K.. - .KJ.O.....O.KJ.. - KJJLOOCDCOOLJJJ. - JJJDDDDDDDDDDKJ. - JCCDDDNDNDDDCCJA - CCDKDDDDDDDJCCCA - CDDKKKDIDJJDCCDA - CDDKDDKJJDDDCDDA - CCDKDDDDDDDKCDDA - JCCDKKDDDKKCDDDA - JJCDKKDDDKKCDDJA - JJ..CCDDDKKAAJJA - J..CDDDADDDKAAJA - ..CDDDAA.DDDK.AA - ................ -} -# tile 617 (balrog,female) -{ - ................ - .K..O.....O..K.. - .KJ.O.....O.KJ.. - KJJLOOCDCOOLJJJ. - JJJDDDDDDDDDDKJ. - JCCDDDNDNDDDCCJA - CCDKDDDDDDDJCCCA - CDDKKKDIDJJDCCDA - CDDKDDKJJDDDCDDA - CCDKDDDDDDDKCDDA - JCCDKKDDDKKCDDDA - JJCDKKDDDKKCDDJA - JJ..CCDDDKKAAJJA - J..CDDDADDDKAAJA - ..CDDDAA.DDDK.AA - ................ -} -# tile 618 (Juiblex,male) -{ - ................ - DD.........DD... - NDC.KKKKJ.CND... - .CCKCCCKKCCAA... - ..KCCCCKCCJAA... - ..KCCCCCK.JJAA.. - ..KCCFCCK..JAA.. - ..FKCFCCKK.JAAA. - .FKKFCCKFK..JAA. - .FKCFCCFKFK.JAA. - .FCFCCKFCFK.JAA. - FKCFCFCFCKK.JAA. - CKFCCFCCKKFKJJA. - CCKKCFCKFFKKKKA. - .CCCCCCCCCCCKA.. - ................ -} -# tile 619 (Juiblex,female) -{ - ................ - DD.........DD... - NDC.KKKKJ.CND... - .CCKCCCKKCCAA... - ..KCCCCKCCJAA... - ..KCCCCCK.JJAA.. - ..KCCFCCK..JAA.. - ..FKCFCCKK.JAAA. - .FKKFCCKFK..JAA. - .FKCFCCFKFK.JAA. - .FCFCCKFCFK.JAA. - FKCFCFCFCKK.JAA. - CKFCCFCCKKFKJJA. - CCKKCFCKFFKKKKA. - .CCCCCCCCCCCKA.. - ................ -} -# tile 620 (Yeenoghu,male) -{ - ....B.HHP....... - ....BPPPP....... - ...BPLCPPH...... - .KBPPCCPPH...... - .PPPPPPP.H...... - .PP...P.PH...... - ....BPPPPPAAA... - ..BPPPPPPPPAAAA. - .BP.PPPPPAPPAAAA - .B...BPP.AAPAAAA - .B...BPP.AAPAAA. - .....BPPAAAAA.A. - ....BP.PPAA...A. - ...BP.AAPPA..A.. - ...BPAA.PPA..... - ................ -} -# tile 621 (Yeenoghu,female) -{ - ....B.HHP....... - ....BPPPP....... - ...BPLCPPH...... - .KBPPCCPPH...... - .PPPPPPP.H...... - .PP...P.PH...... - ....BPPPPPAAA... - ..BPPPPPPPPAAAA. - .BP.PPPPPAPPAAAA - .B...BPP.AAPAAAA - .B...BPP.AAPAAA. - .....BPPAAAAA.A. - ....BP.PPAA...A. - ...BP.AAPPA..A.. - ...BPAA.PPA..... - ................ -} -# tile 622 (Orcus,male) -{ - ................ - .K..O.....O..K.. - KJJO..BBB..O.KJ. - KJJLOBPPPPOLKJJ. - JKJJ.PGPGP.JJKJA - JJKJKPPPPPJJKJJJ - JBPPB.BPPABBPPJJ - PJJPP.BPPAPPJJPA - PJBPPP.AAPPPPJPA - .JBP.PPPP.P.PJAA - .JBPPPP.PPPPPJAA - ..PPP.PPP.PPPAAA - ...P.PPPPPPP.P.A - ...BPPPAPPPPAAPA - ...OOPPAOOPPAGA. - ................ -} -# tile 623 (Orcus,female) -{ - ................ - .K..O.....O..K.. - KJJO..BBB..O.KJ. - KJJLOBPPPPOLKJJ. - JKJJ.PGPGP.JJKJA - JJKJKPPPPPJJKJJJ - JBPPB.BPPABBPPJJ - PJJPP.BPPAPPJJPA - PJBPPP.AAPPPPJPA - .JBP.PPPP.P.PJAA - .JBPPPP.PPPPPJAA - ..PPP.PPP.PPPAAA - ...P.PPPPPPP.P.A - ...BPPPAPPPPAAPA - ...OOPPAOOPPAGA. - ................ -} -# tile 624 (Geryon,male) -{ - .K...........K.. - .K....JJJ....KJ. - KJJ..JJJJJ..KJJ. - KJJJKLLLLLKKJJJ. - KJJJKLBLBLKJJJJA - JJJJKLLLLLJJJJJA - JJALLKLLLJLLAJJA - JA.LLLKJJLLLAAJA - ...LJLLLLLKLAAAA - ...LCKLLLKCLAFGF - ...LLGLLFALLFFFA - .....GFFFAAAFFAA - ....GGGGFFAAFFAA - ....GFFFFFAAFGFA - ....FGGGFFFFFFFA - .....FFFFFFFFFA. -} -# tile 625 (Geryon,female) -{ - .K...........K.. - .K....JJJ....KJ. - KJJ..JJJJJ..KJJ. - KJJJKLLLLLKKJJJ. - KJJJKLBLBLKJJJJA - JJJJKLLLLLJJJJJA - JJALLKLLLJLLAJJA - JA.LLLKJJLLLAAJA - ...LJLLLLLKLAAAA - ...LCKLLLKCLAFGF - ...LLGLLFALLFFFA - .....GFFFAAAFFAA - ....GGGGFFAAFFAA - ....GFFFFFAAFGFA - ....FGGGFFFFFFFA - .....FFFFFFFFFA. -} -# tile 626 (Dispater,male) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ....KACKKJAKAAA. - ....KACKKJAKAAJA - ....KACKKJAKAAJA - ....LACKKJJLAJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 627 (Dispater,female) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ....KACKKJAKAAA. - ....KACKKJAKAAJA - ....KACKKJAKAAJA - ....LACKKJJLAJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 628 (Baalzebub,male) -{ - ......F...F..... - .......F.F...... - ......BFFFB..... - .....BPPFBPP.... - .....PPPFPPP.... - ......PPFPP..... - .....CAFFFAK.... - ....CKKAFAKKKAA. - ....CAKJFAKAKAA. - ....FACJDAJAFAA. - ....FACKJJJAFAA. - ....FACKKKJAFAA. - ......CKKKJAAA.. - ......CKAKJA.A.. - .....FFA..FF.... - ................ -} -# tile 629 (Baalzebub,female) -{ - ......F...F..... - .......F.F...... - ......BFFFB..... - .....BPPFBPP.... - .....PPPFPPP.... - ......PPFPP..... - .....CAFFFAK.... - ....CKKAFAKKKAA. - ....CAKJFAKAKAA. - ....FACJDAJAFAA. - ....FACKJJJAFAA. - ....FACKKKJAFAA. - ......CKKKJAAA.. - ......CKAKJA.A.. - .....FFA..FF.... - ................ -} -# tile 630 (Asmodeus,male) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKJAKKAJA - ...KA.CKKJAAKAJA - ...LA.CKKJJALJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 631 (Asmodeus,female) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKJAKKAJA - ...KA.CKKJAAKAJA - ...LA.CKKJJALJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 632 (Demogorgon,male) -{ - ...KKK..KKK..... - ..KBKBK.BKBK.... - ..KDKKK.KKDK.... - ..DKKFA.GKKD.... - ....GFAAGFAAA... - ...GFFFJFFFA.AAA - ..GFAGFFFAFFAAAA - .GJFAGJFJAFFFAA. - .GFAAGFFFAAFJA.. - .GJA.GFJFAAFFAA. - .GFA.GFFFA.FJAA. - .GJA.GJFJA.FFAA. - .GFAGFAAFFAFFA.. - ..GAGJAAJFAFAA.. - ..GAGFAFFFAFA... - ................ -} -# tile 633 (Demogorgon,female) -{ - ...KKK..KKK..... - ..KBKBK.BKBK.... - ..KDKKK.KKDK.... - ..DKKFA.GKKD.... - ....GFAAGFAAA... - ...GFFFJFFFA.AAA - ..GFAGFFFAFFAAAA - .GJFAGJFJAFFFAA. - .GFAAGFFFAAFJA.. - .GJA.GFJFAAFFAA. - .GFA.GFFFA.FJAA. - .GJA.GJFJA.FFAA. - .GFAGFAAFFAFFA.. - ..GAGJAAJFAFAA.. - ..GAGFAFFFAFA... - ................ -} -# tile 634 (Death,male) -{ - .BBBB....JJJ.... - .BPPPP.JJJJ..... - .C....JJJJJ..... - .C....JAAAJ..... - .C...JADADAJ.AAA - OOJ..JAAAAAJAAA. - OOOJJJAAAAAJJJA. - OOJJJJAAAAJOOJJA - .CJJJJAAAJOOOOJA - .C.JJAAAAJAOAAJA - .C..JAAAAJAOAAJA - .C..JAAAAAJOAJAA - .C..JAAAAAJJJAAA - .C.JAAAAAAAJJAA. - .CJJAAAAAAAAJJA. - ACJAAAAAAAAAAAJ. -} -# tile 635 (Death,female) -{ - .BBBB....JJJ.... - .BPPPP.JJJJ..... - .C....JJJJJ..... - .C....JAAAJ..... - .C...JADADAJ.AAA - OOJ..JAAAAAJAAA. - OOOJJJAAAAAJJJA. - OOJJJJAAAAJOOJJA - .CJJJJAAAJOOOOJA - .C.JJAAAAJAOAAJA - .C..JAAAAJAOAAJA - .C..JAAAAAJOAJAA - .C..JAAAAAJJJAAA - .C.JAAAAAAAJJAA. - .CJJAAAAAAAAJJA. - ACJAAAAAAAAAAAJ. -} -# tile 636 (Pestilence,male) -{ - F........JJJ.... - ..F....JJJJ..... - B...F.JJJJJ..... - ...B..JAAAJ..... - .F...JADADAJ.... - ...F.JAAAAAJ.AA. - .B..JFAAAAFJAA.. - ...FJJAFABJJAA.. - ..F.JFFBAJJJAAA. - ....FAFFJJJJAAA. - ....JABAJJJJAAA. - ...FJFFJJJJJJAA. - ...JJBFJJJJJJAA. - ...JAABFBJJJJAA. - ..JJFBFAFFAJJJA. - .JJAAFAFAAAAAAJ. -} -# tile 637 (Pestilence,female) -{ - F........JJJ.... - ..F....JJJJ..... - B...F.JJJJJ..... - ...B..JAAAJ..... - .F...JADADAJ.... - ...F.JAAAAAJ.AA. - .B..JFAAAAFJAA.. - ...FJJAFABJJAA.. - ..F.JFFBAJJJAAA. - ....FAFFJJJJAAA. - ....JABAJJJJAAA. - ...FJFFJJJJJJAA. - ...JJBFJJJJJJAA. - ...JAABFBJJJJAA. - ..JJFBFAFFAJJJA. - .JJAAFAFAAAAAAJ. -} -# tile 638 (Famine,male) -{ - .........JJJ.... - .......JJJ...... - K.....JJJJJ..... - K.....JAAAJ..... - K....JADADAJ.... - K....JAAAAAJ...A - K.....JAAAJJ..AA - OOJJJJJJAAJAJ.AA - K...JJJAAJJAJAAA - K.....JAJJJOJAA. - K.....JAOOOAAA.. - K.....JAJJAAA... - K.....JAJJAA.... - K.....JAAJAA.... - K...JJAAAJJAA... - K..JJAAAAAJJJA.. -} -# tile 639 (Famine,female) -{ - .........JJJ.... - .......JJJ...... - K.....JJJJJ..... - K.....JAAAJ..... - K....JADADAJ.... - K....JAAAAAJ...A - K.....JAAAJJ..AA - OOJJJJJJAAJAJ.AA - K...JJJAAJJAJAAA - K.....JAJJJOJAA. - K.....JAOOOAAA.. - K.....JAJJAAA... - K.....JAJJAA.... - K.....JAAJAA.... - K...JJAAAJJAA... - K..JJAAAAAJJJA.. -} -# tile 640 (mail daemon,male) -{ - ...OP.BEEE.PO... - ...OOEBEEEEOOD.. - ..DLOBEEEEOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDK.KDAADJJECDD - CCDKEEKKKJEEKCDD - .CCDK.EEEE..CDDD - .CCDAE.EENNNCDD. - .DDDAEEEENDNDDD. - ....BBEEENNNNN.. - ...BEEEAANNNNNA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 641 (mail daemon,female) -{ - ...OP.BEEE.PO... - ...OOEBEEEEOOD.. - ..DLOBEEEEOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDK.KDAADJJECDD - CCDKEEKKKJEEKCDD - .CCDK.EEEE..CDDD - .CCDAE.EENNNCDD. - .DDDAEEEENDNDDD. - ....BBEEENNNNN.. - ...BEEEAANNNNNA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 642 (djinni,male) -{ - .LL..NNN..LL.... - ..L..NGNA.L..... - ..LAALLLAALA.... - ..LAAKKKAALA.... - ...LCKKKCLA..... - ....LCKCLA...... - ....LICLIA..A... - ....IIIIEA.AA..A - ....EIEEIA.AAAAA - ....IEFEAAAAAAAA - .....DEAIAAAAA.. - .....IGIFAAAA... - .......FEDAAA... - .......I.GEA.A.. - .........IFED... - ................ -} -# tile 643 (djinni,female) -{ - .LL..NNN..LL.... - ..L..NGNA.L..... - ..LAALLLAALA.... - ..LAAKKKAALA.... - ...LCKKKCLA..... - ....LCKCLA...... - ....LICLIA..A... - ....IIIIEA.AA..A - ....EIEEIA.AAAAA - ....IEFEAAAAAAAA - .....DEAIAAAAA.. - .....IGIFAAAA... - .......FEDAAA... - .......I.GEA.A.. - .........IFED... - ................ -} -# tile 644 (jellyfish,male) -{ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAA... - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPPEPEEE.. - .PBBPPPEPEPPEE.. - .PEPBBEEPEEPEE.. - .PEEEPEEPEEPE... - ..PEEPE..PE.P... - ..P.EP.EEP..P... - ..PEE.P.E..E.... - .P..E.P..E...... -} -# tile 645 (jellyfish,female) -{ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAA... - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPPEPEEE.. - .PBBPPPEPEPPEE.. - .PEPBBEEPEEPEE.. - .PEEEPEEPEEPE... - ..PEEPE..PE.P... - ..P.EP.EEP..P... - ..PEE.P.E..E.... - .P..E.P..E...... -} -# tile 646 (piranha,male) -{ - ................ - ................ - ................ - ................ - ................ - ....OPP......... - .....OPP........ - ..O..PPAP.....E. - ..POPPPPPA...EEE - ..PPPPP.PPA.E... - ...PP..PPPAAAEE. - ..E.PPPPPPPPPE.. - ..E...PPPPPAA.E. - .....E..PPAE.... - .....E..P....... - ....E..E...E.... -} -# tile 647 (piranha,female) -{ - ................ - ................ - ................ - ................ - ................ - ....OPP......... - .....OPP........ - ..O..PPAP.....E. - ..POPPPPPA...EEE - ..PPPPP.PPA.E... - ...PP..PPPAAAEE. - ..E.PPPPPPPPPE.. - ..E...PPPPPAA.E. - .....E..PPAE.... - .....E..P....... - ....E..E...E.... -} -# tile 648 (shark,male) -{ - ................ - ................ - ................ - ...............P - ........P.....PP - ....E..PP....PP. - ...E...PPA..PPP. - ..EEEEPPPA.PPPPP - .E.EEPPP.PPPPPPE - ...EP.P.PPPPPEEE - ..PPPPPPPPPPEEE. - .APPPPPPPPEEEE.E - PPPPPPP..EE..... - NDPPAPEPPP.E..EE - PDNPPEE..EE..... - .PPPE..EEE..E... -} -# tile 649 (shark,female) -{ - ................ - ................ - ................ - ...............P - ........P.....PP - ....E..PP....PP. - ...E...PPA..PPP. - ..EEEEPPPA.PPPPP - .E.EEPPP.PPPPPPE - ...EP.P.PPPPPEEE - ..PPPPPPPPPPEEE. - .APPPPPPPPEEEE.E - PPPPPPP..EE..... - NDPPAPEPPP.E..EE - PDNPPEE..EE..... - .PPPE..EEE..E... -} -# tile 650 (giant eel,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA...AAA.. - ..AAAAAAA.AA.AA. - ..AAAA.AA.AA.AA. - ...AA..AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA.E.AA.E. - ...E.AAEE.AAAE.. - ...E.AAEEAAAEE.. - ..E..AAAAAAE.E.. - ...EE.AAAAE.E... - ..E...EE.E...E.. -} -# tile 651 (giant eel,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA...AAA.. - ..AAAAAAA.AA.AA. - ..AAAA.AA.AA.AA. - ...AA..AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA.E.AA.E. - ...E.AAEE.AAAE.. - ...E.AAEEAAAEE.. - ..E..AAAAAAE.E.. - ...EE.AAAAE.E... - ..E...EE.E...E.. -} -# tile 652 (electric eel,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA........ - ..AAAAAAA....... - ..AAAA.AA....... - ...AA..AA...DD.. - ......AAA..DD... - ......AA...DD... - .....AAA.E.DD.E. - ...E.AAEE.DD.E.. - ...E.AAEEDD.EE.. - ..E..AAADDDE.E.. - ...EE.AAADE.E... - ..E...EE.E...E.. -} -# tile 653 (electric eel,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA........ - ..AAAAAAA....... - ..AAAA.AA....... - ...AA..AA...DD.. - ......AAA..DD... - ......AA...DD... - .....AAA.E.DD.E. - ...E.AAEE.DD.E.. - ...E.AAEEDD.EE.. - ..E..AAADDDE.E.. - ...EE.AAADE.E... - ..E...EE.E...E.. -} -# tile 654 (kraken,male) -{ - ................ - ................ - ..FF..FF........ - ..DDFDDF........ - ..FFFFF.....GG.. - ..NCNFF......GFA - ..CC.FF.....EGFA - ....GFAA.GFAEGFE - ...GFFAGFFFFAGFE - ...GFAAFFAGFAEEE - ..GFFAGFFAGFEEE. - EEGFFAGFFAEEEE.E - .EGFFAGFFEE..... - EEGFFEEEEE.E..EE - EEEEEEE..EE..... - ..EEE..EEE..E... -} -# tile 655 (kraken,female) -{ - ................ - ................ - ..FF..FF........ - ..DDFDDF........ - ..FFFFF.....GG.. - ..NCNFF......GFA - ..CC.FF.....EGFA - ....GFAA.GFAEGFE - ...GFFAGFFFFAGFE - ...GFAAFFAGFAEEE - ..GFFAGFFAGFEEE. - EEGFFAGFFAEEEE.E - .EGFFAGFFEE..... - EEGFFEEEEE.E..EE - EEEEEEE..EE..... - ..EEE..EEE..E... -} -# tile 656 (newt,male) -{ - ................ - ................ - ................ - ................ - ................ - ......JKKJ...... - .....CLCCLLC.... - ....LAAAACCLCA.. - .......LCCLLLCA. - ....LCCCLLLAALA. - ....CALLLLAAAA.. - ...LLLLCLAAA.... - ...LLAAALLA..... - ................ - ................ - ................ -} -# tile 657 (newt,female) -{ - ................ - ................ - ................ - ................ - ................ - ......JKKJ...... - .....CLCCLLC.... - ....LAAAACCLCA.. - .......LCCLLLCA. - ....LCCCLLLAALA. - ....CALLLLAAAA.. - ...LLLLCLAAA.... - ...LLAAALLA..... - ................ - ................ - ................ -} -# tile 658 (gecko,male) -{ - ................ - ................ - ...........LLP.. - ..........LLOOA. - ......PO.LLOOOA. - ......OOALOOOA.. - .......LLOOOA... - ...POALOOOAA.... - ...OOLOOOOOOA... - ....ALOOOAOPA... - ...DOOOOA.AA.... - ...OOOAOOA...... - ...OODAOPA...... - ..F.AA.AA....... - ................ - ................ -} -# tile 659 (gecko,female) -{ - ................ - ................ - ...........LLP.. - ..........LLOOA. - ......PO.LLOOOA. - ......OOALOOOA.. - .......LLOOOA... - ...POALOOOAA.... - ...OOLOOOOOOA... - ....ALOOOAOPA... - ...DOOOOA.AA.... - ...OOOAOOA...... - ...OODAOPA...... - ..F.AA.AA....... - ................ - ................ -} -# tile 660 (iguana,male) -{ - ................ - ................ - ................ - ................ - ................ - ....GPGPGGPF.... - ..GPAAAAFFGPF... - .GPAA.PFFGPPPAA. - ......FGGPPFPPAA - .PFGGGGPPPFAAPPA - .FGPAPPPPFAAAAA. - .GPPPPFPFAAA.A.. - .PPFFAFPPAA..... - D.AAAAAAPPA..... - ................ - ................ -} -# tile 661 (iguana,female) -{ - ................ - ................ - ................ - ................ - ................ - ....GPGPGGPF.... - ..GPAAAAFFGPF... - .GPAA.PFFGPPPAA. - ......FGGPPFPPAA - .PFGGGGPPPFAAPPA - .FGPAPPPPFAAAAA. - .GPPPPFPFAAA.A.. - .PPFFAFPPAA..... - D.AAAAAAPPA..... - ................ - ................ -} -# tile 662 (baby crocodile,male) -{ - ................ - ................ - ................ - ................ - ................ - .....FFOFOFA.... - ....FOGFGGOFF... - ....GAAAAFOGFA.. - ...FAA.GFOGGGFA. - ...GFOOOGGGFAGA. - ...FGAGGGGFAAA.. - ..FGGGGFGFAA.... - ..GGDFAFGGA..... - ...D............ - ................ - ................ -} -# tile 663 (baby crocodile,female) -{ - ................ - ................ - ................ - ................ - ................ - .....FFOFOFA.... - ....FOGFGGOFF... - ....GAAAAFOGFA.. - ...FAA.GFOGGGFA. - ...GFOOOGGGFAGA. - ...FGAGGGGFAAA.. - ..FGGGGFGFAA.... - ..GGDFAFGGA..... - ...D............ - ................ - ................ -} -# tile 664 (lizard,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ....FFFFGFJ..... - ..FFAAAJJGFJ.... - ......JGFFJFAA.. - ...JGGGFFJAAFA.. - ..JFAFFFJAAAA... - ..FFFFJJAAA..... - .JFAAAAFAA...... - .D.............. - ................ - ................ -} -# tile 665 (lizard,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ....FFFFGFJ..... - ..FFAAAJJGFJ.... - ......JGFFJFAA.. - ...JGGGFFJAAFA.. - ..JFAFFFJAAAA... - ..FFFFJJAAA..... - .JFAAAAFAA...... - .D.............. - ................ - ................ -} -# tile 666 (chameleon,male) -{ - ................ - ................ - ................ - .....GGGG....... - ...GGGGGGGG..... - ...GGFFFFGGFA... - ..GPAAAGFFGGFA.. - .GPAA.PFFGGGGAA. - ...GGGGGGGGFGGAA - .PGGBBGGGGFAAGGA - .FGGABGGGFAAAAA. - .GGGGGFGFAAA.A.. - .DGFFAFGGAA..... - D.AAAAAAGGA..... - .DD............. - ................ -} -# tile 667 (chameleon,female) -{ - ................ - ................ - ................ - .....GGGG....... - ...GGGGGGGG..... - ...GGFFFFGGFA... - ..GPAAAGFFGGFA.. - .GPAA.PFFGGGGAA. - ...GGGGGGGGFGGAA - .PGGBBGGGGFAAGGA - .FGGABGGGFAAAAA. - .GGGGGFGFAAA.A.. - .DGFFAFGGAA..... - D.AAAAAAGGA..... - .DD............. - ................ -} -# tile 668 (crocodile,male) -{ - ................ - ................ - ................ - ................ - ....FFOFOOFA.... - ...FOGFGFGOFFA.. - ..FGAAAAFFOGFFA. - .FFAA.GFFOGGGGFA - ......FOOGGGGGGA - .G.OOOOGGGGFAGGA - .FOGAGGGGGFAAAA. - FGGGGGFGGFAA.... - GGDDFAFGGGA..... - GDDFAAAAGGA..... - .DF............. - ................ -} -# tile 669 (crocodile,female) -{ - ................ - ................ - ................ - ................ - ....FFOFOOFA.... - ...FOGFGFGOFFA.. - ..FGAAAAFFOGFFA. - .FFAA.GFFOGGGGFA - ......FOOGGGGGGA - .G.OOOOGGGGFAGGA - .FOGAGGGGGFAAAA. - FGGGGGFGGFAA.... - GGDDFAFGGGA..... - GDDFAAAAGGA..... - .DF............. - ................ -} -# tile 670 (salamander,male) -{ - ................ - ................ - ................ - ......CCC....... - ....CCCCCCC..... - ...CCDDDDCCDA... - ....AAAADDCCDA.. - ......KDDCCCCAA. - ..LLLCCCCCCDCCAA - .KLCCCLLLCDAACCA - .DCEECLKKDAAAAA. - DCCAECDKDAAA.A.. - CCCCCCDCCAA..... - .DAADAAACCA..... - ..ACCA.......... - ...AAA.......... -} -# tile 671 (salamander,female) -{ - ................ - ................ - ................ - ......CCC....... - ....CCCCCCC..... - ...CCDDDDCCDA... - ....AAAADDCCDA.. - ......KDDCCCCAA. - ..LLLCCCCCCDCCAA - .KLCCCLLLCDAACCA - .DCEECLKKDAAAAA. - DCCAECDKDAAA.A.. - CCCCCCDCCAA..... - .DAADAAACCA..... - ..ACCA.......... - ...AAA.......... -} -# tile 672 (long worm tail,male) -{ - ........ILLLL... - ......IILLAA.... - .....ILLAA...... - .....ILA........ - .....ILA........ - ......LLA...II.. - .......LLIIILLLL - ........ILLAAA.L - ...IIIILLALL.... - .ILLLLLAA..LL... - ILLAAAA.....LA.. - ILA.........LA.. - LLA........LLA.. - LILA......LLA... - .LLLIIIILLLA.... - ...LLLLLAAA..... -} -# tile 673 (long worm tail,female) -{ - ........ILLLL... - ......IILLAA.... - .....ILLAA...... - .....ILA........ - .....ILA........ - ......LLA...II.. - .......LLIIILLLL - ........ILLAAA.L - ...IIIILLALL.... - .ILLLLLAA..LL... - ILLAAAA.....LA.. - ILA.........LA.. - LLA........LLA.. - LILA......LLA... - .LLLIIIILLLA.... - ...LLLLLAAA..... -} -# tile 674 (archeologist,male) -{ - ................ - ................ - ......KJ.J...... - ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - ......CJJKAAAA.. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 675 (archeologist,female) -{ - ................ - ................ - ................ - ......KJJJ...... - ......KKLJ...... - .....KLELE...... - ....KJLLLL...... - ....JJALLA...... - ...JJLBAAPL.AAA. - ...JLLBBBPLLAAA. - ....LABPPPALAAA. - ....LALLLLALAAA. - .....AOJJOAAAA.. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 676 (barbarian,male) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - ......ALLA...... - .....LLAALL.AAA. - ....LLLLLLLLAAA. - ....LALLLLALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 677 (barbarian,female) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - ......ALLA...... - .....LLAALL.AAA. - ....LLLLLLLLAAA. - ....LALLLLALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 678 (cave dweller,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....LLAJJALLAAA. - ...LLLLAALLLLAA. - ...LLALLLLALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 679 (cave dweller,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JLDDLAJ.... - ....LJALLAJLAAA. - ...LLJCAAJJLLAA. - ...LLACKKJALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 680 (healer,male) -{ - ................ - .......NN....... - ......NDDO...... - ......NNNN...... - ......ELEP...... - ......LLLP...... - .......LLP...... - ......O..PA.AAA. - .....NNOOPPAAAA. - ....OOONOPPPAA.. - ....LANOOPALAA.. - ......NOOPAAAA.. - .....NOOOPAA.A.. - ....NOOOOOPA.... - ................ - ................ -} -# tile 681 (healer,female) -{ - ................ - .......NN....... - ......NDDO...... - ......NNNN...... - ......ELEP...... - ......LLLP...... - .......LLP...... - ......O..PA.AAA. - .....NNOOPPAAAA. - ....OOONOPPPAA.. - ....LANOOPALAA.. - ......NOOPAAAA.. - .....NOOOPAA.A.. - ....NOOOOOPA.... - ................ - ................ -} -# tile 682 (knight,male) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - ......ALLAA..... - .....BBAABB.AAA. - ....BPPPPPPPAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... - ................ - ................ -} -# tile 683 (knight,female) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - ......ALLAA..... - .....BBAABB.AAA. - ....BPPPPPPPAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... - ................ - ................ -} -# tile 684 (monk,male) -{ - ................ - ................ - .......CCC...... - ......JCJJJA.... - ......CAAAJA.... - ......CAAAJA.... - ......CKLKCAAAA. - .....CDDDDDDAAAA - ....CDDLALDDDAAA - ....DALLALLADAA. - ....DDDDCDDDDAA. - .....AACCCDAAAA. - .....CDCCCDDA.A. - ....CCCCCCCDD... - ................ - ................ -} -# tile 685 (monk,female) -{ - ................ - ................ - .......CCC...... - ......JCJJJA.... - ......CAAAJA.... - ......CAAAJA.... - ......CKLKCAAAA. - .....CDDDDDDAAAA - ....CDDLALDDDAAA - ....DALLALLADAA. - ....DDDDCDDDDAA. - .....AACCCDAAAA. - .....CDCCCDDA.A. - ....CCCCCCCDD... - ................ - ................ -} -# tile 686 (cleric,male) -{ - ................ - ................ - ......JLLJ...... - ......JLLJA..... - ......LLLLA..... - ......ALLJA..... - ......IJJIAAAA.. - .....ODDDDDAAAA. - ....INNDDDDDAAA. - ...NLNNDDDALAA.. - ......DDDDAAAA.. - ......DIIDAAAA.. - .....DDIIDDA.A.. - ....DIIIIIDD.... - ................ - ................ -} -# tile 687 (cleric,female) -{ - ................ - .......JJ....... - ......JJJJ...... - ......JLLJA..... - ......JLLJJ..... - .....JJLLJJ..... - .....JEJJEJAAA.. - .....ODEEDDAAAA. - ....IDINNDDDAAA. - ....L.DNNDALAA.. - ......IDDDAAAA.. - ......IDDDAAAA.. - .....DDIIDDA.A.. - ....DIIIIIDD.... - ................ - ................ -} -# tile 688 (ranger,male) -{ - ................ - ................ - ........CJA..... - .......CJJJA.... - .......JEEJA.... - .......JLLJA.... - .......ALLAA.... - ......GGAAGG.AAA - .....BPFFFFPPAAA - .....PAGFFFAPAAA - .....LA.FF.ALAAA - .......BP.PAAAA. - .......BPAPAA.A. - ......PPA.PPA... - ................ - ................ -} -# tile 689 (ranger,female) -{ - ................ - ................ - ........CJA..... - .......CJJJA.... - .......JEEJA.... - .......JLLJA.... - .......ALLAA.... - ......GGAAGG.AAA - .....BPFFFFPPAAA - .....PAGFFFAPAAA - .....LA.FF.ALAAA - .......BP.PAAAA. - .......BPAPAA.A. - ......PPA.PPA... - ................ - ................ -} -# tile 690 (rogue,male) -{ - ................ - ................ - ................ - .....OA...OA.... - .....OOIDPPA.... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - ......BAABAA..A. - .....KEBBEJAAAA. - ....KAAEEAAKAA.. - ....LAJJHJALAA.. - ......KKJKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 691 (rogue,female) -{ - ................ - ................ - ................ - .....OA...OA.... - .....OOIDPPA.... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - ......BAABAA..A. - .....KEBBEJAAAA. - ....KAAEEAAKAA.. - ....LAJJHJALAA.. - ......KKJKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 692 (samurai,male) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LABBBBALAAA. - ....LABBBBALAAA. - ......IDDDAAAA.. - ......IDADAA.A.. - .....IIA.IIA.... - ................ -} -# tile 693 (samurai,female) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LABBBBALAAA. - ....LABBBBALAAA. - ......IDDDAAAA.. - ......IDADAA.A.. - .....IIA.IIA.... - ................ -} -# tile 694 (tourist,male) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ...JJJJJJJJJJ... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HGAAGH.AAA. - ....LLGHHGLLAAA. - ....LAHGHGALAAA. - ....LAHHGHALAAA. - ......JJJKAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 695 (tourist,female) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ...JJJJJJJJJJ... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HGAAGH.AAA. - ....LLGHHGLLAAA. - ....LAHGHGALAAA. - ....LAHHGHALAAA. - ......JJJKAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 696 (valkyrie,male) -{ - D..............D - .D............D. - ..D...LHHL...D.. - ...D.HHHHHL.D... - ....DHELELHD.... - ....HDLLLLD..... - ...HHHDLLD...... - ...HJKJDDKJJAAA. - ..HHLJJDDJJLAAA. - ..H.LADKDCALAAA. - ....LDAKKDALAAA. - ....D.KKJKDAAA.. - ...D..KJAJAD.A.. - ..D..KLA.LKAD... - .D...........D.. - D.............D. -} -# tile 697 (valkyrie,female) -{ - ................ - ................ - ......LHHL...... - .....HHHHHL..... - ....LHELELH..... - ....HHLLLLH..... - ...HHHALLA...... - ...HJKJAAKJJAAA. - ..HHLJJKKJJLAAA. - ..H.LACKJCALAAA. - ....LAAKKAALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 698 (wizard,male) -{ - ................ - .........BP..... - .......BBPE..... - ......BPPEA..... - ......BAAEA..... - ......BAAEA..... - ......PLLE...... - ......PAAEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 699 (wizard,female) -{ - ................ - .........BP..... - .......BBPE..... - ......BPPEA..... - ......BAAEA..... - ......BAAEA..... - ......PLLE...... - ......PAAEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 700 (Lord Carnarvon,male) -{ - .......JJ....... - ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CIAAIK.AAA. - ....CKKIIKKKAAA. - ...KKCKKHKJKKAA. - ...KKAKHKJAKKAA. - ...KAIHKKJIAKA.. - ...LAICKKJIALA.. - .....ICKAJIAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 701 (Lord Carnarvon,female) -{ - .......JJ....... - ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CIAAIK.AAA. - ....CKKIIKKKAAA. - ...KKCKKHKJKKAA. - ...KKAKHKJAKKAA. - ...KAIHKKJIAKA.. - ...LAICKKJIALA.. - .....ICKAJIAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 702 (Pelias,male) -{ - ................ - .......JJ....... - ......KKKJ...... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKKAKKAA. - ...KA.CKKJAAKA.. - ...LA.CKAJAALA.. - ......CKAJAAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 703 (Pelias,female) -{ - ................ - .......JJ....... - ......KKKJ...... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKKAKKAA. - ...KA.CKKJAAKA.. - ...LA.CKAJAALA.. - ......CKAJAAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 704 (Shaman Karnov,male) -{ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....LHAJJAHLAA.. - ...LLLHAAHLLLAA. - ...LLLLHHLLLLAA. - ...LLALHHLALLAA. - ...LLALLLLALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ -} -# tile 705 (Shaman Karnov,female) -{ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....LHAJJAHLAA.. - ...LLLHAAHLLLAA. - ...LLLLHHLLLLAA. - ...LLALHHLALLAA. - ...LLALLLLALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ -} -# tile 706 (Earendil,male) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBPLELEABPB.. - ..BBBPLLLLABBB.. - ..PBPPALLAPPP... - ...PPBGAAGBBB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 707 (Earendil,female) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBPLELEABPB.. - ..BBBPLLLLABBB.. - ..PBPPALLAPPP... - ...PPBGAAGBBB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 708 (Elwing,male) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBHLELEHBPB.. - ..BBBHLLLLHBBB.. - ..PBHHALLAHHP... - ...PHHGAAGHHB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 709 (Elwing,female) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBHLELEHBPB.. - ..BBBHLLLLHBBB.. - ..PBHHALLAHHP... - ...PHHGAAGHHB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 710 (Hippocrates,male) -{ - ................ - ....LLLCCD...... - ...LLCCDDA...... - ...LAAAADA...... - ...LBABADA...... - ...LAAAADA...... - ...CCLLDD.B..... - ....CKKDDFBFAAA. - ..LLLCLDDDBFAAA. - .CCCCLDDDFBAAA.. - .LALLCCDDFBDAA.. - ...LCCCCDABFAA.. - ...LCCCCDABAAA.. - ..LLCCCCDAA.AA.. - .LCCCCCCCDA..... - ................ -} -# tile 711 (Hippocrates,female) -{ - ................ - ....LLLCCD...... - ...LLCCDDA...... - ...LAAAADA...... - ...LBABADA...... - ...LAAAADA...... - ...CCLLDD.B..... - ....CKKDDFBFAAA. - ..LLLCLDDDBFAAA. - .CCCCLDDDFBAAA.. - .LALLCCDDFBDAA.. - ...LCCCCDABFAA.. - ...LCCCCDABAAA.. - ..LLCCCCDAA.AA.. - .LCCCCCCCDA..... - ................ -} -# tile 712 (King Arthur,male) -{ - ................ - ................ - ......OHHA...... - .....OHHHHA..... - .....HBLBHA..... - .....HLLLHA..... - .....ALLLAA..... - ....BBAAABB.AAA. - ...BPPPPPPPPAAA. - ...PABPPPPACPAA. - ..NNNNNNNNNCLCA. - .....BPP.PACAA.. - .....BPAPPAA.A.. - .....BPAPPAA.A.. - ....PPAA.PPA.... - ................ -} -# tile 713 (King Arthur,female) -{ - ................ - ................ - ......OHHA...... - .....OHHHHA..... - .....HBLBHA..... - .....HLLLHA..... - .....ALLLAA..... - ....BBAAABB.AAA. - ...BPPPPPPPPAAA. - ...PABPPPPACPAA. - ..NNNNNNNNNCLCA. - .....BPP.PACAA.. - .....BPAPPAA.A.. - .....BPAPPAA.A.. - ....PPAA.PPA.... - ................ -} -# tile 714 (Grand Master,male) -{ - ................ - .......LL....... - ......LLLL...... - ......LLLL...... - ..LC.CALLAC..... - .CLLC.CAACCCC... - .CJLACCCCCCCCC.. - ..JAACCCCCCCCCC. - ..JCCCCCCCCCCC.A - ..J..PPPPPLCCAAA - ..J..CCCCLLCAAAA - ..J..CCCCCCCAAAA - ..J..CCCCCCCAAAA - ..J.ACCCCCCCAAA. - ..JACCCCCCCCAA.. - ................ -} -# tile 715 (Grand Master,female) -{ - ................ - .......LL....... - ......LLLL...... - ......LLLL...... - ..LC.CALLAC..... - .CLLC.CAACCCC... - .CJLACCCCCCCCC.. - ..JAACCCCCCCCCC. - ..JCCCCCCCCCCC.A - ..J..PPPPPLCCAAA - ..J..CCCCLLCAAAA - ..J..CCCCCCCAAAA - ..J..CCCCCCCAAAA - ..J.ACCCCCCCAAA. - ..JACCCCCCCCAA.. - ................ -} -# tile 716 (Arch Priest,male) -{ - ..N............. - .NNN..JLLJ...... - ..N...JLLJ...... - ..N...LLLL...... - ..LC.CALLAC..... - .CLLC.CAACJDK... - .CHLACCCCJCCDK.. - ..HAACCJJCCCCDK. - ..HCCCCJCCJCCC.A - ..H..DCJCCLJCAAA - ..H..DCJCLLCAAAA - ..H..KCJCCDJAAAA - ..H..KCJCCDJAAAA - ..H.ACCJCCDJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 717 (Arch Priest,female) -{ - ..N............. - .NNN..JLLJ...... - ..N...JLLJ...... - ..N...LLLL...... - ..LC.CALLAC..... - .CLLC.CAACJDK... - .CHLACCCCJCCDK.. - ..HAACCJJCCCCDK. - ..HCCCCJCCJCCC.A - ..H..DCJCCLJCAAA - ..H..DCJCLLCAAAA - ..H..KCJCCDJAAAA - ..H..KCJCCDJAAAA - ..H.ACCJCCDJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 718 (Orion,male) -{ - ................ - ................ - .......CJA...... - ......CJJJA..... - ......JEEJA..... - ......JLLJA..... - ......ALLAA..... - .....GGAAGG..... - ....BGFFFFFP.... - ....BPFFFFPPAAA. - ....PAGFFFAPAAA. - ....LANNNNALAAA. - ......BP.PAAAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... -} -# tile 719 (Orion,female) -{ - ................ - ................ - .......CJA...... - ......CJJJA..... - ......JEEJA..... - ......JLLJA..... - ......ALLAA..... - .....GGAAGG..... - ....BGFFFFFP.... - ....BPFFFFPPAAA. - ....PAGFFFAPAAA. - ....LANNNNALAAA. - ......BP.PAAAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... -} -# tile 720 (Master of Thieves,male) -{ - ................ - ...H.....H...... - ...HHIDKHH...... - ....IDDDD....... - ....LLLLLA...... - ....LBLBLA...... - ....LLLLLA...... - .....LLLA....... - ....B.AABAA..... - ...KEBBBEJAAA... - ..KAEEEEEAJAAA.. - ..LAJJHHJALAAA.. - ....JKKKJAAAAA.. - ....KJAJKAAAA... - ...JJA..JJA..... - ................ -} -# tile 721 (Master of Thieves,female) -{ - ................ - ...H.....H...... - ...HHIDKHH...... - ....IDDDD....... - ....LLLLLA...... - ....LBLBLA...... - ....LLLLLA...... - .....LLLA....... - ....B.AABAA..... - ...KEBBBEJAAA... - ..KAEEEEEAJAAA.. - ..LAJJHHJALAAA.. - ....JKKKJAAAAA.. - ....KJAJKAAAA... - ...JJA..JJA..... - ................ -} -# tile 722 (Lord Sato,male) -{ - .....AAA........ - .....AAA........ - ...AAAAAAA...... - ..AALLLLLAA..... - ..ALFFLFFLA..... - ..ALLLLLLLA..... - ...AALLLA....... - IIIIIAAAIIIIAAA. - LLDIIIIIIDLLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - ...IIDDDDAAAAAA. - ...IIAAIDAAA..A. - ..IIIA.IIIAA.... - ................ -} -# tile 723 (Lord Sato,female) -{ - .....AAA........ - .....AAA........ - ...AAAAAAA...... - ..AALLLLLAA..... - ..ALFFLFFLA..... - ..ALLLLLLLA..... - ...AALLLA....... - IIIIIAAAIIIIAAA. - LLDIIIIIIDLLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - ...IIDDDDAAAAAA. - ...IIAAIDAAA..A. - ..IIIA.IIIAA.... - ................ -} -# tile 724 (Twoflower,male) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - .....NNLNNA..... - ....NALNALNA.... - .....NNANNAA.... - .....AAAAAA.AAA. - ....LLHGHGLLAAA. - ....LAGGGGALAAA. - ....LAHGHGALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 725 (Twoflower,female) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - .....NNLNNA..... - ....NALNALNA.... - .....NNANNAA.... - .....AAAAAA.AAA. - ....LLHGHGLLAAA. - ....LAGGGGALAAA. - ....LAHGHGALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 726 (Norn,male) -{ - ................ - ................ - ......NNN....... - .....NNNNN...... - .....NELELN..... - ....NNLLLLN..... - ...NNNALLA...... - ...NJKJAAKJJAAA. - ..NNLJJKKJJLAAA. - ..N.LACKJCALAAA. - ....LAKKKKALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 727 (Norn,female) -{ - ................ - ................ - ......NNN....... - .....NNNNN...... - .....NELELN..... - ....NNLLLLN..... - ...NNNALLA...... - ...NJKJAAKJJAAA. - ..NNLJJKKJJLAAA. - ..N.LACKJCALAAA. - ....LAKKKKALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 728 (Neferet the Green,male) -{ - ................ - ................ - ......GGG....... - .....GFFFG...... - ....GFEFEG...... - ....GFFFFEG..... - .N.GPEFFFEE..... - .I..BBEAAEA.AA.. - .I.BBPPBBEEAAAA. - .IGBPPPPPEEEAA.. - .I.PP.EPEAAGAA.. - .I...BPPPAAAAA.. - .N...BPPPEAA.A.. - ....BPPPPPEA.... - ...BPPPPPPPE.... - ................ -} -# tile 729 (Neferet the Green,female) -{ - ................ - ................ - ......GGG....... - .....GFFFG...... - ....GFEFEG...... - ....GFFFFEG..... - .N.GPEFFFEE..... - .I..BBEAAEA.AA.. - .I.BBPPBBEEAAAA. - .IGBPPPPPEEEAA.. - .I.PP.EPEAAGAA.. - .I...BPPPAAAAA.. - .N...BPPPEAA.A.. - ....BPPPPPEA.... - ...BPPPPPPPE.... - ................ -} -# tile 730 (Minion of Huhetotl,male) -{ - ...OP......PO... - ...OODDDDDDOOD.. - ..DLOOCDDCOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDKKKDAADJJDCDD - CCDKDDKKKJDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 731 (Minion of Huhetotl,female) -{ - ...OP......PO... - ...OODDDDDDOOD.. - ..DLOOCDDCOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDKKKDAADJJDCDD - CCDKDDKKKJDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 732 (Thoth Amon,male) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....BPAAPP.AAA. - ....BPPPPPPPAAA. - ...PPBPPPPJPPAA. - ...PPAPPP.APPA.A - ...PA.BPP.AAPA.A - ...LA.BPP..AL.A. - ......BPA.A..A.. - ......BPAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 733 (Thoth Amon,female) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....BPAAPP.AAA. - ....BPPPPPPPAAA. - ...PPBPPPPJPPAA. - ...PPAPPP.APPA.A - ...PA.BPP.AAPA.A - ...LA.BPP..AL.A. - ......BPA.A..A.. - ......BPAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 734 (Chromatic Dragon,male) -{ - ......GGGFA..... - .....NFNFEEA.... - ....GFFFEECA.... - ..DCHHF..CCA.... - CHCHCD..BCCA.... - HD.D...BFFA..... - ......OBFAAAAAA. - ....HOGFAAAAAAAA - ..HOOIEA.EF.AAA. - .HOOOIEEEEFFJAA. - .HOOOIEEFFFDDAA. - HBOOIIEFFFDDCCA. - HB.OIEFOODD.CJA. - HBAAGE.AADDACCA. - ....GFAA...CCJA. - ........FFFFJA.. -} -# tile 735 (Chromatic Dragon,female) -{ - ......GGGFA..... - .....NFNFEEA.... - ....GFFFEECA.... - ..DCHHF..CCA.... - CHCHCD..BCCA.... - HD.D...BFFA..... - ......OBFAAAAAA. - ....HOGFAAAAAAAA - ..HOOIEA.EF.AAA. - .HOOOIEEEEFFJAA. - .HOOOIEEFFFDDAA. - HBOOIIEFFFDDCCA. - HB.OIEFOODD.CJA. - HBAAGE.AADDACCA. - ....GFAA...CCJA. - ........FFFFJA.. -} -# tile 736 (Goblin King,male) -{ - ................ - ................ - .H..H...H....... - CLC.HCHCH....... - CLC.HHHHH....... - .H..IIIII....... - .HK.IHIHI.I..... - .HICKIIIJKK..... - .H.IIJJJK.AA.... - .H..JICJJAAAAA.. - .H..IIIIJAAAAA.. - ....JIIJJAA..... - ....IJKJJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 737 (Goblin King,female) -{ - ................ - ................ - .H..H...H....... - CLC.HCHCH....... - CLC.HHHHH....... - .H..IIIII....... - .HK.IHIHI.I..... - .HICKIIIJKK..... - .H.IIJJJK.AA.... - .H..JICJJAAAAA.. - .H..IIIIJAAAAA.. - ....JIIJJAA..... - ....IJKJJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 738 (Cyclops,male) -{ - ................ - ....LLLLL....... - ...CLLLLLC...... - ...LBABNNL...... - ...LBBBNNLJA.... - ...CLNNNLCJA.... - ....LLLLLJAAA... - ....LAALLAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.GGGHGGACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 739 (Cyclops,female) -{ - ................ - ....LLLLL....... - ...CLLLLLC...... - ...LBABNNL...... - ...LBBBNNLJA.... - ...CLNNNLCJA.... - ....LLLLLJAAA... - ....LAALLAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.GGGHGGACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 740 (Ixoth,male) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDGDDGDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 741 (Ixoth,female) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDGDDGDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 742 (Master Kaen,male) -{ - ................ - .......KKA...... - ......KJJKA..... - ..KKA.KAAKA.KKA. - .KAAKAKDDKAKAAKA - .KOOJKKOOKKKOOJA - .KJJJJJJJJJKJJJA - ..KJJJJJJJJJJJA. - ....KJJJJJJJA... - ......KJJJAAAAAA - .....KJJJJKAAAAA - .....KJJJJJAAAAA - ....KJJJJJJKAAA. - ...KJJJJJJJJKAA. - ...KJJJJJJJJJA.. - ................ -} -# tile 743 (Master Kaen,female) -{ - ................ - .......KKA...... - ......KJJKA..... - ..KKA.KAAKA.KKA. - .KAAKAKDDKAKAAKA - .KOOJKKOOKKKOOJA - .KJJJJJJJJJKJJJA - ..KJJJJJJJJJJJA. - ....KJJJJJJJA... - ......KJJJAAAAAA - .....KJJJJKAAAAA - .....KJJJJJAAAAA - ....KJJJJJJKAAA. - ...KJJJJJJJJKAA. - ...KJJJJJJJJJA.. - ................ -} -# tile 744 (Nalzok,male) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDBDDBDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 745 (Nalzok,female) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDBDDBDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 746 (Scorpius,male) -{ - .....JLJLJAA.... - ....JA.JCJCKAA.. - ....AJ.....JJJA. - ....LA......LCKA - .JAKJA......JJJA - ..JJA......ALCJA - .......ALLAJCJKA - ....JJALCCAAJJA. - .JJALLAJCJJJAA.. - JA.LCCAJAJJAAAA. - ..JACJJJAAACCJAA - GGJJJJJAACCAAAJA - .JJGGAJACAAJJAAA - D.JJAAJAACA.JAA. - ...D...JAAJA.JJ. - ........JA.JA... -} -# tile 747 (Scorpius,female) -{ - .....JLJLJAA.... - ....JA.JCJCKAA.. - ....AJ.....JJJA. - ....LA......LCKA - .JAKJA......JJJA - ..JJA......ALCJA - .......ALLAJCJKA - ....JJALCCAAJJA. - .JJALLAJCJJJAA.. - JA.LCCAJAJJAAAA. - ..JACJJJAAACCJAA - GGJJJJJAACCAAAJA - .JJGGAJACAAJJAAA - D.JJAAJAACA.JAA. - ...D...JAAJA.JJ. - ........JA.JA... -} -# tile 748 (Master Assassin,male) -{ - ................ - ................ - ................ - .......AA....... - ......AAAA...... - .....ABLBLA..... - .....AAAAAA..... - ......AAAA...... - .....AAAAAA..PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 749 (Master Assassin,female) -{ - ................ - ................ - ................ - .......AA....... - ......AAAA...... - .....ABLBLA..... - .....AAAAAA..... - ......AAAA...... - .....AAAAAA..PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 750 (Ashikaga Takauji,male) -{ - ................ - ................ - ......AA........ - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LAIIIIALAAA. - ....LALHHLALAAA. - ......IIIIAAAA.. - ......IIAIAA.A.. - .....IIA.IIA.... - ................ -} -# tile 751 (Ashikaga Takauji,female) -{ - ................ - ................ - ......AA........ - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LAIIIIALAAA. - ....LALHHLALAAA. - ......IIIIAAAA.. - ......IIAIAA.A.. - .....IIA.IIA.... - ................ -} -# tile 752 (Lord Surtur,male) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLBAAAA. - ...PPDBBBBBBBAA. - ..BDDHDPBPPPPPA. - ..PPHDDPBPPPPPA. - ..LAHDHPBPPAALAA - JLAADDHBBBBAALAA - JJLJDHHPBPPPCLAA - ..LLJBPPABPPLLAA - .....BPPABPPAAAA - ...LLLLJ.BLLLKAA -} -# tile 753 (Lord Surtur,female) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLBAAAA. - ...PPDBBBBBBBAA. - ..BDDHDPBPPPPPA. - ..PPHDDPBPPPPPA. - ..LAHDHPBPPAALAA - JLAADDHBBBBAALAA - JJLJDHHPBPPPCLAA - ..LLJBPPABPPLLAA - .....BPPABPPAAAA - ...LLLLJ.BLLLKAA -} -# tile 754 (Dark One,male) -{ - ................ - ......AAA....... - .....AAAAA...... - .....ADADA...... - .....AAAAA...... - ....AAAAAAA..... - ....AAAAAAA..... - ...AAAAAAAAA.... - ...AAAAAAAAA.... - ..AAAAAAAAAAA... - ..AAAAAAAAAAA... - ...AAAAAAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAAA - ................ -} -# tile 755 (Dark One,female) -{ - ................ - ......AAA....... - .....AAAAA...... - .....ADADA...... - .....AAAAA...... - ....AAAAAAA..... - ....AAAAAAA..... - ...AAAAAAAAA.... - ...AAAAAAAAA.... - ..AAAAAAAAAAA... - ..AAAAAAAAAAA... - ...AAAAAAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAAA - ................ -} -# tile 756 (student,male) -{ - ................ - ................ - .....GGFGG...... - .......G........ - ......NDND...... - ...DDDDDDDD..... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 757 (student,female) -{ - ................ - ................ - .....GGFGG...... - .......G........ - ......NDND...... - ...DDDDDDDD..... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 758 (chieftain,male) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - .....HALLAH..... - ....LLHAAHLLAAA. - ....LLLIILLLAAA. - ....LALIILALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 759 (chieftain,female) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - .....HALLAH..... - ....LLHAAHLLAAA. - ....LLLIILLLAAA. - ....LALIILALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 760 (neanderthal,male) -{ - ................ - ................ - ................ - ......JJJJ...... - .....JJJJJJ..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....JJAJJAJJ.AA. - ...JLLJAAJLLJAA. - ...LLALJJLALLAA. - ....LALCCLALAAA. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 761 (neanderthal,female) -{ - ................ - ................ - ................ - ......JJJJ...... - .....JJJJJJ..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....JJAJJAJJ.AA. - ...JLLJAAJLLJAA. - ...LLALJJLALLAA. - ....LALCCLALAAA. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 762 (High-elf,male) -{ - .........G...... - .......GGF...... - ......GGGGA..... - ......LILIA..... - ......LLLLA..... - ......ALLA...... - ......GAAG..AA.. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LA.GFAALAA.. - ....LA.GFAALAA.. - ....LAGGGFAL.A.. - ......GFAFAA.A.. - ......GFAFAA.... - ......GFAFAA.... - .....KLA.LKA.... -} -# tile 763 (High-elf,female) -{ - .........G...... - .......GGF...... - ......GGGGA..... - ......LILIA..... - ......LLLLA..... - ......ALLA...... - ......GAAG..AA.. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LA.GFAALAA.. - ....LA.GFAALAA.. - ....LAGGGFAL.A.. - ......GFAFAA.A.. - ......GFAFAA.... - ......GFAFAA.... - .....KLA.LKA.... -} -# tile 764 (attendant,male) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......BLB....... - .....CLLLD...... - .....CCKKDA.AAA. - .....LLCLDDAAAA. - ....CCCLDDDDAA.. - ....LALCCDALAA.. - ......LCCDAAAA.. - .....LCCCDAA.A.. - ....LCCCCCDA.... - ................ - ................ -} -# tile 765 (attendant,female) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......BLB....... - .....CLLLD...... - .....CCKKDA.AAA. - .....LLCLDDAAAA. - ....CCCLDDDDAA.. - ....LALCCDALAA.. - ......LCCDAAAA.. - .....LCCCDAA.A.. - ....LCCCCCDA.... - ................ - ................ -} -# tile 766 (page,male) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - .......LLAA..... - ......BAABA.AAA. - .....BPPPPPAAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 767 (page,female) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - .......LLAA..... - ......BAABA.AAA. - .....BPPPPPAAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 768 (abbot,male) -{ - ................ - ................ - ................ - ................ - ................ - ......KLK....... - ......LLL....... - ....CCLLLJJ..... - ....KCKLKKJAAA.. - ....CDDDDDDAAAA. - ...CDDLALDDDAAA. - ...DALLALLADAA.. - ...DDDDCDDDDAA.. - ....AACCCDAAAA.. - ....CDCCCDDA.A.. - ...CCCCCCCDD.... -} -# tile 769 (abbot,female) -{ - ................ - ................ - ................ - ................ - ................ - ......KLK....... - ......LLL....... - ....CCLLLJJ..... - ....KCKLKKJAAA.. - ....CDDDDDDAAAA. - ...CDDLALDDDAAA. - ...DALLALLADAA.. - ...DDDDCDDDDAA.. - ....AACCCDAAAA.. - ....CDCCCDDA.A.. - ...CCCCCCCDD.... -} -# tile 770 (acolyte,male) -{ - ................ - ................ - ................ - ......JJJJ...... - ......JLLJA..... - ......LLLLA..... - ......ALLJA..... - ......CJJCAAAA.. - .....LDDDDDAAAA. - ....CDCCDDDDAAA. - ....L.LCCDALAA.. - ......LCCDAAAA.. - ......LCCDAAAA.. - .....LDCCDDA.A.. - ....LCCCCCDD.... - ................ -} -# tile 771 (acolyte,female) -{ - ................ - ................ - ................ - ......JJJJ...... - ......JLLJA..... - ......LLLLA..... - ......ALLJA..... - ......CJJCAAAA.. - .....LDDDDDAAAA. - ....CDCCDDDDAAA. - ....L.LCCDALAA.. - ......LCCDAAAA.. - ......LCCDAAAA.. - .....LDCCDDA.A.. - ....LCCCCCDD.... - ................ -} -# tile 772 (hunter,male) -{ - ................ - ................ - ................ - ....J..CJA...... - ...J..CJJJA..... - ...J..JEEJA..... - ..J...JLLJA..... - ..J...ALLAA..... - ..J..GGAAGG.AAA. - ..LPBPFFFFPPAAA. - ..J..AGFFFAPAAA. - ..J....FF.ALAAA. - ...J..BP.PAAAA.. - ...J..BPAPAA.A.. - ....JPPA.PPA.... - ................ -} -# tile 773 (hunter,female) -{ - ................ - ................ - ................ - ....J..CJA...... - ...J..CJJJA..... - ...J..JEEJA..... - ..J...JLLJA..... - ..J...ALLAA..... - ..J..GGAAGG.AAA. - ..LPBPFFFFPPAAA. - ..J..AGFFFAPAAA. - ..J....FF.ALAAA. - ...J..BP.PAAAA.. - ...J..BPAPAA.A.. - ....JPPA.PPA.... - ................ -} -# tile 774 (thug,male) -{ - ................ - ................ - ................ - .......ID....... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - .....KKAAKKA..A. - ....KKJKKJJKAAA. - ....KAAJJAAKAA.. - ....LAJJJJALAA.. - ......KKJKAAAA.. - ......KAAKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 775 (thug,female) -{ - ................ - ................ - ................ - .......ID....... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - .....KKAAKKA..A. - ....KKJKKJJKAAA. - ....KAAJJAAKAA.. - ....LAJJJJALAA.. - ......KKJKAAAA.. - ......KAAKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 776 (ninja,male) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....AFLFLA..... - .....AAAAAA..... - ......AAAA...... - ....AAAAAAAA.PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 777 (ninja,female) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....AFLFLA..... - .....AAAAAA..... - ......AAAA...... - ....AAAAAAAA.PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 778 (roshi,male) -{ - ................ - ................ - ................ - .......AAAAA.... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....PPPAAPPPAAA. - ....L.PPPP.LAAA. - ....LAOOOOALAAA. - ....LAOOOOALAAA. - ......P...AAAA.. - ......P.A.AA.A.. - .....PPA.PPA.... - ................ -} -# tile 779 (roshi,female) -{ - ................ - ................ - ................ - .......AAAAA.... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....PPPAAPPPAAA. - ....L.PPPP.LAAA. - ....LAOOOOALAAA. - ....LAOOOOALAAA. - ......P...AAAA.. - ......P.A.AA.A.. - .....PPA.PPA.... - ................ -} -# tile 780 (guide,male) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HHAAHH.AAA. - ....LLHHHHLLAAA. - ....LAHHHHALAAA. - ....LAHHHHALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 781 (guide,female) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HHAAHH.AAA. - ....LLHHHHLLAAA. - ....LAHHHHALAAA. - ....LAHHHHALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 782 (warrior,male) -{ - .....O....O..... - .....NO..ON..... - ......NPPN...... - .....PPPPPP..... - .....PELELP..... - ....HHLLLLH..... - ...HHHALLA...... - ...HJKJAAKJJAAA. - ..HHLJJKKJJLAAA. - ..H.LACKJCALAAA. - ....LAAKKAALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ -} -# tile 783 (warrior,female) -{ - .....O....O..... - .....NO..ON..... - ......NPPN...... - .....PPPPPP..... - .....PELELP..... - ....HHLLLLH..... - ...HHHALLA...... - ...HJKJAAKJJAAA. - ..HHLJJKKJJLAAA. - ..H.LACKJCALAAA. - ....LAAKKAALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ -} -# tile 784 (apprentice,male) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......GLG....... - .....BLLLE...... - .....BBEEEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 785 (apprentice,female) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......GLG....... - .....BLLLE...... - .....BBEEEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 786 (invisible monster, nogender) -{ - ................ - ................ - .....NNNN....... - ....NNNNNN...... - ...NNAAAANN..... - ...NNA...NNA.... - ....AA...NNA.... - ........NNAA.... - .......NNAA..... - ......NNAA...... - ......NNA....... - .......AA....... - ......NN........ - ......NNA....... - .......AA....... - ................ -} From 19583adca9a41e49dffcf01d22fc3e6775fd2706 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 21:31:31 -0500 Subject: [PATCH 695/708] another extraneous file --- win/share/m16807 | 14944 --------------------------------------------- 1 file changed, 14944 deletions(-) delete mode 100644 win/share/m16807 diff --git a/win/share/m16807 b/win/share/m16807 deleted file mode 100644 index a7e97fa09..000000000 --- a/win/share/m16807 +++ /dev/null @@ -1,14944 +0,0 @@ -. = (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) -# tile 0 (giant ant,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......JAJKKA... - .....JAAAKJJJA.. - .....AKJJAJJAA.. - ...KKAJJJAAA.... - ..BJJAAAAAJJA... - ..JBJAJAJAA..... - .....AJA.JA..... - ......JA.JA..... - ................ -} -# tile 1 (giant ant,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......J......... - ......AJAJKKA... - ....JJAAAKJJJA.. - ....AAKJJAJJAA.. - ...KKAJJJAAA.... - ..BJJAAAAAJJ.... - ..JBJAJAJAAAJ... - .....AJA.JA..... - ......JA.JA..... - ................ -} -# tile 2 (killer bee,male) -{ - ................ - ................ - .PPP.....PP..... - PPPPP...PBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAA.. - ABJBBJJJJAHAHH.. - .JJABJAJ.J.HH... - .......J.J...... - ................ - ...AAAAAAAAAAA.. - .....AAAAAA..... - ................ -} -# tile 3 (killer bee,female) -{ - ................ - ................ - .PPP.....PP..... - PPPPP...PBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAA.. - ABJBBJJJJAHAHH.. - .JJABJAJ.J.HH... - .......J.J...... - ................ - ...AAAAAAAAAAA.. - .....AAAAAA..... - ................ -} -# tile 4 (soldier ant,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......JAJKKA... - .....JAAAKJJJA.. - .....AKJJAJJAA.. - .JJKKAJJJAAA.... - JBJJJAAAAAJJA... - JJJBJAJAJAA..... - JAAJJAJA.JA..... - ..JJAAJA.JA..... - ................ -} -# tile 5 (soldier ant,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ......JJAJKKA... - ....JJAAAKJJJA.. - ....AAKJJAJJAA.. - .JJKKAJJJAAA.... - JBJJJAAAAAJJ.... - JJJBJAJAJAAAJ... - JAAJJAJA.JA..... - ..JJAAJA.JA..... - ................ -} -# tile 6 (fire ant,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......DACCCA... - .....DAAACDDDA.. - .....ACDDADDAA.. - ...CCADDDAAA.... - ..GDDAAAAADDA... - ..DGDADADAA..... - .....ADA.DA..... - ......DA.DA..... - ................ -} -# tile 7 (fire ant,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......D......... - ......ADACCCA... - ....DDAAACDDDA.. - ....AACDDADDAA.. - ...CCADDDAAA.... - ..GDDAAAAADD.... - ..DGDADADAAAD... - .....ADA.DA..... - ......DA.DA..... - ................ -} -# tile 8 (giant beetle,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......KKDKK..... - ....KACLCJJD.... - ...KCLCJJDDDK... - ...DCCJDADDAD... - ...ADJDDDDDDD... - ...BAKDDAADKAA.. - ...ABAKDDK...... - ......AA.AA..... - ................ - ................ -} -# tile 9 (giant beetle,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ......KKDKK..... - ....KACLCJJD.... - ...KCLCJJDDDK... - ...DCCJDADDAD... - ...ADJDDDDDDD... - ...BAKDDAADKAA.. - ...ABAKDDK...... - ......AA.AA..... - ................ - ................ -} -# tile 10 (queen bee,male) -{ - ................ - .PPP.....PP..... - PPPPP...PPPP.... - PPPPP..PPBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAAH. - ABJBBJJJJAHAHHH. - .JJABJAJ.JHHHAA. - ...J...J.JAAAHH. - ..JJ..JJ.J.HHAH. - ..JAAAJAAJ..HH.. - .....AAAAAA..... - ................ -} -# tile 11 (queen bee,female) -{ - ................ - .PPP.....PP..... - PPPPP...PPPP.... - PPPPP..PPBPP.... - PBPPP..PBPPP.... - .PPBP.PPLPLL.... - ...PP.PLLALHAH.. - ...AKKKLAHAAHH.. - BBJJJJJJJAHHAAH. - ABJBBJJJJAHAHHH. - .JJABJAJ.JHHHAA. - ...J...J.JAAAHH. - ..JJ..JJ.J.HHAH. - ..JAAAJAAJ..HH.. - .....AAAAAA..... - ................ -} -# tile 12 (acid blob,male) -{ - ................ - ................ - ................ - .....KDDA....... - ...DDKDDKA...... - .DDDIIIDJDA..... - D.IIOOIIDAIA.... - .DKNNNODIDA..IA. - IDJNANOJDDJA.... - ADIDNOIDIDDDA... - ...JDIKIADKIA... - .IA.IDID.JDA.... - ...I.DDA....DA.. - .........IA..... - ..IA............ - ................ -} -# tile 13 (acid blob,female) -{ - ................ - ................ - ................ - .....KDDA....... - ...DDKDDKA...... - .DDDIIIDJDA..... - D.IIOOIIDAIA.... - .DKNNNODIDA..IA. - IDJNANOJDDJA.... - ADIDNOIDIDDDA... - ...JDIKIADKIA... - .IA.IDID.JDA.... - ...I.DDA....DA.. - .........IA..... - ..IA............ - ................ -} -# tile 14 (quivering blob,male) -{ - ................ - ................ - .....PPPP....... - .........P...... - .P.OOOPPE..AAA.. - P.OPBBBPOEAEAA.. - P.PBNNNP.OEAAEA. - P.PNNNNNPOEEAEA. - POPNAANNEO.OAEA. - .OPNAANNE..OAAA. - .OPBNNNEPP.OEAA. - BPOPEEEBBPO.EEA. - BBBPBBBBBBPPPPA. - ..BBBBBBBBBBPA.. - ................ - ................ -} -# tile 15 (quivering blob,female) -{ - ................ - ................ - .....PPPP....... - .........P...... - .P.OOOPPE..AAA.. - P.OPBBBPOEAEAA.. - P.PBNNNP.OEAAEA. - P.PNNNNNPOEEAEA. - POPNAANNEO.OAEA. - .OPNAANNE..OAAA. - .OPBNNNEPP.OEAA. - BPOPEEEBBPO.EEA. - BBBPBBBBBBPPPPA. - ..BBBBBBBBBBPA.. - ................ - ................ -} -# tile 16 (gelatinous cube,male) -{ - ................ - ................ - ................ - ................ - ................ - .......LLL...... - .....LLLLLLLL... - ...LLLLLLLLLD... - ...CLLLLLLLDDA.. - ...CGGCLLLDDDAA. - ...CAGCGGDDDDAAA - ...CCCCAGDDDAAAA - .....CCCCDDAAAA. - .......CCDAAA... - ................ - ................ -} -# tile 17 (gelatinous cube,female) -{ - ................ - ................ - ................ - ................ - ................ - .......LLL...... - .....LLLLLLLL... - ...LLLLLLLLLD... - ...CLLLLLLLDDA.. - ...CGGCLLLDDDAA. - ...CAGCGGDDDDAAA - ...CCCCAGDDDAAAA - .....CCCCDDAAAA. - .......CCDAAA... - ................ - ................ -} -# tile 18 (chickatrice,male) -{ - ................ - ................ - ................ - ................ - .......OO....... - ......HAOO...... - .....HHOOH.HHA.. - ........OOHOA... - ........OOFA.... - ........FGGFA... - ........AGFGAA.. - ...........GA... - .......F..FFA... - .......AFFAA.... - ........AA...... - ................ -} -# tile 19 (chickatrice,female) -{ - ................ - ................ - ................ - ................ - .......OO....... - ......HAOO...... - .....HHOOH.HHA.. - ........OOHOA... - ........OOFA.... - ........FGGFA... - ........AGFGAA.. - ...........GA... - .......F..FFA... - .......AFFAA.... - ........AA...... - ................ -} -# tile 20 (cockatrice,male) -{ - ................ - ...D.DD......... - ....DD.......... - ....NL..AA...... - ..HHAN.AAA...... - .HH.NO..AAAA.... - ...AOOLFFFAA.... - ...OOLKGGFFAA... - ...AOAGGFGFFAA.. - .......GFFGFAA.. - .........FGGAA.. - .....FA...FFA... - ....FA....FFA... - ....FA..FFFA.... - .....FFFFA...... - ................ -} -# tile 21 (cockatrice,female) -{ - ................ - ...D.DD......... - ....DD.......... - ....NL..AA...... - ..HHAN.AAA...... - .HH.NO..AAAA.... - ...AOOLFFFAA.... - ...OOLKGGFFAA... - ...AOAGGFGFFAA.. - .......GFFGFAA.. - .........FGGAA.. - .....FA...FFA... - ....FA....FFA... - ....FA..FFFA.... - .....FFFFA...... - ................ -} -# tile 22 (pyrolisk,male) -{ - ................ - ...D.DD......... - ....DD.......... - ....NB..AA...... - ..HHAN.AAA...... - .HH.NB..AAAA.... - ...APBBJJJAA.... - ...PPPKDDKJAA... - ...APADDKDKJAA.. - .......DJKDJAA.. - .........JDDAA.. - .....JA...JJA... - ....JA....JJA... - ....KA..KKKA.... - .....JKKKA...... - ................ -} -# tile 23 (pyrolisk,female) -{ - ................ - ...D.DD......... - ....DD.......... - ....NB..AA...... - ..HHAN.AAA...... - .HH.NB..AAAA.... - ...APBBJJJAA.... - ...PPPKDDKJAA... - ...APADDKDKJAA.. - .......DJKDJAA.. - .........JDDAA.. - .....JA...JJA... - ....JA....JJA... - ....KA..KKKA.... - .....JKKKA...... - ................ -} -# tile 24 (jackal,male) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOAOOOOOOOAA.. - ..AAOOOOOOOOAA.. - ....OJOOOOOLAA.. - ....OJOLKALKAA.. - ...OOAOAAAOAA... - .....OO..OOA.... - ................ -} -# tile 25 (jackal,female) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOAOOOOOOOAA.. - ..AAOOOOOOOOAA.. - ....OJOOOOOLAA.. - ....OJOLKALKAA.. - ...OOAOAAAOAA... - .....OO..OOA.... - ................ -} -# tile 26 (fox,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....C........... - ....C........... - ..CCAC...CCC.... - ..ACCCCCCACCC... - ...AACCCC.ACC... - ....ACAAC..AA... - ...AC.ACA....... - ................ -} -# tile 27 (fox,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....C........... - ....C........... - ..CCAC...CCC.... - ..ACCCCCCACCC... - ...AACCCC.ACC... - ....ACAAC..AA... - ...AC.ACA....... - ................ -} -# tile 28 (coyote,male) -{ - ................ - ................ - ................ - ...K..K......... - ...K.KK......KKK - ..KKKK......KKKA - ..NCNK.KKKKKAAA. - .KCCKKKKKKKKK... - KKCKAKKKKKKKK... - DKKKAKAKKKKAK... - ..AAKAAKAAAAK... - ....AKAKAAAAK... - ...AKKAKA.AKK... - .....AKK........ - ................ - ................ -} -# tile 29 (coyote,female) -{ - ................ - ................ - ................ - ...K..K......... - ...K.KK......KKK - ..KKKK......KKKA - ..NCNK.KKKKKAAA. - .KCCKKKKKKKKK... - KKCKAKKKKKKKK... - DKKKAKAKKKKAK... - ..AAKAAKAAAAK... - ....AKAKAAAAK... - ...AKKAKA.AKK... - .....AKK........ - ................ - ................ -} -# tile 30 (werejackal,male) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOALLOOOOOAA.. - ..AALLLLOOOOAA.. - ....LJLLLOOLAA.. - ....LJLLKALKAA.. - ..LLLALAAAOAA... - ...L.LL..OOA.... - ......L......... -} -# tile 31 (werejackal,female) -{ - ................ - ................ - ................ - ................ - ...O..O......... - ...O.OO...O..... - ..OOOO.....O.... - ..IOIOO....O.A.. - .OLLOOOL...O.A.. - DOOOALLOOOOOAA.. - ..AALLLLOOOOAA.. - ....LJLLLOOLAA.. - ....LJLLKALKAA.. - ..LLLALAAAOAA... - ...L.LL..OOA.... - ......L......... -} -# tile 32 (little dog,male) -{ - ................ - ................ - ................ - ................ - ...J..J......... - ...J.JJ...K..... - ..JJJJ.....K.... - ..NJNKK....K.A.. - .JJJCKK....K.A.. - .PJJAKCKKCKKAA.. - .DDAACKKCKKKAA.. - ....KJKJCJKJAA.. - ....KJKJJAJJAA.. - ...KKAKAAAKAA... - .....KK...KA.... - ................ -} -# tile 33 (little dog,female) -{ - ................ - ................ - ................ - ................ - ...J..J......... - ...J.JJ...K..... - ..JJJJ.....K.... - ..NJNKK....K.A.. - .JJJCKK....K.A.. - .PJJAKCKKCKKAA.. - .DDAACKKCKKKAA.. - ....KJKJCJKJAA.. - ....KJKJJAJJAA.. - ...KKAKAAAKAA... - .....KK...KA.... - ................ -} -# tile 34 (dingo,male) -{ - ................ - ................ - ................ - .............C.. - ...C..C.......C. - ...C.CC.......CA - ..CCCCK.......CA - ..ACACCKCCCCCCAA - ..LLCCCKCCCLCCCA - .KCCACKCLLLLACCA - ..AACAACLLAAACCA - ....ACACAAAAAACA - ....CCACAAA..CCA - .....ACCA....... - ................ - ................ -} -# tile 35 (dingo,female) -{ - ................ - ................ - ................ - .............C.. - ...C..C.......C. - ...C.CC.......CA - ..CCCCK.......CA - ..ACACCKCCCCCCAA - ..LLCCCKCCCLCCCA - .KCCACKCLLLLACCA - ..AACAACLLAAACCA - ....ACACAAAAAACA - ....CCACAAA..CCA - .....ACCA....... - ................ - ................ -} -# tile 36 (dog,male) -{ - ................ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKK......K.A - .JJJCKKKK....K.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ....KJKKJJJAJJAA - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 37 (dog,female) -{ - ................ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKK......K.A - .JJJCKKKK....K.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ....KJKKJJJAJJAA - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 38 (large dog,male) -{ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKKK.....K.A - .JJJCKKKKK..JK.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ...JKJKKJJJAJJAA - ....KAKJAAAAKJA. - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 39 (large dog,female) -{ - ................ - ................ - ...J..J.....K... - ...J.JJ......K.. - ..JJJJ.......K.. - ..NJNKKK.....K.A - .JJJCKKKKK..JK.A - .PJCAKCKKKKCKKAA - .DDAACKKKKCKKKAA - ..AAKJKKJJCJKJAA - ...JKJKKJJJAJJAA - ....KAKJAAAAKJA. - ....KAKJAAAAKJA. - ...KKAKAAAAAKAA. - .....KKAA...KA.. - ................ -} -# tile 40 (wolf,male) -{ - ................ - ................ - ................ - ...P..P.....P... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPAPPPPPPPPPAA - ..AAP.PP..P.P.AA - ....P.PP...A.PAA - ....PAP.AAAAP.A. - ...PPAPAAAAAPAA. - .....PPAA..PPA.. - ................ -} -# tile 41 (wolf,female) -{ - ................ - ................ - ................ - ...P..P......... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPAPPPPPPPPPAA - ..AAP.PP..P.P.AA - ....P.PP...A.PAA - ....PAP.AAAAP.A. - ...PPAPAAAAAPAA. - .....PPAA..PPA.. - ................ -} -# tile 42 (werewolf,male) -{ - ................ - ................ - ................ - ...P..P.....P... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPALPPPPPPPPAA - ..AALLPL..P.P.AA - ....L.LL...A.PAA - ....LAL.AAAAP.A. - ..LLLALAAAAAPPA. - ...L.LLAA..PP... - .....LL......... -} -# tile 43 (werewolf,female) -{ - ................ - ................ - ................ - ...P..P......... - ...P.PP......P.. - ..PPPP.......P.. - ..N.NPP......P.A - .P..PPPPP....P.A - PP.PAPPPPPPPPPAA - DPPPALPPPPPPPPAA - ..AALLPL..P.P.AA - ....L.LL...A.PAA - ....LAL.AAAAP.A. - ..LLLALAAAAAPPA. - ...L.LLAA..PP... - .....LL......... -} -# tile 44 (winter wolf cub,male) -{ - ................ - ................ - ................ - ................ - ...N..N......... - ...N.NB...N..... - ..NNNN.....N.... - ..DNDNB....N.A.. - ..NNNNB....N.A.. - .NNNNNNNNNNNAA.. - .DNBBNNNNNNBAA.. - ....NNNNNNNBAA.. - ....NNNBBANBAA.. - ...NBANAAANAA... - .....NB..NBA.... - ................ -} -# tile 45 (winter wolf cub,female) -{ - ................ - ................ - ................ - ................ - ...N..N......... - ...N.NB......... - ..NNNN.....N.... - ..DNDNB....N.A.. - ..NNNNB....N.A.. - .NNNNNNNNNNNAA.. - .DNBBNNNNNNBAA.. - ....NNNNNNNBAA.. - ....NNNBBANBAA.. - ...NBANAAANAA... - .....NB..NBA.... - ................ -} -# tile 46 (warg,male) -{ - ................ - ...P..P....PP... - ...P.PP......P.. - ..PPPP.......P.A - ..N.NPP......P.A - .P..PPPPP....P.A - PPPPDPPPPPPPPPAA - DPPNDPPPPPPPPPAA - ..DDDPPPPPPPPPAA - PNDNP.PPPPPPPPAA - .PPPPAPPPPAPP.A. - ...PAAPPAAAAPPAA - ...PAAP.AAAAP.A. - .PPPAAPAAAAAPAA. - ....PPPAA.PPPA.. - ................ -} -# tile 47 (warg,female) -{ - ................ - ...P..P.....P... - ...P.PP......P.. - ..PPPP.......P.A - ..N.NPP......P.A - .P..PPPPP....P.A - PPPPDPPPPPPPPPAA - DPPNDPPPPPPPPPAA - ..DDDPPPPPPPPPAA - PNDNP.PPPPPPPPAA - .PPPPAPPPPAPP.A. - ...PAAPPAAAAPPAA - ...PAAP.AAAAP.A. - .PPPAAPAAAAAPAA. - ....PPPAA.PPPA.. - ................ -} -# tile 48 (winter wolf,male) -{ - ................ - ................ - ................ - ...N..N.....N... - ...N.NN......N.. - ..NNNN.......N.. - ..DODNN......N.A - .NOONNNNN....N.A - NNONANNNNNNNNNAA - DNNBANNNNNNNNNAA - ..AANNNNNNNBNNAA - ....NBNNNBBANNAA - ....NANBAAAANBA. - ...NNANAAAAANAA. - .....NNAA..NNA.. - ................ -} -# tile 49 (winter wolf,female) -{ - ................ - ................ - ................ - ...N..N......... - ...N.NN......N.. - ..NNNN.......N.. - ..DODNN......N.A - .NOONNNNN....N.A - NNONANNNNNNNNNAA - DNNBANNNNNNNNNAA - ..AANNNNNNNBNNAA - ....NBNNNBBANNAA - ....NANBAAAANBA. - ...NNANAAAAANAA. - .....NNAA..NNA.. - ................ -} -# tile 50 (hell hound pup,male) -{ - ................ - ................ - ................ - ................ - ...C..C......... - ...C.CC...C..... - ..CCCC.....C.... - ..DCDCC....C.A.. - .CCCCCC....C.A.. - .PCCACCCCCCCAA.. - .CHAACCCCCCCAA.. - CHC.CCCCCCCCAA.. - .D..CCCCCACCAA.. - ...CCACAAACAA... - .....CC...CA.... - ................ -} -# tile 51 (hell hound pup,female) -{ - ................ - ................ - ................ - ................ - ...C..C......... - ...C.CC...C..... - ..CCCC.....C.... - ..DCDCC....C.A.. - .CCCCCC....C.A.. - .PCCACCCCCCCAA.. - .CHAACCCCCCCAA.. - CHC.CCCCCCCCAA.. - .D..CCCCCACCAA.. - ...CCACAAACAA... - .....CC...CA.... - ................ -} -# tile 52 (hell hound,male) -{ - ................ - ...C..C....CC... - ...C.CC......C.. - ..CCCC.......C.A - ..DJDCC......C.A - .CCCCCCCC....C.A - CCCCDCCCCCCCCCAA - .CHC.CCCCCCCCCAA - CHC..CCCCCCCCCAA - .D..CCCCCCCCCCAA - ...CCACCCCACC.A. - ...CAACCAAAACCAA - ...CAAC.AAAAC.A. - .CCCAACAAAAACAA. - ....CCCAA.CCCA.. - ................ -} -# tile 53 (hell hound,female) -{ - ................ - ...C..C....CC... - ...C.CC......C.. - ..CCCC.......C.A - ..DJDCC......C.A - .CCCCCCCC....C.A - CCCCDCCCCCCCCCAA - .CHC.CCCCCCCCCAA - CHC..CCCCCCCCCAA - .D..CCCCCCCCCCAA - ...CCACCCCACC.A. - ...CAACCAAAACCAA - ...CAAC.AAAAC.A. - .CCCAACAAAAACAA. - ....CCCAA.CCCA.. - ................ -} -# tile 54 (Cerberus,male) -{ - ................ - ..J..J.......... - ..JJJJ.J..J..... - .NJNJ..J.JJ..... - JJJJKAJJJJ....J. - PJJJJANJNKK...J. - DJKJAJJJKJJK..J. - ..AAJPJKAJKJKJJ. - ..JJJDDAJKJJJJJA - ..JJJAAJJJJJJJJA - .JKKKJJJKJJKJJAA - .JJAAKJJKJJJKJAA - JJAAAAJJAAAAJJA. - JAAAAAJAAAAAJAA. - .....JJAA...JA.. - ................ -} -# tile 55 (Cerberus,female) -{ - ................ - ..J..J.......... - ..JJJJ.J..J..... - .NJNJ..J.JJ..... - JJJJKAJJJJ....J. - PJJJJANJNKK...J. - DJKJAJJJKJJK..J. - ..AAJPJKAJKJKJJ. - ..JJJDDAJKJJJJJA - ..JJJAAJJJJJJJJA - .JKKKJJJKJJKJJAA - .JJAAKJJKJJJKJAA - JJAAAAJJAAAAJJA. - JAAAAAJAAAAAJAA. - .....JJAA...JA.. - ................ -} -# tile 56 (gas spore,male) -{ - ................ - ................ - ................ - .....PFGGFP..... - ....PGFFFFFP.... - ...PFFFFFGGFP... - ...FFGGFFGGFF... - ...GFGGFFFFFG... - ...GFFFFFFFFG... - ...FFFFGGFFFF... - ...PGGFGGFGGP... - ....PGFFFFGP.... - .....PFGGFP..... - ................ - ................ - ................ -} -# tile 57 (gas spore,female) -{ - ................ - ................ - ................ - .....PFGGFP..... - ....PGFFFFFP.... - ...PFFFFFGGFP... - ...FFGGFFGGFF... - ...GFGGFFFFFG... - ...GFFFFFFFFG... - ...FFFFGGFFFF... - ...PGGFGGFGGP... - ....PGFFFFGP.... - .....PFGGFP..... - ................ - ................ - ................ -} -# tile 58 (floating eye,male) -{ - ................ - ................ - ......ONNNO..... - ....PNNNNNNNP... - ....NNNNNNNNN... - ...ONNBBBBNNNO.. - ...NNBBEEBBNNN.. - ...NNBEAAEBNNN.. - ...ONBEAAEBNNO.. - ....NBBEEBBNN... - ....PNBBBBNNPAA. - ......ONNNOAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 59 (floating eye,female) -{ - ................ - ................ - ......ONNNO..... - ....PNNNNNNNP... - ....NNNNNNNNN... - ...ONNBBBBNNNO.. - ...NNBBEEBBNNN.. - ...NNBEAAEBNNN.. - ...ONBEAAEBNNO.. - ....NBBEEBBNN... - ....PNBBBBNNPAA. - ......ONNNOAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 60 (freezing sphere,male) -{ - ................ - ................ - ......PBBBP..... - ....PBBBBBBBP... - ....BBBBBBBBB... - ...PBPPPBBBBBP.. - ...BBNNBBPPPBB.. - ...BBANPBNNBBB.. - ...PBBPPBANPBP.. - ....BBBBBBPPB... - ....PBBBBBBBPAA. - ......PBBBPAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 61 (freezing sphere,female) -{ - ................ - ................ - ......PBBBP..... - ....PBBBBBBBP... - ....BBBBBBBBB... - ...PBPPPBBBBBP.. - ...BBNNBBPPPBB.. - ...BBANPBNNBBB.. - ...PBBPPBANPBP.. - ....BBBBBBPPB... - ....PBBBBBBBPAA. - ......PBBBPAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 62 (flaming sphere,male) -{ - ................ - ....C...H....... - ....C....O...C.. - ...C..H.CC...C.. - ...C..C.CC..CC.. - ...DCA.DDC.ACC.. - .AHCDCADDCAADC.. - .AACDCDDDDDADD.. - ..ACDDDJJJDDDD.. - ..ADDCAKDDACDD.. - ...ADAKDDCDAD... - ...ADADHCHCAD... - ....DADDDCDAD... - .....DADDDAD.... - ......JJJJJ..... - ................ -} -# tile 63 (flaming sphere,female) -{ - ................ - ....C...H....... - ....C....O...C.. - ...C..H.CC...C.. - ...C..C.CC..CC.. - ...DCA.DDC.ACC.. - .AHCDCADDCAADC.. - .AACDCDDDDDADD.. - ..ACDDDJJJDDDD.. - ..ADDCAKDDACDD.. - ...ADAKDDCDAD... - ...ADADHCHCAD... - ....DADDDCDAD... - .....DADDDAD.... - ......JJJJJ..... - ................ -} -# tile 64 (shocking sphere,male) -{ - ................ - .....PPPPPP..... - ...PPIAAADAPP... - ..PAAAIAAADDAP.. - ..PHAAAPBOAAAP.. - .PAHHAPBBBOAAAP. - .PHAAAPBBBBAHHP. - .PAAAAPPBBBAAAP. - .PAAAIAPPPAAAIP. - .PIIIAAAAAAIIAP. - ..PIAANAAPAAAIP. - ..PIAANAAAPAAP.. - ...PANANAPAPAP.. - ....PPAIAPAPP... - ......PPPPP..... - ................ -} -# tile 65 (shocking sphere,female) -{ - ................ - .....PPPPPP..... - ...PPIAAADAPP... - ..PAAAIAAADDAP.. - ..PHAAAPBOAAAP.. - .PAHHAPBBBOAAAP. - .PHAAAPBBBBAHHP. - .PAAAAPPBBBAAAP. - .PAAAIAPPPAAAIP. - .PIIIAAAAAAIIAP. - ..PIAANAAPAAAIP. - ..PIAANAAAPAAP.. - ...PANANAPAPAP.. - ....PPAIAPAPP... - ......PPPPP..... - ................ -} -# tile 66 (beholder,male) -{ - ....OA..OA...... - ..OA.DADA.OA.OA. - ...DA.DADADADD.. - ..OADDOOOODDADO. - ...DDHOAAOHDDA.. - ...JDHOAAOHDDJ.. - ...DDDOOOODDDD.. - ...DDDDDDDDDDD.. - ...JDAOAAAOADJ.. - ....DDAAOAADD... - ....PDDDDDDDPAA. - ......JDDDJAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 67 (beholder,female) -{ - ....OA..OA...... - ..OA.DADA.OA.OA. - ...DA.DADADADD.. - ..OADDOOOODDADO. - ...DDHOAAOHDDA.. - ...JDHOAAOHDDJ.. - ...DDDOOOODDDD.. - ...DDDDDDDDDDD.. - ...JDAOAAAOADJ.. - ....DDAAOAADD... - ....PDDDDDDDPAA. - ......JDDDJAAAA. - ......AAAAAAAAA. - .......AAAAAAA.. - ................ - ................ -} -# tile 68 (kitten,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ...........K.... - ............C... - ....C.C.....L.A. - ...CCCCJ....C.A. - ...NCNCJCCLCL.A. - ...CCCCJCCLCCAA. - ....IACCLLCCCAA. - .....CACCJCCJA.. - ......CCA..CA... - ................ -} -# tile 69 (kitten,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ...........N.... - ............N... - ....N.N.....C.A. - ...NNNNC....C.A. - ...ENENNNJJNC.A. - ...NNNNNJJJNNAA. - ....IANNJJNNNAA. - .....NANNWNNWA.. - ......NNA..NA... - ................ -} -# tile 70 (housecat,male) -{ - ................ - ................ - ................ - ................ - ................ - ...........K.... - ............C... - ...C.C......L.A. - ..CCCCJ.....C.A. - .CNCNCJCLCLCL.A. - .CCCCCJCLCLCCAA. - ..CICJCCLCLCLAA. - ...AACCLCLCCCAA. - ...CCACCJJCCJA.. - .....CCA...CA... - ................ -} -# tile 71 (housecat,female) -{ - ................ - ................ - ................ - ................ - ................ - ...........N.... - ............N... - ...N.N......C.A. - ..NNNNC.....C.A. - .NANANCNJJJNN.A. - .NNNNNNNJJNNNAA. - ..NINWNJJJNNNAA. - ...AANNNNNNNNAA. - ...NNANNWWNNWA.. - .....NNA...NA... - ................ -} -# tile 72 (jaguar,male) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - ..CC.CJ......C.A - .CCCCCJ......C.A - .GCGCCJCAACCJC.A - .CCCCCJCCCCCCCAA - .CDDDJCAACCAJCAA - ..CCACCAJCCAACAA - ....CACCJJJCCJA. - ....CACAAAAACJA. - ...CKACAAAAACAA. - .....CCAA...CA.. - ................ -} -# tile 73 (jaguar,female) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - ..CC.CJ......C.A - .CCCCCJ......C.A - .GCGCCJCAACCJC.A - .CCCCCJCCCCCCCAA - .CDDDJCAACCAJCAA - ..CCACCAJCCAACAA - ....CACCJJJCCJA. - ....CACAAAAACJA. - ...CKACAAAAACAA. - .....CCAA...CA.. - ................ -} -# tile 74 (lynx,male) -{ - ................ - ................ - ................ - ................ - O....O.......... - AC.CCA.......... - .CCCA........CA. - .GCGCOAKKKKK.LA. - .CKCCAJCCCCCKA.. - LLDDLLACLLLCCAA. - ..CC.AACLLLCCAA. - .......CAAAACAA. - ....CACAAAACCA.. - ................ - ................ - ................ -} -# tile 75 (lynx,female) -{ - ................ - ................ - ................ - ................ - O....O.......... - AC.CCA.......... - .CCCA........CA. - .GCGCOAKKKKK.LA. - .CKCCAJCCCCCKA.. - LLDDLLACLLLCCAA. - ..CC.AACLLLCCAA. - .......CAAAACAA. - ....CACAAAACCA.. - ................ - ................ - ................ -} -# tile 76 (panther,male) -{ - ................ - ................ - ............AA.. - ..............A. - ..............A. - .A...A........A. - .EA.AE........A. - .AAAAAEAAAAAAA.. - .AAAAAEAAAAAAA.. - .HAHAA.AAAAAAAA. - .AAAA.AAAAAEAAA. - .AAA..AAAAAEAAA. - .....AA....AAA.. - ..AAAA..AAAA.... - ................ - ................ -} -# tile 77 (panther,female) -{ - ................ - ................ - ............AA.. - ..............A. - ..............A. - .A...A........A. - .EA.AE........A. - .AAAAAEAAAAAAA.. - .AAAAAEAAAAAAA.. - .HAHAA.AAAAAAAA. - .AAAA.AAAAAEAAA. - .AAA..AAAAAEAAA. - .....AA....AAA.. - ..AAAA..AAAA.... - ................ - ................ -} -# tile 78 (large cat,male) -{ - ................ - ................ - ................ - ................ - ............K... - .............C.. - ...C.C.......L.A - ..CCCCJ......C.A - .CNCNCJCLCCLCL.A - .CCCCCJCLCCLCCAA - ..CDCJCCLCCLCLAA - ...AACCLCCLCCCAA - ....CACCJJJCCJA. - ...CKALAAAAACAA. - .....CCAA...CA.. - ................ -} -# tile 79 (large cat,female) -{ - ................ - ................ - ................ - ................ - ............N... - .............N.. - ...N.N.......C.A - ..NNNNC......C.A - .NANANCNJJJJNN.A - .NNNNNNNJJJNNNAA - ..NDNWNJJJNNNNAA - ...AANNNNNNNNNAA - ....NANNWWWNNWA. - ...NJANAAAAANAA. - .....NNAA...NA.. - ................ -} -# tile 80 (tiger,male) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - .CCJCC.......C.A - .CAACCJ......A.A - .GAGCCJACACAJC.A - .CCCCCACACACACAA - .ODOCACCACACACAA - .OCOACCJACACACAA - ....CACJAJAJCAA. - ....AACAAAAAAJA. - ...CKACAAAAACAA. - .....CCAA..CCA.. - ................ -} -# tile 81 (tiger,female) -{ - ................ - ................ - ................ - ................ - ..C..C......C... - .CCJCC.......C.A - .CAACCJ......A.A - .GAGCCJACACAJC.A - .CCCCCACACACACAA - .ODOCACCACACACAA - .OCOACCJACACACAA - ....CACJAJAJCAA. - ....AACAAAAAAJA. - ...CKACAAAAACAA. - .....CCAA..CCA.. - ................ -} -# tile 82 (displacer beast,male) -{ - ................ - ........E....... - .......E.E..AA.. - DEEEA..A.E....A. - ....EA.E.D....A. - .A...A.E......A. - .EA.AEAAA.....A. - .AAAAAAAAAA..A.. - .AAAAEAAAAAAAA.. - .HAHAEAAAAAAAAA. - .AAAAEAAAAAAAAA. - .AAA.AAAAAAAAAA. - .....AE.AEEA.EA. - ....AE.AE.EA.EA. - ...AE.AE.EA.EA.. - ................ -} -# tile 83 (displacer beast,female) -{ - ................ - ........E....... - .......E.E..AA.. - DEEEA..A.E....A. - ....EA.E.D....A. - .A...A.E......A. - .EA.AEAAA.....A. - .AAAAAAAAAA..A.. - .AAAAEAAAAAAAA.. - .HAHAEAAAAAAAAA. - .AAAAEAAAAAAAAA. - .AAA.AAAAAAAAAA. - .....AE.AEEA.EA. - ....AE.AE.EA.EA. - ...AE.AE.EA.EA.. - ................ -} -# tile 84 (gremlin,male) -{ - ................ - ................ - ................ - GGGA....AGGG.... - .GGGFAAAGGG..... - ..FFFFFFFF...... - ...NDFFDNA...... - ...GNFFNGA...... - ...GFFFFGA..AA.. - ...AGFFFAFAAAAA. - ..GFAGFAFFFAAAA. - .GFGFAAFFAFAAAA. - .GF.GFAGAAFAAAA. - ....FFAGFAA.AA.. - ...GFA.FGA...... - ................ -} -# tile 85 (gremlin,female) -{ - ................ - ................ - ................ - GGGA....AGGG.... - .GGGFAAAGGG..... - ..FFFFFFFF...... - ...NDFFDNA...... - ...GNFFNGA...... - ...GFFFFGA..AA.. - ...AGFFFAFAAAAA. - ..GFAGFAFFFAAAA. - .GFGFAAFFAFAAAA. - .GF.GFAGAAFAAAA. - ....FFAGFAA.AA.. - ...GFA.FGA...... - ................ -} -# tile 86 (gargoyle,male) -{ - ................ - ................ - ...PAPPPPAP..... - ..PA......AP.... - ..P.DD..DDAP.... - ....PD..DPA..... - ....P....PA..AA. - ....AP...A.AAAAA - ...P.AP.A...AAAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 87 (gargoyle,female) -{ - ................ - ................ - ...PAPPPPAP..... - ..PA......AP.... - ..P.DD..DDAP.... - ....PD..DPA..... - ....P....PA..AA. - ....AP...A.AAAAA - ...P.AP.A...AAAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 88 (winged gargoyle,male) -{ - ...K......K..... - ...KJ....KJ..... - ..KJAPPPPAJJ.... - ..KJ......AJ.... - ..KJDD..DDAJ.... - .KJAPD..DPAJJ... - .KJAP....PAAJAA. - KJA.AP...A.AJJAA - J..P.AP.A...AJAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 89 (winged gargoyle,female) -{ - ...K......K..... - ...KJ....KJ..... - ..KJAPPPPAJJ.... - ..KJ......AJ.... - ..KJDD..DDAJ.... - .KJAPD..DPAJJ... - .KJAP....PAAJAA. - KJA.AP...A.AJJAA - J..P.AP.A...AJAA - ..P.P.AA..A.AAAA - ..PA.P.APAA.AAAA - ..PA.P....A.AA.. - .....P....AAAA.. - .....P.AP.AA.... - ....PFA.FPA..... - ................ -} -# tile 90 (hobbit,male) -{ - ................ - ................ - ................ - ................ - ......JJA....... - .....JJJJA...... - ....JLFLFJ...... - ....JLLLLJ...... - ....JKLLKJJ.AA.. - ...CLLLLLLCAAA.. - ..CLALLLLALCA... - ..LLAJJKJALLA... - ...L.LKJLALAA... - .....LLALLA.A... - ....LLL.LLL..... - ................ -} -# tile 91 (hobbit,female) -{ - ................ - ................ - ................ - ................ - ......JJA....... - .....JJJJA...... - ....JLFLFJ...... - ....JLLLLJ...... - ....JKLLKJJ.AA.. - ...CLLLLLLCAAA.. - ..CLALJKJALCA... - ..LLAJJKJALLA... - ...L.LKJLALAA... - .....LLALLA.A... - ....LLL.LLL..... - ................ -} -# tile 92 (dwarf,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BLLLE....... - .....OLO...AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 93 (dwarf,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BLLLE....... - .....OLO...AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 94 (bugbear,male) -{ - ................ - ................ - ......K......... - .K..KKK......... - .KKKKKK......... - KADKADKKK....... - KKKKKKKJKK...... - KAPAPAKJJKJ..... - KAAAAAKKJKJJ.... - .KKKKKJKAKKJ.... - ..KAJJCAKKKJ.AA. - ..KK.KKKKKJJAA.. - ...C..KJAKJAA... - .....CCAAKJA.... - ........CCA..... - ................ -} -# tile 95 (bugbear,female) -{ - ................ - ................ - ......K......... - .K..KKK......... - .KKKKKK......... - KADKADKKK....... - KKKKKKKJKK...... - KAPAPAKJJKJ..... - KAAAAAKKJKJJ.... - .KKKKKJKAKKJ.... - ..KAJJCAKKKJ.AA. - ..KK.KKKKKJJAA.. - ...C..KJAKJAA... - .....CCAAKJA.... - ........CCA..... - ................ -} -# tile 96 (dwarf leader,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....HHHHH....... - ....BLLLE....... - ....BOLOE..AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 97 (dwarf leader,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....HHHHH....... - ....BLLLE....... - ....BOLOE..AAA.. - ...BBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 98 (dwarf ruler,male) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....BLLLE...A... - .....OLO...AAAA. - ...EBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 99 (dwarf ruler,female) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....BLLLE...A... - .....OLO...AAAA. - ...EBOOOEEAAAA.. - ...BABOEAEAAAA.. - ....LBBELAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 100 (mind flayer,male) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - ....IIIIIC...... - ....IAIAIF...... - ....IAIAIF...... - ....IAIAIFI..... - .....FIFIFIC.AA. - ....CBIBBF.CAAA. - ...IIIBBFFACAAA. - ......BBFCAAAA.. - ......CFFCAA.... - ....IIC.IIA..... -} -# tile 101 (mind flayer,female) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - ....IIIIIC...... - ....IAIAIF...... - ....IAIAIF...... - ....IAIAIFI..... - .....FIFIFIC.AA. - ....CBIBBF.CAAA. - ...IIIBBFFACAAA. - ......BBFCAAAA.. - ......CFFCAA.... - ....IIC.IIA..... -} -# tile 102 (master mind flayer,male) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - .EEEIIIIICEEEE.. - ..EEIAIAIEEEE... - ...EIAIAIEEE.... - ....IAIAIEEE.... - ....EFIFIEEE.AA. - ....CBIBBEEEAAA. - ...IIIBBEEEEAAA. - ....EEBEEEEAAA.. - ...EEECEEEAA.... - ....IIC.IIA..... -} -# tile 103 (master mind flayer,female) -{ - ................ - .......IIIIC.... - .....IIIIIIC.... - ....IIIIIIIC.... - ...IGIIIIGC..... - ...IIGINGIC..... - .EEEIIIIICEEEE.. - ..EEIAIAIEEEE... - ...EIAIAIEEE.... - ....IAIAIEEE.... - ....EFIFIEEE.AA. - ....CBIBBEEEAAA. - ...IIIBBEEEEAAA. - ....EEBEEEEAAA.. - ...EEECEEEAA.... - ....IIC.IIA..... -} -# tile 104 (manes,male) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP......... - ..PPPPP.PPP.P... - ..P..PPPP....... - ..P..PPPPP...P.. - ..PPPPP.PPP..... - ..P.P.P.PP.P.... - .P...P.PPPP..... - .P....PPP.PP.... - ..P....P.P.P.P.. - ........P....... - ................ - ................ -} -# tile 105 (manes,female) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP......... - ..PPPPP.PPP.P... - ..P..PPPP....... - ..P..PPPPP...P.. - ..PPPPP.PPP..... - ..P.P.P.PP.P.... - .P...P.PPPP..... - .P....PPP.PP.... - ..P....P.P.P.P.. - ........P....... - ................ - ................ -} -# tile 106 (homunculus,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ......JJJ....... - ......LLC....... - ......LLC....... - .....BBPPPAA.... - ....L.BPPACAA... - ......BAPAAAA... - .....LLALCA..... - ................ - ................ -} -# tile 107 (homunculus,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ......JJJ....... - ......LLC....... - ......LLC....... - .....BBPPPAA.... - ....L.BPPACAA... - ......BAPAAAA... - .....LLALCA..... - ................ - ................ -} -# tile 108 (imp,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDO...... - ......CDD....... - .....GGFFFAA.... - ....C.GFFADAA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 109 (imp,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDO...... - ......CDD....... - .....GGFFFAA.... - ....C.GFFADAA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 110 (lemure,male) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP....P.... - ..PPPPP..PP.P... - ..P..PPPPPPPP... - ..P..PPPPPPP.... - ..PPPPPPPPP..... - ....PPPPPPPP.... - ..PPPPPPPPPP.... - ...PPPPPPPPPP... - ..P.P..PPPP.PP.. - ........P.PP.... - ................ - ................ -} -# tile 111 (lemure,female) -{ - ................ - ................ - ....PP.......... - ...PPPP......... - ..PAPAP....P.... - ..PPPPP..PP.P... - ..P..PPPPPPPP... - ..P..PPPPPPP.... - ..PPPPPPPPP..... - ....PPPPPPPP.... - ..PPPPPPPPPP.... - ...PPPPPPPPPP... - ..P.P..PPPP.PP.. - ........P.PP.... - ................ - ................ -} -# tile 112 (quasit,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDOD..... - ......CDD.D..... - .....GGFFFAA.... - ....C.GFFAAADA.. - ....C.GFFJJDA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 113 (quasit,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .....O.D.O...... - .....OCDDOD..... - ......CDD.D..... - .....GGFFFAA.... - ....C.GFFAAADA.. - ....C.GFFJJDA... - ......GAFAAAA... - .....CDADDA..... - ................ - ................ -} -# tile 114 (tengu,male) -{ - ................ - .......PP....... - ......PPPP...... - .....DPPNP...... - ....DDDPPP...... - ....DDPPPP...... - ....D..PPA...... - .....PIAAIP.AAA. - ....PPPIIPPPAAA. - ....PAPPPPAPAAA. - ....PAHHHHAPAAA. - ....LAPPPPALAAA. - ......PPPPAAAA.. - ......PPPPAA.A.. - .....LLA.LLA.... - ................ -} -# tile 115 (tengu,female) -{ - ................ - .......PP....... - ......PPPP...... - .....DPPNP...... - ....DDDPPP...... - ....DDPPPP...... - ....D..PPA...... - .....PIAAIP.AAA. - ....PPPIIPPPAAA. - ....PAPPPPAPAAA. - ....PAHHHHAPAAA. - ....LAPPPPALAAA. - ......PPPPAAAA.. - ......PPPPAA.A.. - .....LLA.LLA.... - ................ -} -# tile 116 (blue jelly,male) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OBEBOE.... - ..OBEOBBEOBBE... - ..OBEOBBEOBBE... - ..BBBGGBGGBEEE.. - ..BBBAGBAGEEEEA. - ..BBBBBBEBEEEEAA - ...BBBBBBBEEEAAA - ....BBBBBEEEAAA. - ......BBBEEAA... - ................ - ................ -} -# tile 117 (blue jelly,female) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OBEBOE.... - ..OBEOBBEOBBE... - ..OBEOBBEOBBE... - ..BBBGGBGGBEEE.. - ..BBBAGBAGEEEEA. - ..BBBBBBEBEEEEAA - ...BBBBBBBEEEAAA - ....BBBBBEEEAAA. - ......BBBEEAA... - ................ - ................ -} -# tile 118 (spotted jelly,male) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OCEBOE.... - ..OCEOCCEOBCE... - ..OCEOBCEOCBD... - ..BBBHHBHHBEDD.. - ..CCBAHBAHEEEEA. - ..BBCBBBEBEEDEAA - ...BBBCBBBEEDAAA - ....BCCCBEEDAAA. - ......CCBEEAA... - ................ - ................ -} -# tile 119 (spotted jelly,female) -{ - ................ - ................ - ................ - .......E........ - ......OBE....... - ...BE.OCEBOE.... - ..OCEOCCEOBCE... - ..OCEOBCEOCBD... - ..BBBHHBHHBEDD.. - ..CCBAHBAHEEEEA. - ..BBCBBBEBEEDEAA - ...BBBCBBBEEDAAA - ....BCCCBEEDAAA. - ......CCBEEAA... - ................ - ................ -} -# tile 120 (ochre jelly,male) -{ - ................ - ................ - ................ - .......D........ - ......LCD....... - ...CD.LCDCLD.... - ..LCDLCCDLCCD... - ..LCDLCCDLCCD... - ..CCCGGCGGCDDD.. - ..CCCAGCAGDDDDA. - ..CCCCCCDCDDDDAA - ...CCCCCCCDDDAAA - ....CCCCCDDDAAA. - ......CCCDDAA... - ................ - ................ -} -# tile 121 (ochre jelly,female) -{ - ................ - ................ - ................ - .......D........ - ......LCD....... - ...CD.LCDCLD.... - ..LCDLCCDLCCD... - ..LCDLCCDLCCD... - ..CCCGGCGGCDDD.. - ..CCCAGCAGDDDDA. - ..CCCCCCDCDDDDAA - ...CCCCCCCDDDAAA - ....CCCCCDDDAAA. - ......CCCDDAA... - ................ - ................ -} -# tile 122 (kobold,male) -{ - ................ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.A.. - ..BPBBBBPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 123 (kobold,female) -{ - ................ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.A.. - ..BPBBBBPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 124 (large kobold,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.... - ..BPBBBBPAAA.A.. - ..BAPBPAPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 125 (large kobold,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NBPBN........ - ...BABAB........ - ....BBPA..A..... - ...BBABPA.AA.... - ..BPBBBBPAAA.A.. - ..BAPBPAPAAAAA.. - ..BAPBPAPAAAAA.. - ....PBPAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 126 (kobold leader,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NCCCN........ - ...CABAC........ - ...CBBPC..A..... - ..CCBABCC.AA.... - ..CCBBBCCAAA.A.. - ..BCCBCCPAAAAA.. - ..BACBCAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 127 (kobold leader,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NCCCN........ - ...CABAC........ - ...CBBPC..A..... - ..CCBABCC.AA.... - ..CCBBBCCAAA.A.. - ..BCCBCCPAAAAA.. - ..BACBCAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 128 (kobold shaman,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NHHHN........ - ...HABAH........ - ...HBBPH..A..... - ..HHBABHH.AA.... - .HHHBBBHHHAA.A.. - .HBHHBHHPHAAAA.. - ..BAHBHAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 129 (kobold shaman,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NHHHN........ - ...HABAH........ - ...HBBPH..A..... - ..HHBABHH.AA.... - .HHHBBBHHHAA.A.. - .HBHHBHHPHAAAA.. - ..BAHBHAPAAAAA.. - ....BBBAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 130 (leprechaun,male) -{ - ................ - ................ - ................ - ................ - ......G......... - ......F....K.... - .....GFF..KLK... - ....GFFFF..K.... - .....KLKA.GLAA.. - ...FGFJFFFAKA.A. - ...GAGFFAAAK.AA. - ....LKHKKJAKAA.. - ....GFAGKJAKA... - ...GFAA.GFAK.... - ................ - ................ -} -# tile 131 (leprechaun,female) -{ - ................ - ................ - ................ - ................ - ......G......... - ......F....K.... - .....GFF..KLK... - ....GFFFF..K.... - .....KLKA.GLAA.. - ...FGFLFFFAKA.A. - ...GAGFFAAAK.AA. - ....LKHKKJAKAA.. - ....GFAGKJAKA... - ...GFAA.GFAK.... - ................ - ................ -} -# tile 132 (small mimic,male) -{ - ................ - ................ - ................ - ................ - ......POP....... - ......NNO....... - ......NNO....... - .......OA....... - .....NNNNN..AA.. - ....OONNNOO.AA.. - ....NANOOANAAA.. - ......NAOAAAA... - ......NAOAA.A... - .....NN.OOA..... - ................ - ................ -} -# tile 133 (small mimic,female) -{ - ................ - ................ - ................ - ................ - ......POP....... - ......NNO....... - ......NNO....... - .......OA....... - .....NNNNN..AA.. - ....OONNNOO.AA.. - ....NANOOANAAA.. - ......NAOAAAA... - ......NAOAA.A... - .....NN.OOA..... - ................ - ................ -} -# tile 134 (large mimic,male) -{ - ................ - ................ - ................ - ......LLOA...... - ......NNOA...... - ......NNOA...... - ......ONOA...... - .....NNNNO..AAA. - ....OONNNOO.AAA. - ...NOANNNAOOAAA. - ...NAONONOANAAA. - .....NO.NOAAAA.. - .....NO.NOAA.A.. - ....NNO.NOOA.... - ................ - ................ -} -# tile 135 (large mimic,female) -{ - ................ - ................ - ................ - ......LLOA...... - ......NNOA...... - ......NNOA...... - ......ONOA...... - .....NNNNO..AAA. - ....OONNNOO.AAA. - ...NOANNNAOOAAA. - ...NAONONOANAAA. - .....NO.NOAAAA.. - .....NO.NOAA.A.. - ....NNO.NOOA.... - ................ - ................ -} -# tile 136 (giant mimic,male) -{ - ................ - ......NNO....... - .....NNNNOA..... - .....NNNNOA..... - .....NNNNOA..... - .....ONNNOA..... - ..PONNOOONOOPAAA - .PONONNNNOONOPAA - .ONOANNNNOAONOAA - .NNOANNNNOAOOOAA - ...AANNONNAAAAAA - ....PNO.NNPAAAAA - ....ONO.NNOAA..A - ....NNO.NNOAA..A - ...NNNO.NNOOA... - ................ -} -# tile 137 (giant mimic,female) -{ - ................ - ......NNO....... - .....NNNNOA..... - .....NNNNOA..... - .....NNNNOA..... - .....ONNNOA..... - ..PONNOOONOOPAAA - .PONONNNNOONOPAA - .ONOANNNNOAONOAA - .NNOANNNNOAOOOAA - ...AANNONNAAAAAA - ....PNO.NNPAAAAA - ....ONO.NNOAA..A - ....NNO.NNOAA..A - ...NNNO.NNOOA... - ................ -} -# tile 138 (wood nymph,male) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLFKKKKLA.... - .HKFLFKKKKA..... - OHKJFKKJJK.A.... - HKKLJJGKAAAAAAA. - .JJAJGDKJAAAAA.. - ..JA.KKJJAAAA... - ...J.KKKKJAA.... - ....JKKKKKJA.... - ....KJKJKJKJ.... - ................ -} -# tile 139 (wood nymph,female) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLFKKKKLA.... - .HKFLFKKKKA..... - OHKJFKKJJK.A.... - HKKLJJGKAAAAAAA. - .JJAJGDKJAAAAA.. - ..JA.KKJJAAAA... - ...J.KKKKJAA.... - ....JKKKKKJA.... - ....KJKJKJKJ.... - ................ -} -# tile 140 (water nymph,male) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLJBBBBLA.... - .HBJLJBBBBA..... - OHBPJBBPPB.A.... - HBBLPPNBAAAAAAA. - .PPAPNDB.AAAAA.. - ..PA.BBPPAAAA... - ...P.BBBBPAA.... - ....PBBBBBPA.... - ....BPBPBPBP.... - ................ -} -# tile 141 (water nymph,female) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLJBBBBLA.... - .HBJLJBBBBA..... - OHBPJBBPPB.A.... - HBBLPPNBAAAAAAA. - .PPAPNDB.AAAAA.. - ..PA.BBPPAAAA... - ...P.BBBBPAA.... - ....PBBBBBPA.... - ....BPBPBPBP.... - ................ -} -# tile 142 (mountain nymph,male) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLCOOOOLA.... - .HOCLCOOOOA..... - OHOLCOOLLO.A.... - HOOKLLIOAAAAAAA. - .LLALIBOKAAAAA.. - ..LA.OOLLAAAA... - ...L.OOOOLAA.... - ....LOOOOOLA.... - ....OLOLOLOL.... - ................ -} -# tile 143 (mountain nymph,female) -{ - ................ - ................ - ...OH........... - ..OHHL.......... - ..OHLL.......... - ..HHLA.......... - .OHLLCOOOOLA.... - .HOCLCOOOOA..... - OHOLCOOLLO.A.... - HOOKLLIOAAAAAAA. - .LLALIBOKAAAAA.. - ..LA.OOLLAAAA... - ...L.OOOOLAA.... - ....LOOOOOLA.... - ....OLOLOLOL.... - ................ -} -# tile 144 (goblin,male) -{ - ................ - ................ - ................ - ....LK.......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IGIGIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICJAAAAA... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 145 (goblin,female) -{ - ................ - ................ - ................ - ....LK.......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IGIGIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICJAAAAA... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 146 (hobgoblin,male) -{ - ................ - .....LK......... - ....CKA......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IHIHIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICCAAAAA... - ....IIIIJA...... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 147 (hobgoblin,female) -{ - ................ - .....LK......... - ....CKA......... - ...CJA.......... - ..KJA........... - .JJA.IIK...AA... - .IK.IHIHIJAA.... - J.ICKIIIJK...... - ...IIJJJK.A..... - ....KICCAAAAA... - ....IIIIJA...... - ....ICKKJA...... - ....IKAIJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 148 (orc,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KCCAKKKA.AA... - ..BPCKJ.P.AAA... - ..BAGGFAAPNO.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BJACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 149 (orc,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KCCAKKKA.AA... - ..BPCKJ.P.AAA... - ..BAGGFAAPNO.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BJACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 150 (hill orc,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LKLA........ - .....K.A........ - ..KGGAFFKA.AA... - ..JKGFF.K.AAA... - ..JAHHFAAKNO.... - ..JAGFFNOAAA.... - ....GNNFAAAAAA.. - ...GGAGFAAAA.... - ..KJJAKJJA...... - ................ - ................ -} -# tile 151 (hill orc,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LKLA........ - .....K.A........ - ..KGGAFFKA.AA... - ..JKGFF.K.AAA... - ..JAHHFAAKNO.... - ..JAGFFNOAAA.... - ....GNNFAAAAAA.. - ...GGAGFAAAA.... - ..KJJAKJJA...... - ................ - ................ -} -# tile 152 (Mordor orc,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KIIAIIKA.AA... - ..BPIDD.P.AAA... - ..BAGGFAAP.O.... - ..BAIDDNOAAA.... - ....BNOJAAAAAA.. - ...BIAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 153 (Mordor orc,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..KIIAIIKA.AA... - ..BPIDD.P.AAA... - ..BAGGFAAP.O.... - ..BAIDDNOAAA.... - ....BNOJAAAAAA.. - ...BIAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 154 (Uruk-hai,male) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..IIIAIIIA...... - ..BPIKI.BAAAA... - ..BIG.PPPPAAA... - .NBAD.PDDPAA.... - ..BNNJPDDPAA.... - ....INPPPPAAAA.. - ...BIAK.AAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 155 (Uruk-hai,female) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..IIIAIIIA...... - ..BPIKI.BAAAA... - ..BIG.PPPPAAA... - .NBAD.PDDPAA.... - ..BNNJPDDPAA.... - ....INPPPPAAAA.. - ...BIAK.AAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 156 (orc shaman,male) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..CCCACCCA...... - ..BPCKC.BAAAA... - ..BCGGFJBAAAA... - ..BAJJCJBAAA.... - ..BAJJCJBAAA.... - ....CACJAAAAAA.. - ...BCACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 157 (orc shaman,female) -{ - ................ - ................ - .....OA......... - ....NOPA........ - ....LPLA........ - .....P.A........ - ..CCCACCCA...... - ..BPCKC.BAAAA... - ..BCGGFJBAAAA... - ..BAJJCJBAAA.... - ..BAJJCJBAAA.... - ....CACJAAAAAA.. - ...BCACPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 158 (orc-captain,male) -{ - ................ - ................ - .....OA......... - ...NNOOPA....... - ....LPLA........ - ...IPPPA........ - ..DIIPADDA.AA... - ..BPIAD.P.AAA... - ..BAGGFAAP.O.... - ..BAGGFAAP.O.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BDAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 159 (orc-captain,female) -{ - ................ - ................ - .....OA......... - ...NNOOPA....... - ....LPLA........ - ...IPPPA........ - ..DIIPADDA.AA... - ..BPIAD.P.AAA... - ..BAGGFAAP.O.... - ..BAGGFAAP.O.... - ..BAJJPNOAAA.... - ....BNOJAAAAAA.. - ...BDAIPAAAA.... - ..BPPABPPA...... - ................ - ................ -} -# tile 160 (rock piercer,male) -{ - .JKKKKKKKKJAAA.. - ..JJGKGKJJAAAA.. - ...JKKKJJAAAA... - ...JJKKJJAAAA... - ....JKKJAAAA.... - ....JJKJ.AAA.... - ....JJKJ.AAA.... - ....JJJJ..A..... - .....JJ...A..... - .....JJ...A..... - .....JJ......... - .....JJ......... - .....J.......... - .....J.......... - ................ - ................ -} -# tile 161 (rock piercer,female) -{ - .JKKKKKKKKJAAA.. - ..JJGKGKJJAAAA.. - ...JKKKJJAAAA... - ...JJKKJJAAAA... - ....JKKJAAAA.... - ....JJKJ.AAA.... - ....JJKJ.AAA.... - ....JJJJ..A..... - .....JJ...A..... - .....JJ...A..... - .....JJ......... - .....JJ......... - .....J.......... - .....J.......... - ................ - ................ -} -# tile 162 (iron piercer,male) -{ - .BPPPPPPPP.AAA.. - ..BBDPDP..AAAA.. - ...BPPP..AAAA... - ...PBPP..AAAA... - ....BPP.AAAA.... - ....BBP.AAAA.... - ....PBP.AAAA.... - ....PBP...A..... - .....BP...A..... - .....BP...A..... - .....BP......... - .....BP......... - .....B.......... - .....P.......... - ................ - ................ -} -# tile 163 (iron piercer,female) -{ - .BPPPPPPPP.AAA.. - ..BBDPDP..AAAA.. - ...BPPP..AAAA... - ...PBPP..AAAA... - ....BPP.AAAA.... - ....BBP.AAAA.... - ....PBP.AAAA.... - ....PBP...A..... - .....BP...A..... - .....BP...A..... - .....BP......... - .....BP......... - .....B.......... - .....P.......... - ................ - ................ -} -# tile 164 (glass piercer,male) -{ - .NBBBBBBBBPAAA.. - ..NNDBDBPPAAAA.. - ...NBBBPPAAAA... - ...PNBBPPAAAA... - ....NBBPAAAA.... - ....NNBPAAAA.... - ....PNBPAAAA.... - ....PNBP..A..... - .....NB...A..... - .....NB...A..... - .....NB......... - .....NB......... - .....N.......... - .....P.......... - ................ - ................ -} -# tile 165 (glass piercer,female) -{ - .NBBBBBBBBPAAA.. - ..NNDBDBPPAAAA.. - ...NBBBPPAAAA... - ...PNBBPPAAAA... - ....NBBPAAAA.... - ....NNBPAAAA.... - ....PNBPAAAA.... - ....PNBP..A..... - .....NB...A..... - .....NB...A..... - .....NB......... - .....NB......... - .....N.......... - .....P.......... - ................ - ................ -} -# tile 166 (rothe,male) -{ - ................ - ...........K.... - ............K... - ............K... - .......JJJKKJ... - .....JKKKKKKK... - ..AAAKKKKKKKK... - .AAAAAKKKKKKKA.. - AAKKAAKKKKKAKA.. - .KEKKAKKKJAAKA.. - .KKKJAKKAJAAK... - ..KJAAAKAAA..... - ..AAKA.KA....... - ..A..A.K........ - ................ - ................ -} -# tile 167 (rothe,female) -{ - ................ - ...........K.... - ............K... - ............K... - .......JJJKKJ... - .....JKKKKKKK... - ..AAAKKKKKKKK... - .AAAAAKKKKKKKA.. - AAKKAAKKKKKAKA.. - .KEKKAKKKJAAKA.. - .KKKJAKKAJAAK... - ..KJAAAKAAA..... - ..AAKA.KA....... - ..A..A.K........ - ................ - ................ -} -# tile 168 (mumak,male) -{ - ................ - ...........P.... - .PP.........P... - PPP...PPPPP.P... - PPPPPPPPP.PP.... - PPPPBPPBBP.PP... - PPPBPPPPPP.PP... - .PDPPDDPP.PPP... - ..BPPDDP.PPPPA.. - ..PPPPPPPPPPPA.. - ..PPPPO..PAPPA.. - .OOPPOOAPPAPPA.. - OOPPOOAAPPA..... - .PPPAPA.PP...... - PPPA............ - .AA............. -} -# tile 169 (mumak,female) -{ - ................ - ...........P.... - .PP.........P... - PPP...PPPPP.P... - PPPPPPPPP.PP.... - PPPPBPPBBP.PP... - PPPBPPPPPP.PP... - .PDPPDDPP.PPP... - ..BPPDDP.PPPPA.. - ..PPPPPPPPPPPA.. - ..PPPPO..PAPPA.. - .OOPPOOAPPAPPA.. - OOPPOOAAPPA..... - .PPPAPA.PP...... - PPPA............ - .AA............. -} -# tile 170 (leocrotta,male) -{ - ................ - ..A..A.......... - ..AOOA....J..... - ..AOOAA....J.... - .APOAFA....J.... - .APOAAA.JJJJ.... - .AOPAAJKKKKKJ... - .AOAAKJJKKJKJA.. - ...JKKKKKJAKKA.. - ...JKJKKJAAKKA.. - ..JKJAKKAAPAPA.. - ..KKAAKKAAPAPA.. - .PAPAAPAPA...... - .PAPA.PAPA...... - ................ - ................ -} -# tile 171 (leocrotta,female) -{ - ................ - ..A..A.......... - ..AOOA....J..... - ..AOOAA....J.... - .APOAFA....J.... - .APOAAA.JJJJ.... - .AOPAAJKKKKKJ... - .AOAAKJJKKJKJA.. - ...JKKKKKJAKKA.. - ...JKJKKJAAKKA.. - ..JKJAKKAAPAPA.. - ..KKAAKKAAPAPA.. - .PAPAAPAPA...... - .PAPA.PAPA...... - ................ - ................ -} -# tile 172 (wumpus,male) -{ - ................ - ............B... - .............B.. - .......BBBBB.B.. - ....BBBPPBBBB... - ...BOOBBBPBBBB.. - ...OOBBBBBPBBB.. - ..DABBAABBPBBBA. - .BOOBBDABEBBEBAA - .BOBBBBBBEBEBBAA - .BBBBBBBEBBABBAA - .EBBBBBEABBABBAA - ..EEEEEAABBA.... - .....BBA.BB..... - ................ - ................ -} -# tile 173 (wumpus,female) -{ - ................ - ............B... - .............B.. - .......BBBBB.B.. - ....BBBPPBBBB... - ...BOOBBBPBBBB.. - ...OOBBBBBPBBB.. - ..DABBAABBPBBBA. - .BOOBBDABEBBEBAA - .BOBBBBBBEBEBBAA - .BBBBBBBEBBABBAA - .EBBBBBEABBABBAA - ..EEEEEAABBA.... - .....BBA.BB..... - ................ - ................ -} -# tile 174 (titanothere,male) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - .PPPPP.PPPPPPP.. - .PPEPP.PPPP.PPA. - PBPPP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 175 (titanothere,female) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - .PPPPP.PPPPPPP.. - .PPEPP.PPPP.PPA. - PBPPP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 176 (baluchitherium,male) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - BPPPPP.PPPPPPP.. - B.PEPP.PPPP.PPA. - PB.PP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 177 (baluchitherium,female) -{ - ................ - ................ - ................ - ..........PPP.P. - .......PPPPPPPAP - .....PPPPPPPPP.A - ..P.P.PPPPPPPP.A - ..PPP.PPPPPPPPPA - ..PPPP.PPPPPPPPA - BPPPPP.PPPPPPP.. - B.PEPP.PPPP.PPA. - PB.PP.PPP.AAPPA. - PPPP.AAPPAA..... - .PP.PPAPPA...... - ................ - ................ -} -# tile 178 (mastodon,male) -{ - ................ - ................ - ................ - ................ - ................ - ..O...O......... - .N..POP.P....... - N..PNPPPPP...... - O.PNPPPPPP.PP... - O.POPEPPP.PPPPP. - .OPOPOP..PPPPPAP - ..PPOPP.PPPPPPAA - ..PPAAAPPPPAPPA. - ..P...APPAAAPPA. - .......PPA...... - ................ -} -# tile 179 (mastodon,female) -{ - ................ - ................ - ................ - ................ - ................ - ..O...O......... - .N..POP.P....... - N..PNPPPPP...... - O.PNPPPPPP.PP... - O.POPEPPP.PPPPP. - .OPOPOP..PPPPPAP - ..PPOPP.PPPPPPAA - ..PPAAAPPPPAPPA. - ..P...APPAAAPPA. - .......PPA...... - ................ -} -# tile 180 (sewer rat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKK.... - ..KKKKJKKJKKK... - ..JAKAKJJJKKKJ.. - ..GKGKJKAKKAKKA. - .KKJJJJKAKAAKKA. - .PJJAAKKAJAJKA.. - ..AA.KKA..JKA... - .........JJA.... - ................ -} -# tile 181 (sewer rat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKK.... - ..KKKKJKKJKKK... - ..JAKAKJJJKKKJ.. - ..GKGKJKAKKAKKA. - .KKJJJJKAKAAKKA. - .PJJAAKKAJAJKA.. - ..AA.KKA..JKA... - .........JJA.... - ................ -} -# tile 182 (giant rat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 183 (giant rat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 184 (rabid rat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJOOOKAJKAAKKA - .PJOOAKKAJJAJKA. - ..AOOOKAA..JKA.. - .OOOOOOOO.JJA... - ................ -} -# tile 185 (rabid rat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..JAKAKJKJJKKKJ. - ..GAGAKJKJJKKKK. - ..AKAKJKKAKKAKKA - .KKJOOOKAJKAAKKA - .PJOOAKKAJJAJKA. - ..AOOOKAA..JKA.. - .OOOOOOOO.JJA... - ................ -} -# tile 186 (wererat,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..LLLLKJKJJKKKJ. - ..FLFLLJKJJKKKK. - ..LLLLJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 187 (wererat,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ..K..K.JKKKKK... - ..KKKKJKKKJKKK.. - ..LLLLKJKJJKKKJ. - ..FLFLLJKJJKKKK. - ..LLLLJKKAKKAKKA - .KKJJJJKAJKAAKKA - .PJJAAKKAJJAJKA. - ..AA.KKAA..JKA.. - ..........JJA... - ................ -} -# tile 188 (rock mole,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......AAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - ..JAJAAAAAAAAAA. - .AAAAAAAAAAAAAA. - AN.NAAAAAAAAAAA. - A...AAAA...AAA.. - AN.NAA.AA...AA.. - .AAAA........... -} -# tile 189 (rock mole,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - .......AAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - ..JAJAAAAAAAAAA. - .AAAAAAAAAAAAAA. - AN.NAAAAAAAAAAA. - A...AAAA...AAA.. - AN.NAA.AA...AA.. - .AAAA........... -} -# tile 190 (woodchuck,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .......KJA...... - ......NKKNA..... - ......KNOJA..... - ......KNOJA..... - .....KKKKKJA.... - ....JJKLLJJJAA.. - ......KLLJAAAAA. - ......KJJJAAAA.. - .....JJAAJJAA... - ................ -} -# tile 191 (woodchuck,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - .......KJA...... - ......NKKNA..... - ......KNOJA..... - ......KNOJA..... - .....KKKKKJA.... - ....JJKLLJJJAA.. - ......KLLJAAAAA. - ......KJJJAAAA.. - .....JJAAJJAA... - ................ -} -# tile 192 (cave spider,male) -{ - ................ - ................ - ................ - ................ - ................ - ........PA...... - .......PA....... - ......PAPBBA.... - ...PA.APBPPPA... - ...ABBPPAPPAA.PA - ...GPPPPAAAPPPAA - ...PPGPAAPPAAAA. - ..D.PAPAPAAPPA.. - ....D.PAAPA.APA. - .....PAA.APA.... - ................ -} -# tile 193 (cave spider,female) -{ - ................ - ................ - ................ - ................ - ................ - ........PA...... - .......PA....... - ......PAPBBA.... - ...PA.APBPPPA... - ...ABBPPAPPAA.PA - ...GPPPPAAAPPPAA - ...PPGPAAPPAAAA. - ..D.PAPAPAAPPA.. - ....D.PAAPA.APA. - .....PAA.APA.... - ................ -} -# tile 194 (centipede,male) -{ - ................ - ................ - ......PBPP...... - ....BBPAAA...... - ..PPBAAA........ - .PAPBBBPPPP..... - ..PAAPPBBBA..... - ....PAAPAPBPP... - ......AABBPP.... - ......BB.PPAP... - ....PBBPPAP.A... - ...GPPPAP.AP.... - ...PPGPAAP...... - ..B.PAA......... - ...B............ - ................ -} -# tile 195 (centipede,female) -{ - ................ - ................ - ......PBPP...... - ....BBPAAA...... - ..PPBAAA........ - .PAPBBBPPPP..... - ..PAAPPBBBA..... - ....PAAPAPBPP... - ......AABBPP.... - ......BB.PPAP... - ....PBBPPAP.A... - ...GPPPAP.AP.... - ...PPGPAAP...... - ..B.PAA......... - ...B............ - ................ -} -# tile 196 (giant spider,male) -{ - ................ - ................ - ................ - ................ - ................ - ........JA...... - .......JA....... - ......JAJKKA.... - ...JA.AJKJJJA... - ...AKKJJAJJAA.JA - ...GJJJJAAAJJJAA - ...JJGJAAJJAAAA. - ..D.JAJAJAAJJA.. - ....D.JAAJA.AJA. - .....JAA.AJA.... - ................ -} -# tile 197 (giant spider,female) -{ - ................ - ................ - ................ - ................ - ................ - ........JA...... - .......JA....... - ......JAJKKA.... - ...JA.AJKJJJA... - ...AKKJJAJJAA.JA - ...GJJJJAAAJJJAA - ...JJGJAAJJAAAA. - ..D.JAJAJAAJJA.. - ....D.JAAJA.AJA. - .....JAA.AJA.... - ................ -} -# tile 198 (scorpion,male) -{ - ................ - ................ - .......JKJKJAA.. - ......JA.JKJKKA. - .......KA...JJJA - ......JA....KKJA - ...........JJJKA - .......AJKKAJJA. - .....AAJKJJJAA.. - ...AKKJJAJJAA... - ...GJJJJAAAJJJA. - ...JJGJAAJJAAAJ. - ..D.JAJAJAAJJA.. - ....D.JAAJA.JAA. - .......JAAJA.... - ................ -} -# tile 199 (scorpion,female) -{ - ................ - ................ - .......JKJKJAA.. - ......JA.JKJKKA. - .......KA...JJJA - ......JA....KKJA - ...........JJJKA - .......AJKKAJJA. - .....AAJKJJJAA.. - ...AKKJJAJJAA... - ...GJJJJAAAJJJA. - ...JJGJAAJJAAAJ. - ..D.JAJAJAAJJA.. - ....D.JAAJA.JAA. - .......JAAJA.... - ................ -} -# tile 200 (lurker above,male) -{ - .AAAAAAAAAAAAAAA - ...AAGFAAGFAAA.. - ...AAAAAAAAAAA.. - ....AODODODOA... - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ -} -# tile 201 (lurker above,female) -{ - .AAAAAAAAAAAAAAA - ...AAGFAAGFAAA.. - ...AAAAAAAAAAA.. - ....AODODODOA... - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ -} -# tile 202 (trapper,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....AODODODOA... - ...AAAAAAAAAAA.. - ...AAGFAAGFAAA.. - .AAAAAAAAAAAAAAA -} -# tile 203 (trapper,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ....AODODODOA... - ...AAAAAAAAAAA.. - ...AAGFAAGFAAA.. - .AAAAAAAAAAAAAAA -} -# tile 204 (pony,male) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ...KKEKJ........ - ..KKJKKJ........ - ..JJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKJ..... - ...KKKKKKKJJAAA. - ...KJKJJJJJAJA.. - ...JAJAAAAJAA... - ...JAJAAJAJA.... - ...L.JAALAJ..... - .....LA...L..... - ................ -} -# tile 205 (pony,female) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ...KKEKJ........ - ..KKJKKJ........ - ..JJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKJ..... - ...KKKKKKKJJAAA. - ...KJKJJJJJAJA.. - ...JAJAAAAJAA... - ...JAJAAJAJA.... - ...L.JAALAJ..... - .....LA...L..... - ................ -} -# tile 206 (white unicorn,male) -{ - ................ - ..HP............ - ..PHO.NN........ - ...PHNNB........ - ...ONENB........ - ..ONNNNB........ - ..NOANNBAA...... - ...AONNBA....... - ...ONNNONNN..... - ..NONNNNONNOAAA. - ..N.ONONNONAOA.. - ..OAANAAAAOAA... - ...LAOAAOAOA.... - .....OAALAO..... - .....LA...L..... - ................ -} -# tile 207 (white unicorn,female) -{ - ................ - ..HP............ - ..PHO.NN........ - ...PHNNB........ - ...ONENB........ - ..ONNNNB........ - ..NOANNBAA...... - ...AONNBA....... - ...ONNNONNN..... - ..NONNNNONNOAAA. - ..N.ONONNONAOA.. - ..OAANAAAAOAA... - ...LAOAAOAOA.... - .....OAALAO..... - .....LA...L..... - ................ -} -# tile 208 (gray unicorn,male) -{ - ................ - ..HP............ - ..PHO.PP........ - ...PHPPN........ - ....PGPN........ - ...PPPPN........ - ..PPAPPNAA...... - ...APPPNA....... - ....PPP.PPP..... - ..P.PPPP.PP.AAA. - ..P..P.PP.PA.A.. - ..PAAPAAAA.AA... - ...LA.AA.A.A.... - ......AALA...... - .....LA...L..... - ................ -} -# tile 209 (gray unicorn,female) -{ - ................ - ..HP............ - ..PHO.PP........ - ...PHPPN........ - ....PGPN........ - ...PPPPN........ - ..PPAPPNAA...... - ...APPPNA....... - ....PPP.PPP..... - ..P.PPPP.PP.AAA. - ..P..P.PP.PA.A.. - ..PAAPAAAA.AA... - ...LA.AA.A.A.... - ......AALA...... - .....LA...L..... - ................ -} -# tile 210 (black unicorn,male) -{ - ................ - ..HP............ - ..PHO.AA........ - ...PHAAJ........ - ...AADAJ........ - ..AAAAAJ........ - ..AAPAAJPP...... - ...PAAAJP....... - ...AAAAAAAA..... - ..AAAAAAAAAAPPP. - ..A.AAAAAAAPAP.. - ..APPAPPAPAPP... - ...LPAPPAPAP.... - .....APPLPA..... - .....LP...L..... - ................ -} -# tile 211 (black unicorn,female) -{ - ................ - ..HP............ - ..PHO.AA........ - ...PHAAJ........ - ...AADAJ........ - ..AAAAAJ........ - ..AAPAAJPP...... - ...PAAAJP....... - ...AAAAAAAA..... - ..AAAAAAAAAAPPP. - ..A.AAAAAAAPAP.. - ..APPAPPAPAPP... - ...LPAPPAPAP.... - .....APPLPA..... - .....LP...L..... - ................ -} -# tile 212 (horse,male) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ..KKKEKJ........ - .KKKJKKJAA...... - .JJJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKKJA... - ..KKKKKKKKKKJA.. - ..KJJKJJJJJKAJA. - ..JAAJAAAAAJAJA. - ..JAAJAAAJAJAA.. - ..LA.JAA.L.JA... - .....LA....L.... - ................ -} -# tile 213 (horse,female) -{ - ................ - ................ - .....JJ......... - ....KKKJ........ - ..KKKEKJ........ - .KKKJKKJAA...... - .JJJAKKJAA...... - ...AKKKJA....... - ...KKKKKKKKJA... - ..KKKKKKKKKKJA.. - ..KJJKJJJJJKAJA. - ..JAAJAAAAAJAJA. - ..JAAJAAAJAJAA.. - ..LA.JAA.L.JA... - .....LA....L.... - ................ -} -# tile 214 (warhorse,male) -{ - ................ - .....JJJ........ - ...KKKKJJ....... - .KKKKEKJJ....... - KKKKKKKJJAA..... - JKKKJKKJJAA..... - .JJJAKKJJAA..... - ...AKKKJJA...... - ...KKKKKKKKKJA.. - ..KKKKKKKKKKKJA. - ..KKJKKJKKJKKJJA - ..KJAKJAKJAKJAJA - ..KJAKJAKJAKJA.. - ..LC.KJALC.KJ... - .....LC....LC... - ................ -} -# tile 215 (warhorse,female) -{ - ................ - .....JJJ........ - ...KKKKJJ....... - .KKKKEKJJ....... - KKKKKKKJJAA..... - JKKKJKKJJAA..... - .JJJAKKJJAA..... - ...AKKKJJA...... - ...KKKKKKKKKJA.. - ..KKKKKKKKKKKJA. - ..KKJKKJKKJKKJJA - ..KJAKJAKJAKJAJA - ..KJAKJAKJAKJA.. - ..LC.KJALC.KJ... - .....LC....LC... - ................ -} -# tile 216 (fog cloud,male) -{ - .......P........ - ....P..P........ - .....P.P...P.... - ...P.......P.... - ..P..P.P.P...... - ....PP.PP.P.P... - .P..APAPPP..P... - ...P.PPPP.PP.... - ......PPPPP.P.P. - ...P.PPPPP..P... - ....P..P.PP.P... - .P...P.P...PPP.. - ..P.P....PP..... - .......P....P... - ..P..P.P..P..... - ................ -} -# tile 217 (fog cloud,female) -{ - .......P........ - ....P..P........ - .....P.P...P.... - ...P.......P.... - ..P..P.P.P...... - ....PP.PP.P.P... - .P..APAPPP..P... - ...P.PPPP.PP.... - ......PPPPP.P.P. - ...P.PPPPP..P... - ....P..P.PP.P... - .P...P.P...PPP.. - ..P.P....PP..... - .......P....P... - ..P..P.P..P..... - ................ -} -# tile 218 (dust vortex,male) -{ - ................ - ................ - ....K..KKKK..... - ...K..KKJJJK.... - ..K..KJJJJ..K... - .KJ.KJJ.JKK..K.. - .KJJKJ.JJJJK.... - .KJJJJ....JJK... - .KKJ.J...J.JKK.. - ..KJJ....JJJJK.. - ...KJJJJ.JKJJK.. - .K..KKJ.JJK.JK.. - ..K..JJJJK..K... - ...KJJJKK..K.... - ....KKKK..K..... - ................ -} -# tile 219 (dust vortex,female) -{ - ................ - ................ - ....K..KKKK..... - ...K..KKJJJK.... - ..K..KJJJJ..K... - .KJ.KJJ.JKK..K.. - .KJJKJ.JJJJK.... - .KJJJJ....JJK... - .KKJ.J...J.JKK.. - ..KJJ....JJJJK.. - ...KJJJJ.JKJJK.. - .K..KKJ.JJK.JK.. - ..K..JJJJK..K... - ...KJJJKK..K.... - ....KKKK..K..... - ................ -} -# tile 220 (ice vortex,male) -{ - ................ - ................ - ....N..NNNN..... - ...N..NNOOON.... - ..N..NOOOO..N... - .NO.NOO.ONN..N.. - .NOONO.OOOON.... - .NOOOO....OON... - .NNO.O...O.ONN.. - ..NOO....OOOON.. - ...NOOOO.ONOON.. - .N..NNO.OON.ON.. - ..N..OOOON..N... - ...NOOONN..N.... - ....NNNN..N..... - ................ -} -# tile 221 (ice vortex,female) -{ - ................ - ................ - ....N..NNNN..... - ...N..NNOOON.... - ..N..NOOOO..N... - .NO.NOO.ONN..N.. - .NOONO.OOOON.... - .NOOOO....OON... - .NNO.O...O.ONN.. - ..NOO....OOOON.. - ...NOOOO.ONOON.. - .N..NNO.OON.ON.. - ..N..OOOON..N... - ...NOOONN..N.... - ....NNNN..N..... - ................ -} -# tile 222 (energy vortex,male) -{ - ................ - ................ - ....E..EEEE..... - ...E..EEAAAE.... - ..E..EAAAA..E... - .EA.EAAAAIE..E.. - .EAAIAAAAAAE.... - .EAAAAAAAAAAE... - .EEAAAAAAAAAEE.. - ..EAAAAAAAAAAE.. - ...EAAAAAAIAAE.. - .E..EIAAAAE.AE.. - ..E..AAAAE..E... - ...EAAAEE..E.... - ....EEEE..E..... - ................ -} -# tile 223 (energy vortex,female) -{ - ................ - ................ - ....E..EEEE..... - ...E..EEAAAE.... - ..E..EAAAA..E... - .EA.EAAAAIE..E.. - .EAAIAAAAAAE.... - .EAAAAAAAAAAE... - .EEAAAAAAAAAEE.. - ..EAAAAAAAAAAE.. - ...EAAAAAAIAAE.. - .E..EIAAAAE.AE.. - ..E..AAAAE..E... - ...EAAAEE..E.... - ....EEEE..E..... - ................ -} -# tile 224 (steam vortex,male) -{ - ................ - ................ - ....P..PPPP..... - ...P..PPBBBP.... - ..P..PBBBB..P... - .PB.PBBPBPP..P.. - .PBBPBPBBBBP.... - .PBBBBP.PPBBP... - .PPBPB...BPBPP.. - ..PBBPP.PBBBBP.. - ...PBBBBPBPBBP.. - .P..PPBPBBP.BP.. - ..P..BBBBP..P... - ...PBBBPP..P.... - ....PPPP..P..... - ................ -} -# tile 225 (steam vortex,female) -{ - ................ - ................ - ....P..PPPP..... - ...P..PPBBBP.... - ..P..PBBBB..P... - .PB.PBBPBPP..P.. - .PBBPBPBBBBP.... - .PBBBBP.PPBBP... - .PPBPB...BPBPP.. - ..PBBPP.PBBBBP.. - ...PBBBBPBPBBP.. - .P..PPBPBBP.BP.. - ..P..BBBBP..P... - ...PBBBPP..P.... - ....PPPP..P..... - ................ -} -# tile 226 (fire vortex,male) -{ - ................ - ................ - ....D..DDDD..... - ...D..DDCCCD.... - ..D..DCCCC..D... - .DC.DCCHCDD..D.. - .DCCDCHCCCCD.... - .DCCCCHHHHCCD... - .DDCHCHHHCHCDD.. - ..DCCHHHHCCCCD.. - ...DCCCCHCDCCD.. - .D..DDCHCCD.CD.. - ..D..CCCCD..D... - ...DCCCDD..D.... - ....DDDD..D..... - ................ -} -# tile 227 (fire vortex,female) -{ - ................ - ................ - ....D..DDDD..... - ...D..DDCCCD.... - ..D..DCCCC..D... - .DC.DCCHCDD..D.. - .DCCDCHCCCCD.... - .DCCCCHHHHCCD... - .DDCHCHHHCHCDD.. - ..DCCHHHHCCCCD.. - ...DCCCCHCDCCD.. - .D..DDCHCCD.CD.. - ..D..CCCCD..D... - ...DCCCDD..D.... - ....DDDD..D..... - ................ -} -# tile 228 (baby long worm,male) -{ - ................ - ................ - ................ - ................ - ......CLC....... - ......LLL....... - .....GGAGG.A.... - .....GGAGGAAA... - ......LLLAAA.C.. - ......LLLAA.CC.. - ......CLLCCCCA.. - .......LLLCCA... - ........CLL..... - ................ - ................ - ................ -} -# tile 229 (baby long worm,female) -{ - ................ - ................ - ................ - ................ - ......CLC....... - ......LLL....... - .....GGAGG.A.... - .....GGAGGAAA... - ......LLLAAA.C.. - ......LLLAA.CC.. - ......CLLCCCCA.. - .......LLLCCA... - ........CLL..... - ................ - ................ - ................ -} -# tile 230 (baby purple worm,male) -{ - ................ - ................ - ................ - .......I........ - ......III....... - ......III....... - .....GGAGG.A.... - .....GGAGGAAA... - ......IIIAAA.D.. - ......IIIAA.DD.. - ......IIIDDDDA.. - .......IIIDDA... - ........III..... - ................ - ................ - ................ -} -# tile 231 (baby purple worm,female) -{ - ................ - ................ - ................ - .......I........ - ......III....... - ......III....... - .....GGAGG.A.... - .....GGAGGAAA... - ......IIIAAA.D.. - ......IIIAA.DD.. - ......IIIDDDDA.. - .......IIIDDA... - ........III..... - ................ - ................ - ................ -} -# tile 232 (long worm,male) -{ - ................ - ................ - .....CLC........ - ....CLLLC....... - ....LLLLL....... - ...GGGLGGGAA.... - ...GAGLGAGAAA... - ...GGGLGGGAAA... - ....LLLLLAAACC.. - ....LLLLLAACCC.. - ....CLLLLCCCCA.. - .....LLLLLCCA... - ......CLLLL..... - ................ - ................ - ................ -} -# tile 233 (long worm,female) -{ - ................ - ................ - .....CLC........ - ....CLLLC....... - ....LLLLL....... - ...GGGLGGGAA.... - ...GAGLGAGAAA... - ...GGGLGGGAAA... - ....LLLLLAAACC.. - ....LLLLLAACCC.. - ....CLLLLCCCCA.. - .....LLLLLCCA... - ......CLLLL..... - ................ - ................ - ................ -} -# tile 234 (purple worm,male) -{ - ................ - ................ - .....DID........ - ....DIIID....... - ....IIIII....... - ...GGGIGGGAA.... - ...GAGIGAGAAA... - ...GGGIGGGAAA... - ....IIIIIAAADD.. - ....IIIIIAADDD.. - ....DIIIIDDDDA.. - .....IIIIIDDA... - ......DIIII..... - ................ - ................ - ................ -} -# tile 235 (purple worm,female) -{ - ................ - ................ - .....DID........ - ....DIIID....... - ....IIIII....... - ...GGGIGGGAA.... - ...GAGIGAGAAA... - ...GGGIGGGAAA... - ....IIIIIAAADD.. - ....IIIIIAADDD.. - ....DIIIIDDDDA.. - .....IIIIIDDA... - ......DIIII..... - ................ - ................ - ................ -} -# tile 236 (grid bug,male) -{ - ................ - ................ - ................ - ................ - ..D....NHCN..D.. - .D.D..NHDNCNDED. - D.D.D.NNHCND.DED - .D...D.NNHDND... - .DDD..ENNG.D.DE. - ..DDDDEEEEGD..DE - D.....DEHEE.D... - .D.......H...... - ................ - ................ - ................ - ................ -} -# tile 237 (grid bug,female) -{ - ................ - ................ - ................ - ................ - ..D....NHCN..D.. - .D.D..NHDNCNDED. - D.D.D.NNHCND.DED - .D...D.NNHDND... - .DDD..ENNG.D.DE. - ..DDDDEEEEGD..DE - D.....DEHEE.D... - .D.......H...... - ................ - ................ - ................ - ................ -} -# tile 238 (xan,male) -{ - ................ - ................ - ..........GG.... - ...HHH...GOGG... - .....HH..GGGG... - ...HHHHH.GGG.... - .......GG...AAA. - .....GOGGHHAAAA. - ....GOGG..HHAAA. - NNNGOGG.AAHHHA.. - NANGGGG.AAHAH... - NNNGGNNNAAAAAA.. - ..GGGNANAA.AAA.. - .GGGANNNAA.A.A.. - ..G..AAAAAA..... - ......AA.AA..... -} -# tile 239 (xan,female) -{ - ................ - ................ - ..........GG.... - ...HHH...GOGG... - .....HH..GGGG... - ...HHHHH.GGG.... - .......GG...AAA. - .....GOGGHHAAAA. - ....GOGG..HHAAA. - NNNGOGG.AAHHHA.. - NANGGGG.AAHAH... - NNNGGNNNAAAAAA.. - ..GGGNANAA.AAA.. - .GGGANNNAA.A.A.. - ..G..AAAAAA..... - ......AA.AA..... -} -# tile 240 (yellow light,male) -{ - ................ - ......NA........ - ......HA........ - ..NA.NHNA.NA.... - ...LALHLALA..... - ....NHHHNA...... - ..NLHHHHHLNA.... - NHHHHHHHHHHHNA.. - ..NLHHHHHLNA.... - ....NHHHNA...... - ...LALHLALA..... - ..NA.NNNA.NA.... - ......HA........ - ......NA........ - ................ - ................ -} -# tile 241 (yellow light,female) -{ - ................ - ......NA........ - ......HA........ - ..NA.NHNA.NA.... - ...LALHLALA..... - ....NHHHNA...... - ..NLHHHHHLNA.... - NHHHHHHHHHHHNA.. - ..NLHHHHHLNA.... - ....NHHHNA...... - ...LALHLALA..... - ..NA.NNNA.NA.... - ......HA........ - ......NA........ - ................ - ................ -} -# tile 242 (black light,male) -{ - ................ - ......AA........ - ......AA........ - ..AA.AAAA.AA.... - ...AAAAAAAA..... - ....AAAAAA...... - ..AAAAAAAAAA.... - AAAAAAAAAAAAAA.. - ..AAAAAAAAAA.... - ....AAAAAA...... - ...AAAAAAAA..... - ..AA.AAAA.AA.... - ......AA........ - ......AA........ - ................ - ................ -} -# tile 243 (black light,female) -{ - ................ - ......AA........ - ......AA........ - ..AA.AAAA.AA.... - ...AAAAAAAA..... - ....AAAAAA...... - ..AAAAAAAAAA.... - AAAAAAAAAAAAAA.. - ..AAAAAAAAAA.... - ....AAAAAA...... - ...AAAAAAAA..... - ..AA.AAAA.AA.... - ......AA........ - ......AA........ - ................ - ................ -} -# tile 244 (zruty,male) -{ - ................ - ......FFGF...... - ....OOFGFFFF.... - ...AOFGFOOKFF... - ...FFGFAOAJKKF.. - ..FFFFFFJAAJKK.. - ..ODOFFJAJJKKJA. - ..DDDDJAJJKJJAA. - ..JODOAJJJAJJAAA - .KKJAJJJKJAJJAAA - .KKAAJKKKKJAAAAA - ...AJJKKKKJJAAAA - ...KJJAAAAKJAAA. - ..JKJJJAAJJJJ... - ................ - ................ -} -# tile 245 (zruty,female) -{ - ................ - ......FFGF...... - ....OOFGFFFF.... - ...AOFGFOOKFF... - ...FFGFAOAJKKF.. - ..FFFFFFJAAJKK.. - ..ODOFFJAJJKKJA. - ..DDDDJAJJKJJAA. - ..JODOAJJJAJJAAA - .KKJAJJJKJAJJAAA - .KKAAJKKKKJAAAAA - ...AJJKKKKJJAAAA - ...KJJAAAAKJAAA. - ..JKJJJAAJJJJ... - ................ - ................ -} -# tile 246 (couatl,male) -{ - ................ - ................ - ........I....I.. - ....KKAIII..III. - ...NAOJAKI.IIIII - ...KKJAJJKKK..II - ...KKAAIJJJJJ..I - ...FAA.I...KJ..I - ..FAFA..AAAKJAA. - .......AAAJJAAA. - ......AKKJJAAA.. - ......KJAAAAAJA. - .....JJAA...JA.. - ......JJJJJJA... - ................ - ................ -} -# tile 247 (couatl,female) -{ - ................ - ................ - ........I....I.. - ....KKAIII..III. - ...NAOJAKI.IIIII - ...KKJAJJKKK..II - ...KKAAIJJJJJ..I - ...FAA.I...KJ..I - ..FAFA..AAAKJAA. - .......AAAJJAAA. - ......AKKJJAAA.. - ......KJAAAAAJA. - .....JJAA...JA.. - ......JJJJJJA... - ................ - ................ -} -# tile 248 (Aleax,male) -{ - ................ - ......BBBB..I... - ..I..BF...B..... - ....BF.HHA.B.... - ...BF.HHHHA.B.I. - ...BF.LFLFA.FB.. - .I.BF.LLLLA.FB.. - ...BF.ALLA.FB... - ..BF.LLAALL.ABA. - .BF.LLLLLLLLAFB. - .BF.LALLLLALAFB. - .BF.LAJJKJALAFB. - ..BF..LJJLAAABA. - ...BF.LLALAABA.. - ..BF.LLAALLAFB.. - ................ -} -# tile 249 (Aleax,female) -{ - ................ - ......BBBB..I... - ..I..BF...B..... - ....BF.HHA.B.... - ...BF.HHHHA.B.I. - ...BF.LFLFA.FB.. - .I.BF.LLLLA.FB.. - ...BF.ALLA.FB... - ..BF.LJAAJL.ABA. - .BF.LLJJJJLLAFB. - .BF.LAJKJJALAFB. - .BF.LAJJKJALAFB. - ..BF..LJJLAAABA. - ...BF.LLALAABA.. - ..BF.LLAALLAFB.. - ................ -} -# tile 250 (Angel,male) -{ - ................ - ................ - ......HHHH...... - ................ - .......CC....... - ......CLLC..AA.. - ......PLLP....A. - ......NPPPA.A... - .....BBLLPPAAA.. - .....NNLLPPAAA.. - ......BNNPAAAA.. - ......BNNPAAAA.. - .....BNNNPAA.A.. - .....BNNNNPA.... - ....BNNNNNNP.... - ................ -} -# tile 251 (Angel,female) -{ - ................ - ................ - ......HHHH...... - ................ - .......CC....... - ......CLLC..AA.. - ......PLLP....A. - ......NPPPA.A... - .....BBLLPPAAA.. - .....NNLLPPAAA.. - ......BNNPAAAA.. - ......BNNPAAAA.. - .....BNNNPAA.A.. - .....BNNNNPA.... - ....BNNNNNNP.... - ................ -} -# tile 252 (ki-rin,male) -{ - ................ - ................ - ..LP............ - ..PLO.C.C....... - ...PLCCD........ - ...KCIKD........ - ..KCCCCD........ - ..CKACCDA....... - ...ACCCCCC...A.. - ...KCCCKCCKAA... - ..CAKCKCKCAKA... - ..CAAKAKAKA..... - ...L.KALAK...... - .....LA..L...... - ................ - ................ -} -# tile 253 (ki-rin,female) -{ - ................ - ................ - ..LP............ - ..PLO.C.C....... - ...PLCCD........ - ...KCIKD........ - ..KCCCCD........ - ..CKACCDA....... - ...ACCCCCC...A.. - ...KCCCKCCKAA... - ..CAKCKCKCAKA... - ..CAAKAKAKA..... - ...L.KALAK...... - .....LA..L...... - ................ - ................ -} -# tile 254 (Archon,male) -{ - ................ - ......OOOO...... - .....OOOOOO..... - .....OJLLJO..... - .....OLLLLO..... - ....OOJLLJOO.... - ......AJJA...... - .....AAAAAAA.... - ....AAAAAAAAA... - ...OAAOAAAJLJ... - ..OOAOAAAACJC... - ....LAAAACCJCC.. - .....AAAAAJJJ... - ....AAAAAAAA.... - ................ - ................ -} -# tile 255 (Archon,female) -{ - ................ - ......OOOO...... - .....OOOOOO..... - .....OJLLJO..... - .....OLLLLO..... - ....OOKLLKOO.... - ......AKKA...... - .....AAAAAAA.... - ....AAAAAAAAA... - ...OAAOAAAJLJ... - ..OOAOAAAACJC... - ....LAAAACCJCC.. - .....AAAAAJJJ... - ....AAAAAAAA.... - ................ - ................ -} -# tile 256 (bat,male) -{ - ................ - ................ - ................ - ................ - ...JJJCACJJJ.... - ..JJAAHJHAAJJ... - ..JA...JA..AJ... - ................ - ................ - ......AAAA...... - ....AAAAAAAA.... - ...AAA.AA.AAA... - .......AA....... - ................ - ................ - ................ -} -# tile 257 (bat,female) -{ - ................ - ................ - ................ - ................ - ...JJJCACJJJ.... - ..JJAAHJHAAJJ... - ..JA...JA..AJ... - ................ - ................ - ......AAAA...... - ....AAAAAAAA.... - ...AAA.AA.AAA... - .......AA....... - ................ - ................ - ................ -} -# tile 258 (giant bat,male) -{ - ................ - ................ - ................ - ...JK.J.J.JK.... - ..KJJJCACJJKJ... - .JJJAAHJHAAJJK.. - .KJA...JA..AJJ.. - ..JA.......AJ... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 259 (giant bat,female) -{ - ................ - ................ - ................ - ...JK.J.J.JK.... - ..KJJJCACJJKJ... - .JJJAAHJHAAJJK.. - .KJA...JA..AJJ.. - ..JA.......AJ... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 260 (raven,male) -{ - ..AAAA...AAA.... - .AAAAAA.AAA..... - AAAAAAAAAAA.AA.. - A...AAAAAAAAAAA. - ......AAAAAAAAA. - .....AAAA.....AA - .....ADA.......A - .....PA......... - .....P.......... - .........P.P.P.. - ........P.P.P.P. - .......P.P.P.... - ........P.P.P... - ...........P.... - ................ - ................ -} -# tile 261 (raven,female) -{ - ..AAAA...AAA.... - .AAAAAA.AAA..... - AAAAAAAAAAA.AA.. - A...AAAAAAAAAAA. - ......AAAAAAAAA. - .....AAAA.....AA - .....ADA.......A - .....PA......... - .....P.......... - .........P.P.P.. - ........P.P.P.P. - .......P.P.P.... - ........P.P.P... - ...........P.... - ................ - ................ -} -# tile 262 (vampire bat,male) -{ - ................ - ................ - ................ - ...AA.A.A.AA.... - ..AAAAAAAAAAA... - .AAAA.DAD.AAAA.. - .AAA...A...AAA.. - ..A.........A... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 263 (vampire bat,female) -{ - ................ - ................ - ................ - ...AA.A.A.AA.... - ..AAAAAAAAAAA... - .AAAA.DAD.AAAA.. - .AAA...A...AAA.. - ..A.........A... - ................ - .....AAAAAA..... - ...AAAAAAAAAA... - ..AAAA.AA.AAAA.. - .......AA....... - ................ - ................ - ................ -} -# tile 264 (plains centaur,male) -{ - ................ - ...KKA.......... - ...LLAA......... - .AAKKAA......... - .LLAALLA........ - LALLLLALA....... - LALLLKALA.A..... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 265 (plains centaur,female) -{ - ................ - ...KKA.......... - ...LLAA......... - .AAKKAA......... - .LLAALLA........ - LALLLLALA....... - LALLLKALA.A..... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 266 (forest centaur,male) -{ - ................ - ................ - ................ - ...KKA.......... - LA.LLAALA....... - LAALLAALA....... - .LLAALLA........ - ..LLLLA.A....... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKA.A.. - .KAKJJJJKJAAAA.. - .KAAKAAJAKA..... - ..C.KAAKAK...... - ....CA...C...... - ................ -} -# tile 267 (forest centaur,female) -{ - ................ - ................ - ................ - ...KKA.......... - LA.LLAALA....... - LAALLAALA....... - .LLAALLA........ - ..LLLLA.A....... - ..LKLKAAAAA..... - ..KLKJKJJKAA.... - .KJKJKJKJAKA.A.. - .KAKJJJJKJAAAA.. - .KAAKAAJAKA..... - ..C.KAAKAK...... - ....CA...C...... - ................ -} -# tile 268 (mountain centaur,male) -{ - ................ - ................ - ...KKA.......... - ...LLAA......... - ..AKKAA......... - .LJJJJLA........ - LAJKKJALA.A..... - LAKKKKALAAA..... - ..JJJJKJJKAA.... - .KJJJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 269 (mountain centaur,female) -{ - ................ - ................ - ...KKA.......... - ...LLAA......... - ..AKKAA......... - .LJJJJLA........ - LAJKKJALA.A..... - LAKKKKALAAA..... - ..JJJJKJJKAA.... - .KJJJKJKJAKAAAA. - .KAKJJJJKJAAA.A. - .KAAKAAAAKAA.... - ..CAKAAJAKA..... - ....KAAKAK...... - ....CA...C...... - ................ -} -# tile 270 (baby gray dragon,male) -{ - ................ - ................ - ................ - .....BBBA....... - ....NPNPPA...... - ...BPPPPPA...... - ..CHHPABPA.AAA.. - .CHCDA.BPAAAAAA. - ..D..BPPAAAAAAA. - ....BBPPPPPAAAA. - ...BOOPPPPPPAAA. - ..BPOBPPPPPPPAA. - ..BPPBPPOBPAPPA. - ..BPABP.ABPAPPA. - .....BPAA..PPAA. - ...........PAA.. -} -# tile 271 (baby gray dragon,female) -{ - ................ - ................ - ................ - .....BBBA....... - ....NPNPPA...... - ...BPPPPPA...... - ..CHHPABPA.AAA.. - .CHCDA.BPAAAAAA. - ..D..BPPAAAAAAA. - ....BBPPPPPAAAA. - ...BOOPPPPPPAAA. - ..BPOBPPPPPPPAA. - ..BPPBPPOBPAPPA. - ..BPABP.ABPAPPA. - .....BPAA..PPAA. - ...........PAA.. -} -# tile 272 (baby silver dragon,male) -{ - ................ - ................ - ................ - .....PPPA....... - ....OBOBBA...... - ...PBBBBBA...... - ..CHHBAPBA.AAA.. - .CHCDA.PBAAAAAA. - ..D..PBBAAAAAAA. - ....PPBBBBBAAAA. - ...PNNBBBBBBAAA. - ..PBNPBBBBBBBAA. - ..PBBPBBNPBABBA. - ..PBAPB.APBABBA. - .....PBAA..BBAA. - ...........BAA.. -} -# tile 273 (baby silver dragon,female) -{ - ................ - ................ - ................ - .....PPPA....... - ....OBOBBA...... - ...PBBBBBA...... - ..CHHBAPBA.AAA.. - .CHCDA.PBAAAAAA. - ..D..PBBAAAAAAA. - ....PPBBBBBAAAA. - ...PNNBBBBBBAAA. - ..PBNPBBBBBBBAA. - ..PBBPBBNPBABBA. - ..PBAPB.APBABBA. - .....PBAA..BBAA. - ...........BAA.. -} -# tile 274 (baby shimmering dragon,male) -{ - .I.............. - ...BBBBBBB.I.... - ..BF.FFF.FB...I. - .BF..BBBA.FB.... - BF..NPNPPAFB.I.. - BF.BPPPPPA.B.... - B.CHHPABPAFBAAI. - BCHCDA.BPAAFBAA. - B.D..BPPAAAAFBA. - B...BBPPPPPAAFB. - BF.BOOPPPPPPAAAB - BFBPOBPPPPPPPAFB - BFBPPBPPOBPAPPFB - B.BPABP.ABPAPPFB - B....BPAA..PPAAB - .B.........PAAB. -} -# tile 275 (baby shimmering dragon,female) -{ - .I.............. - ...BBBBBBB.I.... - ..BF.FFF.FB...I. - .BF..BBBA.FB.... - BF..NPNPPAFB.I.. - BF.BPPPPPA.B.... - B.CHHPABPAFBAAI. - BCHCDA.BPAAFBAA. - B.D..BPPAAAAFBA. - B...BBPPPPPAAFB. - BF.BOOPPPPPPAAAB - BFBPOBPPPPPPPAFB - BFBPPBPPOBPAPPFB - B.BPABP.ABPAPPFB - B....BPAA..PPAAB - .B.........PAAB. -} -# tile 276 (baby red dragon,male) -{ - ................ - ................ - ................ - .....IIIA....... - ....NDNDDA...... - ...IDDDDDA...... - ..CHHDAIDA.AAA.. - .CHCDA.IDAAAAAA. - ..D..IDDAAAAAAA. - ....IIDDDDDAAAA. - ...IHHDDDDDDAAA. - ..IDHIDDDDDDDAA. - ..IDDIDDHIDADDA. - ..IDAID.AIDADDA. - .....IDAA..DDAA. - ...........DAA.. -} -# tile 277 (baby red dragon,female) -{ - ................ - ................ - ................ - .....IIIA....... - ....NDNDDA...... - ...IDDDDDA...... - ..CHHDAIDA.AAA.. - .CHCDA.IDAAAAAA. - ..D..IDDAAAAAAA. - ....IIDDDDDAAAA. - ...IHHDDDDDDAAA. - ..IDHIDDDDDDDAA. - ..IDDIDDHIDADDA. - ..IDAID.AIDADDA. - .....IDAA..DDAA. - ...........DAA.. -} -# tile 278 (baby white dragon,male) -{ - ................ - ................ - ................ - .....NNNA....... - ....IOIOOA...... - ...NOOOOOA...... - ..CHHOANOA.AAA.. - .CHCDA.NOAAAAAA. - ..D..NOOAAAAAAA. - ....NNOOOOOAAAA. - ...NOOOOOOOOAAA. - ..NOONOOOOOOOAA. - ..NOONOOONOAOOA. - ..NOANO.ANOAOOA. - .....NOAA..OOAA. - ...........OAA.. -} -# tile 279 (baby white dragon,female) -{ - ................ - ................ - ................ - .....NNNA....... - ....IOIOOA...... - ...NOOOOOA...... - ..CHHOANOA.AAA.. - .CHCDA.NOAAAAAA. - ..D..NOOAAAAAAA. - ....NNOOOOOAAAA. - ...NOOOOOOOOAAA. - ..NOONOOOOOOOAA. - ..NOONOOONOAOOA. - ..NOANO.ANOAOOA. - .....NOAA..OOAA. - ...........OAA.. -} -# tile 280 (baby orange dragon,male) -{ - ................ - ................ - ................ - .....LLLA....... - ....NCNCCA...... - ...LCCCCCA...... - ..CHHCALCA.AAA.. - .CHCDA.LCAAAAAA. - ..D..LCCAAAAAAA. - ....LLCCCCCAAAA. - ...LOOCCCCCCAAA. - ..LCOLCCCCCCCAA. - ..LCCLCCOLCACCA. - ..LCALC.ALCACCA. - .....LCAA..CCAA. - ...........CAA.. -} -# tile 281 (baby orange dragon,female) -{ - ................ - ................ - ................ - .....LLLA....... - ....NCNCCA...... - ...LCCCCCA...... - ..CHHCALCA.AAA.. - .CHCDA.LCAAAAAA. - ..D..LCCAAAAAAA. - ....LLCCCCCAAAA. - ...LOOCCCCCCAAA. - ..LCOLCCCCCCCAA. - ..LCCLCCOLCACCA. - ..LCALC.ALCACCA. - .....LCAA..CCAA. - ...........CAA.. -} -# tile 282 (baby black dragon,male) -{ - ................ - ................ - ................ - .....AAA........ - ....NANAA....... - ...AAAAAA....... - ..CHHA.AA..PPP.. - .CHCD..AA.PPPPP. - ..D..AAAPPP.PPP. - ....AAAAAAAPPPP. - ...AAAAAAAAAPPP. - ..AAAAAAAAAAAPP. - ..AAAAAAAAAPAAP. - ..AAPAA.PAAPAAP. - .....AAP...AAPP. - ...........APP.. -} -# tile 283 (baby black dragon,female) -{ - ................ - ................ - ................ - .....AAA........ - ....NANAA....... - ...AAAAAA....... - ..CHHA.AA..PPP.. - .CHCD..AA.PPPPP. - ..D..AAAPPP.PPP. - ....AAAAAAAPPPP. - ...AAAAAAAAAPPP. - ..AAAAAAAAAAAPP. - ..AAAAAAAAAPAAP. - ..AAPAA.PAAPAAP. - .....AAP...AAPP. - ...........APP.. -} -# tile 284 (baby blue dragon,male) -{ - ................ - ................ - ................ - .....BBBA....... - ....NENEEA...... - ...BEEEEEA...... - ..CHHEABEA.AAA.. - CCHCDA.BEAAAAAA. - ..D..BEEAAAAAAA. - ....BBEEEEEAAAA. - ...BOOEEEEEEAAA. - ..BEOBEEEEEEEAA. - ..BEEBEEOBEAEEA. - ..BEABE.ABEAEEA. - .....BEAA..EEAA. - ...........EAA.. -} -# tile 285 (baby blue dragon,female) -{ - ................ - ................ - ................ - .....BBBA....... - ....NENEEA...... - ...BEEEEEA...... - ..CHHEABEA.AAA.. - CCHCDA.BEAAAAAA. - ..D..BEEAAAAAAA. - ....BBEEEEEAAAA. - ...BOOEEEEEEAAA. - ..BEOBEEEEEEEAA. - ..BEEBEEOBEAEEA. - ..BEABE.ABEAEEA. - .....BEAA..EEAA. - ...........EAA.. -} -# tile 286 (baby green dragon,male) -{ - ................ - ................ - ................ - .....GGGA....... - ....NFNFFA...... - ...GFFFFFA...... - ..CHHFAGFA.AAA.. - .CHCDA.GFAAAAAA. - ..D..GFFAAAAAAA. - ....GGFFFFFAAAA. - ...GOOFFFFFFAAA. - ..GFOGFFFFFFFAA. - ..GFFGFFOGFAFFA. - ..GFAGF.AGFAFFA. - .....GFAA..FFAA. - ...........FAA.. -} -# tile 287 (baby green dragon,female) -{ - ................ - ................ - ................ - .....GGGA....... - ....NFNFFA...... - ...GFFFFFA...... - ..CHHFAGFA.AAA.. - .CHCDA.GFAAAAAA. - ..D..GFFAAAAAAA. - ....GGFFFFFAAAA. - ...GOOFFFFFFAAA. - ..GFOGFFFFFFFAA. - ..GFFGFFOGFAFFA. - ..GFAGF.AGFAFFA. - .....GFAA..FFAA. - ...........FAA.. -} -# tile 288 (baby yellow dragon,male) -{ - ................ - ................ - ................ - .....NNNA....... - ....DHDHHA...... - ...NHHHHHA...... - ..CHHHANHA.AAA.. - .CHCDA.NHAAAAAA. - ..D..NHHAAAAAAA. - ....NNHHHHHAAAA. - ...NOOHHHHHHAAA. - ..NHONHHHHHHHAA. - ..NHHNHHONHAHHA. - ..NHANH.ANHAHHA. - .....NHAA..HHAA. - ...........HAA.. -} -# tile 289 (baby yellow dragon,female) -{ - ................ - ................ - ................ - .....NNNA....... - ....DHDHHA...... - ...NHHHHHA...... - ..CHHHANHA.AAA.. - .CHCDA.NHAAAAAA. - ..D..NHHAAAAAAA. - ....NNHHHHHAAAA. - ...NOOHHHHHHAAA. - ..NHONHHHHHHHAA. - ..NHHNHHONHAHHA. - ..NHANH.ANHAHHA. - .....NHAA..HHAA. - ...........HAA.. -} -# tile 290 (gray dragon,male) -{ - ......BBBPA..... - .....NPNPPPA.... - ....BPPPPPPA.... - ..DCHHP..PPA.... - CHCHCD..BPPA.... - HD.D...BPPA..... - ......OBPAAAAAA. - ....BOBPAAAAAAAA - ..BOOBPA.PP.AAA. - .BOOOBPPPPPP.AA. - .BOOOBPPPPPPPAA. - PPOOBBPPPPPPPPA. - BP.OBPPOOPP.P.A. - BPAABP.AAPPAPPA. - ....BPAA...PP.A. - ........PPPP.A.. -} -# tile 291 (gray dragon,female) -{ - ......BBBPA..... - .....NPNPPPA.... - ....BPPPPPPA.... - ..DCHHP..PPA.... - CHCHCD..BPPA.... - HD.D...BPPA..... - ......OBPAAAAAA. - ....BOBPAAAAAAAA - ..BOOBPA.PP.AAA. - .BOOOBPPPPPP.AA. - .BOOOBPPPPPPPAA. - PPOOBBPPPPPPPPA. - BP.OBPPOOPP.P.A. - BPAABP.AAPPAPPA. - ....BPAA...PP.A. - ........PPPP.A.. -} -# tile 292 (silver dragon,male) -{ - ......PPPBA..... - .....OBOBBBA.... - ....PBBBBBBA.... - ..DCHHB..BBA.... - CHCHCD..PBBA.... - HD.D...PBBA..... - ......NPBAAAAAA. - ....PNPBAAAAAAAA - ..PNNPBA.BB.AAA. - .PNNNPBBBBBB.AA. - .PNNNPBBBBBBBAA. - BBNNPPBBBBBBBBA. - PB.NPBBNNBB.B.A. - PBAAPB.AABBABBA. - ....PBAA...BB.A. - ........BBBB.A.. -} -# tile 293 (silver dragon,female) -{ - ......PPPBA..... - .....OBOBBBA.... - ....PBBBBBBA.... - ..DCHHB..BBA.... - CHCHCD..PBBA.... - HD.D...PBBA..... - ......NPBAAAAAA. - ....PNPBAAAAAAAA - ..PNNPBA.BB.AAA. - .PNNNPBBBBBB.AA. - .PNNNPBBBBBBBAA. - BBNNPPBBBBBBBBA. - PB.NPBBNNBB.B.A. - PBAAPB.AABBABBA. - ....PBAA...BB.A. - ........BBBB.A.. -} -# tile 294 (shimmering dragon,male) -{ - .I.BF.BBBPAFB... - ..BF.NPNPPPAFB.I - .BF.BPPPPPPAFB.. - .BDCHHP..PPAFBI. - CBCHCD..BPPAFB.. - HDBB...BPPA.B..I - ..BF..OBPAAAABA. - .BF.BOBPAAAAAFBA - BFBOOBPA.PP.AAFB - .BOOOBPPPPPP.AFB - .BOOOBPPPPPPPAFB - PPOOBBPPPPPPPPFB - BP.OBPPOOPP.P.FB - BPAABP.AAPPAPPFB - ....BPAA...PP.AB - ........PPPP.AB. -} -# tile 295 (shimmering dragon,female) -{ - .I.BF.BBBPAFB... - ..BF.NPNPPPAFB.I - .BF.BPPPPPPAFB.. - .BDCHHP..PPAFBI. - CBCHCD..BPPAFB.. - HDBB...BPPA.B..I - ..BF..OBPAAAABA. - .BF.BOBPAAAAAFBA - BFBOOBPA.PP.AAFB - .BOOOBPPPPPP.AFB - .BOOOBPPPPPPPAFB - PPOOBBPPPPPPPPFB - BP.OBPPOOPP.P.FB - BPAABP.AAPPAPPFB - ....BPAA...PP.AB - ........PPPP.AB. -} -# tile 296 (red dragon,male) -{ - ......IIIDA..... - .....NDNDDDA.... - ....IDDDDDDA.... - ..DCHHD..DDA.... - CHCHCD..IDDA.... - HD.D...IDDA..... - ......HIDAAAAAA. - ....IHIDAAAAAAAA - ..IHHIDAJDDJAAA. - .IHHHIDDDDDDJAA. - .IHHHIDDDDDDDAA. - DDHHIIDDDDDDDDA. - ID.HIDDHHDDJDJA. - IDAAID.AADDADDA. - ....IDAAJJJDDJA. - ........DDDDJA.. -} -# tile 297 (red dragon,female) -{ - ......IIIDA..... - .....NDNDDDA.... - ....IDDDDDDA.... - ..DCHHD..DDA.... - CHCHCD..IDDA.... - HD.D...IDDA..... - ......HIDAAAAAA. - ....IHIDAAAAAAAA - ..IHHIDAJDDJAAA. - .IHHHIDDDDDDJAA. - .IHHHIDDDDDDDAA. - DDHHIIDDDDDDDDA. - ID.HIDDHHDDJDJA. - IDAAID.AADDADDA. - ....IDAAJJJDDJA. - ........DDDDJA.. -} -# tile 298 (white dragon,male) -{ - ......NNNOA..... - .....IOIOOOA.... - ....NOOOOOOA.... - ..DCHHO..OOA.... - CHCHCD..NOOA.... - HD.D...NOOA..... - ......ONOAAAAAA. - ....NONOAAAAAAAA - ..NOONOA.OO.AAA. - .NOOONOOOOOOJAA. - .NOOONOOOOOOOAA. - OOOONNOOOOOOOOA. - NO.ONOOOOOO.OJA. - NOAANO.AAOOAOOA. - ....NOAA...OOJA. - ........OOOOJA.. -} -# tile 299 (white dragon,female) -{ - ......NNNOA..... - .....IOIOOOA.... - ....NOOOOOOA.... - ..DCHHO..OOA.... - CHCHCD..NOOA.... - HD.D...NOOA..... - ......ONOAAAAAA. - ....NONOAAAAAAAA - ..NOONOA.OO.AAA. - .NOOONOOOOOOJAA. - .NOOONOOOOOOOAA. - OOOONNOOOOOOOOA. - NO.ONOOOOOO.OJA. - NOAANO.AAOOAOOA. - ....NOAA...OOJA. - ........OOOOJA.. -} -# tile 300 (orange dragon,male) -{ - ......LLLCA..... - .....NCNCCCA.... - ....LCCCCCCA.... - ..DCHHC..CCA.... - CHCHCD..LCCA.... - HD.D...LCCA..... - ......OLCAAAAAA. - ....LOLCAAAAAAAA - ..LOOLCA.CCKAAA. - .LOOOLCCCCCCJAA. - .LOOOLCCCCCCCAA. - CCOOLLCCCCCCCCA. - LC.OLCCOOCCKCJA. - LCAALC.AACCACCA. - ....LCAA.KKCCJA. - ........CCCCJA.. -} -# tile 301 (orange dragon,female) -{ - ......LLLCA..... - .....NCNCCCA.... - ....LCCCCCCA.... - ..DCHHC..CCA.... - CHCHCD..LCCA.... - HD.D...LCCA..... - ......OLCAAAAAA. - ....LOLCAAAAAAAA - ..LOOLCA.CCKAAA. - .LOOOLCCCCCCJAA. - .LOOOLCCCCCCCAA. - CCOOLLCCCCCCCCA. - LC.OLCCOOCCKCJA. - LCAALC.AACCACCA. - ....LCAA.KKCCJA. - ........CCCCJA.. -} -# tile 302 (black dragon,male) -{ - ......AAAA...... - .....NANAAA..... - ....AAAAAAA..... - ..DCHHA..AA..... - CHCHCD..AAA..... - HD.D...AAA...... - ......AAA..PPPP. - ....AAAAPPPPPPPP - ..AAAAAAAAA.PPP. - .AAAAAAAAAAAAPP. - .AAAAAAAAAAAAPP. - AAAAAAAAAAAAAAP. - AA.AAAAAAAA.AAP. - AAPPAA.PPAAPAAP. - ....AAPP...AAAP. - ........AAAAA... -} -# tile 303 (black dragon,female) -{ - ......AAAA...... - .....NANAAA..... - ....AAAAAAA..... - ..DCHHA..AA..... - CHCHCD..AAA..... - HD.D...AAA...... - ......AAA..PPPP. - ....AAAAPPPPPPPP - ..AAAAAAAAA.PPP. - .AAAAAAAAAAAAPP. - .AAAAAAAAAAAAPP. - AAAAAAAAAAAAAAP. - AA.AAAAAAAA.AAP. - AAPPAA.PPAAPAAP. - ....AAPP...AAAP. - ........AAAAA... -} -# tile 304 (blue dragon,male) -{ - ......BBBEA..... - .....NENEEEA.... - ....BEEEEEEA.... - ..DCHHE..EEA.... - CHCHCD..BEEA.... - HD.D...BEEA..... - ......OBEAAAAAA. - ....BOBEAAAAAAAA - ..BOOBEA.EE.AAA. - .BOOOBEEEEEEJAA. - .BOOOBEEEEEEEAA. - EEOOBBEEEEEEEEA. - BE.OBEEOOEE.EJA. - BEAABE.AAEEAEEA. - ....BEAA...EEJA. - ...P....EEEEJA.. -} -# tile 305 (blue dragon,female) -{ - ......BBBEA..... - .....NENEEEA.... - ....BEEEEEEA.... - ..DCHHE..EEA.... - CHCHCD..BEEA.... - HD.D...BEEA..... - ......OBEAAAAAA. - ....BOBEAAAAAAAA - ..BOOBEA.EE.AAA. - .BOOOBEEEEEEJAA. - .BOOOBEEEEEEEAA. - EEOOBBEEEEEEEEA. - BE.OBEEOOEE.EJA. - BEAABE.AAEEAEEA. - ....BEAA...EEJA. - ...P....EEEEJA.. -} -# tile 306 (green dragon,male) -{ - ......GGGFA..... - .....NFNFFFA.... - ....GFFFFFFA.... - ..DCHHF..FFA.... - CHCHCD..GFFA.... - HD.D...GFFA..... - ......OGFAAAAAA. - ....GOGFAAAAAAAA - ..GOOGFA.FF.AAA. - .GOOOGFFFFFFJAA. - .GOOOGFFFFFFFAA. - FFOOGGFFFFFFFFA. - GF.OGFFOOFF.FJA. - GFAAGF.AAFFAFFA. - ....GFAA...FFJA. - ........FFFFJA.. -} -# tile 307 (green dragon,female) -{ - ......GGGFA..... - .....NFNFFFA.... - ....GFFFFFFA.... - ..DCHHF..FFA.... - CHCHCD..GFFA.... - HD.D...GFFA..... - ......OGFAAAAAA. - ....GOGFAAAAAAAA - ..GOOGFA.FF.AAA. - .GOOOGFFFFFFJAA. - .GOOOGFFFFFFFAA. - FFOOGGFFFFFFFFA. - GF.OGFFOOFF.FJA. - GFAAGF.AAFFAFFA. - ....GFAA...FFJA. - ........FFFFJA.. -} -# tile 308 (yellow dragon,male) -{ - ......NNNHA..... - .....DHDHHHA.... - ....NHHHHHHA.... - ..DCHHH..HHA.... - CHCHCD..NHHA.... - HD.D...NHHA..... - ......ONHAAAAAA. - ....NONHAAAAAAAA - ..NOONHAJHHJAAA. - .NOOONHHHHHHJAA. - .NOOONHHHHHHHAA. - HHOONNHHHHHHHHA. - NH.ONHHOOHHJHJA. - NHAANH.AAHHAHHA. - ....NHAAJJJHHJA. - ........HHHHJA.. -} -# tile 309 (yellow dragon,female) -{ - ......NNNHA..... - .....DHDHHHA.... - ....NHHHHHHA.... - ..DCHHH..HHA.... - CHCHCD..NHHA.... - HD.D...NHHA..... - ......ONHAAAAAA. - ....NONHAAAAAAAA - ..NOONHAJHHJAAA. - .NOOONHHHHHHJAA. - .NOOONHHHHHHHAA. - HHOONNHHHHHHHHA. - NH.ONHHOOHHJHJA. - NHAANH.AAHHAHHA. - ....NHAAJJJHHJA. - ........HHHHJA.. -} -# tile 310 (stalker,male) -{ - ................ - .......PPP...... - ......P.P.P..... - .....PPPPPP..... - .....PP..PPP.... - ....PPPPPP.P.... - ....P.PPPP.P.... - ....P.PPP..P.... - ....P..PP..P.... - ....P.PPPP.P.... - ....P.P..P.P.... - ....P.P..P.P.... - ......P..P...... - ......P..P...... - .....PP..PP..... - ................ -} -# tile 311 (stalker,female) -{ - ................ - .......PPP...... - ......P.P.P..... - .....PPPPPP..... - .....PP..PPP.... - ....PPPPPP.P.... - ....P.PPPP.P.... - ....P.PPP..P.... - ....P..PP..P.... - ....P.PPPP.P.... - ....P.P..P.P.... - ....P.P..P.P.... - ......P..P...... - ......P..P...... - .....PP..PP..... - ................ -} -# tile 312 (air elemental,male) -{ - ................ - ...P.PPP..P..... - ..P.PAPA.P...... - P..PPPPPP..P.... - .P.PPAAPPP...P.. - ..PPPAAP.P.P.... - ..PAPAAPAP...... - P.PAPPP.AP.P.AA. - ..PA.PP.AP.AAAA. - ..PAPPPPAPAAAA.. - ..PAP.APAPAAAA.. - ..PAP.APAPAAAAA. - ....P.APAAAAAAA. - ..P.P.APPAAAAAA. - ...PP.APPPA..... - ................ -} -# tile 313 (air elemental,female) -{ - ................ - ...P.PPP..P..... - ..P.PAPA.P...... - P..PPPPPP..P.... - .P.PPAAPPP...P.. - ..PPPAAP.P.P.... - ..PAPAAPAP...... - P.PAPPP.AP.P.AA. - ..PA.PP.AP.AAAA. - ..PAPPPPAPAAAA.. - ..PAP.APAPAAAA.. - ..PAP.APAPAAAAA. - ....P.APAAAAAAA. - ..P.P.APPAAAAAA. - ...PP.APPPA..... - ................ -} -# tile 314 (fire elemental,male) -{ - ................ - .H..LDDD........ - ...LDADAC.H..... - H..DDDDDD..H.H.. - ..LDDAADDD...... - ..DDDAADCD.H.... - ..DADAACAD...... - H.DADDDCAD...AA. - ..DACDDCAD.AAAA. - ..DADDDDADAAAA.. - ..DADCADADAAAA.. - H.DADCADADAAAAA. - ....DCADAAAAAAA. - .H.LDCADDAAAAAA. - ..LDDCADDDA..... - ................ -} -# tile 315 (fire elemental,female) -{ - ................ - .H..LDDD........ - ...LDADAC.H..... - H..DDDDDD..H.H.. - ..LDDAADDD...... - ..DDDAADCD.H.... - ..DADAACAD...... - H.DADDDCAD...AA. - ..DACDDCAD.AAAA. - ..DADDDDADAAAA.. - ..DADCADADAAAA.. - H.DADCADADAAAAA. - ....DCADAAAAAAA. - .H.LDCADDAAAAAA. - ..LDDCADDDA..... - ................ -} -# tile 316 (earth elemental,male) -{ - ..F............. - ....CKKK..F..... - ...CKAKAJ....F.. - ...KKKKKK....... - ..CKKAAKKK.F..F. - .FKKKAAKJK...... - ..KAKAAJAK..F... - ..KAKJJJAK...AA. - F.KAJKKJAK.AAAA. - ..KAKKKKAKAAAA.. - ..KAKJAKAKAAAA.. - ..KAKJAKAKAAAAA. - ....KJAKAAAAAAA. - .F.CKJAKKAAAAAA. - ..CKKJAKKKA..... - ................ -} -# tile 317 (earth elemental,female) -{ - ..F............. - ....CKKK..F..... - ...CKAKAJ....F.. - ...KKKKKK....... - ..CKKAAKKK.F..F. - .FKKKAAKJK...... - ..KAKAAJAK..F... - ..KAKJJJAK...AA. - F.KAJKKJAK.AAAA. - ..KAKKKKAKAAAA.. - ..KAKJAKAKAAAA.. - ..KAKJAKAKAAAAA. - ....KJAKAAAAAAA. - .F.CKJAKKAAAAAA. - ..CKKJAKKKA..... - ................ -} -# tile 318 (water elemental,male) -{ - ................ - ....PBBB..E..... - .E.PBABAE...E... - ...BBBBBB....... - ..PBBAABBB.E..E. - E.BBBAABEB...... - ..BABAABEB.E.... - ..BABBBBEB...AA. - ..BAPBBEAB.AAAA. - E.BABBBBABAAAA.. - ..BABEABABAAAA.. - ..BABEABABAAAAA. - ....BEABAAAAAAA. - .E.PBEABBAAAAAA. - ..PBBEABBBA..... - ................ -} -# tile 319 (water elemental,female) -{ - ................ - ....PBBB..E..... - .E.PBABAE...E... - ...BBBBBB....... - ..PBBAABBB.E..E. - E.BBBAABEB...... - ..BABAABEB.E.... - ..BABBBBEB...AA. - ..BAPBBEAB.AAAA. - E.BABBBBABAAAA.. - ..BABEABABAAAA.. - ..BABEABABAAAAA. - ....BEABAAAAAAA. - .E.PBEABBAAAAAA. - ..PBBEABBBA..... - ................ -} -# tile 320 (lichen,male) -{ - ................ - ................ - ...FFF...FFF.... - ..FCFFFFFCCFA... - .FCOOFFFCOFFFA.. - .FCOOFFFCFFFFA.. - ..FFFFFFFFFFA... - ...AFFFCCFFFA... - ...FFFFCOFFAA... - ..FCCFFCOFCFA... - ..FCOFFCFFOCFA.. - ..FFCFFFCFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 321 (lichen,female) -{ - ................ - ................ - ...FFF...FFF.... - ..FCFFFFFCCFA... - .FCOOFFFCOFFFA.. - .FCOOFFFCFFFFA.. - ..FFFFFFFFFFA... - ...AFFFCCFFFA... - ...FFFFCOFFAA... - ..FCCFFCOFCFA... - ..FCOFFCFFOCFA.. - ..FFCFFFCFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 322 (brown mold,male) -{ - ................ - ................ - ...JJJ...JJJ.... - ..JKJJJJJKKJA... - .JKCCJJJKCJJJA.. - .JKCCJJJKJJJJA.. - ..JJJJJJJJJJA... - ...AJJJKKJJJA... - ...JJJJKCJJAA... - ..JKKJJKCJKJA... - ..JKCJJKJJCKJA.. - ..JJKJJJKJJJJA.. - ...JJJAAJJJJJA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 323 (brown mold,female) -{ - ................ - ................ - ...JJJ...JJJ.... - ..JKJJJJJKKJA... - .JKCCJJJKCJJJA.. - .JKCCJJJKJJJJA.. - ..JJJJJJJJJJA... - ...AJJJKKJJJA... - ...JJJJKCJJAA... - ..JKKJJKCJKJA... - ..JKCJJKJJCKJA.. - ..JJKJJJKJJJJA.. - ...JJJAAJJJJJA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 324 (yellow mold,male) -{ - ................ - ................ - ...HHH...HHH.... - ..HHHHHHHNHHA... - .HHNNOHHNNOHHA.. - .HHNNOOHHOOHHA.. - ..HHOOHHHHHHA... - ...AHHHHHHHHA... - ...HHHHNNOHAA... - ..HHHHHNNOHHA... - ..HNNOHHHONOHA.. - ..HHOHHHHHOOHA.. - ...HHHAAHHHHHA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 325 (yellow mold,female) -{ - ................ - ................ - ...HHH...HHH.... - ..HHHHHHHNHHA... - .HHNNOHHNNOHHA.. - .HHNNOOHHOOHHA.. - ..HHOOHHHHHHA... - ...AHHHHHHHHA... - ...HHHHNNOHAA... - ..HHHHHNNOHHA... - ..HNNOHHHONOHA.. - ..HHOHHHHHOOHA.. - ...HHHAAHHHHHA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 326 (green mold,male) -{ - ................ - ................ - ...FFF...FFF.... - ..FGFFFFFGGFA... - .FGOOFFFGOFFFA.. - .FGOOFFFGFFFFA.. - ..FFFFFFFFFFA... - ...AFFFGGFFFA... - ...FFFFGOFFAA... - ..FGGFFGOFGFA... - ..FGOFFGFFOGFA.. - ..FFGFFFGFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 327 (green mold,female) -{ - ................ - ................ - ...FFF...FFF.... - ..FGFFFFFGGFA... - .FGOOFFFGOFFFA.. - .FGOOFFFGFFFFA.. - ..FFFFFFFFFFA... - ...AFFFGGFFFA... - ...FFFFGOFFAA... - ..FGGFFGOFGFA... - ..FGOFFGFFOGFA.. - ..FFGFFFGFFFFA.. - ...FFFAAFFFFFA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 328 (red mold,male) -{ - ................ - ................ - ...DDD...DDD.... - ..DCDDDDDCCDA... - .DLLCDDDCLDDDA.. - .DCCCDDDCDDDDA.. - ..DDDDDDDDDDA... - ...ADDDCCDDDA... - ...DDDDCLDDAA... - ..DCCDDCLDCDA... - ..DCLDDCDDLCDA.. - ..DDCDDDCDDDDA.. - ...DDDAADDDDDA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 329 (red mold,female) -{ - ................ - ................ - ...DDD...DDD.... - ..DCDDDDDCCDA... - .DLLCDDDCLDDDA.. - .DCCCDDDCDDDDA.. - ..DDDDDDDDDDA... - ...ADDDCCDDDA... - ...DDDDCLDDAA... - ..DCCDDCLDCDA... - ..DCLDDCDDLCDA.. - ..DDCDDDCDDDDA.. - ...DDDAADDDDDA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 330 (shrieker,male) -{ - ................ - ................ - ................ - ................ - .....GGGGFF..... - ...GGGGIGIDFF... - .GGGIIGGGIIFFFF. - GIIGIIGGGGGGGDDF - GIIGGGGIIGIIGIDF - GGGGIGGIIGIIGGFF - ..GGGGGGGGGGG... - ......FFF..AAAAA - ....AGGGFFAAAAAA - ...AGGGGGGFAAAA. - ...AAAAAAAAAA... - ................ -} -# tile 331 (shrieker,female) -{ - ................ - ................ - ................ - ................ - .....GGGGFF..... - ...GGGGIGIDFF... - .GGGIIGGGIIFFFF. - GIIGIIGGGGGGGDDF - GIIGGGGIIGIIGIDF - GGGGIGGIIGIIGGFF - ..GGGGGGGGGGG... - ......FFF..AAAAA - ....AGGGFFAAAAAA - ...AGGGGGGFAAAA. - ...AAAAAAAAAA... - ................ -} -# tile 332 (violet fungus,male) -{ - ................ - ................ - ...III...III.... - ..ILIIIIILLIA... - .IOOLIIILOIIIA.. - .ILLLIIILIIIIA.. - ..IIIIIIIIIIA... - ...AIIILLIIIA... - ...IIIILOIIAA... - ..ILLIILOILIA... - ..ILOIILIIOLIA.. - ..IILIIILIIIIA.. - ...IIIAAIIIIIA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 333 (violet fungus,female) -{ - ................ - ................ - ...III...III.... - ..ILIIIIILLIA... - .IOOLIIILOIIIA.. - .ILLLIIILIIIIA.. - ..IIIIIIIIIIA... - ...AIIILLIIIA... - ...IIIILOIIAA... - ..ILLIILOILIA... - ..ILOIILIIOLIA.. - ..IILIIILIIIIA.. - ...IIIAAIIIIIA.. - .....AA.AAAAA... - ................ - ................ -} -# tile 334 (gnome,male) -{ - ................ - ................ - ................ - .....DF......... - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - .....OLO...AAA.. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 335 (gnome,female) -{ - ................ - ................ - ................ - .....DF......... - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - .....LLL...AAA.. - ...FGGGGFFAAAA.. - ...GAGFFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 336 (gnome leader,male) -{ - ................ - ................ - ......D......... - ......G......... - ......G......... - .....GFF........ - ....HHHHH....... - ....GLLLF.....A. - .....OLO...AAA.. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 337 (gnome leader,female) -{ - ................ - ................ - ......D......... - ......G......... - ......G......... - .....GFF........ - ....HHHHH....... - ....GLLLF.....A. - .....LLL...AAA.. - ...FGGGGFFAAAA.. - ...GAGGFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 338 (gnomish wizard,male) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - ...FFOLOFF.AAA.. - ...GFOOOFFAAAA.. - ...FAGOFAFAAAA.. - ...GLKNKFFAAA... - ...FFGFFFFA..... - ...GFFFFGFA..... - ................ - ................ -} -# tile 339 (gnomish wizard,female) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GLLLF....... - ...FFLLLFF.AAA.. - ...GFGFGFFAAAA.. - ...FAGGFAFAAAA.. - ...GLKNKFFAAA... - ...FFGFFFFA..... - ...GFFFFGFA..... - ................ - ................ -} -# tile 340 (gnome ruler,male) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....GLLLF...A... - .....OLO...AAAA. - ...FGOOOFFAAAA.. - ...GAGOFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 341 (gnome ruler,female) -{ - ................ - ................ - ................ - ................ - ....H.C.H....... - ....HCHCH....... - ....HHHHH....... - ....GLLLF...A... - .....LLL...AAAA. - ...FGGGGFFAAAA.. - ...GAGFFAFAAAA.. - ....LKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 342 (giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLKLKCKCLKLLLA - .LLAALLCCLLAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 343 (giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLKLKCKCLKLLLA - .LLAALLCCLLAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 344 (stone giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLAAKCKCLKLLLA - .LLPPPACCLLAALLA - .LLPPPPAKKJAALLA - .CLCPPPAJJKKCLAA - ..LLPPALACLJLLAA - .....ALJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 345 (stone giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCLLJJJJLLCCAA - .CLLLCCKCKCLLLCA - .LLLAAKCKCLKLLLA - .LLPPPACCLLAALLA - .LLPPPPAKKJAALLA - .CLCPPPAJJKKCLAA - ..LLPPALACLJLLAA - .....ALJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 346 (hill giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ...JJKJJJJJJJAA. - ..LJJCCKCKCJJLA. - ..JLKKKCKCKKLJA. - ..LAAKKCCKJAALAA - ..LAAJJJKKJAALAA - ..LC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 347 (hill giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ...JJKJJJJJJJAA. - ..LJJCCKCKCJJLA. - ..JLKKKCKCKKLJA. - ..LAAKKCCKJAALAA - ..LAAJJJKKJAALAA - ..LC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 348 (fire giant,male) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLJAAAA. - ...JPDJJJJJJJAA. - ..LDDHDKCKCJJLA. - ..JLHDDCKCKKLJA. - ..LAHDHCCKJAALAA - JLAADDHJKKJAALAA - JJLJDHHJJJKKCLAA - ..LLJJJJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 349 (fire giant,female) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLJAAAA. - ...JPDJJJJJJJAA. - ..LDDHDKCKCJJLA. - ..JLHDDCKCKKLJA. - ..LAHDHCCKJAALAA - JLAADDHJKKJAALAA - JJLJDHHJJJKKCLAA - ..LLJJJJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.LLLLKAA -} -# tile 350 (frost giant,male) -{ - .....KJJJJAA.... - ....KJJJJJJJA... - ....JJLLLLJJA... - ....JEELLEEJA... - ....JLLLLLLJA... - ....AKJJJJJAAA.. - .....KJAAJJAAAA. - ....KKJJJJAJAAAA - ...KJKJJJJAJJAAA - ..KJKKJJJJJKJJAA - ..KAAJKJJAJAAJAA - ..JAAJKKAKJAAJAA - ..LC.JJJJJKKCLAA - ..LL.CJJAJLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 351 (frost giant,female) -{ - .....KJJJJAA.... - ....KJJJJJJJA... - ....JJLLLLJJA... - ....JEELLEEJA... - ....JLLLLLLJA... - ....ALLLLLLAAA.. - .....LLAALLAAAA. - ....KKLLLLKKAAAA - ...KJKKKKKKJJAAA - ..KJKKJJJJKKJJAA - ..KAAJKJJKJAAJAA - ..JAAJKKKKJAAJAA - ..LC.JJJJJKKCLAA - ..LL.CJJAJLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 352 (ettin,male) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NPP..NPP..P... - ..ALPPLALPPLA... - ..APPPPAPPPPA... - ..APAAPAPAAPAA.. - ..APPPPAPPPPAAA. - ..BIIIIJJJIIIBAA - .BPPPIIIIIIPPPBA - .PPPFPIIIIPFPPPA - .PPAAPIIIIPAAPPA - .PPAAIIIIIIAAPPA - .BPB.IIFFIIABPAA - ..PP.BPAABPAPPAA - .....BPAABPAAAAA - ...PPPPA.BPPPFAA -} -# tile 353 (ettin,female) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NPP..NPP..P... - ..ALPPLALPPLA... - ..APPPPAPPPPA... - ..APAAPAPAAPAA.. - ..APPPPAPPPPAAA. - ..BIIIIJJJIIIBAA - .BPPPIIIIIIPPPBA - .PPPFPIIIIPFPPPA - .PPAAPIIIIPAAPPA - .PPAAIIIIIIAAPPA - .BPB.IIFFIIABPAA - ..PP.BPAABPAPPAA - .....BPAABPAAAAA - ...PPPPA.BPPPFAA -} -# tile 354 (storm giant,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAH.. - .....ALLLLJAHAA. - ...JJKJJJJJHHAA. - ..LJJCCKCKHHLAA. - ..JLKKKCKHHHHHH. - ..LAAKKCCKJAHHAA - ..LAAJJJKKJHHALA - ..LC.JJJJJKHAAAA - ..LL.CLJACHAAAAA - .....CLJACCJAAAA - ...LLLLJ.LLLLKAA -} -# tile 355 (storm giant,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJLLLLJJA... - ....JFFLLFFJA... - ....JLLLLLLJA... - ....ALLAALLAAH.. - .....ALLLLJAHAA. - ...JJKJJJJJHHAA. - ..LJJCCKCKHHLAA. - ..JLKKKCKHHHHHH. - ..LAAKKCCKJAHHAA - ..LAAJJJKKJHHALA - ..LC.JJJJJKHAAAA - ..LL.CLJACHAAAAA - .....CLJACCJAAAA - ...LLLLJ.LLLLKAA -} -# tile 356 (titan,male) -{ - .....AAAAAAA.... - ....AALLLLAAA... - ....A..LL..AA... - ....ALLLLLLAA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCJJJJJJJJCCA. - .CLLLCCKCKCLLLCA - .LLLKJKCKCJKLLLA - .LLAAJJCCJJAALLA - .LLAAJJCCJJAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 357 (titan,female) -{ - .....AAAAAAA.... - ....AALLLLAAA... - ....A..LL..AA... - ....ALLLLLLAA... - ....ALLAALLAAA.. - .....ALLLLJAAAA. - ..CCJJJJJJJJCCA. - .CLLLCCKCKCLLLCA - .LLLKJKCKCJKLLLA - .LLAAJJCCJJAALLA - .LLAAJJCCJJAALLA - .LLAAJJJKKJAALLA - .CLC.JJJJJKKCLAA - ..LL.CLJACLJLLAA - .....CLJACLJAAAA - ...LLLLJ.CLLLKAA -} -# tile 358 (minotaur,male) -{ - ................ - .O..........O... - .OOOJJJJJJOOO... - ..OOJJKJJJOO.... - ...JGAKJGAJA.... - ...JJJKJJJJA.... - ....JJKJJJAAA... - ....JKKKJAAAA... - ..CLJAJAKALCAA.A - .CLLJJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. - .LL.JJJJJJJLLAAA - .LL.JJJJJJJLLAAA - ....CLCACLCAAAAA - ..LLLLL.LLLLLAA. -} -# tile 359 (minotaur,female) -{ - ................ - .O..........O... - .OOOJJJJJJOOO... - ..OOJJKJJJOO.... - ...JGAKJGAJA.... - ...JJJKJJJJA.... - ....JJKJJJAAA... - ....JKKKJAAAA... - ..CLJAJAKALCAA.A - .CLLJJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAAJLLLLJAALAA. - .LL.JJJJJJJLLAAA - .LL.JJJJJJJLLAAA - ....CLCACLCAAAAA - ..LLLLL.LLLLLAA. -} -# tile 360 (jabberwock,male) -{ - ................ - ...DP........... - ....DP.ADOO..... - ..DAIDADIPAD.... - ...DIAPIPA...... - ...DBDDDA....... - ..IBBDADDA..AA.. - .DDDDAODDIAAAA.. - ..OAOA.DDAIAAA.. - ..IOAODDAAADDAA. - ..DDDADDDDAIDA.. - ...AAADDIDIDDD.. - ....IDDAIDDDDA.. - ....IDAAIDAA.... - ...IDAA..ID..... - ................ -} -# tile 361 (jabberwock,female) -{ - ................ - ...DP........... - ....DP.ADOO..... - ..DAIDADIPAD.... - ...DIAPIPA...... - ...DBDDDA....... - ..IBBDADDA..AA.. - .DDDDAODDIAAAA.. - ..OAOA.DDAIAAA.. - ..IOAODDAAADDAA. - ..DDDADDDDAIDA.. - ...AAADDIDIDDD.. - ....IDDAIDDDDA.. - ....IDAAIDAA.... - ...IDAA..ID..... - ................ -} -# tile 362 (vorpal jabberwock,male) -{ - ................ - ...GP........... - ....GP.AGOO..... - ..GAFGAGFPAG.... - ...GFAPFPA...... - ...GHGGGA....... - ..FHHGAGGA..AA.. - .GGGGAOGGFAAAA.. - ..OAOA.GGAFAAA.. - ..FOAOGGAAAGGAA. - ..GGGAGGGGAFGA.. - ...AAAGGFGFGGG.. - ....FGGAFGGGGA.. - ....FGAAFGAA.... - ...FGAA..FG..... - ................ -} -# tile 363 (vorpal jabberwock,female) -{ - ................ - ...GP........... - ....GP.AGOO..... - ..GAFGAGFPAG.... - ...GFAPFPA...... - ...GHGGGA....... - ..FHHGAGGA..AA.. - .GGGGAOGGFAAAA.. - ..OAOA.GGAFAAA.. - ..FOAOGGAAAGGAA. - ..GGGAGGGGAFGA.. - ...AAAGGFGFGGG.. - ....FGGAFGGGGA.. - ....FGAAFGAA.... - ...FGAA..FG..... - ................ -} -# tile 364 (Keystone Kop,male) -{ - ................ - ....AA.......... - ...AAAA......... - ...AOAA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.PPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 365 (Keystone Kop,female) -{ - ................ - ....AA.......... - ...AAAA......... - ...AOAA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.PPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 366 (Kop Sergeant,male) -{ - ................ - ....AA.......... - ...AOOA......... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 367 (Kop Sergeant,female) -{ - ................ - ....AA.......... - ...AOOA......... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ...AAAA.AAA..... - ..AAAAAAAAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 368 (Kop Lieutenant,male) -{ - ................ - ....AA.......... - ...AOOA...C..... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ..OAAAO.AAA..... - .OAAAAA.AAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 369 (Kop Lieutenant,female) -{ - ................ - ....AA.......... - ...AOOA...C..... - ...AOOA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - ..OAAAO.AAA..... - .OAAAAA.AAC.P... - .AA.AAAAA.CPPP.. - ..AAAAAA.PPPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 370 (Kop Kaptain,male) -{ - ................ - ....AA....C..... - ...AHHA...C..... - ...AHHA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - .HHAAAAHHAA..... - .AAAAHAAAACCC... - .AA.AHAAA.CPPP.. - ..AAAHAA.PCPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 371 (Kop Kaptain,female) -{ - ................ - ....AA....C..... - ...AHHA...C..... - ...AHHA...C..... - ..AAAAAA..C..... - ...LLLL...C..... - ....LL....C..... - .HHAAAAHHAA..... - .AAAAHAAAACCC... - .AA.AHAAA.CPPP.. - ..AAAHAA.PCPPPP. - ....AAAAPPPAPP.. - .A.AAAAAAPAAA... - AAAAA.PAAAAA.... - ..AA....AA...... - ................ -} -# tile 372 (lich,male) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....O.PPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 373 (lich,female) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....O.PPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 374 (demilich,male) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....L.PPPAAAA.A. - ......LPPAAA.A.. - .....LLAL.A..... - ...LLLA.LA...... - ......LLL....... - ................ -} -# tile 375 (demilich,female) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...OOPPP....AAA. - ..O.PPPPPA..AAA. - .O...PPPP.AAAAA. - ....L.PPPAAAA.A. - ......LPPAAA.A.. - .....LLAL.A..... - ...LLLA.LA...... - ......LLL....... - ................ -} -# tile 376 (master lich,male) -{ - ...H............ - ...HCH.H........ - ...HHHCH........ - ..AOAOHH........ - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...PPPPP....AAA. - ..PPPPPPPA..AAA. - .O..PPPPP.AAAAA. - ....OPPPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 377 (master lich,female) -{ - ...H............ - ...HCH.H........ - ...HHHCH........ - ..AOAOHH........ - ..OOOOO......... - ..OO.O.......... - .....PPP........ - ...PPPPP....AAA. - ..PPPPPPPA..AAA. - .O..PPPPP.AAAAA. - ....OPPPPAAAA.A. - ......PPPAAA.A.. - .....OPAP.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 378 (arch-lich,male) -{ - ................ - ................ - ...OOO.......... - ..DODOO......... - ..OOOOO......... - H.OO.O.......... - A....PPP........ - A..OOPPP....AAA. - .AO.PPPPPA..AAA. - .O...PPPP.AAAAA. - .A..O.PPPAAAA.A. - ..A...PPPAAA.A.. - ..A..OPAP.A..... - ..AOOOA.OA...... - ......OOO....... - ................ -} -# tile 379 (arch-lich,female) -{ - ................ - ................ - ...OOO.......... - ..DODOO......... - ..OOOOO......... - H.OO.O.......... - A....PPP........ - A..OOPPP....AAA. - .AO.PPPPPA..AAA. - .O...PPPP.AAAAA. - .A..O.PPPAAAA.A. - ..A...PPPAAA.A.. - ..A..OPAP.A..... - ..AOOOA.OA...... - ......OOO....... - ................ -} -# tile 380 (kobold mummy,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NONONO....... - ...OAOAO.OP..... - ....ONN...A..... - ...ONODNA.AA.... - ..OLONNONAAA.A.. - ..NALONANAAAAA.. - ..NAOLOAOAAAAA.. - ....NOLAAAAAA... - ....NANAAAA..... - ...OOANOA....... - ................ - ................ -} -# tile 381 (kobold mummy,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NONONO....... - ...OAOAO.OP..... - ....ONN...A..... - ...ONODNA.AA.... - ..OLONNONAAA.A.. - ..NALONANAAAAA.. - ..NAOLOAOAAAAA.. - ....NOLAAAAAA... - ....NANAAAA..... - ...OOANOA....... - ................ - ................ -} -# tile 382 (gnome mummy,male) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GGFO....... - ....GGFFOOP..... - ....GDODF....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 383 (gnome mummy,female) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GGFO....... - ....GGFFOOP..... - ....GDODF....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 384 (orc mummy,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOOP........ - ....DODPOP...... - ....OOOA........ - ..OOOOOOOA.AA... - ..OOOOOOO.AAA... - ..OAOOOAACCC.... - ..OAOOOCCAAA.... - ....OCCOAAAAAA.. - ...CCAOOAAAA.... - ..OOOAOOOA...... - ................ - ................ -} -# tile 385 (orc mummy,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOOP........ - ....DODPOP...... - ....OOOA........ - ..OOOOOOOA.AA... - ..OOOOOOO.AAA... - ..OAOOOAACCC.... - ..OAOOOCCAAA.... - ....OCCOAAAAAA.. - ...CCAOOAAAA.... - ..OOOAOOOA...... - ................ - ................ -} -# tile 386 (dwarf mummy,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BBEO....... - ....BBEEEOP..... - ....BDODE....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 387 (dwarf mummy,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BBEO....... - ....BBEEEOP..... - ....BDODE....... - .....ONO...AAA.. - ...NONOONOAAAA.. - ...OANLOAOAAAA.. - ....NNOLOAAAA... - ....NOANDAA..... - ....NOAOO.A..... - ................ - ................ -} -# tile 388 (elf mummy,male) -{ - ................ - ................ - .........O...... - .......OOOP..... - ......OOOOP..... - ......OEOEAP.... - ......OOOOA..... - ......AOOA....A. - ......OAAO..AAA. - .....OOOOOOAAAA. - ....OALOOLAOAAA. - ....OADOOOAOAA.. - ......OOAOAA.A.. - .....OOA.OOA.... - ................ - ................ -} -# tile 389 (elf mummy,female) -{ - ................ - ................ - .........O...... - .......OOOP..... - ......OOOOP..... - ......OEOEAP.... - ......OOOOA..... - ......AOOA....A. - ......OAAO..AAA. - .....OOOOOOAAAA. - ....OALOOLAOAAA. - ....OADOOOAOAA.. - ......OOAOAA.A.. - .....OOA.OOA.... - ................ - ................ -} -# tile 390 (human mummy,male) -{ - ................ - ................ - ...ONNO......... - ...NNNNOP....... - ..PANAN.OPP..... - ..PNNNN......... - ..ONOONNP....... - .ONLNNOOO....... - .NJNOOOOO..AAA.. - .OJOOOODN.AAAA.. - .NJOLNOAOAAAAAA. - .OCNO.NKNAAAAA.. - .N.OO.OLAAAAAAA. - ...OOAOOAAA..... - ..NNN.NNNA...... - ................ -} -# tile 391 (human mummy,female) -{ - ................ - ................ - ...ONNO......... - ...NNNNOP....... - ..PANAN.OPP..... - ..PNNNN......... - ..ONOONNP....... - .ONLNNOOO....... - .NJNOOOOO..AAA.. - .OJOOOODN.AAAA.. - .NJOLNOAOAAAAAA. - .OCNO.NKNAAAAA.. - .N.OO.OLAAAAAAA. - ...OOAOOAAA..... - ..NNN.NNNA...... - ................ -} -# tile 392 (ettin mummy,male) -{ - .....NN..ONOO... - ...NNOOONNOOOO.. - ...NOOOONOOOOOO. - ...OFOFOLOFOFO.O - ...OOOOOLOOOOO.P - ...NOOOOLNNOOOA. - ...ONOOOLOOOOAAA - ..OOOONNNNNNNOAA - .ONNNNNNOONOOOOA - .ONODNNOOOOOOOOA - .NNAAONNONOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 393 (ettin mummy,female) -{ - .....NN..ONOO... - ...NNOOONNOOOO.. - ...NOOOONOOOOOO. - ...OFOFOLOFOFO.O - ...OOOOOLOOOOO.P - ...NOOOOLNNOOOA. - ...ONOOOLOOOOAAA - ..OOOONNNNNNNOAA - .ONNNNNNOONOOOOA - .ONODNNOOOOOOOOA - .NNAAONNONOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 394 (giant mummy,male) -{ - ......ONOOAA.... - ....ONNNOOOOA... - ....NNOOOOOOO... - ....NFFOOFFOOP.. - ....NONOOOOOAOP. - ....AONOOOOAAAP. - .....ANOOODAAAA. - ..OOOONOOONNNOAA - .ONNNNNOOOOOOOOA - .ONODNNLOOOOOOOA - .NNAAONOLNOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 395 (giant mummy,female) -{ - ......ONOOAA.... - ....ONNNOOOOA... - ....NNOOOOOOO... - ....NFFOOFFOOP.. - ....NONOOOOOAOP. - ....AONOOOOAAAP. - .....ANOOODAAAA. - ..OOOONOOONNNOAA - .ONNNNNOOOOOOOOA - .ONODNNLOOOOOOOA - .NNAAONOLNOAAOOA - .NOAAONOONLAAOOA - .OOO.ONOONOOOOAA - ..OO.NNOANOLOOAA - .....NOOANOOAAAA - ...OOOOO.OOOOKAA -} -# tile 396 (red naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LDLAA........ - ...IDDAAAAADA... - ...IDDDAAADDA... - ....IIDDDDDA.... - ................ -} -# tile 397 (red naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LDLAA........ - ...IDDAAAAADA... - ...IDDDAAADDA... - ....IIDDDDDA.... - ................ -} -# tile 398 (black naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLA......... - ...LALAA........ - ...AAAPA..PAA... - ...AAAAPPPAAA... - ....AAAAAAAA.... - ................ -} -# tile 399 (black naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLA......... - ...LALAA........ - ...AAAPA..PAA... - ...AAAAPPPAAA... - ....AAAAAAAA.... - ................ -} -# tile 400 (golden naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LHLAA........ - ...NHHAAAAAHA... - ...NHHHAAAHHA... - ....NNHHHHHA.... - ................ -} -# tile 401 (golden naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LHLAA........ - ...NHHAAAAAHA... - ...NHHHAAAHHA... - ....NNHHHHHA.... - ................ -} -# tile 402 (guardian naga hatchling,male) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LFLAA........ - ...GFFAAAAAFA... - ...GFFFAAAFFA... - ....GGFFFFFA.... - ................ -} -# tile 403 (guardian naga hatchling,female) -{ - ................ - ................ - ................ - ................ - ....K........... - ...KLK.......... - ...LLLA......... - ...ALAA......... - ...LALA......... - ...LLLA......... - ...LLLAA........ - ...LFLAA........ - ...GFFAAAAAFA... - ...GFFFAAAFFA... - ....GGFFFFFA.... - ................ -} -# tile 404 (red naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLDA..AA.... - ...LDLDA.AAAA... - ...IDDDAAAIIA... - ...IDDDAIDDDIDA. - ...IDDDIDDDDDDDA - ...IDDDDDDAA.DDA - ....DDDDDA..DDA. - .....DDAA..DDA.. - ..........DA.... -} -# tile 405 (red naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLDA..AA.... - ...LDLDA.AAAA... - ...IDDDAAAIIA... - ...IDDDAIDDDIDA. - ...IDDDIDDDDDDDA - ...IDDDDDDAA.DDA - ....DDDDDA..DDA. - .....DDAA..DDA.. - ..........DA.... -} -# tile 406 (black naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLAA........ - ...LALAA..PPP... - ...AAAAPPPAAP... - ...AAAAPAAAAAAP. - ...AAAAAAAAAAAAP - ...AAAAAAAPP.AAP - ....AAAAAP..AAP. - .....AAPP..AAP.. - ..........AP.... -} -# tile 407 (black naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLAA........ - ...LALAA..PPP... - ...AAAAPPPAAP... - ...AAAAPAAAAAAP. - ...AAAAAAAAAAAAP - ...AAAAAAAPP.AAP - ....AAAAAP..AAP. - .....AAPP..AAP.. - ..........AP.... -} -# tile 408 (golden naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLHA..AA.... - ...LHLHA.AAAA... - ...NHHHAAANNA... - ...NHHHANHHHNHA. - ...NHHHNHHHHHHHA - ...NHHHHHHAA.HHA - ....HHHHHA..HHA. - .....HHAA..HHA.. - ..........HA.... -} -# tile 409 (golden naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ...LAALA........ - ...LLLLA........ - ...LLLHA..AA.... - ...LHLHA.AAAA... - ...NHHHAAANNA... - ...NHHHANHHHNHA. - ...NHHHNHHHHHHHA - ...NHHHHHHAA.HHA - ....HHHHHA..HHA. - .....HHAA..HHA.. - ..........HA.... -} -# tile 410 (guardian naga,male) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ..CLAALC........ - ..LLLLLL........ - ..CLLCLC..AA.... - ...CLLCA.AAAA... - ...GLFCAAAGGA... - ...GFFFAAFFFGFA. - ...GFFFGFFFFFFFA - ...GFFFFFFAA.FFA - ....FFFFFA..FFA. - .....FFAA..FFA.. - ..........FA.... -} -# tile 411 (guardian naga,female) -{ - ................ - ....KK.......... - ...KLLK......... - ...LLLLA........ - ...ALLAA........ - ..CLAALC........ - ..LLLLLL........ - ..CLLCLC..AA.... - ...CLLCA.AAAA... - ...GLFCAAAGGA... - ...GFFFAAFFFGFA. - ...GFFFGFFFFFFFA - ...GFFFFFFAA.FFA - ....FFFFFA..FFA. - .....FFAA..FFA.. - ..........FA.... -} -# tile 412 (ogre,male) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CAAACJAAA... - ....LDDDLAAAA... - ..CLJLLLKALCAA.A - .CLLAJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 413 (ogre,female) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CAAACJAAA... - ....LDDDLAAAA... - ..CLJLLLKALCAA.A - .CLLAJJJJALLCAAA - .LLCLAAAALCLLAA. - .LAACLLLLCAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 414 (ogre leader,male) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 415 (ogre leader,female) -{ - ................ - ................ - ....CLLLC....... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 416 (ogre tyrant,male) -{ - ...H..C..H...... - ...HDCHCDH...... - ...HHHHHHH...... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CJKAJJJJAKJCAAA - .LJJKAAAAKJJLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 417 (ogre tyrant,female) -{ - ...HH.C.HH...... - ...HDCHCDH...... - ...HHHHHHH...... - ..LCKKLKKCL..... - ...LAALAALJA.... - ...CLLLLLCJA.... - ....CLLLCJAAA... - ....LAAALAAAA... - ..JKJLLLKAKJAA.A - .CJKAJJJJAKJCAAA - .LJJKAAAAKJJLAA. - .LAAJKKKKJAALAA. - .LC.HHHBHHACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 418 (gray ooze,male) -{ - ................ - ................ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAAA.. - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPBBPPAAA. - .PBBPPPBAAPPPAA. - ...PBBBAAAKPPJ.. - ........ACPPAK.. - .........KCCCJ.. - ................ -} -# tile 419 (gray ooze,female) -{ - ................ - ................ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAAA.. - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPBBPPAAA. - .PBBPPPBAAPPPAA. - ...PBBBAAAKPPJ.. - ........ACPPAK.. - .........KCCCJ.. - ................ -} -# tile 420 (brown pudding,male) -{ - ................ - ................ - ................ - ................ - ............J... - ....JKKJJJ..JJ.. - ...KKKCJJJJJ.... - ..KKNNJNNJJJ.... - ..KJANJANJJJA... - ..KKJJJJJCJJAA.. - ..JKJJCJJJJJAA.. - ...JJJJJJJJAAA.. - ....JJJJJJAAA... - .....AAAAAAA.... - ................ - ................ -} -# tile 421 (brown pudding,female) -{ - ................ - ................ - ................ - ................ - ............J... - ....JKKJJJ..JJ.. - ...KKKCJJJJJ.... - ..KKNNJNNJJJ.... - ..KJANJANJJJA... - ..KKJJJJJCJJAA.. - ..JKJJCJJJJJAA.. - ...JJJJJJJJAAA.. - ....JJJJJJAAA... - .....AAAAAAA.... - ................ - ................ -} -# tile 422 (green slime,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ............G... - .....G......G..G - .G....G..G.NGN.G - ..NG.NGGNGGGGGGG - ..GGNGGNGGGFGGF. - GGNGGGGGGGGGFF.G - .NGGGGGFGFG..... - NGGGGFGGFG.G..GF - NGGFGGF..GF..... - ..GGF..GGF..G... -} -# tile 423 (green slime,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ............G... - .....G......G..G - .G....G..G.NGN.G - ..NG.NGGNGGGGGGG - ..GGNGGNGGGFGGF. - GGNGGGGGGGGGFF.G - .NGGGGGFGFG..... - NGGGGFGGFG.G..GF - NGGFGGF..GF..... - ..GGF..GGF..G... -} -# tile 424 (black pudding,male) -{ - ........A....... - ........AA...... - .....AAA........ - ....AAAAA....... - ....CACAA....... - ....DADAA....... - ....AAAAA....... - ....AAAAA....... - ....AAAAA....... - .....AAAAA...... - .....AAAAA...... - ......AAAAA..... - ......AAAAAA.... - .......AAAAAA.A. - ........AAAAAAAA - ..........AAAA.. -} -# tile 425 (black pudding,female) -{ - ........A....... - ........AA...... - .....AAA........ - ....AAAAA....... - ....CACAA....... - ....DADAA....... - ....AAAAA....... - ....AAAAA....... - ....AAAAA....... - .....AAAAA...... - .....AAAAA...... - ......AAAAA..... - ......AAAAAA.... - .......AAAAAA.A. - ........AAAAAAAA - ..........AAAA.. -} -# tile 426 (quantum mechanic,male) -{ - ................ - ......LLLL...... - ...FGGCLCGGF.... - ...GNNGLGNNGL... - B.BGANGGGANGL... - B.BFGGCLCGGFL... - BIB..CLLLCCL.... - BILN.LLAALLAAAA. - BILNN.LLLLJAAAA. - BIB.NNJJJJNAAA.. - BIB.BNNNONNNAA.. - .B...NNNONNLAA.. - .....NBEBENA.A.. - .....NBEBENN.... - ....NAAEBAANN... - ................ -} -# tile 427 (quantum mechanic,female) -{ - ................ - ......JJJJJ..... - ...FGGCLCGGF.... - ...GNNGLGNNGJ... - B.BGANGGGANGL... - B.BFGGCLCGGFLJ.. - BIB.JCLLLCCLJJ.. - BILN.LLAALLAAAA. - BILNN.LLLLCAAAA. - BIB.NNCCCCNAAA.. - BIB.BNNNONNNAA.. - .B...NNNONNLAA.. - .....NBEBENA.A.. - .....NBEBENN.... - ....NAAEBAANN... - ................ -} -# tile 428 (genetic engineer,male) -{ - ................ - ......LLLL...... - ...LAALLLAAL.... - ...LNNLLLNNLL... - ...LANLLLANLL... - ...LLLLLLLLLL... - .....CLLLCCL.... - ..LN.LLAALL..... - ..LNN.LLLLJ..... - ..A.NNLLLLN..... - .A.ABNNNONNN.... - .AA..NNNONNL.... - .A.A.NPEPENA.... - .AA..NPEPENN.... - ..AANAAEPAANN... - ................ -} -# tile 429 (genetic engineer,female) -{ - ................ - ......LLLL...... - ...LAALLLAAL.... - ...LNNLLLNNLL... - ...LANLLLANLL... - ...LLLLLLLLLL... - .....CLLLCCL.... - ..LN.LLAALL..... - ..LNN.LLLLJ..... - ..A.NNLLLLN..... - .A.ABNNNONNN.... - .AA..NNNONNL.... - .A.A.NPEPENA.... - .AA..NPEPENN.... - ..AANAAEPAANN... - ................ -} -# tile 430 (rust monster,male) -{ - ................ - ....EEEE........ - ...EEHEHE....... - ...EEEAEE....... - ...EEPAPE....... - ...EPEAEP...E... - ....EEEE.AAEE... - ....EEEEEAAEEE.. - ...EEEEEEEAEAEE. - ..EEEEEEAAAAE... - ..EEAEEEEAEEEA.. - ..AAEEEEEEEEEAA. - ....AEEEEEEEAAA. - .....EEEEEAA..A. - ......AAAA...... - ................ -} -# tile 431 (rust monster,female) -{ - ................ - ....EEEE........ - ...EEHEHE....... - ...EEEAEE....... - ...EEPAPE....... - ...EPEAEP...E... - ....EEEE.AAEE... - ....EEEEEAAEEE.. - ...EEEEEEEAEAEE. - ..EEEEEEAAAAE... - ..EEAEEEEAEEEA.. - ..AAEEEEEEEEEAA. - ....AEEEEEEEAAA. - .....EEEEEAA..A. - ......AAAA...... - ................ -} -# tile 432 (disenchanter,male) -{ - ................ - ....PPPP........ - ...PPDPDP....... - ...PPPAPP....... - ...PPOAOP....... - ...POPAPO...P... - ....PPPP.AAPP... - ....PPPPPAAPPP.. - ...PPPPPPPAPAPP. - ..PPPPPPAAAAP... - ..PPAPPPPAPPPA.. - ..AAPPPPPPPPPAA. - ....APPPPPPPAAA. - .....PPPPPAA..A. - ......AAAA...... - ................ -} -# tile 433 (disenchanter,female) -{ - ................ - ....PPPP........ - ...PPDPDP....... - ...PPPAPP....... - ...PPOAOP....... - ...POPAPO...P... - ....PPPP.AAPP... - ....PPPPPAAPPP.. - ...PPPPPPPAPAPP. - ..PPPPPPAAAAP... - ..PPAPPPPAPPPA.. - ..AAPPPPPPPPPAA. - ....APPPPPPPAAA. - .....PPPPPAA..A. - ......AAAA...... - ................ -} -# tile 434 (garter snake,male) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOKA........ - ...KKAKA........ - ...KKAKA....KA.. - ....APKAP..KAPP. - .....PKAPP.KAP.. - .....KAAP..KAP.. - ....KAAP..KAAP.. - ....KAAPPKAAP... - ....KAAKKAAP.... - .....KAAAAP..... - ................ - ................ -} -# tile 435 (garter snake,female) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOKA........ - ...KKAKA........ - ...KKAKA....KA.. - ....APKAP..KAPP. - .....PKAPP.KAP.. - .....KAAP..KAP.. - ....KAAP..KAAP.. - ....KAAPPKAAP... - ....KAAKKAAP.... - .....KAAAAP..... - ................ - ................ -} -# tile 436 (snake,male) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOJA........ - ...KKJAJ........ - ...KKAAJ....KK.. - ...FAAKJ...KJAA. - ..FAFAKJAA.KJA.. - .....KJAA..KJA.. - ....KJAA..KJJA.. - ....KJAAAKJJA... - ....KJJJJJJA.... - .....KJJJJA..... - ................ - ................ -} -# tile 437 (snake,female) -{ - ................ - ................ - ................ - ....KKA......... - ...NAOJA........ - ...KKJAJ........ - ...KKAAJ....KK.. - ...FAAKJ...KJAA. - ..FAFAKJAA.KJA.. - .....KJAA..KJA.. - ....KJAA..KJJA.. - ....KJAAAKJJA... - ....KJJJJJJA.... - .....KJJJJA..... - ................ - ................ -} -# tile 438 (water moccasin,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AA... - ...OAOAAA.AA.... - ...AAA.AA.AA.... - ...DA..AA.AA.... - ..D.D.AAA..AA... - .....AAA...AA... - .....AAA...AA... - ....AAA...AAA... - ....AAAAAAAA.... - ....AAAAAAA..... - .....AAAAA...... - ................ -} -# tile 439 (water moccasin,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AA... - ...OAOAAA.AA.... - ...AAA.AA.AA.... - ...DA..AA.AA.... - ..D.D.AAA..AA... - .....AAA...AA... - .....AAA...AA... - ....AAA...AAA... - ....AAAAAAAA.... - ....AAAAAAA..... - .....AAAAA...... - ................ -} -# tile 440 (python,male) -{ - ................ - ................ - ................ - ...KKKA.....JJ.. - ...GAGJA...JJJ.. - ..JKKJAJ..KJJ... - ..KKKAJJ..KJJ.AA - ..KKAAKJA.KKJAA. - .....AKJAA.KJAA. - ....JKJAA..KJJA. - ...JJJAA..KJJJA. - ...JJJAAAKJJJA.. - ...JJJJJJJJJAA.. - ....JJJJJJJAA... - .....JJJJJAA.... - ................ -} -# tile 441 (python,female) -{ - ................ - ................ - ................ - ...KKKA.....JJ.. - ...GAGJA...JJJ.. - ..JKKJAJ..KJJ... - ..KKKAJJ..KJJ.AA - ..KKAAKJA.KKJAA. - .....AKJAA.KJAA. - ....JKJAA..KJJA. - ...JJJAA..KJJJA. - ...JJJAAAKJJJA.. - ...JJJJJJJJJAA.. - ....JJJJJJJAA... - .....JJJJJAA.... - ................ -} -# tile 442 (pit viper,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AAA.. - ...OAAAAA.AA.AA. - ...AA..AA.AA.AA. - ...D...AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA...AA... - .....AA...AAA... - .....AA..AAA.... - .....AAAAAA..... - ......AAAA...... - ................ -} -# tile 443 (pit viper,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAA...AAA.. - ...OAAAAA.AA.AA. - ...AA..AA.AA.AA. - ...D...AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA...AA... - .....AA...AAA... - .....AA..AAA.... - .....AAAAAA..... - ......AAAA...... - ................ -} -# tile 444 (cobra,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAAA....... - ..PA..AAAA...... - ..A..AAAAA..AA.. - ..D..AAAAA....A. - ......AAA.....A. - ......AA..AAAA.. - .....AA..AA..... - ....AA...AA..... - ....AA....AAAA.. - ....AAA......AA. - .....AAAAAAAAA.. - ................ -} -# tile 445 (cobra,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAAAAA....... - ..PA..AAAA...... - ..A..AAAAA..AA.. - ..D..AAAAA....A. - ......AAA.....A. - ......AA..AAAA.. - .....AA..AA..... - ....AA...AA..... - ....AA....AAAA.. - ....AAA......AA. - .....AAAAAAAAA.. - ................ -} -# tile 446 (troll,male) -{ - ................ - ..AAAAAA........ - AAAANANA........ - .AAKKKJJA....... - AAAKAAAKA....... - AKAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAFGFJJAAAA.. - ..KJA.PFJAAAA... - ...AFAGFAAAAAA.. - ...GFAGP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 447 (troll,female) -{ - ................ - ..AAAAAA........ - AAAANANA........ - .AAKKKJJA....... - AAAKAAAKA....... - AKAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAFGFJJAAAA.. - ..KJA.PFJAAAA... - ...AFAGFAAAAAA.. - ...GFAGP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 448 (ice troll,male) -{ - ................ - ..OONOOO........ - NONOAOAOO....... - .NOKKKJJO....... - NOJKAAAKOO...... - OKJKAAAKAO...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 449 (ice troll,female) -{ - ................ - ..OONOOO........ - NONOAOAOO....... - .NOKKKJJO....... - NOJKAAAKOO...... - OKJKAAAKAO...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 450 (rock troll,male) -{ - ................ - ...AAAAA........ - .AAANANAAAA..... - .AAKKKJJAA...... - AAAKAAAKAAAA.... - AKAKAAAKAAA..... - KJJAKKKAJKAA.... - KJAJAAAJJJA..... - KJAPAKJJKJA..... - PKJPPAGFJJAAAA.. - PPPPPAFFJAAAA... - .PPPAAGFAAAAAA.. - ...AFAGF.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 451 (rock troll,female) -{ - ................ - ...AAAAA........ - .AAANANAAAA..... - .AAKKKJJAA...... - AAAKAAAKAAAA.... - AKAKAAAKAAA..... - KJJAKKKAJKAA.... - KJAJAAAJJJA..... - KJAPAKJJKJA..... - PKJPPAGFJJAAAA.. - PPPPPAFFJAAAA... - .PPPAAGFAAAAAA.. - ...AFAGF.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 452 (water troll,male) -{ - ................ - ...AAAAA........ - ..AANANAA....... - .AAKKKJJAA...... - .AAKAAAKAA...... - .KAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 453 (water troll,female) -{ - ................ - ...AAAAA........ - ..AANANAA....... - .AAKKKJJAA...... - .AAKAAAKAA...... - .KAKAAAKAA...... - KJJAKKKAJKA..... - KJAJAAAJJJA..... - KJAJKKJJKJA..... - .KJJAEBEJJAAAA.. - ..KJA.PEJAAAA... - ...AEABEAAAAAA.. - ...BEABP.AA.AA.. - ..KJJAKJAA.AA... - ..KJA..KA....... - ................ -} -# tile 454 (Olog-hai,male) -{ - ...PPPPP........ - ..PPAAAPP....... - ..PANANAP....... - ..PAAAAAP....... - .PPAAAAAPP...... - PPPAAAAAPPP..... - AAPPAAAPPAA..... - AAAPPPPPAAA..... - AAAPPPPPAAA..... - .AAAAPPPAAAPPP.. - PONNNNNNAACPP... - ...APAPPAPPPPP.. - ...PPAPP.PP.PP.. - ..AAAAAAAP.PP... - ..AAA.AAA....... - ................ -} -# tile 455 (Olog-hai,female) -{ - ...PPPPP........ - ..PPAAAPP....... - ..PANANAP....... - ..PAAAAAP....... - .PPAAAAAPP...... - PPPAAAAAPPP..... - AAPPAAAPPAA..... - AAAPPPPPAAA..... - AAAPPPPPAAA..... - .AAAAPPPAAAPPP.. - PONNNNNNAACPP... - ...APAPPAPPPPP.. - ...PPAPP.PP.PP.. - ..AAAAAAAP.PP... - ..AAA.AAA....... - ................ -} -# tile 456 (umber hulk,male) -{ - ................ - ...AAAAA........ - ..AAAAAAA....... - .ADADADADA...... - .AAAAAAAAA.A.... - .AAAOAOAAA.AA... - .A.AOAOA.AAA.... - .A.AAAAAPAA..... - .AAAAAAAP....... - .A.AAAAA.PPPPPP. - ...AA.AA.PPPPP.. - ...AA.AAPPPPPPP. - ...AAPAAPPPP.... - ..AAAPAAAPP..... - .AAAP..AAP...... - ................ -} -# tile 457 (umber hulk,female) -{ - ................ - ...AAAAA........ - ..AAAAAAA....... - .ADADADADA...... - .AAAAAAAAA.A.... - .AAAOAOAAA.AA... - .A.AOAOA.AAA.... - .A.AAAAAPAA..... - .AAAAAAAP....... - .A.AAAAA.PPPPPP. - ...AA.AA.PPPPP.. - ...AA.AAPPPPPPP. - ...AAPAAPPPP.... - ..AAAPAAAPP..... - .AAAP..AAP...... - ................ -} -# tile 458 (vampire,male) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAAAAAAA...... - ..AAAAAAAA...... - ...AAAAAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 459 (vampire,female) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAAAAAAA...... - ..AAAAAAAA...... - ...AAAAAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 460 (vampire leader,male) -{ - ................ - .....AAAA....... - .N..AAOOAA...... - .NDDAGAAGADA.... - .NADALLLOAD..... - AAAAAAAAAAA..... - AAAAAAAAAAA..... - .AAAAAAAAAA..... - .NAAAAAAAAA..... - .N.AAAAAAAAPPPPP - .NADAAAAAAAPPPPP - .NADDAAAAAAPPPP. - .NAAAAAAAAAPPP.. - .N...AAAPAAPP... - .N..AAPP..AP.... - ................ -} -# tile 461 (vampire leader,female) -{ - ................ - .....AAAA....... - .N..AAOOAA...... - .NDDAGAAGADA.... - .NADALLLOAD..... - AAAAAAAAAAA..... - AAAAAAAAAAA..... - .AAAAAAAAAA..... - .NAAAAAAAAA..... - .N.AAAAAAAAPPPPP - .NADAAAAAAAPPPPP - .NADDAAAAAAPPPP. - .NAAAAAAAAAPPP.. - .N...AAAPAAPP... - .N..AAPP..AP.... - ................ -} -# tile 462 (vampire mage,male) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAA.A.AA...... - ..AAAACAAA...... - ...AAADAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 463 (vampire mage,female) -{ - ................ - ................ - .....AAA........ - ....AAOAA....... - .ADDAGAGADA..... - ..ADALLOAD...... - .AAAA.A.AA...... - ..AAAACAAA...... - ...AAADAAA...... - ..ADAAAAAAPPPPP. - ..ADDAAAAAPPPP.. - ..AAAAAAAAPPP... - .....AAPAAPP.... - ....AAP..AP..... - ................ - ................ -} -# tile 464 (Vlad the Impaler,male) -{ - ................ - ..N..AAAA....... - ADNDAAOOAADDDA.. - .ANDAGAAGADDA... - ..NDALLLOADA.... - ..NAAAAAAAAAAAAA - .HHHDAAAAADDDDDA - HEHEHJAAAADDDAA. - LLLLLJAAAADDAAPP - .LLLJAAAAADDAPPP - ..NJDAAAAADAPPPP - .ANDDAAAAAAAPPPP - .ANAAAAAAAAPPPP. - ..N..AAAPAAPPP.. - ..N.AAPP..AP.... - ................ -} -# tile 465 (Vlad the Impaler,female) -{ - ................ - ..N..AAAA....... - ADNDAAOOAADDDA.. - .ANDAGAAGADDA... - ..NDALLLOADA.... - ..NAAAAAAAAAAAAA - .HHHDAAAAADDDDDA - HEHEHJAAAADDDAA. - LLLLLJAAAADDAAPP - .LLLJAAAAADDAPPP - ..NJDAAAAADAPPPP - .ANDDAAAAAAAPPPP - .ANAAAAAAAAPPPP. - ..N..AAAPAAPPP.. - ..N.AAPP..AP.... - ................ -} -# tile 466 (barrow wight,male) -{ - ................ - ................ - ...LLO.......... - ..DLDLO......... - ..LLLLO......... - ..LJL..P........ - ..OOO.PP...AAAA. - ..POO.PP.AAAAAA. - .LPOO.PP.PAAAA.. - .JJOO.PP.PAAAA.. - .J.O..PL.PPAAA.. - .J.O.PPPPPPAAA.. - .J...PPPPPPPAA.. - .J..LLPPPPPPA... - .J.....LLAA..... - ................ -} -# tile 467 (barrow wight,female) -{ - ................ - .......OOOOO.... - ..OOOOOOO....... - .ODLDLOO.OOO.... - .OLLLLOOOOOOO... - .OLJLLOPOO...... - .OPLLL.POOOAAAA. - ..PPP.PP.AAAAAA. - .LPPPPPP.PAAAA.. - .JJ.PPPP.PAAAA.. - .J...PPL.PPAAA.. - .J...PPPPPPAAA.. - .J...PPPPPPPAA.. - .J..LLPPPPPPA... - .J.....LLAA..... - ................ -} -# tile 468 (wraith,male) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - ..AAPPPPAP..AAA. - ..PPPPPOLPAAAAA. - ...A.PPAAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ - ................ - ................ -} -# tile 469 (wraith,female) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - ..AAPPPPAP..AAA. - ..PPPPPOLPAAAAA. - ...A.PPAAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ - ................ - ................ -} -# tile 470 (Nazgul,male) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - .OPAPPPPAP..AAA. - ..PAPPPPAP..AAA. - ..PA.PPPLP..AAA. - ..PP.PPOLPAAAAA. - ...AAPPOAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ -} -# tile 471 (Nazgul,female) -{ - ................ - ................ - ...PPPPP........ - ...PAAPPP....... - ....PAAPP....... - ....PAAPP....... - ..PP.PPP.P...... - .OLAPPP.PP...... - .OPAPPPPAP..AAA. - ..PAPPPPAP..AAA. - ..PA.PPPLP..AAA. - ..PP.PPOLPAAAAA. - ...AAPPOAAAPPA.. - .....PPAPPPPA... - ......PPPPA..... - ................ -} -# tile 472 (xorn,male) -{ - ................ - ................ - ................ - ...OB.OP.BP..... - ...BBBBPPPP..... - ...B............ - ...DDBB.BDDA.A.. - ...DDBB.PDDAAAA. - ...B.......AAAA. - ...BOB.BPP.AAAA. - ...BBB.PPP.AAAA. - ...B.......AAA.. - ...BOBBPPBPAA... - ...BO.BP.PPA.... - ................ - ................ -} -# tile 473 (xorn,female) -{ - ................ - ................ - ................ - ...OB.OP.BP..... - ...BBBBPPPP..... - ...B............ - ...DDBB.BDDA.A.. - ...DDBB.PDDAAAA. - ...B.......AAAA. - ...BOB.BPP.AAAA. - ...BBB.PPP.AAAA. - ...B.......AAA.. - ...BOBBPPBPAA... - ...BO.BP.PPA.... - ................ - ................ -} -# tile 474 (monkey,male) -{ - ................ - ................ - ................ - ................ - ................ - .......KKA...... - ......KLLJA..... - ......KLLJA..... - .......KJA...... - .....KKKKKJAA... - ....KJKLLJJJAA.. - ....LAKLLJALAA.. - ......KJJJAAAA.. - ......JAAJAAA... - .....JJA.JJA.... - ................ -} -# tile 475 (monkey,female) -{ - ................ - ................ - ................ - ................ - ................ - .......KKA...... - ......KLLJA..... - ......KLLJA..... - .......KJA...... - .....KKKKKJAA... - ....KJKLLJJJAA.. - ....LAKLLJALAA.. - ......KJJJAAAA.. - ......JAAJAAA... - .....JJA.JJA.... - ................ -} -# tile 476 (ape,male) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCLACCAJJAAA - ..KKKKCCCAJKJJAA - ..KKAKJAAJJAJJAA - ..KAAKJJJJJAAJAA - ..LC.KJJJJJKCLAA - ..LL.CJJAKLJLLAA - .....CLJACLJAAAA - ...LLLLJACLLLKA. - ................ - ................ -} -# tile 477 (ape,female) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCLACCAJJAAA - ..KKKKCCCAJKJJAA - ..KKAKJAAJJAJJAA - ..KAAKJJJJJAAJAA - ..LC.KJJJJJKCLAA - ..LL.CJJAKLJLLAA - .....CLJACLJAAAA - ...LLLLJACLLLKA. - ................ - ................ -} -# tile 478 (owlbear,male) -{ - ................ - ....K.....K..... - ....CK...KK..... - ....CKKKKKK..... - ...KOOOKOOOK.... - ...KOOOKOOOKA..A - ...KOOAJAOOKAAAA - ..CKCJJHJJKAKAAA - .CKKKCKLKKAJJKAA - .KJJJJCKKJJJJJAA - .KJJJPAKJPJJJJAA - ..KJJJAKJJJJJAAA - ...JJPAKJPJJAAA. - ...JAAJAJAAJAA.. - ...PJPJAJPJPA... - ................ -} -# tile 479 (owlbear,female) -{ - ................ - ....K.....K..... - ....CK...KK..... - ....CKKKKKK..... - ...KOOOKOOOK.... - ...KOOOKOOOKA..A - ...KOOAJAOOKAAAA - ..CKCJJHJJKAKAAA - .CKKKCKLKKAJJKAA - .KJJJJCKKJJJJJAA - .KJJJPAKJPJJJJAA - ..KJJJAKJJJJJAAA - ...JJPAKJPJJAAA. - ...JAAJAJAAJAA.. - ...PJPJAJPJPA... - ................ -} -# tile 480 (yeti,male) -{ - ................ - ....BNNN........ - ...BNANAP....... - ..BNNNNNNP...... - ..NNNADANN...... - ..NNNNNNPN...... - ..N.NNBPPNP..... - ..N.NNNNANP..AA. - ..NNBNNNPN.AAAA. - ....NNNNP.KAAA.. - ....NN.NPAKKAA.. - ....NB.NPAACKAA. - ....NNANPAAKKJA. - ...BNNANNPAACKA. - ..BNNA..NNA..... - ................ -} -# tile 481 (yeti,female) -{ - ................ - ....BNNN........ - ...BNANAP....... - ..BNNNNNNP...... - ..NNNADANN...... - ..NNNNNNPN...... - ..N.NNBPPNP..... - ..N.NNNNANP..AA. - ..NNBNNNPN.AAAA. - ....NNNNP.KAAA.. - ....NN.NPAKKAA.. - ....NB.NPAACKAA. - ....NNANPAAKKJA. - ...BNNANNPAACKA. - ..BNNA..NNA..... - ................ -} -# tile 482 (carnivorous ape,male) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCAAACAJJAAA - ..KKKCDDDCAKJJAA - ..KKAKCCCAJAJJAA - ..KAAKJAAJJAAJAA - ..LC.AJJJJJKCLAA - ..LLDDAJAKLJLLAA - ...DDALJACLJAAAA - ..DDALLJACLLLKA. - ................ - ................ -} -# tile 483 (carnivorous ape,female) -{ - ................ - ................ - ......KKKJ...... - .....JJJJJJ..... - ....KCELECJJ.AA. - ....KLLLLCAJAAAA - ...KKCAAACAJJAAA - ..KKKCDDDCAKJJAA - ..KKAKCCCAJAJJAA - ..KAAKJAAJJAAJAA - ..LC.AJJJJJKCLAA - ..LLDDAJAKLJLLAA - ...DDALJACLJAAAA - ..DDALLJACLLLKA. - ................ - ................ -} -# tile 484 (sasquatch,male) -{ - ................ - ....CCCCC....... - ...CGAJGAJ...... - ..CKKKKJJJ...... - ..CKKAAAKJJ..... - .CKKKAAAKKJ..... - .CKJKKKKKKKJ.... - .CKAJJJJJAKJ.... - .CKAJKKKJAKJ.AA. - .CKJAJKJACKJAAAA - .CKJAJJJACKJAAA. - ..J.AJAKKAJAAAAA - ...CKJAKKJAAAAA. - .KCKJJACKJKJAA.. - .CJJJKACKJJKA... - ................ -} -# tile 485 (sasquatch,female) -{ - ................ - ....CCCCC....... - ...CGAJGAJ...... - ..CKKKKJJJ...... - ..CKKAAAKJJ..... - .CKKKAAAKKJ..... - .CKJKKKKKKKJ.... - .CKAJJJJJAKJ.... - .CKAJKKKJAKJ.AA. - .CKJAJKJACKJAAAA - .CKJAJJJACKJAAA. - ..J.AJAKKAJAAAAA - ...CKJAKKJAAAAA. - .KCKJJACKJKJAA.. - .CJJJKACKJJKA... - ................ -} -# tile 486 (kobold zombie,male) -{ - ................ - ................ - ................ - ...N...N........ - ...NGFBN........ - ...GABAB........ - ....GBFA..A..... - ...GBABFA.AA.... - ..GFBBBIKAAA.A.. - ..BAFBFFEAAAAA.. - ..BAFBFFAAAAAA.. - ....FBFAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 487 (kobold zombie,female) -{ - ................ - ................ - ................ - ...N...N........ - ...NGFBN........ - ...GABAB........ - ....GBFA..A..... - ...GBABFA.AA.... - ..GFBBBIKAAA.A.. - ..BAFBFFEAAAAA.. - ..BAFBFFAAAAAA.. - ....FBFAAAAAA... - ....BABAAAA..... - ...BBABBA....... - ................ - ................ -} -# tile 488 (gnome zombie,male) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GDFDF....... - .....PFP...AAA.. - ...FGFPFEGAAAA.. - ..GAAGFFFAGAAA.. - ....AKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 489 (gnome zombie,female) -{ - ................ - ................ - ................ - ................ - ......G......... - .....GFF........ - ....GGFFF....... - ....GDFDF....... - .....GFF...AAA.. - ...FGFFFEGAAAA.. - ..GAAGFFFAGAAA.. - ....AKNKFAAAA... - ....FGAFFAA..... - ....GFAFG.A..... - ................ - ................ -} -# tile 490 (orc zombie,male) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....GPGA........ - .....PFA........ - ..KCCAKKKA.AA... - .BBPCKJ.BBAAA... - BB.AGGFAABBA.... - B..AJJPAAABA.... - ....BAPPPAAAAA.. - ...BJAAEPAAA.... - ..BPPAAAPP...... - ................ - ................ -} -# tile 491 (orc zombie,female) -{ - ................ - ................ - ................ - .....OA......... - ....NOPA........ - ....GPGA........ - .....PFA........ - ..KCCAKKKA.AA... - .BBPCKJ.BBAAA... - BB.AGGFAABBA.... - B..AJJPAAABA.... - ....BAPPPAAAAA.. - ...BJAAEPAAA.... - ..BPPAAAPP...... - ................ - ................ -} -# tile 492 (dwarf zombie,male) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BFFFE....... - .....PFP...AAA.. - ...BBPPPEEAAAA.. - ..FBABPEAEAAAA.. - ..F.EBBEFAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 493 (dwarf zombie,female) -{ - ................ - ................ - ................ - ................ - ......B......... - .....BEE........ - ....BBEEE....... - ....BFFFE....... - .....PFP...AAA.. - ...BBPPPEEAAAA.. - ..FBABPEAEAAAA.. - ..F.EBBEFAAAA... - ....EBAEEAA..... - ....BEAEB.A..... - ................ - ................ -} -# tile 494 (elf zombie,male) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......FEFEA..... - ......FFFFA..... - ......AFDA....A. - ......GAAG..AAA. - ....FFGGGFFFAAA. - ...FAAAGFAAAFAA. - .....AGGGFAAAA.. - ......GFAFAA.A.. - .....KDA.FKA.... - ................ - ................ -} -# tile 495 (elf zombie,female) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......FEFEA..... - ......FFFFA..... - ......AFDA....A. - ......GAAG..AAA. - ....FFGGGFFFAAA. - ...FAAAGFAAAFAA. - .....AGGGFAAAA.. - ......GFAFAA.A.. - .....KDA.FKA.... - ................ - ................ -} -# tile 496 (human zombie,male) -{ - ......AAA....... - .....FFGAA...... - .....AGAFA...... - .....FFGFA...... - ....FKF..JJ..... - ....JJJFJKJ..... - ...FJ.KJJAKJ.... - ..FK..KFJFFJ.... - ..G...KKJG...... - .....BP.BPAAAAA. - .....FPAPFAAAA.. - .....BFABFAAAA.. - .....PFABPAA.... - .....BFABFA..... - ....GGAGGA...... - ................ -} -# tile 497 (human zombie,female) -{ - ......AAA....... - .....FFGAA...... - .....AGAFA...... - .....FFGFA...... - ....FKF..JJ..... - ....JJJFJKJ..... - ...FJ.KJJAKJ.... - ..FK..KFJFFJ.... - ..G...KKJG...... - .....BP.BPAAAAA. - .....FPAPFAAAA.. - .....BFABFAAAA.. - .....PFABPAA.... - .....BFABFA..... - ....GGAGGA...... - ................ -} -# tile 498 (ettin zombie,male) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NFF..NFF..P... - ..ADFFDADFFDA... - ..AFFFFAFFFFA... - ..AFAAFAFAAFAA.. - ..AFFFFAFFFFAAA. - ..GIIIIJJJIIIGAA - .GFFFIIIIIIFFFGA - .GFFFFIIIIFFFFFA - .FFAAFIIIIFAAFFA - .FFAAIIIIIIAAFFA - .FFF.IIFFIIAGFAA - ..FF.GFAAGFAFFAA - .....GFAAGFAAAAA - ...FFFFA.GFFFFAA -} -# tile 499 (ettin zombie,female) -{ - ....NN..ONOP.... - ..NNOOPNNOOPP... - ..NFF..NFF..P... - ..ADFFDADFFDA... - ..AFFFFAFFFFA... - ..AFAAFAFAAFAA.. - ..AFFFFAFFFFAAA. - ..GIIIIJJJIIIGAA - .GFFFIIIIIIFFFGA - .GFFFFIIIIFFFFFA - .FFAAFIIIIFAAFFA - .FFAAIIIIIIAAFFA - .FFF.IIFFIIAGFAA - ..FF.GFAAGFAFFAA - .....GFAAGFAAAAA - ...FFFFA.GFFFFAA -} -# tile 500 (ghoul,male) -{ - ......AAA....... - .....OOOAA...... - .....DODOA...... - .....OOOOA...... - ....PPOOOPP..... - ....PPPPPPP..... - ...PP.PPPAPP.... - ..PP..PPPOOP.... - ..O...PPPO...... - .....PP.PPAAAAA. - .....PPAPPAAAA.. - .....PPAPPAAAA.. - .....PPAPPAA.... - .....PPAPPA..... - ....OOAOOA...... - ................ -} -# tile 501 (ghoul,female) -{ - ......AAA....... - .....OOOAA...... - .....DODOA...... - .....OOOOA...... - ....PPOOOPP..... - ....PPPPPPP..... - ...PP.PPPAPP.... - ..PP..PPPOOP.... - ..O...PPPO...... - .....PP.PPAAAAA. - .....PPAPPAAAA.. - .....PPAPPAAAA.. - .....PPAPPAA.... - .....PPAPPA..... - ....OOAOOA...... - ................ -} -# tile 502 (giant zombie,male) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJFFFFJJA... - ....JDDFFDDJA... - ....JFFFFFFJA... - ....AFFAAFFAAA.. - .....AFFFFJAAAA. - ..GGFFJJJJFFGGAA - .GFFFGGFFFFFFFCA - .FFFKFFFFFFKFFFA - FFFAAFFFFFFAAFFA - FFAA.JJJKKJAAFFA - FFA..JJJJJKAGFAA - .....GFAGFFAFFAA - ....GFFAGFFAAAAA - ...GFFAAGFFFAAAA -} -# tile 503 (giant zombie,female) -{ - ......JJJJAA.... - ....JJJJJJJJA... - ....JJFFFFJJA... - ....JDDFFDDJA... - ....JFFFFFFJA... - ....AFFAAFFAAA.. - .....AFFFFJAAAA. - ..GGFFJJJJFFGGAA - .GFFFGGFFFFFFFCA - .FFFKFFFFFFKFFFA - FFFAAFFFFFFAAFFA - FFAA.JJJKKJAAFFA - FFA..JJJJJKAGFAA - .....GFAGFFAFFAA - ....GFFAGFFAAAAA - ...GFFAAGFFFAAAA -} -# tile 504 (skeleton,male) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - ......O......... - ....OOOOO...AAA. - ...OA.OOOA..AAA. - ..OA.OAAO.AAAAA. - ....OA.OOOAAA.A. - ......OOOAAA.A.. - .....O.AO.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 505 (skeleton,female) -{ - ................ - ................ - ...OOO.......... - ..AOAOO......... - ..OOOOO......... - ..OO.O.......... - ......O......... - ....OOOOO...AAA. - ...OA.OOOA..AAA. - ..OA.OAAO.AAAAA. - ....OA.OOOAAA.A. - ......OOOAAA.A.. - .....O.AO.A..... - ...OOOA.OA...... - ......OOO....... - ................ -} -# tile 506 (straw golem,male) -{ - ......LJ........ - ......LJHJ...... - ....HJLJH...A... - ....AAAAAL.....A - ....DAADAL.A.AA. - ....LJHJL..AAAA. - ....LLHJLHHCHHL. - ...HHLJL.AJLJL.A - .HHJJLLLLAAA.AA. - ..JL..LALHAAAAAA - .LL..CJLHJHAAAAA - .....HJLAHJHAAA. - .....HJAACALHAAA - ....CJLAAJHALHA. - ....HALA.AHAAL.. - ..........L..... -} -# tile 507 (straw golem,female) -{ - ......LJ........ - ......LJHJ...... - ....HJLJH...A... - ....AAAAAL.....A - ....DAADAL.A.AA. - ....LJHJL..AAAA. - ....LLHJLHHCHHL. - ...HHLJL.AJLJL.A - .HHJJLLLLAAA.AA. - ..JL..LALHAAAAAA - .LL..CJLHJHAAAAA - .....HJLAHJHAAA. - .....HJAACALHAAA - ....CJLAAJHALHA. - ....HALA.AHAAL.. - ..........L..... -} -# tile 508 (paper golem,male) -{ - ................ - .......OA....... - .....NNNOA...... - .....ONNNOA..... - ......ONNOA..... - .......NOA...... - ..NNOA.NOA...... - ..NONOAOAONNOA.. - ..OAOANNOAOOOA.. - ......NNNOAAAAA. - ......ONOAAAAAA. - .......OOAAAAAA. - .....NOAAOAAAAA. - .....NOA..NOAA.. - ....OOA...OOA... - ................ -} -# tile 509 (paper golem,female) -{ - ................ - .......OA....... - .....NNNOA...... - .....ONNNOA..... - ......ONNOA..... - .......NOA...... - ..NNOA.NOA...... - ..NONOAOAONNOA.. - ..OAOANNOAOOOA.. - ......NNNOAAAAA. - ......ONOAAAAAA. - .......OOAAAAAA. - .....NOAAOAAAAA. - .....NOA..NOAA.. - ....OOA...OOA... - ................ -} -# tile 510 (rope golem,male) -{ - ................ - ................ - ......OOO....... - .....O...O...... - .....O...O...AA. - .OO...O..O..A..A - O..O...LL..OO..A - ...O...LOOO.AOA. - ....OOOOOAAAAO.. - .......OO..AA.A. - .......LO.AA...A - ......O..OOAA..A - ....OO..A..O.A.. - ...O..AA...O.A.. - ...O.A....OAA... - ....OA.......... -} -# tile 511 (rope golem,female) -{ - ................ - ................ - ......OOO....... - .....O...O...... - .....O...O...AA. - .OO...O..O..A..A - O..O...LL..OO..A - ...O...LOOO.AOA. - ....OOOOOAAAAO.. - .......OO..AA.A. - .......LO.AA...A - ......O..OOAA..A - ....OO..A..O.A.. - ...O..AA...O.A.. - ...O.A....OAA... - ....OA.......... -} -# tile 512 (gold golem,male) -{ - ................ - ......HNH....... - ......DND...N... - ......HNH...JC.. - ......HNH...NC.. - ...HHHAAAAHANC.. - ..HNJNHNHNJNAC.A - ..HHHHHHHHHHHA.A - .NCACCCCCCCCA..A - .HH.AAAAAAAAA.AA - .NH.ANC.AHNC.AAA - .NJ.AHC.AHHC.AAA - ..H.ANC.AHNC.AAA - ....HJC.AHJC.AA. - H...HNC.AHNC.A.H - ..H............. -} -# tile 513 (gold golem,female) -{ - ................ - ......HNH....... - ......DND...N... - ......HNH...JC.. - ......HNH...NC.. - ...HHHAAAAHANC.. - ..HNJNHNHNJNAC.A - ..HHHHHHHHHHHA.A - .NCACCCCCCCCA..A - .HH.AAAAAAAAA.AA - .NH.ANC.AHNC.AAA - .NJ.AHC.AHHC.AAA - ..H.ANC.AHNC.AAA - ....HJC.AHJC.AA. - H...HNC.AHNC.A.H - ..H............. -} -# tile 514 (leather golem,male) -{ - ......KKKK...... - .....KHKHJ...... - ....KAKKJJA..... - ...KKAJJJJAJ.... - ..KKJJAJAAKJJ... - .KKKJJAAKKKJJJ.. - ..KKJJJAKKJJJJ.. - ...KKJJJA.AAA.A. - ....AAAA.KJAAAA. - ....KJAAAKKAAAAA - ...KJJAA.KJJAAA. - ...KKJA..KKJAAA. - ..KKJJJAKKJJJAA. - ..KKKJJAKKKJJA.. - ...KJJA..KJJA... - ....KA....KA.... -} -# tile 515 (leather golem,female) -{ - ......KKKK...... - .....KHKHJ...... - ....KAKKJJA..... - ...KKAJJJJAJ.... - ..KKJJAJAAKJJ... - .KKKJJAAKKKJJJ.. - ..KKJJJAKKJJJJ.. - ...KKJJJA.AAA.A. - ....AAAA.KJAAAA. - ....KJAAAKKAAAAA - ...KJJAA.KJJAAA. - ...KKJA..KKJAAA. - ..KKJJJAKKJJJAA. - ..KKKJJAKKKJJA.. - ...KJJA..KJJA... - ....KA....KA.... -} -# tile 516 (wood golem,male) -{ - ................ - ......KCKJ...... - ......HCHJ..C... - ......KCKJ..CK.. - ......KCKJ..CKJ. - ...KKKAAAAKACKJ. - ..KCCCCCCCCCAKJA - ..KKKKKKKKKKKAJA - .CJAJJJJJJJJA..A - .CKJAAAAAAAAA.AA - .CKJACKJAKCKJAAA - .CKJACKJAKCKJAAA - ..KJACKJAKCKJAAA - ....KCKJAKCKJAA. - ....KCKJAKCKJA.. - ................ -} -# tile 517 (wood golem,female) -{ - ................ - ......KCKJ...... - ......HCHJ..C... - ......KCKJ..CK.. - ......KCKJ..CKJ. - ...KKKAAAAKACKJ. - ..KCCCCCCCCCAKJA - ..KKKKKKKKKKKAJA - .CJAJJJJJJJJA..A - .CKJAAAAAAAAA.AA - .CKJACKJAKCKJAAA - .CKJACKJAKCKJAAA - ..KJACKJAKCKJAAA - ....KCKJAKCKJAA. - ....KCKJAKCKJA.. - ................ -} -# tile 518 (flesh golem,male) -{ - ................ - ................ - ...D..DDC....... - .....DLDDL...... - ..DD..LLLLC.D... - ...CDL.LLLLADL.. - ..CLDLA.CLLA.LL. - ..LLLAA.LLCA..L. - .CLLAA.CLLAA..CA - .LLA..CLLALLAAAA - ..LA.CLCAALCAAAA - ...A..LLCACLCAAA - ....LLALLAALLAAA - ..CLLLAAAADLLA.. - ..LLDDD..DDDDD.. - ................ -} -# tile 519 (flesh golem,female) -{ - ................ - ................ - ...D..DDC....... - .....DLDDL...... - ..DD..LLLLC.D... - ...CDL.LLLLADL.. - ..CLDLA.CLLA.LL. - ..LLLAA.LLCA..L. - .CLLAA.CLLAA..CA - .LLA..CLLALLAAAA - ..LA.CLCAALCAAAA - ...A..LLCACLCAAA - ....LLALLAALLAAA - ..CLLLAAAADLLA.. - ..LLDDD..DDDDD.. - ................ -} -# tile 520 (clay golem,male) -{ - ................ - ................ - ................ - ....LCCCCK...... - ...LKKKKKKK..... - ...CKAKKAKK..... - ...CKAKKAKK..... - .LCKKKKKKKKLC... - CKKJKKKKKKCKKJ.. - KKKJKKJJKKJKKJAA - .JJAKKJAKKAJJAAA - ..AKKKJAKKKAAAAA - ..CKKKKKKKKKAAAA - ..CKKKAACKKKAA.. - ..CKKKA.CKKKAA.. - ................ -} -# tile 521 (clay golem,female) -{ - ................ - ................ - ................ - ....LCCCCK...... - ...LKKKKKKK..... - ...CKAKKAKK..... - ...CKAKKAKK..... - .LCKKKKKKKKLC... - CKKJKKKKKKCKKJ.. - KKKJKKJJKKJKKJAA - .JJAKKJAKKAJJAAA - ..AKKKJAKKKAAAAA - ..CKKKKKKKKKAAAA - ..CKKKAACKKKAA.. - ..CKKKA.CKKKAA.. - ................ -} -# tile 522 (stone golem,male) -{ - ................ - ................ - ................ - ....BBBPP....... - ...BBPPPPP...... - ...BHAPHAP...... - ...PPPPPPP...... - .BBPPPPPP.BPA... - BPPPP....PPPPAA. - BPP.BPPPP.PPPAAA - .PP.BP.PP.PPPAAA - ...BPP.PPPAAAAAA - ..BPPPAPPPAAAAA. - ..PPPPAPPPPAAA.. - ...PPAA.PPPA.... - ................ -} -# tile 523 (stone golem,female) -{ - ................ - ................ - ................ - ....BBBPP....... - ...BBPPPPP...... - ...BHAPHAP...... - ...PPPPPPP...... - .BBPPPPPP.BPA... - BPPPP....PPPPAA. - BPP.BPPPP.PPPAAA - .PP.BP.PP.PPPAAA - ...BPP.PPPAAAAAA - ..BPPPAPPPAAAAA. - ..PPPPAPPPPAAA.. - ...PPAA.PPPA.... - ................ -} -# tile 524 (glass golem,male) -{ - ................ - .....BBBBBBA.... - .....BPNPPPA.... - .....BNPPPNA.... - .....NPPPNPA.... - .....BPPNPPA.... - .......BA...BA.. - .BNBBABPBA.BPNA. - .NPPNABPNBBANPBA - .....BPNPPPAABAA - .....BNPPPAAAAAA - ......BPPNAAAAAA - ....BNABNABPAAA. - ...BNPA...BNAAA. - ..BNPA....NPAA.. - ...BA.....BPA... -} -# tile 525 (glass golem,female) -{ - ................ - .....BBBBBBA.... - .....BPNPPPA.... - .....BNPPPNA.... - .....NPPPNPA.... - .....BPPNPPA.... - .......BA...BA.. - .BNBBABPBA.BPNA. - .NPPNABPNBBANPBA - .....BPNPPPAABAA - .....BNPPPAAAAAA - ......BPPNAAAAAA - ....BNABNABPAAA. - ...BNPA...BNAAA. - ..BNPA....NPAA.. - ...BA.....BPA... -} -# tile 526 (iron golem,male) -{ - ................ - ......PBP....... - ......HBH...B... - ......PBP...JP.. - ......PBP...BP.. - ...PPPAAAAPABP.. - ..PBJBBBBBJBAP.A - ..PPPPPPPPPPPA.A - .B.A........A..A - .BP.AAAAAAAAA.AA - .BP.ABP.APBP.AAA - .BJ.ABP.APBP.AAA - ..P.ABP.APBP.AAA - ....PJP.APJP.AA. - ....PBP.APBP.A.. - ................ -} -# tile 527 (iron golem,female) -{ - ................ - ......PBP....... - ......HBH...B... - ......PBP...JP.. - ......PBP...BP.. - ...PPPAAAAPABP.. - ..PBJBBBBBJBAP.A - ..PPPPPPPPPPPA.A - .B.A........A..A - .BP.AAAAAAAAA.AA - .BP.ABP.APBP.AAA - .BJ.ABP.APBP.AAA - ..P.ABP.APBP.AAA - ....PJP.APJP.AA. - ....PBP.APBP.A.. - ................ -} -# tile 528 (human,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......ELELA..... - ......LLLLA..... - ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 529 (human,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......ELELA..... - ......LLLLA..... - ......ALLA...... - .....CJAAJC.AAA. - ....CLJLLJLCAAA. - ....LAKJJJALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 530 (wererat,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......GJGJA..... - ......LLLLA..... - ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 531 (wererat,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......GJGJA..... - ......LLLLA..... - ......ALLA...... - .....CJAAJC.AAA. - ....CLJLLJLCAAA. - ....LAKJJJALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 532 (werejackal,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......IPIPA..... - ......LLLLA..... - ......ALLA...... - .....CLAALC.AAA. - ....CLLLLLLCAAA. - ....LACLLCALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 533 (werejackal,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - ......IPIPA..... - ......LLLLA..... - ......ALLA...... - .....CJAAJC.AAA. - ....CLJLLJLCAAA. - ....LAKJJJALAAA. - ....LAJJKJALAAA. - ......JJJKAAAA.. - ......JJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 534 (werewolf,male) -{ - ................ - ................ - ......JJA....... - .....JJJJA...... - .....NJNJA...... - .....LLLLA...... - .....ALLA....... - ....CLAALC.AAA.. - ...CLLLLLLCAAA.. - ...LACLLCALAAA.. - ...LAJJKJALAAA.. - .....JJJKAAAA... - .....JJAJAA.A... - ....KLA.LKA..... - ................ - ................ -} -# tile 535 (werewolf,female) -{ - ................ - ................ - ......JJA....... - .....JJJJA...... - .....NJNJA...... - .....LLLLA...... - .....ALLA....... - ....CJAAJC.AAA.. - ...CLJLLJLCAAA.. - ...LAKJJJALAAA.. - ...LAJJKJALAAA.. - .....JJJKAAAA... - .....JJAJAA.A... - ....KLA.LKA..... - ................ - ................ -} -# tile 536 (elf,male) -{ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 537 (elf,female) -{ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 538 (Woodland-elf,male) -{ - ................ - ................ - .........K...... - .......KKJ...... - ......KKKKA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......KAAK..AAA. - .....LKKKJLAAAA. - ....LAPPJAALAAA. - ..KKLKKKKJALAA.. - ......PPAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 539 (Woodland-elf,female) -{ - ................ - ................ - .........K...... - .......KKJ...... - ......KKKKA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......KAAK..AAA. - .....LKKKJLAAAA. - ....LAPPJAALAAA. - ..KKLKKKKJALAA.. - ......PPAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 540 (Green-elf,male) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 541 (Green-elf,female) -{ - ................ - ................ - .........G...... - .......GGF...... - ......GGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......GAAG..AAA. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LAGGGFALAA.. - ......GFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 542 (Grey-elf,male) -{ - ................ - ................ - .........P...... - .......PP....... - ......PPPPA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......PAAP..AAA. - .....LPPP.LAAAA. - ....LAAP.AALAAA. - ....LAPPP.ALAA.. - ......P.A.AA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 543 (Grey-elf,female) -{ - ................ - ................ - .........P...... - .......PP....... - ......PPPPA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......PAAP..AAA. - .....LPPP.LAAAA. - ....LAAP.AALAAA. - ....LAPPP.ALAA.. - ......P.A.AA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 544 (elf-leader,male) -{ - ................ - ................ - ........II...... - .......HGF...... - ......HGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......HAAH..AAA. - .....LHHHFLAAAA. - ....LAAIIAALAAA. - ....LAHGGFALAA.. - ......HFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 545 (elf-leader,female) -{ - ................ - ................ - ........II...... - .......HGF...... - ......HGGGA..... - ......LELEA..... - ......LLLLA..... - ......ALLA....A. - ......HAAH..AAA. - .....LHHHFLAAAA. - ....LAAIIAALAAA. - ....LAHGGFALAA.. - ......HFAFAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 546 (elven monarch,male) -{ - ................ - ................ - ......H..H...... - ......HCHH...... - ......HHHHA..... - ......LELEA..... - ......LLLLA..... - .....IALLAI...A. - ....IIIAAIDIAAA. - .....LIIGDLAAAAA - ....LADIFDALAAAA - ....LAIIGDALAAA. - .....IIFAFDAAA.. - ...IIKLAILKDI... - ................ - ................ -} -# tile 547 (elven monarch,female) -{ - ................ - ......H..H...... - ......H..H...... - ......HCHH...... - ......HHHHA..... - ......LELEA..... - ......LLLLA..... - .....IALLAI...A. - ....IIIAAIDIAAA. - .....LIIGDLAAAAA - ....LADIFDALAAAA - ....LAIIGDALAAA. - .....IIFAFDAAA.. - ...IIKLAILKDI... - ................ - ................ -} -# tile 548 (doppelganger,male) -{ - ................ - ......CCCC..I... - ..I..CD...C..... - ....CD.HHA.C.... - ...CD.HHHHA.C.I. - ...CD.LFLFA.DC.. - .I.CD.LLLLA.DC.. - ...CD.ALLA.DC... - ..CD.LLAALL.ACA. - .CD.LLLLLLLLADC. - .CD.LALLLLALADC. - .CD.LAJJKJALADC. - ..CD..LJJLAAACA. - ...CD.LLALAACA.. - ..CD.LLAALLADC.. - ................ -} -# tile 549 (doppelganger,female) -{ - ................ - ......CCCC..I... - ..I..CD...C..... - ....CD.HHA.C.... - ...CD.HHHHA.C.I. - ...CD.LFLFA.DC.. - .I.CD.LLLLA.DC.. - ...CD.ALLA.DC... - ..CD.LLAALL.ACA. - .CD.LLLLLLLLADC. - .CD.LALLLLALADC. - .CD.LAJJKJALADC. - ..CD..LJJLAAACA. - ...CD.LLALAACA.. - ..CD.LLAALLADC.. - ................ -} -# tile 550 (shopkeeper,male) -{ - ................ - ................ - ......AAAA...... - .....AAAAAA..... - ......JLJL...... - ......LLLL...... - ......ALLA...... - .....EBAABEA.AA. - ....EBBBBBBEAAA. - ....BAEBBEABAAA. - ....LAGFFFALAAA. - ......GFAFAAAA.. - ......GFAFAA.A.. - .....JJA.JJA.... - ................ - ................ -} -# tile 551 (shopkeeper,female) -{ - ................ - ................ - ......AAAA...... - .....AAAAAA..... - ......JLJL...... - ......LLLL...... - ......ALLA...... - .....EBAABEA.AA. - ....EBBBBBBEAAA. - ....BAEBBEABAAA. - ....LAGFFFALAAA. - ......GFAFAAAA.. - ......GFAFAA.A.. - .....JJA.JJA.... - ................ - ................ -} -# tile 552 (guard,male) -{ - ................ - .....BBPPPAA.... - ....BNPPPPPPA... - ....BPPBPPPPA... - ....BAABPAAPA... - ....BCLBPCLPA... - ....AKCPPCJAAA.. - ....BKJJJJAPAAAA - ...BPKJAAJAPPAAA - ..BPPKJJJJAPPPAA - ..PPABKJJAPPAPPA - ..PPABPKAPPPAPPA - ..LC.BPPPPPPCLAA - ..LL.BPPABPPLLAA - .....BPPABPPAAAA - ....BPPP.BPPPAAA -} -# tile 553 (guard,female) -{ - ................ - .....BBPPPAA.... - ....BNPPPPPPA... - ....BPPBPPPPA... - ....BAABPAAPA... - ....BCLBPCLPA... - ....JCLPPCLJAA.. - ....BPLLLLAPAAAA - ...BPPLAALAPPAAA - ..BPPPPLLPPPPPAA - ..PPABPPPPPPAPPA - ..PPABPPPPPPAPPA - ..LC.BPPPPPPCLAA - ..LL.BPPABPPLLAA - .....BPPABPPAAAA - ....BPPP.BPPPAAA -} -# tile 554 (prisoner,male) -{ - ................ - ................ - .......NOA...... - .......LLA...... - .......LLA...... - .......NOA...... - ......NOONA..... - .....NOOOONA.... - ....NANOOOANAA.. - ....PANOOOAPAAA. - ....LANOOOALAAA. - ......NOOOAAAA.. - ......NAANAAA... - ......PAAPAA.... - .....LLA.LLA.... - ................ -} -# tile 555 (prisoner,female) -{ - ................ - ................ - .......NOA...... - .......LLA...... - .......LLA...... - .......NOA...... - ......NOONA..... - .....NOOOONA.... - ....NANOOOANAA.. - ....PANOOOAPAAA. - ....LANOOOALAAA. - ......NOOOAAAA.. - ......NAANAAA... - ......PAAPAA.... - .....LLA.LLA.... - ................ -} -# tile 556 (Oracle,male) -{ - ................ - ................ - .......NN....... - LLL...GLLG...LLL - ..L..NLLLLN..L.. - ...L.NLAALN.L... - ....LNLLLLNL.... - .....LNLLNL..AA. - .....NBBEEN.AAAA - ......BBEEAAAAAA - .LLA..BBBEAAALL. - .LLLLBBBEBELLLLA - ..LLCLBLLELLCLAA - ...CLLLLLLLCLAA. - ....LELLLLELAA.. - ................ -} -# tile 557 (Oracle,female) -{ - ................ - ................ - .......NN....... - LLL...GLLG...LLL - ..L..NLLLLN..L.. - ...L.NLAALN.L... - ....LNLLLLNL.... - .....LNLLNL..AA. - .....NBBEEN.AAAA - ......BBEEAAAAAA - .LLA..BBBEAAALL. - .LLLLBBBEBELLLLA - ..LLCLBLLELLCLAA - ...CLLLLLLLCLAA. - ....LELLLLELAA.. - ................ -} -# tile 558 (aligned priest,male) -{ - ................ - INI............. - III..KCCK....... - .J..KCCCCK...... - .J..CAAKCC...... - .LC.CAAACC...... - CLLC.CAACJKC.... - CJLACCCCJKCCC... - .JAACCJJCKCCCK.. - .JKCCCJCCJCCK.AA - .J..CCJCCLJCAAAA - .J..CCJCLLCAAAA. - .J..KCJCCCJAAAA. - .J.ACCJCCCJAAA.. - .JACCCJJCCCAA... - ................ -} -# tile 559 (aligned priest,female) -{ - ................ - INI............. - III..KCCK....... - .J..KCCCCK...... - .J..CAAKCC...... - .LC.CAAACC...... - CLLC.CAACJKC.... - CJLACCCCJKCCC... - .JAACCJJCKCCCK.. - .JKCCCJCCJCCK.AA - .J..CCJCCLJCAAAA - .J..CCJCLLCAAAA. - .J..KCJCCCJAAAA. - .J.ACCJCCCJAAA.. - .JACCCJJCCCAA... - ................ -} -# tile 560 (high priest,male) -{ - .INI............ - IIIII.KCCK...... - .IHI.KCAACK..... - ..H..CGAGAC..... - ..LC.CAAAAC..... - .CLLC.CAACJCK... - .CHLACCCCJCCCK.. - ..HAACCJJCCCCCK. - ..HCCCCJCCJCCC.A - ..H..CCJCCLJCAAA - ..H..CCJCLLCAAAA - ..H..KCJCCCJAAAA - ..H..KCJCCCJAAAA - ..H.ACCJCCCJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 561 (high priest,female) -{ - .INI............ - IIIII.KCCK...... - .IHI.KCAACK..... - ..H..CGAGAC..... - ..LC.CAAAAC..... - .CLLC.CAACJCK... - .CHLACCCCJCCCK.. - ..HAACCJJCCCCCK. - ..HCCCCJCCJCCC.A - ..H..CCJCCLJCAAA - ..H..CCJCLLCAAAA - ..H..KCJCCCJAAAA - ..H..KCJCCCJAAAA - ..H.ACCJCCCJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 562 (soldier,male) -{ - .....J.......... - .....JAAA....... - .....ALLLA...... - .....LLLLC...... - .....JLLC....... - .....JF..F...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....JJ.JJ...... - ................ -} -# tile 563 (soldier,female) -{ - .....J.......... - .....JAAA....... - .....ALLLA...... - .....LLLLC...... - .....JLLC....... - .....JF..F...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....JJ.JJ...... - ................ -} -# tile 564 (sergeant,male) -{ - .....J.......... - .....JFFF....... - ....FFFFFF...... - .....LLLLC...... - .....JLLC....... - .....JF..G...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 565 (sergeant,female) -{ - .....J.......... - .....JFFF....... - ....FFFFFF...... - .....LLLLC...... - .....JLLC....... - .....JF..G...... - ....FJFFFFF..A.. - ....FJFFFAF.A... - ....FLFFFFFAAA.. - ....FJFFAAAAAAA. - .....LFAFFAAAA.. - .....FFAF.AAAA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 566 (nurse,male) -{ - ................ - .......NO....... - ......NDDO...... - ......NNOOA..... - .....DBLBLD..... - .....CLLLLDC.... - .....DALLACD.... - .....CNAAODCAAA. - .....NNNOOLAAAA. - ....LANNDOALAAA. - ....LANNOOALAAA. - ......NNOOAAAA.. - ......NNAOAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 567 (nurse,female) -{ - ................ - .......NO....... - ......NDDO...... - ......NNOOA..... - .....DBLBLD..... - .....CLLLLDC.... - .....DALLACD.... - .....CNAAODCAAA. - .....NNNOOLAAAA. - ....LANNDOALAAA. - ....LANNOOALAAA. - ......NNOOAAAA.. - ......NNAOAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 568 (lieutenant,male) -{ - ................ - .......FFF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....GF.FGA..... - ....FFFFFFFF.... - ....FAFFFFAFAAA. - ....FAFFFFAFAAAA - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 569 (lieutenant,female) -{ - ................ - .......FFF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....GF.FGA..... - ....FFFFFFFF.... - ....FAFFFFAFAAA. - ....FAFFFFAFAAAA - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.AA.... - .....FFAFFA..... - .....AA.AA...... - ................ -} -# tile 570 (captain,male) -{ - ................ - ......FHHF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....HF.FHF..... - ....FFFFFFFFAA.. - ....FAFFIFAFAAAA - ....FAFFFFAFAAA. - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.JJJA.. - .....FFAFFJJJA.. - .....AA.AAAAA... - ................ -} -# tile 571 (captain,female) -{ - ................ - ......FHHF...... - .....FFFFFF..... - ......LLLL...... - .......LLCA..... - .....HF.FHF..... - ....FFFFFFFFAA.. - ....FAFFIFAFAAAA - ....FAFFFFAFAAA. - ....FAFFFFAFAAA. - ....LFFAFFJLJA.. - .....FFAFFJJJA.. - ......FAF.JJJA.. - .....FFAFFJJJA.. - .....AA.AAAAA... - ................ -} -# tile 572 (watchman,male) -{ - ................ - ......PPP....... - ....PPPPPP...... - .....LLLLC...... - ......LLC....... - .....PP..P...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - ......PAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 573 (watchman,female) -{ - ................ - ......PPP....... - ....PPPPPP...... - .....LLLLC...... - ......LLC....... - .....PP..P...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - ......PAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 574 (watch captain,male) -{ - ......PPP....... - .....PHHHP...... - ....PPPPPPP..... - .....LLLLC...... - ......LLC....... - .....HP..H...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - .....JPAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 575 (watch captain,female) -{ - ......PPP....... - .....PHHHP...... - ....PPPPPPP..... - .....LLLLC...... - ......LLC....... - .....HP..H...... - ....PPPPPPP..... - ....PAPPHAPPA... - ....PAPPPANNAAA. - ....PJPPAPNNAAA. - ....JLPAPPAAAA.. - .....JPAP.AAAA.. - .....JPAP.AA.... - .....PPAPPA..... - ....JJJ.JJJ..... - ................ -} -# tile 576 (Medusa,male) -{ - ................ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....A.. - .GAFLLLLA..A..A. - ....JLLKA.A.A.A. - ...KBLLBKAAAAA.. - ..KIIBBIIIAAA.A. - ..IIIKKILLIAAA.. - ..KIILLIALIAA... - ...KIALKAAIAA... - ...IKAAKIIAAA... - ...IIKKIIIAA.... - ..IIKIKIKIA..... - ................ -} -# tile 577 (Medusa,female) -{ - ................ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....A.. - .GAFLLLLA..A..A. - ....JLLKA.A.A.A. - ...KBLLBKAAAAA.. - ..KIIBBIIIAAA.A. - ..IIIKKILLIAAA.. - ..KIILLIALIAA... - ...KIALKAAIAA... - ...IKAAKIIAAA... - ...IIKKIIIAA.... - ..IIKIKIKIA..... - ................ -} -# tile 578 (Wizard of Yendor,male) -{ - .EEE.......EEE.. - EFFAE..E..EAFFE. - EAAAE.EEE.EAAAE. - EAAAEEEAEEEAAAE. - EEAAEEDADEEAAEE. - .EEEEAAAAAEEEE.. - ..EEEEAAAEEEE... - ..EEEEEEEEEE.... - ...EEEEEEEE..... - ...EEEEEEEE....A - ....EEEEEE...AAA - ....EEEEEEAAAAAA - ...EEEEEEEEAAAAA - ..EEEEEEEEEAAAAA - .EEEEEEEEEEEAAA. - EEEEEEEEEEEEEEA. -} -# tile 579 (Wizard of Yendor,female) -{ - .EEE.......EEE.. - EFFAE..E..EAFFE. - EAAAE.EEE.EAAAE. - EAAAEEEAEEEAAAE. - EEAAEEDADEEAAEE. - .EEEEAAAAAEEEE.. - ..EEEEAAAEEEE... - ..EEEEEEEEEE.... - ...EEEEEEEE..... - ...EEEEEEEE....A - ....EEEEEE...AAA - ....EEEEEEAAAAAA - ...EEEEEEEEAAAAA - ..EEEEEEEEEAAAAA - .EEEEEEEEEEEAAA. - EEEEEEEEEEEEEEA. -} -# tile 580 (Croesus,male) -{ - ....H..H..H..... - ....HCHEHCH..... - ....HHHHHHH..... - ....ALLLLLA..... - ....LLALALL..... - .....LLLLL...... - ....HLLDLLH..... - ...HIALLLAIH.A.A - ...HIHAAAHIHAAAA - ..IIIEHHHIIIIAAA - ..IIIIEHIIIIIAA. - ..ILLIHHHILLIAAA - ...LIIKHIIILAAAA - ..GIIIKJIIIIGAA. - .GIIIKJJKKIIIGG. - ................ -} -# tile 581 (Croesus,female) -{ - ....H..H..H..... - ....HCHEHCH..... - ....HHHHHHH..... - ....ALLLLLA..... - ....LLALALL..... - .....LLLLL...... - ....HLLDLLH..... - ...HIALLLAIH.A.A - ...HIHAAAHIHAAAA - ..IIIEHHHIIIIAAA - ..IIIIEHIIIIIAA. - ..ILLIHHHILLIAAA - ...LIIKHIIILAAAA - ..GIIIKJIIIIGAA. - .GIIIKJJKKIIIGG. - ................ -} -# tile 582 (Charon,male) -{ - ................ - .......J........ - ......JJJ....... - ....JJJAJJJ..... - ....JJDADJJ..... - ...JJAAAAAJJ.... - ...JJJAAAJJJ.... - ..JJJJJJJJJJ.... - .JJJJJJJJJJJJ... - JJJJJJJJJJJJJJ.A - .OO.JJJJJJ.OOAAA - ....JJJJJJAAAAAA - ...JJJJJJJJAAAAA - ..JJJJJJJJJAAAAA - .JJJJJJJJJJJAAA. - JJJJJJJJJJJJJJA. -} -# tile 583 (Charon,female) -{ - ................ - .......J........ - ......JJJ....... - ....JJJAJJJ..... - ....JJDADJJ..... - ...JJAAAAAJJ.... - ...JJJAAAJJJ.... - ..JJJJJJJJJJ.... - .JJJJJJJJJJJJ... - JJJJJJJJJJJJJJ.A - .OO.JJJJJJ.OOAAA - ....JJJJJJAAAAAA - ...JJJJJJJJAAAAA - ..JJJJJJJJJAAAAA - .JJJJJJJJJJJAAA. - JJJJJJJJJJJJJJA. -} -# tile 584 (ghost,male) -{ - ................ - ................ - ...NNN.......... - ..NANANN........ - .NNNNNNNNN...... - .NNPAAPNNNNN.... - .NNAAAANNNOONO.. - .NNAAAANONNNPNNO - .NNPAAPNONNOOOP. - .NNNNNNONOPNPPO. - .NNONNOPNNOPOOP. - .NOPNNOOOPPOOP.. - .OOOPOPPOPPP.PP. - .PP.PPOPPP...P.. - .O...P....P..... - ........P....... -} -# tile 585 (ghost,female) -{ - ................ - ................ - ...NNN.......... - ..NANANN........ - .NNNNNNNNN...... - .NNPAAPNNNNN.... - .NNAAAANNNOONO.. - .NNAAAANONNNPNNO - .NNPAAPNONNOOOP. - .NNNNNNONOPNPPO. - .NNONNOPNNOPOOP. - .NOPNNOOOPPOOP.. - .OOOPOPPOPPP.PP. - .PP.PPOPPP...P.. - .O...P....P..... - ........P....... -} -# tile 586 (shade,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ........AAAAAAA. - ....AAAAAAAA.... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAA. - ..AAAAAAAAAAAAAA - .AAAAAAAAAAAAA.. - AAAA.AAAAJA..... - ................ -} -# tile 587 (shade,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ................ - ........AAAAAAA. - ....AAAAAAAA.... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAA. - ..AAAAAAAAAAAAAA - .AAAAAAAAAAAAA.. - AAAA.AAAAJA..... - ................ -} -# tile 588 (water demon,male) -{ - ................ - ................ - ................ - ................ - ..EE.....EE..... - .E.EE...EE.E.... - ....EEEEE....... - ....EBEBE..A.... - ...EEEEEEEAAAA.. - ..EEE...EEEAA.A. - ..EEEEEEEEEAAA.. - ..EEAEEEAEEAAA.. - ...AAEEEAAAAA... - ....EEAEEAA..... - ....EEAEEA...... - ................ -} -# tile 589 (water demon,female) -{ - ................ - ................ - ................ - ................ - ..EE.....EE..... - .E.EE...EE.E.... - ....EEEEE....... - ....EBEBE..A.... - ...EEEEEEEAAAA.. - ..EEE...EEEAA.A. - ..EEEEEEEEEAAA.. - ..EEAEEEAEEAAA.. - ...AAEEEAAAAA... - ....EEAEEAA..... - ....EEAEEA...... - ................ -} -# tile 590 (amorous demon,male) -{ - DD.OHHD......... - DDOHHDGD........ - DDOHDDDDD....... - DDHHDDDA........ - DDDHDJADDDD..... - DDDJDDDDDDDD.... - .DDDDDCDD.DDD... - .DDCDDDKK..DD... - ..DDKKDDDAADDA.. - ...DDDDDDAAAAA.. - ....DDDDDDDDDA.. - ....DDJDJJAAAAAA - ....JDJJADKAA... - ....DDKAADDKA... - ...DDKAA..DDAA.. - ..DDKAA...DDDA.. -} -# tile 595 (amorous demon,female) -{ - DD.OHHD......... - DDOHHDGD........ - DDOHDDDDD....... - DDHHDDDA........ - DHHHDJADDDD..... - .HHJJDDDJDDD.... - OHDDCDCDDJDD.... - HHHCDDCDLJ.DD... - HHHCDLJJJAADDA.. - HHHDJJDDDAADAA.. - HHHHDDAADAAAA... - HHHH.DKJDDAA.... - H.H..DDAADDAA... - ..H..DDAA.DAA... - ....DDAA..DDAA.. - ...DDJA...DDDA.. -} -# tile 592 (horned devil,male) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - ...LOCDCOL...... - ...CDDDDDC...... - ...DAADAADA..D.. - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - ..CDAKKKACDAAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - ...CDDADDKAA.... - ..CDDAA.DDK..... - ................ -} -# tile 593 (horned devil,female) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - ...LOCDCOL...... - ...CDDDDDC...... - ...DAADAADA..D.. - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - ..CDAKKKACDAAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - ...CDDADDKAA.... - ..CDDAA.DDK..... - ................ -} -# tile 596 (erinys,male) -{ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....... - .GAFDLDLA..A.A.. - ....LLLEA.A.A.A. - ...EBLLBEAAAA.A. - ..EBBBBBBBAAAA.. - ..BBBEBBLLBAA.A. - ..EBBLLBALBAAA.. - ...EBALBAABAA... - ...BEAABBBAAA... - ...BBBBBBBAAA... - ...BBBBBBBAA.... - ..BBEBEBEBA..... - ................ -} -# tile 597 (erinys,female) -{ - ..GA...GA....... - ...FA.FA..GA.... - ....FJFFFF...... - ..FAFLLFA....... - .GAFDLDLA..A.A.. - ....LLLEA.A.A.A. - ...EBLLBEAAAA.A. - ..EBBBBBBBAAAA.. - ..BBBEBBLLBAA.A. - ..EBBLLBALBAAA.. - ...EBALBAABAA... - ...BEAABBBAAA... - ...BBBBBBBAAA... - ...BBBBBBBAA.... - ..BBEBEBEBA..... - ................ -} -# tile 598 (barbed devil,male) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - .O.LOCDCOL.O.... - ...CDDDDDC....DD - ...DAADAADA..D.D - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - .C.DAKKKACDKAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - .K.CDDADDKAAK... - .CCDDAA.DDKK.... - ................ -} -# tile 599 (barbed devil,female) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..... - .O.LOCDCOL.O.... - ...CDDDDDC....DD - ...DAADAADA..D.D - ...DDDDDDDA.D... - ..CCDDFDDCCAD.A. - ..CDKDDDKCDADA.. - .C.DAKKKACDKAAA. - ..DDADDDADDAAAA. - ....CDDDKAAAAA.. - .K.CDDADDKAAK... - .CCDDAA.DDKK.... - ................ -} -# tile 600 (marilith,male) -{ - .D..HHH.....D... - DD.HHHHHA...DD.. - .DCHDDDHHAAD..A. - ..HDBDBDHDDAAAA. - .CHKDDDKHAAADD.. - CDDDKKKDHDDDDFF. - D..CDDCDKAAFFFAA - D.KDDKDDDDDDFAA. - D.DKDDKDKAFDFAA. - ..D.GDDFAAFDFFAA - .D.GGFFFAAAFFFFA - ...GFFFFFAAAFFFA - ..FGFFFFFFAFFFFA - ..FGFFFFFFFFFFA. - ..FGFFFFFFFFFA.. - ....GFFFFFFAA... -} -# tile 601 (marilith,female) -{ - .D..HHH.....D... - DD.HHHHHA...DD.. - .DCHDDDHHAAD..A. - ..HDBDBDHDDAAAA. - .CHKDDDKHAAADD.. - CDDDKKKDHDDDDFF. - D..CDDCDKAAFFFAA - D.KDDKDDDDDDFAA. - D.DKDDKDKAFDFAA. - ..D.GDDFAAFDFFAA - .D.GGFFFAAAFFFFA - ...GFFFFFAAAFFFA - ..FGFFFFFFAFFFFA - ..FGFFFFFFFFFFA. - ..FGFFFFFFFFFA.. - ....GFFFFFFAA... -} -# tile 602 (vrock,male) -{ - ................ - ......OPP.O..... - ......PPPP...... - .....CPPDP...... - ....CCCPPP...... - ....CCPPPP...... - ....C..PPA...... - .....DDAADD.AAA. - ....DDDDDDDDAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ......DAADAAAA.. - ......DAADAA.A.. - .....DDA.DDA.... - ................ -} -# tile 603 (vrock,female) -{ - ................ - ......OPP.O..... - ......PPPP...... - .....CPPDP...... - ....CCCPPP...... - ....CCPPPP...... - ....C..PPA...... - .....DDAADD.AAA. - ....DDDDDDDDAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ....DADDDDADAAA. - ......DAADAAAA.. - ......DAADAA.A.. - .....DDA.DDA.... - ................ -} -# tile 604 (hezrou,male) -{ - ................ - ................ - ....GGGFF....... - ..NGFFNNFFF..... - .DFFFDDNFF.F.... - .GFFFDNFF.FFFAA. - .AFAFFFFFFFFFFAA - .GFFFF.FFF.FGFAA - .GAAAFF..LFGFFAA - ..FFFF.FFLFGFFFA - ..LLA.FLLLJJG.FA - .LLAFFLLFJJGFFFA - ..LAFLLLAAGF.FAA - .....L.LAGFFFFAA - ...........FFFA. - ................ -} -# tile 605 (hezrou,female) -{ - ................ - ................ - ....GGGFF....... - ..NGFFNNFFF..... - .DFFFDDNFF.F.... - .GFFFDNFF.FFFAA. - .AFAFFFFFFFFFFAA - .GFFFF.FFF.FGFAA - .GAAAFF..LFGFFAA - ..FFFF.FFLFGFFFA - ..LLA.FLLLJJG.FA - .LLAFFLLFJJGFFFA - ..LAFLLLAAGF.FAA - .....L.LAGFFFFAA - ...........FFFA. - ................ -} -# tile 606 (bone devil,male) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..O.. - ...LNLOLOL....O. - ...LOOOOOL....O. - ...NAAOAAOA..O.. - ...NOOOOOOA.O... - ..NOOOFOOOOAO.A. - ..OOKNOOKOOALA.. - ..OOANOOAOOAKAA. - ..LLANOOALLAAAA. - ....NOOOLAAAAA.. - ...NOOAOOLAA.... - ..NOOAA.OOL..... - ................ -} -# tile 607 (bone devil,female) -{ - ................ - ................ - ..O.......O..... - ..OO.....OO..O.. - ...LNLOLOL....O. - ...LOOOOOL....O. - ...NAAOAAOA..O.. - ...NOOOOOOA.O... - ..NOOOFOOOOAO.A. - ..OOKNOOKOOALA.. - ..OOANOOAOOAKAA. - ..LLANOOALLAAAA. - ....NOOOLAAAAA.. - ...NOOAOOLAA.... - ..NOOAA.OOL..... - ................ -} -# tile 608 (ice devil,male) -{ - ................ - ................ - ..N.......N..... - ..NN.....NN..... - ...PBPNPNP..BNB. - ...PNNNNNP..N.N. - ...BAANAANA...N. - ...BNNNNNNA.BNB. - ..BNNNFNNNNAN.A. - ..NNKBNNKNNABA.. - ..NNABNNANNA.AA. - ..PPABNNAPPAAAA. - ....BNNNPAAAAA.. - ...BNNANNPAA.... - ..BNNAA.NNP..... - ................ -} -# tile 609 (ice devil,female) -{ - ................ - ................ - ..N.......N..... - ..NN.....NN..... - ...PBPNPNP..BNB. - ...PNNNNNP..N.N. - ...BAANAANA...N. - ...BNNNNNNA.BNB. - ..BNNNFNNNNAN.A. - ..NNKBNNKNNABA.. - ..NNABNNANNA.AA. - ..PPABNNAPPAAAA. - ....BNNNPAAAAA.. - ...BNNANNPAA.... - ..BNNAA.NNP..... - ................ -} -# tile 610 (nalfeshnee,male) -{ - ................ - ................ - ......BB...BB... - ..KKKKKBB.BB.... - .KADKADKKKB..... - .KKKKKKKDKK..... - .OKDKOKKDDKD.... - .OKDKOKKKDKDD... - .KAAAKKDKAKKD... - ..KKKDDLAKKKD.A. - ...KK.KKKKKDDA.. - ....L..KDAKDAA.. - ......LLAAKDA... - .........LLA.... - ................ - ................ -} -# tile 611 (nalfeshnee,female) -{ - ................ - ................ - ......BB...BB... - ..KKKKKBB.BB.... - .KADKADKKKB..... - .KKKKKKKDKK..... - .OKDKOKKDDKD.... - .OKDKOKKKDKDD... - .KAAAKKDKAKKD... - ..KKKDDLAKKKD.A. - ...KK.KKKKKDDA.. - ....L..KDAKDAA.. - ......LLAAKDA... - .........LLA.... - ................ - ................ -} -# tile 612 (pit fiend,male) -{ - ................ - .K.O.......O.K.. - .K.OO.....OO.KJ. - KJJ.LOCDCOL.KJJ. - KJJJKDDDDDKKJJJ. - KJJCKDNDNDKCJJJA - JJCCKDDDDDJCCJJA - JJCCCKDIDJDCCJJA - JACCDDKJJDDCDAJA - JACCKDDDDDKCDAJA - ...CDKDDDKCDDAAA - ....DKDDDKCDAAAA - .....CDDDKAAAA.. - ....CDDADDKA.... - ...CDDAA.DDK.... - ................ -} -# tile 613 (pit fiend,female) -{ - ................ - .K.O.......O.K.. - .K.OO.....OO.KJ. - KJJ.LOCDCOL.KJJ. - KJJJKDDDDDKKJJJ. - KJJCKDNDNDKCJJJA - JJCCKDDDDDJCCJJA - JJCCCKDIDJDCCJJA - JACCDDKJJDDCDAJA - JACCKDDDDDKCDAJA - ...CDKDDDKCDDAAA - ....DKDDDKCDAAAA - .....CDDDKAAAA.. - ....CDDADDKA.... - ...CDDAA.DDK.... - ................ -} -# tile 614 (sandestin,male) -{ - .....CCCCC..I... - .I..CD....C..... - ...CD.DDD..C..I. - ..CD.DDDDD..C... - ..CD.DNDNDA.DC.. - I.CD.DDDDDA.DC.. - ..CD.ADDDA.DC..A - .CD.DDAAADD.DCAA - CD.DDDDDDDDDADCA - CD.DADDDDDADADCA - CD.DADDDDDADADCA - CD.DADDDDDADADC. - .CD..DDJDDAADCA. - ..CD.DDADDADCA.. - .CD.DDAADDDADC.. - ................ -} -# tile 615 (sandestin,female) -{ - .....CCCCC..I... - .I..CD....C..... - ...CD.DDD..C..I. - ..CD.DDDDD..C... - ..CD.DNDNDA.DC.. - I.CD.DDDDDA.DC.. - ..CD.ADDDA.DC..A - .CD.DDAAADD.DCAA - CD.DDDDDDDDDADCA - CD.DADDDDDADADCA - CD.DADDDDDADADCA - CD.DADDDDDADADC. - .CD..DDJDDAADCA. - ..CD.DDADDADCA.. - .CD.DDAADDDADC.. - ................ -} -# tile 616 (balrog,male) -{ - ................ - .K..O.....O..K.. - .KJ.O.....O.KJ.. - KJJLOOCDCOOLJJJ. - JJJDDDDDDDDDDKJ. - JCCDDDNDNDDDCCJA - CCDKDDDDDDDJCCCA - CDDKKKDIDJJDCCDA - CDDKDDKJJDDDCDDA - CCDKDDDDDDDKCDDA - JCCDKKDDDKKCDDDA - JJCDKKDDDKKCDDJA - JJ..CCDDDKKAAJJA - J..CDDDADDDKAAJA - ..CDDDAA.DDDK.AA - ................ -} -# tile 617 (balrog,female) -{ - ................ - .K..O.....O..K.. - .KJ.O.....O.KJ.. - KJJLOOCDCOOLJJJ. - JJJDDDDDDDDDDKJ. - JCCDDDNDNDDDCCJA - CCDKDDDDDDDJCCCA - CDDKKKDIDJJDCCDA - CDDKDDKJJDDDCDDA - CCDKDDDDDDDKCDDA - JCCDKKDDDKKCDDDA - JJCDKKDDDKKCDDJA - JJ..CCDDDKKAAJJA - J..CDDDADDDKAAJA - ..CDDDAA.DDDK.AA - ................ -} -# tile 618 (Juiblex,male) -{ - ................ - DD.........DD... - NDC.KKKKJ.CND... - .CCKCCCKKCCAA... - ..KCCCCKCCJAA... - ..KCCCCCK.JJAA.. - ..KCCFCCK..JAA.. - ..FKCFCCKK.JAAA. - .FKKFCCKFK..JAA. - .FKCFCCFKFK.JAA. - .FCFCCKFCFK.JAA. - FKCFCFCFCKK.JAA. - CKFCCFCCKKFKJJA. - CCKKCFCKFFKKKKA. - .CCCCCCCCCCCKA.. - ................ -} -# tile 619 (Juiblex,female) -{ - ................ - DD.........DD... - NDC.KKKKJ.CND... - .CCKCCCKKCCAA... - ..KCCCCKCCJAA... - ..KCCCCCK.JJAA.. - ..KCCFCCK..JAA.. - ..FKCFCCKK.JAAA. - .FKKFCCKFK..JAA. - .FKCFCCFKFK.JAA. - .FCFCCKFCFK.JAA. - FKCFCFCFCKK.JAA. - CKFCCFCCKKFKJJA. - CCKKCFCKFFKKKKA. - .CCCCCCCCCCCKA.. - ................ -} -# tile 620 (Yeenoghu,male) -{ - ....B.HHP....... - ....BPPPP....... - ...BPLCPPH...... - .KBPPCCPPH...... - .PPPPPPP.H...... - .PP...P.PH...... - ....BPPPPPAAA... - ..BPPPPPPPPAAAA. - .BP.PPPPPAPPAAAA - .B...BPP.AAPAAAA - .B...BPP.AAPAAA. - .....BPPAAAAA.A. - ....BP.PPAA...A. - ...BP.AAPPA..A.. - ...BPAA.PPA..... - ................ -} -# tile 621 (Yeenoghu,female) -{ - ....B.HHP....... - ....BPPPP....... - ...BPLCPPH...... - .KBPPCCPPH...... - .PPPPPPP.H...... - .PP...P.PH...... - ....BPPPPPAAA... - ..BPPPPPPPPAAAA. - .BP.PPPPPAPPAAAA - .B...BPP.AAPAAAA - .B...BPP.AAPAAA. - .....BPPAAAAA.A. - ....BP.PPAA...A. - ...BP.AAPPA..A.. - ...BPAA.PPA..... - ................ -} -# tile 622 (Orcus,male) -{ - ................ - .K..O.....O..K.. - KJJO..BBB..O.KJ. - KJJLOBPPPPOLKJJ. - JKJJ.PGPGP.JJKJA - JJKJKPPPPPJJKJJJ - JBPPB.BPPABBPPJJ - PJJPP.BPPAPPJJPA - PJBPPP.AAPPPPJPA - .JBP.PPPP.P.PJAA - .JBPPPP.PPPPPJAA - ..PPP.PPP.PPPAAA - ...P.PPPPPPP.P.A - ...BPPPAPPPPAAPA - ...OOPPAOOPPAGA. - ................ -} -# tile 623 (Orcus,female) -{ - ................ - .K..O.....O..K.. - KJJO..BBB..O.KJ. - KJJLOBPPPPOLKJJ. - JKJJ.PGPGP.JJKJA - JJKJKPPPPPJJKJJJ - JBPPB.BPPABBPPJJ - PJJPP.BPPAPPJJPA - PJBPPP.AAPPPPJPA - .JBP.PPPP.P.PJAA - .JBPPPP.PPPPPJAA - ..PPP.PPP.PPPAAA - ...P.PPPPPPP.P.A - ...BPPPAPPPPAAPA - ...OOPPAOOPPAGA. - ................ -} -# tile 624 (Geryon,male) -{ - .K...........K.. - .K....JJJ....KJ. - KJJ..JJJJJ..KJJ. - KJJJKLLLLLKKJJJ. - KJJJKLBLBLKJJJJA - JJJJKLLLLLJJJJJA - JJALLKLLLJLLAJJA - JA.LLLKJJLLLAAJA - ...LJLLLLLKLAAAA - ...LCKLLLKCLAFGF - ...LLGLLFALLFFFA - .....GFFFAAAFFAA - ....GGGGFFAAFFAA - ....GFFFFFAAFGFA - ....FGGGFFFFFFFA - .....FFFFFFFFFA. -} -# tile 625 (Geryon,female) -{ - .K...........K.. - .K....JJJ....KJ. - KJJ..JJJJJ..KJJ. - KJJJKLLLLLKKJJJ. - KJJJKLBLBLKJJJJA - JJJJKLLLLLJJJJJA - JJALLKLLLJLLAJJA - JA.LLLKJJLLLAAJA - ...LJLLLLLKLAAAA - ...LCKLLLKCLAFGF - ...LLGLLFALLFFFA - .....GFFFAAAFFAA - ....GGGGFFAAFFAA - ....GFFFFFAAFGFA - ....FGGGFFFFFFFA - .....FFFFFFFFFA. -} -# tile 626 (Dispater,male) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ....KACKKJAKAAA. - ....KACKKJAKAAJA - ....KACKKJAKAAJA - ....LACKKJJLAJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 627 (Dispater,female) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ....KACKKJAKAAA. - ....KACKKJAKAAJA - ....KACKKJAKAAJA - ....LACKKJJLAJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 628 (Baalzebub,male) -{ - ......F...F..... - .......F.F...... - ......BFFFB..... - .....BPPFBPP.... - .....PPPFPPP.... - ......PPFPP..... - .....CAFFFAK.... - ....CKKAFAKKKAA. - ....CAKJFAKAKAA. - ....FACJDAJAFAA. - ....FACKJJJAFAA. - ....FACKKKJAFAA. - ......CKKKJAAA.. - ......CKAKJA.A.. - .....FFA..FF.... - ................ -} -# tile 629 (Baalzebub,female) -{ - ......F...F..... - .......F.F...... - ......BFFFB..... - .....BPPFBPP.... - .....PPPFPPP.... - ......PPFPP..... - .....CAFFFAK.... - ....CKKAFAKKKAA. - ....CAKJFAKAKAA. - ....FACJDAJAFAA. - ....FACKJJJAFAA. - ....FACKKKJAFAA. - ......CKKKJAAA.. - ......CKAKJA.A.. - .....FFA..FF.... - ................ -} -# tile 630 (Asmodeus,male) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKJAKKAJA - ...KA.CKKJAAKAJA - ...LA.CKKJJALJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 631 (Asmodeus,female) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKJAKKAJA - ...KA.CKKJAAKAJA - ...LA.CKKJJALJA. - ......CKAJAJJA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 632 (Demogorgon,male) -{ - ...KKK..KKK..... - ..KBKBK.BKBK.... - ..KDKKK.KKDK.... - ..DKKFA.GKKD.... - ....GFAAGFAAA... - ...GFFFJFFFA.AAA - ..GFAGFFFAFFAAAA - .GJFAGJFJAFFFAA. - .GFAAGFFFAAFJA.. - .GJA.GFJFAAFFAA. - .GFA.GFFFA.FJAA. - .GJA.GJFJA.FFAA. - .GFAGFAAFFAFFA.. - ..GAGJAAJFAFAA.. - ..GAGFAFFFAFA... - ................ -} -# tile 633 (Demogorgon,female) -{ - ...KKK..KKK..... - ..KBKBK.BKBK.... - ..KDKKK.KKDK.... - ..DKKFA.GKKD.... - ....GFAAGFAAA... - ...GFFFJFFFA.AAA - ..GFAGFFFAFFAAAA - .GJFAGJFJAFFFAA. - .GFAAGFFFAAFJA.. - .GJA.GFJFAAFFAA. - .GFA.GFFFA.FJAA. - .GJA.GJFJA.FFAA. - .GFAGFAAFFAFFA.. - ..GAGJAAJFAFAA.. - ..GAGFAFFFAFA... - ................ -} -# tile 634 (Death,male) -{ - .BBBB....JJJ.... - .BPPPP.JJJJ..... - .C....JJJJJ..... - .C....JAAAJ..... - .C...JADADAJ.AAA - OOJ..JAAAAAJAAA. - OOOJJJAAAAAJJJA. - OOJJJJAAAAJOOJJA - .CJJJJAAAJOOOOJA - .C.JJAAAAJAOAAJA - .C..JAAAAJAOAAJA - .C..JAAAAAJOAJAA - .C..JAAAAAJJJAAA - .C.JAAAAAAAJJAA. - .CJJAAAAAAAAJJA. - ACJAAAAAAAAAAAJ. -} -# tile 635 (Death,female) -{ - .BBBB....JJJ.... - .BPPPP.JJJJ..... - .C....JJJJJ..... - .C....JAAAJ..... - .C...JADADAJ.AAA - OOJ..JAAAAAJAAA. - OOOJJJAAAAAJJJA. - OOJJJJAAAAJOOJJA - .CJJJJAAAJOOOOJA - .C.JJAAAAJAOAAJA - .C..JAAAAJAOAAJA - .C..JAAAAAJOAJAA - .C..JAAAAAJJJAAA - .C.JAAAAAAAJJAA. - .CJJAAAAAAAAJJA. - ACJAAAAAAAAAAAJ. -} -# tile 636 (Pestilence,male) -{ - F........JJJ.... - ..F....JJJJ..... - B...F.JJJJJ..... - ...B..JAAAJ..... - .F...JADADAJ.... - ...F.JAAAAAJ.AA. - .B..JFAAAAFJAA.. - ...FJJAFABJJAA.. - ..F.JFFBAJJJAAA. - ....FAFFJJJJAAA. - ....JABAJJJJAAA. - ...FJFFJJJJJJAA. - ...JJBFJJJJJJAA. - ...JAABFBJJJJAA. - ..JJFBFAFFAJJJA. - .JJAAFAFAAAAAAJ. -} -# tile 637 (Pestilence,female) -{ - F........JJJ.... - ..F....JJJJ..... - B...F.JJJJJ..... - ...B..JAAAJ..... - .F...JADADAJ.... - ...F.JAAAAAJ.AA. - .B..JFAAAAFJAA.. - ...FJJAFABJJAA.. - ..F.JFFBAJJJAAA. - ....FAFFJJJJAAA. - ....JABAJJJJAAA. - ...FJFFJJJJJJAA. - ...JJBFJJJJJJAA. - ...JAABFBJJJJAA. - ..JJFBFAFFAJJJA. - .JJAAFAFAAAAAAJ. -} -# tile 638 (Famine,male) -{ - .........JJJ.... - .......JJJ...... - K.....JJJJJ..... - K.....JAAAJ..... - K....JADADAJ.... - K....JAAAAAJ...A - K.....JAAAJJ..AA - OOJJJJJJAAJAJ.AA - K...JJJAAJJAJAAA - K.....JAJJJOJAA. - K.....JAOOOAAA.. - K.....JAJJAAA... - K.....JAJJAA.... - K.....JAAJAA.... - K...JJAAAJJAA... - K..JJAAAAAJJJA.. -} -# tile 639 (Famine,female) -{ - .........JJJ.... - .......JJJ...... - K.....JJJJJ..... - K.....JAAAJ..... - K....JADADAJ.... - K....JAAAAAJ...A - K.....JAAAJJ..AA - OOJJJJJJAAJAJ.AA - K...JJJAAJJAJAAA - K.....JAJJJOJAA. - K.....JAOOOAAA.. - K.....JAJJAAA... - K.....JAJJAA.... - K.....JAAJAA.... - K...JJAAAJJAA... - K..JJAAAAAJJJA.. -} -# tile 640 (mail daemon,male) -{ - ...OP.BEEE.PO... - ...OOEBEEEEOOD.. - ..DLOBEEEEOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDK.KDAADJJECDD - CCDKEEKKKJEEKCDD - .CCDK.EEEE..CDDD - .CCDAE.EENNNCDD. - .DDDAEEEENDNDDD. - ....BBEEENNNNN.. - ...BEEEAANNNNNA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 641 (mail daemon,female) -{ - ...OP.BEEE.PO... - ...OOEBEEEEOOD.. - ..DLOBEEEEOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDK.KDAADJJECDD - CCDKEEKKKJEEKCDD - .CCDK.EEEE..CDDD - .CCDAE.EENNNCDD. - .DDDAEEEENDNDDD. - ....BBEEENNNNN.. - ...BEEEAANNNNNA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 642 (djinni,male) -{ - .LL..NNN..LL.... - ..L..NGNA.L..... - ..LAALLLAALA.... - ..LAAKKKAALA.... - ...LCKKKCLA..... - ....LCKCLA...... - ....LICLIA..A... - ....IIIIEA.AA..A - ....EIEEIA.AAAAA - ....IEFEAAAAAAAA - .....DEAIAAAAA.. - .....IGIFAAAA... - .......FEDAAA... - .......I.GEA.A.. - .........IFED... - ................ -} -# tile 643 (djinni,female) -{ - .LL..NNN..LL.... - ..L..NGNA.L..... - ..LAALLLAALA.... - ..LAAKKKAALA.... - ...LCKKKCLA..... - ....LCKCLA...... - ....LICLIA..A... - ....IIIIEA.AA..A - ....EIEEIA.AAAAA - ....IEFEAAAAAAAA - .....DEAIAAAAA.. - .....IGIFAAAA... - .......FEDAAA... - .......I.GEA.A.. - .........IFED... - ................ -} -# tile 644 (jellyfish,male) -{ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAA... - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPPEPEEE.. - .PBBPPPEPEPPEE.. - .PEPBBEEPEEPEE.. - .PEEEPEEPEEPE... - ..PEEPE..PE.P... - ..P.EP.EEP..P... - ..PEE.P.E..E.... - .P..E.P..E...... -} -# tile 645 (jellyfish,female) -{ - ................ - .....PBPA....... - ...PBBBPBA...... - ..BBNNBPPBAA.... - .BBNNPPPBBPAA... - PBBBPPPBPBBAAA.. - BBBPBPPPPPBPAAA. - BBPBPPPPPPPBAAA. - PBPPBPPPPEPEEE.. - .PBBPPPEPEPPEE.. - .PEPBBEEPEEPEE.. - .PEEEPEEPEEPE... - ..PEEPE..PE.P... - ..P.EP.EEP..P... - ..PEE.P.E..E.... - .P..E.P..E...... -} -# tile 646 (piranha,male) -{ - ................ - ................ - ................ - ................ - ................ - ....OPP......... - .....OPP........ - ..O..PPAP.....E. - ..POPPPPPA...EEE - ..PPPPP.PPA.E... - ...PP..PPPAAAEE. - ..E.PPPPPPPPPE.. - ..E...PPPPPAA.E. - .....E..PPAE.... - .....E..P....... - ....E..E...E.... -} -# tile 647 (piranha,female) -{ - ................ - ................ - ................ - ................ - ................ - ....OPP......... - .....OPP........ - ..O..PPAP.....E. - ..POPPPPPA...EEE - ..PPPPP.PPA.E... - ...PP..PPPAAAEE. - ..E.PPPPPPPPPE.. - ..E...PPPPPAA.E. - .....E..PPAE.... - .....E..P....... - ....E..E...E.... -} -# tile 648 (shark,male) -{ - ................ - ................ - ................ - ...............P - ........P.....PP - ....E..PP....PP. - ...E...PPA..PPP. - ..EEEEPPPA.PPPPP - .E.EEPPP.PPPPPPE - ...EP.P.PPPPPEEE - ..PPPPPPPPPPEEE. - .APPPPPPPPEEEE.E - PPPPPPP..EE..... - NDPPAPEPPP.E..EE - PDNPPEE..EE..... - .PPPE..EEE..E... -} -# tile 649 (shark,female) -{ - ................ - ................ - ................ - ...............P - ........P.....PP - ....E..PP....PP. - ...E...PPA..PPP. - ..EEEEPPPA.PPPPP - .E.EEPPP.PPPPPPE - ...EP.P.PPPPPEEE - ..PPPPPPPPPPEEE. - .APPPPPPPPEEEE.E - PPPPPPP..EE..... - NDPPAPEPPP.E..EE - PDNPPEE..EE..... - .PPPE..EEE..E... -} -# tile 650 (giant eel,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA...AAA.. - ..AAAAAAA.AA.AA. - ..AAAA.AA.AA.AA. - ...AA..AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA.E.AA.E. - ...E.AAEE.AAAE.. - ...E.AAEEAAAEE.. - ..E..AAAAAAE.E.. - ...EE.AAAAE.E... - ..E...EE.E...E.. -} -# tile 651 (giant eel,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA...AAA.. - ..AAAAAAA.AA.AA. - ..AAAA.AA.AA.AA. - ...AA..AA.AA..A. - ......AAA..AA.A. - ......AA...AA... - .....AAA.E.AA.E. - ...E.AAEE.AAAE.. - ...E.AAEEAAAEE.. - ..E..AAAAAAE.E.. - ...EE.AAAAE.E... - ..E...EE.E...E.. -} -# tile 652 (electric eel,male) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA........ - ..AAAAAAA....... - ..AAAA.AA....... - ...AA..AA...DD.. - ......AAA..DD... - ......AA...DD... - .....AAA.E.DD.E. - ...E.AAEE.DD.E.. - ...E.AAEEDD.EE.. - ..E..AAADDDE.E.. - ...EE.AAADE.E... - ..E...EE.E...E.. -} -# tile 653 (electric eel,female) -{ - ................ - ................ - ................ - ....AAA......... - ...AAOAA........ - ..AAAAAAA....... - ..AAAA.AA....... - ...AA..AA...DD.. - ......AAA..DD... - ......AA...DD... - .....AAA.E.DD.E. - ...E.AAEE.DD.E.. - ...E.AAEEDD.EE.. - ..E..AAADDDE.E.. - ...EE.AAADE.E... - ..E...EE.E...E.. -} -# tile 654 (kraken,male) -{ - ................ - ................ - ..FF..FF........ - ..DDFDDF........ - ..FFFFF.....GG.. - ..NCNFF......GFA - ..CC.FF.....EGFA - ....GFAA.GFAEGFE - ...GFFAGFFFFAGFE - ...GFAAFFAGFAEEE - ..GFFAGFFAGFEEE. - EEGFFAGFFAEEEE.E - .EGFFAGFFEE..... - EEGFFEEEEE.E..EE - EEEEEEE..EE..... - ..EEE..EEE..E... -} -# tile 655 (kraken,female) -{ - ................ - ................ - ..FF..FF........ - ..DDFDDF........ - ..FFFFF.....GG.. - ..NCNFF......GFA - ..CC.FF.....EGFA - ....GFAA.GFAEGFE - ...GFFAGFFFFAGFE - ...GFAAFFAGFAEEE - ..GFFAGFFAGFEEE. - EEGFFAGFFAEEEE.E - .EGFFAGFFEE..... - EEGFFEEEEE.E..EE - EEEEEEE..EE..... - ..EEE..EEE..E... -} -# tile 656 (newt,male) -{ - ................ - ................ - ................ - ................ - ................ - ......JKKJ...... - .....CLCCLLC.... - ....LAAAACCLCA.. - .......LCCLLLCA. - ....LCCCLLLAALA. - ....CALLLLAAAA.. - ...LLLLCLAAA.... - ...LLAAALLA..... - ................ - ................ - ................ -} -# tile 657 (newt,female) -{ - ................ - ................ - ................ - ................ - ................ - ......JKKJ...... - .....CLCCLLC.... - ....LAAAACCLCA.. - .......LCCLLLCA. - ....LCCCLLLAALA. - ....CALLLLAAAA.. - ...LLLLCLAAA.... - ...LLAAALLA..... - ................ - ................ - ................ -} -# tile 658 (gecko,male) -{ - ................ - ................ - ...........LLP.. - ..........LLOOA. - ......PO.LLOOOA. - ......OOALOOOA.. - .......LLOOOA... - ...POALOOOAA.... - ...OOLOOOOOOA... - ....ALOOOAOPA... - ...DOOOOA.AA.... - ...OOOAOOA...... - ...OODAOPA...... - ..F.AA.AA....... - ................ - ................ -} -# tile 659 (gecko,female) -{ - ................ - ................ - ...........LLP.. - ..........LLOOA. - ......PO.LLOOOA. - ......OOALOOOA.. - .......LLOOOA... - ...POALOOOAA.... - ...OOLOOOOOOA... - ....ALOOOAOPA... - ...DOOOOA.AA.... - ...OOOAOOA...... - ...OODAOPA...... - ..F.AA.AA....... - ................ - ................ -} -# tile 660 (iguana,male) -{ - ................ - ................ - ................ - ................ - ................ - ....GPGPGGPF.... - ..GPAAAAFFGPF... - .GPAA.PFFGPPPAA. - ......FGGPPFPPAA - .PFGGGGPPPFAAPPA - .FGPAPPPPFAAAAA. - .GPPPPFPFAAA.A.. - .PPFFAFPPAA..... - D.AAAAAAPPA..... - ................ - ................ -} -# tile 661 (iguana,female) -{ - ................ - ................ - ................ - ................ - ................ - ....GPGPGGPF.... - ..GPAAAAFFGPF... - .GPAA.PFFGPPPAA. - ......FGGPPFPPAA - .PFGGGGPPPFAAPPA - .FGPAPPPPFAAAAA. - .GPPPPFPFAAA.A.. - .PPFFAFPPAA..... - D.AAAAAAPPA..... - ................ - ................ -} -# tile 662 (baby crocodile,male) -{ - ................ - ................ - ................ - ................ - ................ - .....FFOFOFA.... - ....FOGFGGOFF... - ....GAAAAFOGFA.. - ...FAA.GFOGGGFA. - ...GFOOOGGGFAGA. - ...FGAGGGGFAAA.. - ..FGGGGFGFAA.... - ..GGDFAFGGA..... - ...D............ - ................ - ................ -} -# tile 663 (baby crocodile,female) -{ - ................ - ................ - ................ - ................ - ................ - .....FFOFOFA.... - ....FOGFGGOFF... - ....GAAAAFOGFA.. - ...FAA.GFOGGGFA. - ...GFOOOGGGFAGA. - ...FGAGGGGFAAA.. - ..FGGGGFGFAA.... - ..GGDFAFGGA..... - ...D............ - ................ - ................ -} -# tile 664 (lizard,male) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ....FFFFGFJ..... - ..FFAAAJJGFJ.... - ......JGFFJFAA.. - ...JGGGFFJAAFA.. - ..JFAFFFJAAAA... - ..FFFFJJAAA..... - .JFAAAAFAA...... - .D.............. - ................ - ................ -} -# tile 665 (lizard,female) -{ - ................ - ................ - ................ - ................ - ................ - ................ - ....FFFFGFJ..... - ..FFAAAJJGFJ.... - ......JGFFJFAA.. - ...JGGGFFJAAFA.. - ..JFAFFFJAAAA... - ..FFFFJJAAA..... - .JFAAAAFAA...... - .D.............. - ................ - ................ -} -# tile 666 (chameleon,male) -{ - ................ - ................ - ................ - .....GGGG....... - ...GGGGGGGG..... - ...GGFFFFGGFA... - ..GPAAAGFFGGFA.. - .GPAA.PFFGGGGAA. - ...GGGGGGGGFGGAA - .PGGBBGGGGFAAGGA - .FGGABGGGFAAAAA. - .GGGGGFGFAAA.A.. - .DGFFAFGGAA..... - D.AAAAAAGGA..... - .DD............. - ................ -} -# tile 667 (chameleon,female) -{ - ................ - ................ - ................ - .....GGGG....... - ...GGGGGGGG..... - ...GGFFFFGGFA... - ..GPAAAGFFGGFA.. - .GPAA.PFFGGGGAA. - ...GGGGGGGGFGGAA - .PGGBBGGGGFAAGGA - .FGGABGGGFAAAAA. - .GGGGGFGFAAA.A.. - .DGFFAFGGAA..... - D.AAAAAAGGA..... - .DD............. - ................ -} -# tile 668 (crocodile,male) -{ - ................ - ................ - ................ - ................ - ....FFOFOOFA.... - ...FOGFGFGOFFA.. - ..FGAAAAFFOGFFA. - .FFAA.GFFOGGGGFA - ......FOOGGGGGGA - .G.OOOOGGGGFAGGA - .FOGAGGGGGFAAAA. - FGGGGGFGGFAA.... - GGDDFAFGGGA..... - GDDFAAAAGGA..... - .DF............. - ................ -} -# tile 669 (crocodile,female) -{ - ................ - ................ - ................ - ................ - ....FFOFOOFA.... - ...FOGFGFGOFFA.. - ..FGAAAAFFOGFFA. - .FFAA.GFFOGGGGFA - ......FOOGGGGGGA - .G.OOOOGGGGFAGGA - .FOGAGGGGGFAAAA. - FGGGGGFGGFAA.... - GGDDFAFGGGA..... - GDDFAAAAGGA..... - .DF............. - ................ -} -# tile 670 (salamander,male) -{ - ................ - ................ - ................ - ......CCC....... - ....CCCCCCC..... - ...CCDDDDCCDA... - ....AAAADDCCDA.. - ......KDDCCCCAA. - ..LLLCCCCCCDCCAA - .KLCCCLLLCDAACCA - .DCEECLKKDAAAAA. - DCCAECDKDAAA.A.. - CCCCCCDCCAA..... - .DAADAAACCA..... - ..ACCA.......... - ...AAA.......... -} -# tile 671 (salamander,female) -{ - ................ - ................ - ................ - ......CCC....... - ....CCCCCCC..... - ...CCDDDDCCDA... - ....AAAADDCCDA.. - ......KDDCCCCAA. - ..LLLCCCCCCDCCAA - .KLCCCLLLCDAACCA - .DCEECLKKDAAAAA. - DCCAECDKDAAA.A.. - CCCCCCDCCAA..... - .DAADAAACCA..... - ..ACCA.......... - ...AAA.......... -} -# tile 672 (long worm tail,male) -{ - ........ILLLL... - ......IILLAA.... - .....ILLAA...... - .....ILA........ - .....ILA........ - ......LLA...II.. - .......LLIIILLLL - ........ILLAAA.L - ...IIIILLALL.... - .ILLLLLAA..LL... - ILLAAAA.....LA.. - ILA.........LA.. - LLA........LLA.. - LILA......LLA... - .LLLIIIILLLA.... - ...LLLLLAAA..... -} -# tile 673 (long worm tail,female) -{ - ........ILLLL... - ......IILLAA.... - .....ILLAA...... - .....ILA........ - .....ILA........ - ......LLA...II.. - .......LLIIILLLL - ........ILLAAA.L - ...IIIILLALL.... - .ILLLLLAA..LL... - ILLAAAA.....LA.. - ILA.........LA.. - LLA........LLA.. - LILA......LLA... - .LLLIIIILLLA.... - ...LLLLLAAA..... -} -# tile 674 (archeologist,male) -{ - ................ - ................ - ......KJ.J...... - ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - ......CJJKAAAA.. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 675 (archeologist,female) -{ - ................ - ................ - ................ - ......KJJJ...... - ......KKLJ...... - .....KLELE...... - ....KJLLLL...... - ....JJALLA...... - ...JJLBAAPL.AAA. - ...JLLBBBPLLAAA. - ....LABPPPALAAA. - ....LALLLLALAAA. - .....AOJJOAAAA.. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 676 (barbarian,male) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - ......ALLA...... - .....LLAALL.AAA. - ....LLLLLLLLAAA. - ....LALLLLALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 677 (barbarian,female) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - ......ALLA...... - .....LLAALL.AAA. - ....LLLLLLLLAAA. - ....LALLLLALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 678 (cave dweller,male) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....LLAJJALLAAA. - ...LLLLAALLLLAA. - ...LLALLLLALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 679 (cave dweller,female) -{ - ................ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JLDDLAJ.... - ....LJALLAJLAAA. - ...LLJCAAJJLLAA. - ...LLACKKJALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 680 (healer,male) -{ - ................ - .......NN....... - ......NDDO...... - ......NNNN...... - ......ELEP...... - ......LLLP...... - .......LLP...... - ......O..PA.AAA. - .....NNOOPPAAAA. - ....OOONOPPPAA.. - ....LANOOPALAA.. - ......NOOPAAAA.. - .....NOOOPAA.A.. - ....NOOOOOPA.... - ................ - ................ -} -# tile 681 (healer,female) -{ - ................ - .......NN....... - ......NDDO...... - ......NNNN...... - ......ELEP...... - ......LLLP...... - .......LLP...... - ......O..PA.AAA. - .....NNOOPPAAAA. - ....OOONOPPPAA.. - ....LANOOPALAA.. - ......NOOPAAAA.. - .....NOOOPAA.A.. - ....NOOOOOPA.... - ................ - ................ -} -# tile 682 (knight,male) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - ......ALLAA..... - .....BBAABB.AAA. - ....BPPPPPPPAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... - ................ - ................ -} -# tile 683 (knight,female) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - ......ALLAA..... - .....BBAABB.AAA. - ....BPPPPPPPAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... - ................ - ................ -} -# tile 684 (monk,male) -{ - ................ - ................ - .......CCC...... - ......JCJJJA.... - ......CAAAJA.... - ......CAAAJA.... - ......CKLKCAAAA. - .....CDDDDDDAAAA - ....CDDLALDDDAAA - ....DALLALLADAA. - ....DDDDCDDDDAA. - .....AACCCDAAAA. - .....CDCCCDDA.A. - ....CCCCCCCDD... - ................ - ................ -} -# tile 685 (monk,female) -{ - ................ - ................ - .......CCC...... - ......JCJJJA.... - ......CAAAJA.... - ......CAAAJA.... - ......CKLKCAAAA. - .....CDDDDDDAAAA - ....CDDLALDDDAAA - ....DALLALLADAA. - ....DDDDCDDDDAA. - .....AACCCDAAAA. - .....CDCCCDDA.A. - ....CCCCCCCDD... - ................ - ................ -} -# tile 686 (cleric,male) -{ - ................ - ................ - ......JLLJ...... - ......JLLJA..... - ......LLLLA..... - ......ALLJA..... - ......IJJIAAAA.. - .....ODDDDDAAAA. - ....INNDDDDDAAA. - ...NLNNDDDALAA.. - ......DDDDAAAA.. - ......DIIDAAAA.. - .....DDIIDDA.A.. - ....DIIIIIDD.... - ................ - ................ -} -# tile 687 (cleric,female) -{ - ................ - .......JJ....... - ......JJJJ...... - ......JLLJA..... - ......JLLJJ..... - .....JJLLJJ..... - .....JEJJEJAAA.. - .....ODEEDDAAAA. - ....IDINNDDDAAA. - ....L.DNNDALAA.. - ......IDDDAAAA.. - ......IDDDAAAA.. - .....DDIIDDA.A.. - ....DIIIIIDD.... - ................ - ................ -} -# tile 688 (ranger,male) -{ - ................ - ................ - ........CJA..... - .......CJJJA.... - .......JEEJA.... - .......JLLJA.... - .......ALLAA.... - ......GGAAGG.AAA - .....BPFFFFPPAAA - .....PAGFFFAPAAA - .....LA.FF.ALAAA - .......BP.PAAAA. - .......BPAPAA.A. - ......PPA.PPA... - ................ - ................ -} -# tile 689 (ranger,female) -{ - ................ - ................ - ........CJA..... - .......CJJJA.... - .......JEEJA.... - .......JLLJA.... - .......ALLAA.... - ......GGAAGG.AAA - .....BPFFFFPPAAA - .....PAGFFFAPAAA - .....LA.FF.ALAAA - .......BP.PAAAA. - .......BPAPAA.A. - ......PPA.PPA... - ................ - ................ -} -# tile 690 (rogue,male) -{ - ................ - ................ - ................ - .....OA...OA.... - .....OOIDPPA.... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - ......BAABAA..A. - .....KEBBEJAAAA. - ....KAAEEAAKAA.. - ....LAJJHJALAA.. - ......KKJKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 691 (rogue,female) -{ - ................ - ................ - ................ - .....OA...OA.... - .....OOIDPPA.... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - ......BAABAA..A. - .....KEBBEJAAAA. - ....KAAEEAAKAA.. - ....LAJJHJALAA.. - ......KKJKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 692 (samurai,male) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LABBBBALAAA. - ....LABBBBALAAA. - ......IDDDAAAA.. - ......IDADAA.A.. - .....IIA.IIA.... - ................ -} -# tile 693 (samurai,female) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LABBBBALAAA. - ....LABBBBALAAA. - ......IDDDAAAA.. - ......IDADAA.A.. - .....IIA.IIA.... - ................ -} -# tile 694 (tourist,male) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ...JJJJJJJJJJ... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HGAAGH.AAA. - ....LLGHHGLLAAA. - ....LAHGHGALAAA. - ....LAHHGHALAAA. - ......JJJKAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 695 (tourist,female) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ...JJJJJJJJJJ... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HGAAGH.AAA. - ....LLGHHGLLAAA. - ....LAHGHGALAAA. - ....LAHHGHALAAA. - ......JJJKAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 696 (valkyrie,male) -{ - D..............D - .D............D. - ..D...LHHL...D.. - ...D.HHHHHL.D... - ....DHELELHD.... - ....HDLLLLD..... - ...HHHDLLD...... - ...HJKJDDKJJAAA. - ..HHLJJDDJJLAAA. - ..H.LADKDCALAAA. - ....LDAKKDALAAA. - ....D.KKJKDAAA.. - ...D..KJAJAD.A.. - ..D..KLA.LKAD... - .D...........D.. - D.............D. -} -# tile 697 (valkyrie,female) -{ - ................ - ................ - ......LHHL...... - .....HHHHHL..... - ....LHELELH..... - ....HHLLLLH..... - ...HHHALLA...... - ...HJKJAAKJJAAA. - ..HHLJJKKJJLAAA. - ..H.LACKJCALAAA. - ....LAAKKAALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 698 (wizard,male) -{ - ................ - .........BP..... - .......BBPE..... - ......BPPEA..... - ......BAAEA..... - ......BAAEA..... - ......PLLE...... - ......PAAEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 699 (wizard,female) -{ - ................ - .........BP..... - .......BBPE..... - ......BPPEA..... - ......BAAEA..... - ......BAAEA..... - ......PLLE...... - ......PAAEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 700 (Lord Carnarvon,male) -{ - .......JJ....... - ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CIAAIK.AAA. - ....CKKIIKKKAAA. - ...KKCKKHKJKKAA. - ...KKAKHKJAKKAA. - ...KAIHKKJIAKA.. - ...LAICKKJIALA.. - .....ICKAJIAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 701 (Lord Carnarvon,female) -{ - .......JJ....... - ......KJJJ...... - ....KCKKKJJJ.... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CIAAIK.AAA. - ....CKKIIKKKAAA. - ...KKCKKHKJKKAA. - ...KKAKHKJAKKAA. - ...KAIHKKJIAKA.. - ...LAICKKJIALA.. - .....ICKAJIAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 702 (Pelias,male) -{ - ................ - .......JJ....... - ......KKKJ...... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKKAKKAA. - ...KA.CKKJAAKA.. - ...LA.CKAJAALA.. - ......CKAJAAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 703 (Pelias,female) -{ - ................ - .......JJ....... - ......KKKJ...... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKK.AAA. - ....CKKKKKKKAAA. - ...KKCKKKKJKKAA. - ...KKAKKKKAKKAA. - ...KA.CKKJAAKA.. - ...LA.CKAJAALA.. - ......CKAJAAAA.. - ......CKAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 704 (Shaman Karnov,male) -{ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....LHAJJAHLAA.. - ...LLLHAAHLLLAA. - ...LLLLHHLLLLAA. - ...LLALHHLALLAA. - ...LLALLLLALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ -} -# tile 705 (Shaman Karnov,female) -{ - ................ - .......JJA...... - ......JJJJA..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....LHAJJAHLAA.. - ...LLLHAAHLLLAA. - ...LLLLHHLLLLAA. - ...LLALHHLALLAA. - ...LLALLLLALLAA. - ....LACKKJALAAA. - ......CKKJAAAA.. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ -} -# tile 706 (Earendil,male) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBPLELEABPB.. - ..BBBPLLLLABBB.. - ..PBPPALLAPPP... - ...PPBGAAGBBB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 707 (Earendil,female) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBPLELEABPB.. - ..BBBPLLLLABBB.. - ..PBPPALLAPPP... - ...PPBGAAGBBB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 708 (Elwing,male) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBHLELEHBPB.. - ..BBBHLLLLHBBB.. - ..PBHHALLAHHP... - ...PHHGAAGHHB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 709 (Elwing,female) -{ - .........G...... - ....B..GGF..B... - ...BB.GGGGABB... - ..BPBHLELEHBPB.. - ..BBBHLLLLHBBB.. - ..PBHHALLAHHP... - ...PHHGAAGHHB... - ...BBLGGGFLBBB.. - ..BBLAAGFAALBB.. - ...BLAGGGFALB... - ......GFAF...... - ......L..L.AAA.. - ......AAAAAAAA.. - ....AAAAAAAA.... - .....AAAAAA..... - ................ -} -# tile 710 (Hippocrates,male) -{ - ................ - ....LLLCCD...... - ...LLCCDDA...... - ...LAAAADA...... - ...LBABADA...... - ...LAAAADA...... - ...CCLLDD.B..... - ....CKKDDFBFAAA. - ..LLLCLDDDBFAAA. - .CCCCLDDDFBAAA.. - .LALLCCDDFBDAA.. - ...LCCCCDABFAA.. - ...LCCCCDABAAA.. - ..LLCCCCDAA.AA.. - .LCCCCCCCDA..... - ................ -} -# tile 711 (Hippocrates,female) -{ - ................ - ....LLLCCD...... - ...LLCCDDA...... - ...LAAAADA...... - ...LBABADA...... - ...LAAAADA...... - ...CCLLDD.B..... - ....CKKDDFBFAAA. - ..LLLCLDDDBFAAA. - .CCCCLDDDFBAAA.. - .LALLCCDDFBDAA.. - ...LCCCCDABFAA.. - ...LCCCCDABAAA.. - ..LLCCCCDAA.AA.. - .LCCCCCCCDA..... - ................ -} -# tile 712 (King Arthur,male) -{ - ................ - ................ - ......OHHA...... - .....OHHHHA..... - .....HBLBHA..... - .....HLLLHA..... - .....ALLLAA..... - ....BBAAABB.AAA. - ...BPPPPPPPPAAA. - ...PABPPPPACPAA. - ..NNNNNNNNNCLCA. - .....BPP.PACAA.. - .....BPAPPAA.A.. - .....BPAPPAA.A.. - ....PPAA.PPA.... - ................ -} -# tile 713 (King Arthur,female) -{ - ................ - ................ - ......OHHA...... - .....OHHHHA..... - .....HBLBHA..... - .....HLLLHA..... - .....ALLLAA..... - ....BBAAABB.AAA. - ...BPPPPPPPPAAA. - ...PABPPPPACPAA. - ..NNNNNNNNNCLCA. - .....BPP.PACAA.. - .....BPAPPAA.A.. - .....BPAPPAA.A.. - ....PPAA.PPA.... - ................ -} -# tile 714 (Grand Master,male) -{ - ................ - .......LL....... - ......LLLL...... - ......LLLL...... - ..LC.CALLAC..... - .CLLC.CAACCCC... - .CJLACCCCCCCCC.. - ..JAACCCCCCCCCC. - ..JCCCCCCCCCCC.A - ..J..PPPPPLCCAAA - ..J..CCCCLLCAAAA - ..J..CCCCCCCAAAA - ..J..CCCCCCCAAAA - ..J.ACCCCCCCAAA. - ..JACCCCCCCCAA.. - ................ -} -# tile 715 (Grand Master,female) -{ - ................ - .......LL....... - ......LLLL...... - ......LLLL...... - ..LC.CALLAC..... - .CLLC.CAACCCC... - .CJLACCCCCCCCC.. - ..JAACCCCCCCCCC. - ..JCCCCCCCCCCC.A - ..J..PPPPPLCCAAA - ..J..CCCCLLCAAAA - ..J..CCCCCCCAAAA - ..J..CCCCCCCAAAA - ..J.ACCCCCCCAAA. - ..JACCCCCCCCAA.. - ................ -} -# tile 716 (Arch Priest,male) -{ - ..N............. - .NNN..JLLJ...... - ..N...JLLJ...... - ..N...LLLL...... - ..LC.CALLAC..... - .CLLC.CAACJDK... - .CHLACCCCJCCDK.. - ..HAACCJJCCCCDK. - ..HCCCCJCCJCCC.A - ..H..DCJCCLJCAAA - ..H..DCJCLLCAAAA - ..H..KCJCCDJAAAA - ..H..KCJCCDJAAAA - ..H.ACCJCCDJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 717 (Arch Priest,female) -{ - ..N............. - .NNN..JLLJ...... - ..N...JLLJ...... - ..N...LLLL...... - ..LC.CALLAC..... - .CLLC.CAACJDK... - .CHLACCCCJCCDK.. - ..HAACCJJCCCCDK. - ..HCCCCJCCJCCC.A - ..H..DCJCCLJCAAA - ..H..DCJCLLCAAAA - ..H..KCJCCDJAAAA - ..H..KCJCCDJAAAA - ..H.ACCJCCDJAAA. - ..HACCCJJCCCAA.. - ................ -} -# tile 718 (Orion,male) -{ - ................ - ................ - .......CJA...... - ......CJJJA..... - ......JEEJA..... - ......JLLJA..... - ......ALLAA..... - .....GGAAGG..... - ....BGFFFFFP.... - ....BPFFFFPPAAA. - ....PAGFFFAPAAA. - ....LANNNNALAAA. - ......BP.PAAAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... -} -# tile 719 (Orion,female) -{ - ................ - ................ - .......CJA...... - ......CJJJA..... - ......JEEJA..... - ......JLLJA..... - ......ALLAA..... - .....GGAAGG..... - ....BGFFFFFP.... - ....BPFFFFPPAAA. - ....PAGFFFAPAAA. - ....LANNNNALAAA. - ......BP.PAAAAA. - ......BP.PAAAA.. - ......BPAPAA.A.. - .....PPA.PPA.... -} -# tile 720 (Master of Thieves,male) -{ - ................ - ...H.....H...... - ...HHIDKHH...... - ....IDDDD....... - ....LLLLLA...... - ....LBLBLA...... - ....LLLLLA...... - .....LLLA....... - ....B.AABAA..... - ...KEBBBEJAAA... - ..KAEEEEEAJAAA.. - ..LAJJHHJALAAA.. - ....JKKKJAAAAA.. - ....KJAJKAAAA... - ...JJA..JJA..... - ................ -} -# tile 721 (Master of Thieves,female) -{ - ................ - ...H.....H...... - ...HHIDKHH...... - ....IDDDD....... - ....LLLLLA...... - ....LBLBLA...... - ....LLLLLA...... - .....LLLA....... - ....B.AABAA..... - ...KEBBBEJAAA... - ..KAEEEEEAJAAA.. - ..LAJJHHJALAAA.. - ....JKKKJAAAAA.. - ....KJAJKAAAA... - ...JJA..JJA..... - ................ -} -# tile 722 (Lord Sato,male) -{ - .....AAA........ - .....AAA........ - ...AAAAAAA...... - ..AALLLLLAA..... - ..ALFFLFFLA..... - ..ALLLLLLLA..... - ...AALLLA....... - IIIIIAAAIIIIAAA. - LLDIIIIIIDLLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - ...IIDDDDAAAAAA. - ...IIAAIDAAA..A. - ..IIIA.IIIAA.... - ................ -} -# tile 723 (Lord Sato,female) -{ - .....AAA........ - .....AAA........ - ...AAAAAAA...... - ..AALLLLLAA..... - ..ALFFLFFLA..... - ..ALLLLLLLA..... - ...AALLLA....... - IIIIIAAAIIIIAAA. - LLDIIIIIIDLLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - LLABBBBBBALLAAA. - ...IIDDDDAAAAAA. - ...IIAAIDAAA..A. - ..IIIA.IIIAA.... - ................ -} -# tile 724 (Twoflower,male) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - .....NNLNNA..... - ....NALNALNA.... - .....NNANNAA.... - .....AAAAAA.AAA. - ....LLHGHGLLAAA. - ....LAGGGGALAAA. - ....LAHGHGALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 725 (Twoflower,female) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - .....NNLNNA..... - ....NALNALNA.... - .....NNANNAA.... - .....AAAAAA.AAA. - ....LLHGHGLLAAA. - ....LAGGGGALAAA. - ....LAHGHGALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 726 (Norn,male) -{ - ................ - ................ - ......NNN....... - .....NNNNN...... - .....NELELN..... - ....NNLLLLN..... - ...NNNALLA...... - ...NJKJAAKJJAAA. - ..NNLJJKKJJLAAA. - ..N.LACKJCALAAA. - ....LAKKKKALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 727 (Norn,female) -{ - ................ - ................ - ......NNN....... - .....NNNNN...... - .....NELELN..... - ....NNLLLLN..... - ...NNNALLA...... - ...NJKJAAKJJAAA. - ..NNLJJKKJJLAAA. - ..N.LACKJCALAAA. - ....LAKKKKALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ - ................ -} -# tile 728 (Neferet the Green,male) -{ - ................ - ................ - ......GGG....... - .....GFFFG...... - ....GFEFEG...... - ....GFFFFEG..... - .N.GPEFFFEE..... - .I..BBEAAEA.AA.. - .I.BBPPBBEEAAAA. - .IGBPPPPPEEEAA.. - .I.PP.EPEAAGAA.. - .I...BPPPAAAAA.. - .N...BPPPEAA.A.. - ....BPPPPPEA.... - ...BPPPPPPPE.... - ................ -} -# tile 729 (Neferet the Green,female) -{ - ................ - ................ - ......GGG....... - .....GFFFG...... - ....GFEFEG...... - ....GFFFFEG..... - .N.GPEFFFEE..... - .I..BBEAAEA.AA.. - .I.BBPPBBEEAAAA. - .IGBPPPPPEEEAA.. - .I.PP.EPEAAGAA.. - .I...BPPPAAAAA.. - .N...BPPPEAA.A.. - ....BPPPPPEA.... - ...BPPPPPPPE.... - ................ -} -# tile 730 (Minion of Huhetotl,male) -{ - ...OP......PO... - ...OODDDDDDOOD.. - ..DLOOCDDCOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDKKKDAADJJDCDD - CCDKDDKKKJDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 731 (Minion of Huhetotl,female) -{ - ...OP......PO... - ...OODDDDDDOOD.. - ..DLOOCDDCOOLDD. - .DDDLDDDDDDLDDD. - .CCDDDNDDNDDDCC. - CCDKDDDDDDDDJCCC - CDDKKDDIIDDJJCCD - CDDKKKDAADJJDCDD - CCDKDDKKKJDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 732 (Thoth Amon,male) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....BPAAPP.AAA. - ....BPPPPPPPAAA. - ...PPBPPPPJPPAA. - ...PPAPPP.APPA.A - ...PA.BPP.AAPA.A - ...LA.BPP..AL.A. - ......BPA.A..A.. - ......BPAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 733 (Thoth Amon,female) -{ - ................ - ......OJJO...... - ......JJJJA..... - ......BLBLA..... - ......LLLLA..... - ......ALLA...... - .....BPAAPP.AAA. - ....BPPPPPPPAAA. - ...PPBPPPPJPPAA. - ...PPAPPP.APPA.A - ...PA.BPP.AAPA.A - ...LA.BPP..AL.A. - ......BPA.A..A.. - ......BPAPAAAA.. - .....PPA.PPA.... - ................ -} -# tile 734 (Chromatic Dragon,male) -{ - ......GGGFA..... - .....NFNFEEA.... - ....GFFFEECA.... - ..DCHHF..CCA.... - CHCHCD..BCCA.... - HD.D...BFFA..... - ......OBFAAAAAA. - ....HOGFAAAAAAAA - ..HOOIEA.EF.AAA. - .HOOOIEEEEFFJAA. - .HOOOIEEFFFDDAA. - HBOOIIEFFFDDCCA. - HB.OIEFOODD.CJA. - HBAAGE.AADDACCA. - ....GFAA...CCJA. - ........FFFFJA.. -} -# tile 735 (Chromatic Dragon,female) -{ - ......GGGFA..... - .....NFNFEEA.... - ....GFFFEECA.... - ..DCHHF..CCA.... - CHCHCD..BCCA.... - HD.D...BFFA..... - ......OBFAAAAAA. - ....HOGFAAAAAAAA - ..HOOIEA.EF.AAA. - .HOOOIEEEEFFJAA. - .HOOOIEEFFFDDAA. - HBOOIIEFFFDDCCA. - HB.OIEFOODD.CJA. - HBAAGE.AADDACCA. - ....GFAA...CCJA. - ........FFFFJA.. -} -# tile 736 (Goblin King,male) -{ - ................ - ................ - .H..H...H....... - CLC.HCHCH....... - CLC.HHHHH....... - .H..IIIII....... - .HK.IHIHI.I..... - .HICKIIIJKK..... - .H.IIJJJK.AA.... - .H..JICJJAAAAA.. - .H..IIIIJAAAAA.. - ....JIIJJAA..... - ....IJKJJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 737 (Goblin King,female) -{ - ................ - ................ - .H..H...H....... - CLC.HCHCH....... - CLC.HHHHH....... - .H..IIIII....... - .HK.IHIHI.I..... - .HICKIIIJKK..... - .H.IIJJJK.AA.... - .H..JICJJAAAAA.. - .H..IIIIJAAAAA.. - ....JIIJJAA..... - ....IJKJJA...... - ...IKAA.IK...... - ................ - ................ -} -# tile 738 (Cyclops,male) -{ - ................ - ....LLLLL....... - ...CLLLLLC...... - ...LBABNNL...... - ...LBBBNNLJA.... - ...CLNNNLCJA.... - ....LLLLLJAAA... - ....LAALLAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.GGGHGGACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 739 (Cyclops,female) -{ - ................ - ....LLLLL....... - ...CLLLLLC...... - ...LBABNNL...... - ...LBBBNNLJA.... - ...CLNNNLCJA.... - ....LLLLLJAAA... - ....LAALLAAAA... - ..JKJLLLKAKJAA.A - .CLKAJJJJAKLCAAA - .LLJKAAAAKJLLAA. - .LAAJKKKKJAALAA. - .LC.GGGHGGACLAAA - .LL.JJJJJJALLAAA - ....CJJJCLAAAAAA - ..LLLLL.LLLLLAA. -} -# tile 740 (Ixoth,male) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDGDDGDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 741 (Ixoth,female) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDGDDGDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 742 (Master Kaen,male) -{ - ................ - .......KKA...... - ......KJJKA..... - ..KKA.KAAKA.KKA. - .KAAKAKDDKAKAAKA - .KOOJKKOOKKKOOJA - .KJJJJJJJJJKJJJA - ..KJJJJJJJJJJJA. - ....KJJJJJJJA... - ......KJJJAAAAAA - .....KJJJJKAAAAA - .....KJJJJJAAAAA - ....KJJJJJJKAAA. - ...KJJJJJJJJKAA. - ...KJJJJJJJJJA.. - ................ -} -# tile 743 (Master Kaen,female) -{ - ................ - .......KKA...... - ......KJJKA..... - ..KKA.KAAKA.KKA. - .KAAKAKDDKAKAAKA - .KOOJKKOOKKKOOJA - .KJJJJJJJJJKJJJA - ..KJJJJJJJJJJJA. - ....KJJJJJJJA... - ......KJJJAAAAAA - .....KJJJJKAAAAA - .....KJJJJJAAAAA - ....KJJJJJJKAAA. - ...KJJJJJJJJKAA. - ...KJJJJJJJJJA.. - ................ -} -# tile 744 (Nalzok,male) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDBDDBDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 745 (Nalzok,female) -{ - ....O......O.... - ....O......O.... - ...LOOCDDCOOL... - ...DDDDDDDDDDD.. - .CCDDDBDDBDDDCC. - CCDKDDDDDDDDJCCC - CDDKKKDIIDJJDCCD - CDDKDDKJJJDDDCDD - CCDKDDDDDDDDKCDD - .CCDKKDDDDKKCDDD - .CCDADKDDKDACDD. - .DDDADDDDDDADDD. - ....CCDDDDKKAA.. - ...CDDDAADDDKAA. - ..CDDDAAA.DDDK.. - ................ -} -# tile 746 (Scorpius,male) -{ - .....JLJLJAA.... - ....JA.JCJCKAA.. - ....AJ.....JJJA. - ....LA......LCKA - .JAKJA......JJJA - ..JJA......ALCJA - .......ALLAJCJKA - ....JJALCCAAJJA. - .JJALLAJCJJJAA.. - JA.LCCAJAJJAAAA. - ..JACJJJAAACCJAA - GGJJJJJAACCAAAJA - .JJGGAJACAAJJAAA - D.JJAAJAACA.JAA. - ...D...JAAJA.JJ. - ........JA.JA... -} -# tile 747 (Scorpius,female) -{ - .....JLJLJAA.... - ....JA.JCJCKAA.. - ....AJ.....JJJA. - ....LA......LCKA - .JAKJA......JJJA - ..JJA......ALCJA - .......ALLAJCJKA - ....JJALCCAAJJA. - .JJALLAJCJJJAA.. - JA.LCCAJAJJAAAA. - ..JACJJJAAACCJAA - GGJJJJJAACCAAAJA - .JJGGAJACAAJJAAA - D.JJAAJAACA.JAA. - ...D...JAAJA.JJ. - ........JA.JA... -} -# tile 748 (Master Assassin,male) -{ - ................ - ................ - ................ - .......AA....... - ......AAAA...... - .....ABLBLA..... - .....AAAAAA..... - ......AAAA...... - .....AAAAAA..PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 749 (Master Assassin,female) -{ - ................ - ................ - ................ - .......AA....... - ......AAAA...... - .....ABLBLA..... - .....AAAAAA..... - ......AAAA...... - .....AAAAAA..PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 750 (Ashikaga Takauji,male) -{ - ................ - ................ - ......AA........ - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LAIIIIALAAA. - ....LALHHLALAAA. - ......IIIIAAAA.. - ......IIAIAA.A.. - .....IIA.IIA.... - ................ -} -# tile 751 (Ashikaga Takauji,female) -{ - ................ - ................ - ......AA........ - .......AAA...... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....IIIAAIIIAAA. - ....LDIIIIDLAAA. - ....LAIIIIALAAA. - ....LALHHLALAAA. - ......IIIIAAAA.. - ......IIAIAA.A.. - .....IIA.IIA.... - ................ -} -# tile 752 (Lord Surtur,male) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLBAAAA. - ...PPDBBBBBBBAA. - ..BDDHDPBPPPPPA. - ..PPHDDPBPPPPPA. - ..LAHDHPBPPAALAA - JLAADDHBBBBAALAA - JJLJDHHPBPPPCLAA - ..LLJBPPABPPLLAA - .....BPPABPPAAAA - ...LLLLJ.BLLLKAA -} -# tile 753 (Lord Surtur,female) -{ - ....PPDDDDAA.... - ....PDDDDDDDA... - ...PPDLLLLDDA... - ...PDPFLLFFDA... - ...PPPLLLLLDA... - ....PLLAALLAAA.. - ...PPALLLLBAAAA. - ...PPDBBBBBBBAA. - ..BDDHDPBPPPPPA. - ..PPHDDPBPPPPPA. - ..LAHDHPBPPAALAA - JLAADDHBBBBAALAA - JJLJDHHPBPPPCLAA - ..LLJBPPABPPLLAA - .....BPPABPPAAAA - ...LLLLJ.BLLLKAA -} -# tile 754 (Dark One,male) -{ - ................ - ......AAA....... - .....AAAAA...... - .....ADADA...... - .....AAAAA...... - ....AAAAAAA..... - ....AAAAAAA..... - ...AAAAAAAAA.... - ...AAAAAAAAA.... - ..AAAAAAAAAAA... - ..AAAAAAAAAAA... - ...AAAAAAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAAA - ................ -} -# tile 755 (Dark One,female) -{ - ................ - ......AAA....... - .....AAAAA...... - .....ADADA...... - .....AAAAA...... - ....AAAAAAA..... - ....AAAAAAA..... - ...AAAAAAAAA.... - ...AAAAAAAAA.... - ..AAAAAAAAAAA... - ..AAAAAAAAAAA... - ...AAAAAAAAA.... - ...AAAAAAAAAA... - ..AAAAAAAAAAAA.. - AAAAAAAAAAAAAAAA - ................ -} -# tile 756 (student,male) -{ - ................ - ................ - .....GGFGG...... - .......G........ - ......NDND...... - ...DDDDDDDD..... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 757 (student,female) -{ - ................ - ................ - .....GGFGG...... - .......G........ - ......NDND...... - ...DDDDDDDD..... - ......LELEA..... - ......LLLLA..... - ......ALLA...... - .....CKAAKJ.AAA. - ....CKKKJJJJAAA. - ....KACKJJAJAAA. - ....LACJKJALAAA. - .....KCJAJJA.A.. - .....CJJ.JKJ.... - ................ -} -# tile 758 (chieftain,male) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - .....HALLAH..... - ....LLHAAHLLAAA. - ....LLLIILLLAAA. - ....LALIILALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 759 (chieftain,female) -{ - ................ - ................ - .......HHA...... - ......HHHHA..... - ......LFLFA..... - ......LLLLA..... - .....HALLAH..... - ....LLHAAHLLAAA. - ....LLLIILLLAAA. - ....LALIILALAAA. - ....LAALLAALAAA. - ....LAJJKJALAAA. - ......LJJLAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ -} -# tile 760 (neanderthal,male) -{ - ................ - ................ - ................ - ......JJJJ...... - .....JJJJJJ..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....JJAJJAJJ.AA. - ...JLLJAAJLLJAA. - ...LLALJJLALLAA. - ....LALCCLALAAA. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 761 (neanderthal,female) -{ - ................ - ................ - ................ - ......JJJJ...... - .....JJJJJJ..... - .....JFLFLJ..... - .....JLLLLJ..... - .....JJDDJA..... - ....JJAJJAJJ.AA. - ...JLLJAAJLLJAA. - ...LLALJJLALLAA. - ....LALCCLALAAA. - ......LA.LAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 762 (High-elf,male) -{ - .........G...... - .......GGF...... - ......GGGGA..... - ......LILIA..... - ......LLLLA..... - ......ALLA...... - ......GAAG..AA.. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LA.GFAALAA.. - ....LA.GFAALAA.. - ....LAGGGFAL.A.. - ......GFAFAA.A.. - ......GFAFAA.... - ......GFAFAA.... - .....KLA.LKA.... -} -# tile 763 (High-elf,female) -{ - .........G...... - .......GGF...... - ......GGGGA..... - ......LILIA..... - ......LLLLA..... - ......ALLA...... - ......GAAG..AA.. - .....LGGGFLAAAA. - ....LAAGFAALAAA. - ....LA.GFAALAA.. - ....LA.GFAALAA.. - ....LAGGGFAL.A.. - ......GFAFAA.A.. - ......GFAFAA.... - ......GFAFAA.... - .....KLA.LKA.... -} -# tile 764 (attendant,male) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......BLB....... - .....CLLLD...... - .....CCKKDA.AAA. - .....LLCLDDAAAA. - ....CCCLDDDDAA.. - ....LALCCDALAA.. - ......LCCDAAAA.. - .....LCCCDAA.A.. - ....LCCCCCDA.... - ................ - ................ -} -# tile 765 (attendant,female) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......BLB....... - .....CLLLD...... - .....CCKKDA.AAA. - .....LLCLDDAAAA. - ....CCCLDDDDAA.. - ....LALCCDALAA.. - ......LCCDAAAA.. - .....LCCCDAA.A.. - ....LCCCCCDA.... - ................ - ................ -} -# tile 766 (page,male) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - .......LLAA..... - ......BAABA.AAA. - .....BPPPPPAAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 767 (page,female) -{ - ................ - ................ - .......BPA...... - ......BPPPA..... - ......PEEPA..... - ......PLLPA..... - .......LLAA..... - ......BAABA.AAA. - .....BPPPPPAAAA. - ....PABPPPAPAAA. - ....LA.PP.ALAAA. - ......BP.PAAAA.. - ......LLALAA.A.. - .....LLA.LLA.... - ................ - ................ -} -# tile 768 (abbot,male) -{ - ................ - ................ - ................ - ................ - ................ - ......KLK....... - ......LLL....... - ....CCLLLJJ..... - ....KCKLKKJAAA.. - ....CDDDDDDAAAA. - ...CDDLALDDDAAA. - ...DALLALLADAA.. - ...DDDDCDDDDAA.. - ....AACCCDAAAA.. - ....CDCCCDDA.A.. - ...CCCCCCCDD.... -} -# tile 769 (abbot,female) -{ - ................ - ................ - ................ - ................ - ................ - ......KLK....... - ......LLL....... - ....CCLLLJJ..... - ....KCKLKKJAAA.. - ....CDDDDDDAAAA. - ...CDDLALDDDAAA. - ...DALLALLADAA.. - ...DDDDCDDDDAA.. - ....AACCCDAAAA.. - ....CDCCCDDA.A.. - ...CCCCCCCDD.... -} -# tile 770 (acolyte,male) -{ - ................ - ................ - ................ - ......JJJJ...... - ......JLLJA..... - ......LLLLA..... - ......ALLJA..... - ......CJJCAAAA.. - .....LDDDDDAAAA. - ....CDCCDDDDAAA. - ....L.LCCDALAA.. - ......LCCDAAAA.. - ......LCCDAAAA.. - .....LDCCDDA.A.. - ....LCCCCCDD.... - ................ -} -# tile 771 (acolyte,female) -{ - ................ - ................ - ................ - ......JJJJ...... - ......JLLJA..... - ......LLLLA..... - ......ALLJA..... - ......CJJCAAAA.. - .....LDDDDDAAAA. - ....CDCCDDDDAAA. - ....L.LCCDALAA.. - ......LCCDAAAA.. - ......LCCDAAAA.. - .....LDCCDDA.A.. - ....LCCCCCDD.... - ................ -} -# tile 772 (hunter,male) -{ - ................ - ................ - ................ - ....J..CJA...... - ...J..CJJJA..... - ...J..JEEJA..... - ..J...JLLJA..... - ..J...ALLAA..... - ..J..GGAAGG.AAA. - ..LPBPFFFFPPAAA. - ..J..AGFFFAPAAA. - ..J....FF.ALAAA. - ...J..BP.PAAAA.. - ...J..BPAPAA.A.. - ....JPPA.PPA.... - ................ -} -# tile 773 (hunter,female) -{ - ................ - ................ - ................ - ....J..CJA...... - ...J..CJJJA..... - ...J..JEEJA..... - ..J...JLLJA..... - ..J...ALLAA..... - ..J..GGAAGG.AAA. - ..LPBPFFFFPPAAA. - ..J..AGFFFAPAAA. - ..J....FF.ALAAA. - ...J..BP.PAAAA.. - ...J..BPAPAA.A.. - ....JPPA.PPA.... - ................ -} -# tile 774 (thug,male) -{ - ................ - ................ - ................ - .......ID....... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - .....KKAAKKA..A. - ....KKJKKJJKAAA. - ....KAAJJAAKAA.. - ....LAJJJJALAA.. - ......KKJKAAAA.. - ......KAAKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 775 (thug,female) -{ - ................ - ................ - ................ - .......ID....... - ......IDDDA..... - ......LKLKA..... - ......LLLLA..... - ......ALLA...... - .....KKAAKKA..A. - ....KKJKKJJKAAA. - ....KAAJJAAKAA.. - ....LAJJJJALAA.. - ......KKJKAAAA.. - ......KAAKAAAA.. - .....KKA.KKA.... - ................ -} -# tile 776 (ninja,male) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....AFLFLA..... - .....AAAAAA..... - ......AAAA...... - ....AAAAAAAA.PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 777 (ninja,female) -{ - ................ - ................ - .........AA..... - .......AAA...... - ......AAAAA..... - .....AFLFLA..... - .....AAAAAA..... - ......AAAA...... - ....AAAAAAAA.PP. - ....AAAAAAAAPPP. - ....AAAAAAAAPPP. - ....LAAAAAALPPP. - ......AAAAAPPP.. - ......AAAAAP.P.. - .....AAA.AAA.... - ................ -} -# tile 778 (roshi,male) -{ - ................ - ................ - ................ - .......AAAAA.... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....PPPAAPPPAAA. - ....L.PPPP.LAAA. - ....LAOOOOALAAA. - ....LAOOOOALAAA. - ......P...AAAA.. - ......P.A.AA.A.. - .....PPA.PPA.... - ................ -} -# tile 779 (roshi,female) -{ - ................ - ................ - ................ - .......AAAAA.... - ......AAAAA..... - .....ALFLFA..... - .....ALLLLA..... - ......ALLA...... - ....PPPAAPPPAAA. - ....L.PPPP.LAAA. - ....LAOOOOALAAA. - ....LAOOOOALAAA. - ......P...AAAA.. - ......P.A.AA.A.. - .....PPA.PPA.... - ................ -} -# tile 780 (guide,male) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HHAAHH.AAA. - ....LLHHHHLLAAA. - ....LAHHHHALAAA. - ....LAHHHHALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 781 (guide,female) -{ - ................ - ................ - ......JKJJA..... - ......KJJJA..... - ....JJJJJJJJ.... - ......LFLFAA.... - ......LLLLA..... - ......ALLA...... - .....HHAAHH.AAA. - ....LLHHHHLLAAA. - ....LAHHHHALAAA. - ....LAHHHHALAAA. - ......JJJKAAAA.. - ......JJAKAA.A.. - .....LLA.LLA.... - ................ -} -# tile 782 (warrior,male) -{ - .....O....O..... - .....NO..ON..... - ......NPPN...... - .....PPPPPP..... - .....PELELP..... - ....HHLLLLH..... - ...HHHALLA...... - ...HJKJAAKJJAAA. - ..HHLJJKKJJLAAA. - ..H.LACKJCALAAA. - ....LAAKKAALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ -} -# tile 783 (warrior,female) -{ - .....O....O..... - .....NO..ON..... - ......NPPN...... - .....PPPPPP..... - .....PELELP..... - ....HHLLLLH..... - ...HHHALLA...... - ...HJKJAAKJJAAA. - ..HHLJJKKJJLAAA. - ..H.LACKJCALAAA. - ....LAAKKAALAAA. - ......KKJKAAAA.. - ......KJAJAA.A.. - ......KJAJAA.A.. - .....KLA.LKA.... - ................ -} -# tile 784 (apprentice,male) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......GLG....... - .....BLLLE...... - .....BBEEEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 785 (apprentice,female) -{ - ................ - ................ - ................ - ......JJJ....... - .....JLLLJ...... - ......GLG....... - .....BLLLE...... - .....BBEEEA.AAA. - .....BBPBEEAAAA. - ....PPPBEEEEAA.. - ....LABPPEALAA.. - ......BPPEAAAA.. - .....BPPPEAA.A.. - .....BPPPPEA.... - ....BPPPPPPE.... - ................ -} -# tile 786 (invisible monster, nogender) -{ - ................ - ................ - .....NNNN....... - ....NNNNNN...... - ...NNAAAANN..... - ...NNA...NNA.... - ....AA...NNA.... - ........NNAA.... - .......NNAA..... - ......NNAA...... - ......NNA....... - .......AA....... - ......NN........ - ......NNA....... - .......AA....... - ................ -} From 242a59ac195ded010c31c9656ca5d9cb27164981 Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 21:44:51 -0500 Subject: [PATCH 696/708] have a ^G-created monster's gender done in makemon instead of after --- src/read.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/read.c b/src/read.c index e32dcdfbc..b5be06491 100644 --- a/src/read.c +++ b/src/read.c @@ -2571,11 +2571,15 @@ struct _create_particular_data *d; whichpm = &mons[d->which]; } for (i = 0; i < d->quan; i++) { + long mmflags = NO_MM_FLAGS; + if (d->monclass != MAXMCLASSES) whichpm = mkclass(d->monclass, 0); else if (d->randmonst) whichpm = rndmonst(); - mtmp = makemon(whichpm, u.ux, u.uy, NO_MM_FLAGS); + if (d->fem != -1 && !is_male(whichpm) && !is_female(whichpm)) + mmflags |= (d->fem == FEMALE) ? MM_FEMALE : MM_MALE; + mtmp = makemon(whichpm, u.ux, u.uy, mmflags); if (!mtmp) { /* quit trying if creation failed and is going to repeat */ if (d->monclass == MAXMCLASSES && !d->randmonst) @@ -2585,8 +2589,6 @@ struct _create_particular_data *d; } mx = mtmp->mx, my = mtmp->my; /* 'is_FOO()' ought to be called 'always_FOO()' */ - if (d->fem != -1 && !is_male(mtmp->data) && !is_female(mtmp->data)) - mtmp->female = d->fem; /* ignored for is_neuter() */ if (d->maketame) { (void) tamedog(mtmp, (struct obj *) 0); } else if (d->makepeaceful || d->makehostile) { From 1d063218d3e5126854b0f0e32af63d74539a081c Mon Sep 17 00:00:00 2001 From: nhmall Date: Sun, 27 Dec 2020 22:38:41 -0500 Subject: [PATCH 697/708] another wishing gender processing tweak --- src/read.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/read.c b/src/read.c index b5be06491..7ed7cdb5d 100644 --- a/src/read.c +++ b/src/read.c @@ -2522,8 +2522,7 @@ struct _create_particular_data *d; * With the introduction of male and female monster names * in 3.7, preserve that detail. */ - if (gender_name_var != NEUTRAL) - d->fem = gender_name_var; + d->fem = gender_name_var; if (d->which >= LOW_PM) return TRUE; /* got one */ d->monclass = name_to_monclass(bufp, &d->which); @@ -2578,7 +2577,8 @@ struct _create_particular_data *d; else if (d->randmonst) whichpm = rndmonst(); if (d->fem != -1 && !is_male(whichpm) && !is_female(whichpm)) - mmflags |= (d->fem == FEMALE) ? MM_FEMALE : MM_MALE; + mmflags |= (d->fem == FEMALE) ? MM_FEMALE + : (d->fem == MALE) ? MM_MALE : 0; mtmp = makemon(whichpm, u.ux, u.uy, mmflags); if (!mtmp) { /* quit trying if creation failed and is going to repeat */ From 30fe65b5e02624ee9c7f61dbfe10c3b34b9ab912 Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Dec 2020 09:14:39 -0500 Subject: [PATCH 698/708] fix tilemap.c compile when STATUES_LOOK_LIKE_MONSTERS wasn't defined --- doc/fixes37.0 | 3 +++ win/share/tilemap.c | 21 +++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 90e698172..95e1a491e 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -459,6 +459,9 @@ splitting #if MAIL into #if MAIL_STRUCTURES and #if MAIL made it possible to to read such a scroll issued impossible "What weird effect is this?" remove M2_MALE flag that was unintentionally left on dwarf lord/lady/leader entry and was preventing female incarnations +tilemap.c wasn't building if STATUES_LOOK_LIKE_MONSTERS wasn't defined; also, + to match the code that should be defined so change the preprocessor + test to 'ifndef STATUES_DONT_LOOK_LIKE_MONSTERS' curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/win/share/tilemap.c b/win/share/tilemap.c index c7766a63b..9351756f4 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -42,10 +42,6 @@ extern void FDECL(exit, (int)); #endif #endif -#if defined(MSDOS) || defined(WIN32) || defined(X11_GRAPHICS) -#define STATUES_LOOK_LIKE_MONSTERS -#endif - enum {MON_GLYPH, OBJ_GLYPH, OTH_GLYPH, TERMINATOR = -1}; #define EXTRA_SCROLL_DESCR_COUNT ((SCR_BLANK_PAPER - SCR_STINKING_CLOUD) - 1) @@ -279,7 +275,7 @@ struct tilemap_t { } tilemap[MAX_GLYPH]; -#ifdef STATUES_LOOK_LIKE_MONSTERS +#ifndef STATUES_DONT_LOOK_LIKE_MONSTERS int lastmontile, lastobjtile, lastothtile, laststatuetile; #else int lastmontile, lastobjtile, lastothtile; @@ -514,11 +510,12 @@ init_tilemap() file_entry++; } -#ifndef STATUES_LOOK_LIKE_MONSTERS - /* statue patch: statues still use the same glyph as in vanilla */ +#ifndef STATUES_DONT_LOOK_LIKE_MONSTERS + /* statue patch: statues still use the same glyph as in 3.4.x */ for (i = 0; i < NUMMONS; i++) { - tilemap[GLYPH_STATUE_OFF + i].tilenum = tilemap[GLYPH_OBJ_OFF + STATUE]; + tilemap[GLYPH_STATUE_OFF + i].tilenum + = tilemap[GLYPH_OBJ_OFF + STATUE].tilenum; #ifdef OBTAIN_TILEMAP Sprintf(tilemap[GLYPH_STATUE_OFF + i].name, "%s (%d)", tilename(OTH_GLYPH, file_entry, 0), file_entry); @@ -528,7 +525,7 @@ init_tilemap() lastothtile = tilenum - 1; -#ifdef STATUES_LOOK_LIKE_MONSTERS +#ifndef STATUES_DONT_LOOK_LIKE_MONSTERS file_entry = 0; /* fast-forward over the substitutes to grayscale statues loc */ for (i = 0; i < SIZE(substitutes); i++) { @@ -557,7 +554,7 @@ init_tilemap() file_entry += 2; } laststatuetile = tilenum - 2; -#endif /* STATUES_LOOK_LIKE_MONSTERS */ +#endif /* STATUES_DONT_LOOK_LIKE_MONSTERS */ #ifdef OBTAIN_TILEMAP for (i = 0; i < MAX_GLYPH; ++i) { Fprintf(tilemap_file, "[%04d] [%04d] %-80s\n", @@ -638,7 +635,7 @@ FILE *ofp; } lastothtile = start - 1; -#ifdef STATUES_LOOK_LIKE_MONSTERS +#ifndef STATUES_DONT_LOOK_LIKE_MONSTERS start = laststatuetile + 1; #endif Fprintf(ofp, "\nint total_tiles_used = %d;\n", start); @@ -688,7 +685,7 @@ main() Fprintf(ofp, "\n#define MAXMONTILE %d\n", lastmontile); Fprintf(ofp, "#define MAXOBJTILE %d\n", lastobjtile); Fprintf(ofp, "#define MAXOTHTILE %d\n", lastothtile); -#ifdef STATUES_LOOK_LIKE_MONSTERS +#ifndef STATUES_DONT_LOOK_LIKE_MONSTERS Fprintf(ofp, "/* #define MAXSTATUETILE %d */\n", laststatuetile); #endif Fprintf(ofp, "\n/*tile.c*/\n"); From c31047984b4422019d9e3a5a397357490d87c34c Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Dec 2020 09:19:07 -0500 Subject: [PATCH 699/708] typo in tilemap.c update --- win/share/tilemap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/share/tilemap.c b/win/share/tilemap.c index 9351756f4..550a90288 100644 --- a/win/share/tilemap.c +++ b/win/share/tilemap.c @@ -510,7 +510,7 @@ init_tilemap() file_entry++; } -#ifndef STATUES_DONT_LOOK_LIKE_MONSTERS +#ifdef STATUES_DONT_LOOK_LIKE_MONSTERS /* statue patch: statues still use the same glyph as in 3.4.x */ for (i = 0; i < NUMMONS; i++) { From 524f9dd82bdc1b9fdf8768d45442e6af0972a796 Mon Sep 17 00:00:00 2001 From: PatR Date: Mon, 28 Dec 2020 10:01:43 -0800 Subject: [PATCH 700/708] Qt map's "ttychar" Change the glyphttychar[ROWNO][COLNO] array from uchar to unsighed short. DrawWalls() has handling for values in over 2000. This also reformats pretty much all of the NetHackQtMapViewport portion of qt_map.cpp. --- win/Qt/qt_map.cpp | 254 +++++++++++++++++++--------------------------- win/Qt/qt_map.h | 38 ++++--- 2 files changed, 128 insertions(+), 164 deletions(-) diff --git a/win/Qt/qt_map.cpp b/win/Qt/qt_map.cpp index 34a55eb1f..01047e83a 100644 --- a/win/Qt/qt_map.cpp +++ b/win/Qt/qt_map.cpp @@ -126,11 +126,11 @@ NetHackQtMapViewport::NetHackQtMapViewport(NetHackQtClickBuffer& click_sink) : NetHackQtMapViewport::~NetHackQtMapViewport(void) { - delete rogue_font; + delete rogue_font; //rogue_font = NULL; } // pick a font to use for text map; rogue level is always displayed as text -void NetHackQtMapViewport::SetRogueFont(QPainter &painter) +void NetHackQtMapViewport::SetupTextmapFont(QPainter &painter) { QString fontfamily = iflags.wc_font_map ? iflags.wc_font_map : "Monospace"; @@ -167,7 +167,6 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) std::min(ROWNO - 1, area.bottom() / gH)); QPainter painter; - painter.begin(this); if (Is_rogue_level(&u.uz) || iflags.wc_ascii_map) { @@ -177,11 +176,11 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) painter.fillRect( event->rect(), Qt::black ); if (!rogue_font) - SetRogueFont(painter); + SetupTextmapFont(painter); painter.setFont(*rogue_font); - for (int j=garea.top(); j<=garea.bottom(); j++) { - for (int i=garea.left(); i<=garea.right(); i++) { + for (int j = garea.top(); j <= garea.bottom(); j++) { + for (int i = garea.left(); i <= garea.right(); i++) { #if 0 unsigned short g = Glyph(i, j); int colortmp; @@ -189,10 +188,11 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) unsigned special; /* map glyph to character and color */ mapglyph(g, &chtmp, &colortmp, &special, i, j, 0); - uchar ch = (uchar) chtmp, color = (uchar) colortmp; + unsigned short ch = (unsigned short) chtmp, + color = (unsigned short) colortmp; #else - uchar color = Glyphcolor(i, j); - uchar ch = Glyphttychar(i, j); + unsigned short color = Glyphcolor(i, j); + unsigned short ch = Glyphttychar(i, j); unsigned special = Glyphflags(i, j); #endif ch = cp437(ch); @@ -220,9 +220,9 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) painter.setFont(font()); } else { // tiles - for (int j=garea.top(); j<=garea.bottom(); j++) { - for (int i=garea.left(); i<=garea.right(); i++) { - unsigned short g=Glyph(i,j); + for (int j = garea.top(); j <= garea.bottom(); j++) { + for (int i = garea.left(); i <= garea.right(); i++) { + unsigned short g = Glyph(i,j); #if 0 int color; int ch; @@ -293,10 +293,8 @@ void NetHackQtMapViewport::paintEvent(QPaintEvent* event) painter.end(); } -bool NetHackQtMapViewport::DrawWalls( - QPainter& painter, - int x, int y, int w, int h, - unsigned ch) +bool NetHackQtMapViewport::DrawWalls(QPainter& painter, int x, int y, + int w, int h, unsigned short ch) { enum wallbits { w_left = 0x01, @@ -312,89 +310,72 @@ bool NetHackQtMapViewport::DrawWalls( unsigned walls; int x1, y1, x2, y2, x3, y3; - linewidth = ((w < h) ? w : h)/8; - if (linewidth == 0) linewidth = 1; + linewidth = ((w < h) ? w : h) / 8; + if (linewidth == 0) + linewidth = 1; // Single walls walls = 0; - switch (ch) - { - case 0x2500: // BOX DRAWINGS LIGHT HORIZONTAL + switch (ch) { + case 0x2500: // box drawings light horizontal walls = w_left | w_right; break; - - case 0x2502: // BOX DRAWINGS LIGHT VERTICAL + case 0x2502: // box drawings light vertical walls = w_up | w_down; break; - - case 0x250C: // BOX DRAWINGS LIGHT DOWN AND RIGHT + case 0x250C: // box drawings light down and right walls = w_down | w_right; break; - - case 0x2510: // BOX DRAWINGS LIGHT DOWN AND LEFT + case 0x2510: // box drawings light down and left walls = w_down | w_left; break; - - case 0x2514: // BOX DRAWINGS LIGHT UP AND RIGHT + case 0x2514: // box drawings light up and right walls = w_up | w_right; break; - - case 0x2518: // BOX DRAWINGS LIGHT UP AND LEFT + case 0x2518: // box drawings light up and left walls = w_up | w_left; break; - - case 0x251C: // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + case 0x251C: // box drawings light vertical and right walls = w_up | w_down | w_right; break; - - case 0x2524: // BOX DRAWINGS LIGHT VERTICAL AND LEFT + case 0x2524: // box drawings light vertical and left walls = w_up | w_down | w_left; break; - - case 0x252C: // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + case 0x252C: // box drawings light down and horizontal walls = w_down | w_left | w_right; break; - - case 0x2534: // BOX DRAWINGS LIGHT UP AND HORIZONTAL + case 0x2534: // box drawings light up and horizontal walls = w_up | w_left | w_right; break; - - case 0x253C: // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + case 0x253C: // box drawings light vertical and horizontal walls = w_up | w_down | w_left | w_right; break; } - if (walls != 0) - { - x1 = x + w/2; - switch (walls & (w_up | w_down)) - { + if (walls != 0) { + x1 = x + w / 2; + switch (walls & (w_up | w_down)) { case w_up: - painter.drawLine(x1, y, x1, y+h/2); + painter.drawLine(x1, y, x1, y + h / 2); break; - case w_down: - painter.drawLine(x1, y+h/2, x1, y+h-1); + painter.drawLine(x1, y + h / 2, x1, y + h - 1); break; - case w_up | w_down: - painter.drawLine(x1, y, x1, y+h-1); + painter.drawLine(x1, y, x1, y + h - 1); break; } - y1 = y + h/2; - switch (walls & (w_left | w_right)) - { + y1 = y + h / 2; + switch (walls & (w_left | w_right)) { case w_left: - painter.drawLine(x, y1, x+w/2, y1); + painter.drawLine(x, y1, x + w / 2, y1); break; - case w_right: - painter.drawLine(x+w/2, y1, x+w-1, y1); + painter.drawLine(x + w / 2, y1, x + w - 1, y1); break; - case w_left | w_right: - painter.drawLine(x, y1, x+w-1, y1); + painter.drawLine(x, y1, x + w - 1, y1); break; } @@ -403,108 +384,88 @@ bool NetHackQtMapViewport::DrawWalls( // Double walls walls = 0; - switch (ch) - { - case 0x2550: // BOX DRAWINGS DOUBLE HORIZONTAL + switch (ch) { + case 0x2550: // box drawings double horizontal walls = w_left | w_right | w_sq_top | w_sq_bottom; break; - - case 0x2551: // BOX DRAWINGS DOUBLE VERTICAL + case 0x2551: // box drawings double vertical walls = w_up | w_down | w_sq_left | w_sq_right; break; - - case 0x2554: // BOX DRAWINGS DOUBLE DOWN AND RIGHT + case 0x2554: // box drawings double down and right walls = w_down | w_right | w_sq_top | w_sq_left; break; - - case 0x2557: // BOX DRAWINGS DOUBLE DOWN AND LEFT + case 0x2557: // box drawings double down and left walls = w_down | w_left | w_sq_top | w_sq_right; break; - - case 0x255A: // BOX DRAWINGS DOUBLE UP AND RIGHT + case 0x255A: // box drawings double up and right walls = w_up | w_right | w_sq_bottom | w_sq_left; break; - - case 0x255D: // BOX DRAWINGS DOUBLE UP AND LEFT + case 0x255D: // box drawings double up and left walls = w_up | w_left | w_sq_bottom | w_sq_right; break; - - case 0x2560: // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + case 0x2560: // box drawings double vertical and right walls = w_up | w_down | w_right | w_sq_left; break; - - case 0x2563: // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + case 0x2563: // box drawings double vertical and left walls = w_up | w_down | w_left | w_sq_right; break; - - case 0x2566: // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + case 0x2566: // box drawings double down and horizontal walls = w_down | w_left | w_right | w_sq_top; break; - - case 0x2569: // BOX DRAWINGS DOUBLE UP AND HORIZONTAL + case 0x2569: // box drawings double up and horizontal walls = w_up | w_left | w_right | w_sq_bottom; break; - - case 0x256C: // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + case 0x256C: // box drawings double vertical and horizontal walls = w_up | w_down | w_left | w_right; break; } - if (walls != 0) - { - x1 = x + w/2 - linewidth; - x2 = x + w/2 + linewidth; + + if (walls != 0) { + x1 = x + w / 2 - linewidth; + x2 = x + w / 2 + linewidth; x3 = x + w - 1; - y1 = y + h/2 - linewidth; - y2 = y + h/2 + linewidth; + y1 = y + h / 2 - linewidth; + y2 = y + h / 2 + linewidth; y3 = y + h - 1; - if (walls & w_up) - { + if (walls & w_up) { painter.drawLine(x1, y, x1, y1); painter.drawLine(x2, y, x2, y1); } - if (walls & w_down) - { + if (walls & w_down) { painter.drawLine(x1, y2, x1, y3); painter.drawLine(x2, y2, x2, y3); } - if (walls & w_left) - { + if (walls & w_left) { painter.drawLine(x, y1, x1, y1); painter.drawLine(x, y2, x1, y2); } - if (walls & w_right) - { + if (walls & w_right) { painter.drawLine(x2, y1, x3, y1); painter.drawLine(x2, y2, x3, y2); } - if (walls & w_sq_top) - { + if (walls & w_sq_top) { painter.drawLine(x1, y1, x2, y1); } - if (walls & w_sq_bottom) - { + if (walls & w_sq_bottom) { painter.drawLine(x1, y2, x2, y2); } - if (walls & w_sq_left) - { + if (walls & w_sq_left) { painter.drawLine(x1, y1, x1, y2); } - if (walls & w_sq_right) - { + if (walls & w_sq_right) { painter.drawLine(x2, y1, x2, y2); } + return true; } // Solid blocks - if (0x2591 <= ch && ch <= 0x2593) - { + if (0x2591 <= ch && ch <= 0x2593) { unsigned shade = ch - 0x2590; QColor rgb(painter.pen().color()); - QColor rgb2( - rgb.red()*shade/4, - rgb.green()*shade/4, - rgb.blue()*shade/4); + QColor rgb2(rgb.red() * shade / 4, + rgb.green() * shade / 4, + rgb.blue() * shade / 4); painter.fillRect(x, y, w, h, rgb2); return true; } @@ -514,26 +475,23 @@ bool NetHackQtMapViewport::DrawWalls( void NetHackQtMapViewport::mousePressEvent(QMouseEvent* event) { - clicksink.Put( - event->pos().x()/qt_settings->glyphs().width(), - event->pos().y()/qt_settings->glyphs().height(), - event->button()==Qt::LeftButton ? CLICK_1 : CLICK_2 - ); + clicksink.Put(event->pos().x() / qt_settings->glyphs().width(), + event->pos().y() / qt_settings->glyphs().height(), + (event->button() == Qt::LeftButton) ? CLICK_1 : CLICK_2); qApp->exit(); } void NetHackQtMapViewport::updateTiles() { change.clear(); - change.add(0,0,COLNO,ROWNO); + change.add(0, 0, COLNO, ROWNO); delete rogue_font; rogue_font = NULL; } QSize NetHackQtMapViewport::sizeHint() const { - return QSize( - qt_settings->glyphs().width() * COLNO, - qt_settings->glyphs().height() * ROWNO); + return QSize(qt_settings->glyphs().width() * COLNO, + qt_settings->glyphs().height() * ROWNO); } QSize NetHackQtMapViewport::minimumSizeHint() const @@ -543,7 +501,7 @@ QSize NetHackQtMapViewport::minimumSizeHint() const void NetHackQtMapViewport::clickCursor() { - clicksink.Put(cursor.x(),cursor.y(),CLICK_1); + clicksink.Put(cursor.x(), cursor.y(), CLICK_1); qApp->exit(); } @@ -557,65 +515,63 @@ void NetHackQtMapViewport::Clear() Glyph(0, j) = GLYPH_NOTHING; Glyphttychar(0, j) = ' '; Glyphcolor(0, j) = NO_COLOR; - Glyphflags(0, j) = 0; + Glyphflags(0, j) = 0U; for (int i = 1; i < COLNO; ++i) { Glyph(i, j) = GLYPH_UNEXPLORED; Glyphttychar(i, j) = ' '; Glyphcolor(i, j) = NO_COLOR; - Glyphflags(i, j) = 0; + Glyphflags(i, j) = 0U; } } change.clear(); - change.add(0,0,COLNO,ROWNO); + change.add(0, 0, COLNO, ROWNO); } void NetHackQtMapViewport::Display(bool block) { - for (int i=0; iglyphs().width(), - ch.y()*qt_settings->glyphs().height(), - ch.width()*qt_settings->glyphs().width(), - ch.height()*qt_settings->glyphs().height() - ); - } + int gW = qt_settings->glyphs().width(), + gH = qt_settings->glyphs().height(); + for (int i = 0; i < change.clusters(); i++) { + const QRect& chg = change[i]; + repaint(chg.x() * gW, chg.y() * gH, + chg.width() * gW, chg.height() * gH); + } change.clear(); if (block) { - yn_function("Press a key when done viewing",0,'\0'); + yn_function("Press a key when done viewing", NULL, '\0'); } } void NetHackQtMapViewport::CursorTo(int x,int y) { - Changed(cursor.x(),cursor.y()); + Changed(cursor.x(), cursor.y()); cursor.setX(x); cursor.setY(y); - Changed(cursor.x(),cursor.y()); + Changed(cursor.x(), cursor.y()); } void NetHackQtMapViewport::PrintGlyph(int x, int y, int theglyph, unsigned *glyphmod) { - Glyph(x, y) = theglyph; - Glyphttychar(x, y) = (uchar) glyphmod[GM_TTYCHAR]; - Glyphcolor(x, y) = (uchar) glyphmod[GM_COLOR]; + Glyph(x, y) = (unsigned short) theglyph; + Glyphttychar(x, y) = (unsigned short) glyphmod[GM_TTYCHAR]; + Glyphcolor(x, y) = (unsigned short) glyphmod[GM_COLOR]; Glyphflags(x, y) = glyphmod[GM_FLAGS]; Changed(x, y); } void NetHackQtMapViewport::Changed(int x, int y) { - change.add(x,y); + change.add(x, y); } NetHackQtMapWindow2::NetHackQtMapWindow2(NetHackQtClickBuffer& click_sink) : - QScrollArea(NULL), - m_viewport(new NetHackQtMapViewport(click_sink)) + QScrollArea(NULL), + m_viewport(new NetHackQtMapViewport(click_sink)) { QPalette palette; palette.setColor(backgroundRole(), Qt::black); @@ -623,22 +579,22 @@ NetHackQtMapWindow2::NetHackQtMapWindow2(NetHackQtClickBuffer& click_sink) : setWidget(m_viewport); - connect(qt_settings,SIGNAL(tilesChanged()),this,SLOT(updateTiles())); + connect(qt_settings, SIGNAL(tilesChanged()), this, SLOT(updateTiles())); updateTiles(); } void NetHackQtMapWindow2::updateTiles() { NetHackQtGlyphs& glyphs = qt_settings->glyphs(); - int gw = glyphs.width(); - int gh = glyphs.height(); + int gW = glyphs.width(); + int gH = glyphs.height(); // Be exactly the size we want to be - full map... - m_viewport->resize(COLNO*gw,ROWNO*gh); + m_viewport->resize(COLNO * gW, ROWNO * gH); - verticalScrollBar()->setSingleStep(gh); - verticalScrollBar()->setPageStep(gh); - horizontalScrollBar()->setSingleStep(gw); - horizontalScrollBar()->setPageStep(gw); + verticalScrollBar()->setSingleStep(gH); + verticalScrollBar()->setPageStep(gH); + horizontalScrollBar()->setSingleStep(gW); + horizontalScrollBar()->setPageStep(gW); m_viewport->updateTiles(); Display(false); diff --git a/win/Qt/qt_map.h b/win/Qt/qt_map.h index 0c6937bae..82050dc98 100644 --- a/win/Qt/qt_map.h +++ b/win/Qt/qt_map.h @@ -23,26 +23,34 @@ public: protected: virtual void paintEvent(QPaintEvent* event); bool DrawWalls(QPainter& painter, int x, int y, - int w, int h, unsigned ch); + int w, int h, unsigned short ch); virtual QSize sizeHint() const; virtual QSize minimumSizeHint() const; virtual void mousePressEvent(QMouseEvent* event); private: - QFont *rogue_font; - unsigned short glyph[ROWNO][COLNO]; - unsigned short& Glyph(int x, int y) { return glyph[y][x]; } - uchar glyphttychar[ROWNO][COLNO]; - uchar& Glyphttychar(int x, int y) { return glyphttychar[y][x]; } - uchar glyphcolor[ROWNO][COLNO]; - uchar& Glyphcolor(int x, int y) { return glyphcolor[y][x]; } - unsigned int glyphflags[ROWNO][COLNO]; - unsigned int& Glyphflags(int x, int y) { return glyphflags[y][x]; } - QPoint cursor; - QPixmap pet_annotation; + QFont *rogue_font; + unsigned short glyph[ROWNO][COLNO]; + unsigned short &Glyph(int x, int y) { + return glyph[y][x]; + } + unsigned short glyphttychar[ROWNO][COLNO]; + unsigned short &Glyphttychar(int x, int y) { + return glyphttychar[y][x]; + } + unsigned short glyphcolor[ROWNO][COLNO]; + unsigned short &Glyphcolor(int x, int y) { + return glyphcolor[y][x]; + } + unsigned int glyphflags[ROWNO][COLNO]; + unsigned int &Glyphflags(int x, int y) { + return glyphflags[y][x]; + } + QPoint cursor; + QPixmap pet_annotation; QPixmap pile_annotation; - NetHackQtClickBuffer& clicksink; - Clusterizer change; + NetHackQtClickBuffer &clicksink; + Clusterizer change; void clickCursor(); void Clear(); @@ -51,7 +59,7 @@ private: void PrintGlyph(int x,int y,int glyph,unsigned *glyphmod); void Changed(int x, int y); void updateTiles(); - void SetRogueFont(QPainter &painter); + void SetupTextmapFont(QPainter &painter); // NetHackQtMapWindow2 passes through many calls to the viewport friend class NetHackQtMapWindow2; From f30bb8aaa49d6338b9e076c6e1c30d972a9bbbcf Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Dec 2020 14:02:22 -0500 Subject: [PATCH 701/708] another monster gender name handling tweak ensure that monster female name variation ends up as a female during ^G arbitrate when there is a conflict between gender term (male or female) and a gender-tied monster name (cavewoman) during ^G; gender term wins --- doc/fixes37.0 | 5 ++++- include/decl.h | 3 ++- src/read.c | 46 +++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index 95e1a491e..a50894cb1 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -461,7 +461,10 @@ remove M2_MALE flag that was unintentionally left on dwarf lord/lady/leader entry and was preventing female incarnations tilemap.c wasn't building if STATUES_LOOK_LIKE_MONSTERS wasn't defined; also, to match the code that should be defined so change the preprocessor - test to 'ifndef STATUES_DONT_LOOK_LIKE_MONSTERS' + test to 'ifndef STATUES_DONT_LOOK_LIKE_MONSTERS' +ensure that monster female name variation ends up as a female during ^G +arbitrate when there is a conflict between gender term (male or female) and + a gender-tied monster name (cavewoman) during ^G; gender term wins curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/include/decl.h b/include/decl.h index 0a9b61ba9..59f599866 100644 --- a/include/decl.h +++ b/include/decl.h @@ -628,7 +628,8 @@ struct role_filter { struct _create_particular_data { int quan; int which; - int fem; + int fem; /* -1, MALE, FEMALE, NEUTRAL */ + int genderconf; /* conflicting gender */ char monclass; boolean randmonst; boolean maketame, makepeaceful, makehostile; diff --git a/src/read.c b/src/read.c index 7ed7cdb5d..a6fa79b1a 100644 --- a/src/read.c +++ b/src/read.c @@ -2454,7 +2454,8 @@ struct _create_particular_data *d; d->quan = 1 + ((g.multi > 0) ? g.multi : 0); d->monclass = MAXMCLASSES; d->which = g.urole.malenum; /* an arbitrary index into mons[] */ - d->fem = -1; /* gender not specified */ + d->fem = -1; /* gender not specified */ + d->genderconf = -1; /* no confusion on which gender to assign */ d->randmonst = FALSE; d->maketame = d->makepeaceful = d->makehostile = FALSE; d->sleeping = d->saddled = d->invisible = d->hidden = FALSE; @@ -2521,8 +2522,19 @@ struct _create_particular_data *d; /* * With the introduction of male and female monster names * in 3.7, 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. */ - d->fem = gender_name_var; + if (d->fem == MALE || d->fem == FEMALE) { /* explicity expressed */ + if ((gender_name_var != NEUTRAL) && (d->fem != gender_name_var)) { + /* apparent selection incompatibility */ + d->genderconf = gender_name_var; /* resolve later */ + } + /* otherwise keep the value of d->fem, as it's okay */ + } else { /* no explicit gender term was specified */ + d->fem = gender_name_var; + } if (d->which >= LOW_PM) return TRUE; /* got one */ d->monclass = name_to_monclass(bufp, &d->which); @@ -2576,9 +2588,33 @@ struct _create_particular_data *d; whichpm = mkclass(d->monclass, 0); else if (d->randmonst) whichpm = rndmonst(); - if (d->fem != -1 && !is_male(whichpm) && !is_female(whichpm)) - mmflags |= (d->fem == FEMALE) ? MM_FEMALE - : (d->fem == MALE) ? MM_MALE : 0; + if (d->genderconf == -1) { + /* no confict exists between explicit gender term and + the specified monster name */ + if (d->fem != -1 && !is_male(whichpm) && !is_female(whichpm)) + mmflags |= (d->fem == FEMALE) ? MM_FEMALE + : (d->fem == MALE) ? MM_MALE : 0; + } else { + /* conundrum alert: an explicit gender term conflicts with an + explicit gender-tied naming term (i.e. male cavewoman) */ + + /* option not gone with: name overrides the explicit gender as + commented out here */ + /* d->fem = d->genderconf; */ + + /* option chosen: let the explicit gender term (male or female) + override the gender-tied naming term, so leave d->fem as-is */ + + mmflags |= (d->fem == FEMALE) ? MM_FEMALE + : (d->fem == MALE) ? MM_MALE : 0; + + /* another option would be to consider it a faulty specification + and reject the request completely and produce a random monster + with a gender matching that specified instead (i.e. there is + no such thing as a male cavewoman) */ + /* whichpm = rndmonst(); */ + /* mmflags |= (d->fem == FEMALE) ? MM_FEMALE : MM_MALE; */ + } mtmp = makemon(whichpm, u.ux, u.uy, mmflags); if (!mtmp) { /* quit trying if creation failed and is going to repeat */ From 1c2c5dae1b5f2398aa77afea7165d4dad881847d Mon Sep 17 00:00:00 2001 From: nhmall Date: Mon, 28 Dec 2020 22:07:00 -0500 Subject: [PATCH 702/708] remove vision tables from Windows and msdos builds --- Porting | 1 - sys/msdos/Makefile.GCC | 17 +++-------------- sys/winnt/Makefile.gcc | 21 ++++++--------------- sys/winnt/Makefile.msc | 20 +++++--------------- win/win32/vs/NetHackW.vcxproj | 2 -- win/win32/vs/aftermakedefs.proj | 1 - win/win32/vs/files.props | 3 --- 7 files changed, 14 insertions(+), 51 deletions(-) diff --git a/Porting b/Porting index 120292d2e..da8d74594 100644 --- a/Porting +++ b/Porting @@ -192,7 +192,6 @@ line options to produce several output files that are required for: util/makedefs -v util/makedefs -o util/makedefs -p - util/makedefs -z util/makedefs -d util/makedefs -r util/makedefs -h diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC index 0837d991b..f1d3f7e6f 100644 --- a/sys/msdos/Makefile.GCC +++ b/sys/msdos/Makefile.GCC @@ -273,7 +273,7 @@ VOBJ16 = $(O)role.o $(O)rumors.o $(O)save.o $(O)sfstruct.o $(O)shk.o VOBJ17 = $(O)shknam.o $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o VOBJ18 = $(O)steal.o $(O)steed.o $(O)symbols.o $(O)sys.o $(O)termcap.o VOBJ19 = $(O)timeout.o $(O)topl.o $(O)topten.o $(O)track.o $(O)trap.o -VOBJ20 = $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o $(O)vis_tab.o +VOBJ20 = $(O)u_init.o $(O)uhitm.o $(O)vault.o $(O)vision.o VOBJ21 = $(O)weapon.o $(O)were.o $(O)wield.o $(O)windows.o $(O)wintty.o VOBJ22 = $(O)wizard.o $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o VOBJ23 = $(O)light.o $(O)dlb.o $(O)dig.o $(O)teleport.o $(O)region.o @@ -548,7 +548,7 @@ default: $(GAMEFILE) util: $(O)utility.tag $(O)utility.tag: $(INCL)/date.h $(INCL)/trap.h $(INCL)/onames.h \ - $(INCL)/pm.h vis_tab.c $(TILEUTIL) + $(INCL)/pm.h $(TILEUTIL) $(subst /,\,echo utilities made > $@) tileutil: $(U)gif2txt.exe $(U)txt2ppm.exe @@ -653,12 +653,6 @@ $(INCL)/onames.h: $(U)makedefs.exe $(INCL)/pm.h: $(U)makedefs.exe -$(subst /,\,$(U)makedefs -p) -$(INCL)/vis_tab.h: $(U)makedefs.exe - -$(subst /,\,$(U)makedefs -z) - -vis_tab.c: $(U)makedefs.exe - -$(subst /,\,$(U)makedefs -z) - #========================================== # Makedefs Stuff #========================================== @@ -913,12 +907,10 @@ spotless: clean $(subst /,\,if exist $(U)til2bin2.exe del $(U)til2bin2.exe) $(subst /,\,if exist $(U)thintile.exe del $(U)thintile.exe) $(subst /,\,if exist $(U)dlb_main.exe del $(U)dlb_main.exe) - $(subst /,\,if exist $(INCL)/vis_tab.h del $(INCL)/vis_tab.h) $(subst /,\,if exist $(INCL)/onames.h del $(INCL)/onames.h) $(subst /,\,if exist $(INCL)/pm.h del $(INCL)/pm.h) $(subst /,\,if exist $(INCL)/date.h del $(INCL)/date.h) $(subst /,\,if exist $(SRC)/monstr.c del $(SRC)/monstr.c) - $(subst /,\,if exist $(SRC)/vis_tab.c del $(SRC)/vis_tab.c) $(subst /,\,if exist $(SRC)/tile.c del $(SRC)/tile.c) $(subst /,\,if exist $(DAT)/options del $(DAT)/options) $(subst /,\,if exist $(DAT)/data del $(DAT)/data) @@ -996,11 +988,9 @@ spotless: clean $(subst /,\,if exist $(U)til2bin2.exe del $(U)til2bin2.exe) $(subst /,\,if exist $(U)thintile.exe del $(U)thintile.exe) $(subst /,\,if exist $(U)dlb_main.exe del $(U)dlb_main.exe) - $(subst /,\,if exist $(INCL)/vis_tab.h del $(INCL)/vis_tab.h) $(subst /,\,if exist $(INCL)/onames.h del $(INCL)/onames.h) $(subst /,\,if exist $(INCL)/pm.h del $(INCL)/pm.h) $(subst /,\,if exist $(INCL)/date.h del $(INCL)/date.h) - $(subst /,\,if exist $(SRC)/vis_tab.c del $(SRC)/vis_tab.c) $(subst /,\,if exist $(SRC)/tile.c del $(SRC)/tile.c) $(subst /,\,if exist $(DAT)/options del $(DAT)/options) $(subst /,\,if exist $(DAT)/data del $(DAT)/data) @@ -1218,7 +1208,6 @@ $(O)qt_clust.o: ../win/Qt/qt_clust.cpp $(INCL)/qt_clust.h $(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h $(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qttableview.cpp $(O)monstr.o: monstr.c $(CONFIG_H) -$(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h $(O)allmain.o: allmain.c $(HACK_H) $(O)alloc.o: alloc.c $(CONFIG_H) $(O)apply.o: apply.c $(HACK_H) @@ -1325,7 +1314,7 @@ $(O)u_init.o: u_init.c $(HACK_H) $(O)uhitm.o: uhitm.c $(HACK_H) $(O)vault.o: vault.c $(HACK_H) $(O)version.o: version.c $(HACK_H) $(INCL)/date.h -$(O)vision.o: vision.c $(HACK_H) $(INCL)/vis_tab.h +$(O)vision.o: vision.c $(HACK_H) $(O)weapon.o: weapon.c $(HACK_H) $(O)were.o: were.c $(HACK_H) $(O)wield.o: wield.c $(HACK_H) diff --git a/sys/winnt/Makefile.gcc b/sys/winnt/Makefile.gcc index 8d42e247d..45c790a60 100644 --- a/sys/winnt/Makefile.gcc +++ b/sys/winnt/Makefile.gcc @@ -330,9 +330,9 @@ VOBJ22 = $(O)shknam.o $(O)sit.o $(O)sounds.o $(O)sp_lev.o VOBJ23 = $(O)spell.o $(O)steal.o $(O)steed.o $(O)symbols.o VOBJ24 = $(O)sys.o $(O)teleport.o $(O)timeout.o $(O)topten.o VOBJ25 = $(O)track.o $(O)trap.o $(O)u_init.o $(O)uhitm.o -VOBJ26 = $(O)vault.o $(O)vis_tab.o $(O)vision.o $(O)weapon.o -VOBJ27 = $(O)were.o $(O)wield.o $(O)windows.o $(O)wizard.o -VOBJ28 = $(O)worm.o $(O)worn.o $(O)write.o $(O)zap.o +VOBJ26 = $(O)vault.o $(O)vision.o $(O)weapon.o $(O)were.o +VOBJ27 = $(O)wield.o $(O)windows.o $(O)wizard.o $(O)worm.o +VOBJ28 = $(O)worn.o $(O)write.o $(O)zap.o ifeq "$(ADD_LUA)" "Y" LUAOBJ = $(O)nhlua.o $(O)nhlsel.o $(O)nhlobj.o @@ -807,7 +807,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(subst /,\,echo sp_levs done > $(O)sp_lev.tag) $(O)utility.tag: $(INCL)/date.h $(INCL)/onames.h $(INCL)/pm.h \ - $(SRC)/vis_tab.c $(INCL)/vis_tab.h $(TILEUTIL16) + $(TILEUTIL16) $(subst /,\,@echo utilities made >$@) @echo utilities made. @@ -937,12 +937,6 @@ $(INCL)/onames.h : $(U)makedefs.exe $(INCL)/pm.h : $(U)makedefs.exe $(subst /,\,$(U)makedefs -p) -$(INCL)/vis_tab.h: $(U)makedefs.exe - $(subst /,\,$(U)makedefs -z) - -$(SRC)/vis_tab.c: $(U)makedefs.exe - $(subst /,\,$(U)makedefs -z) - $(DAT)/data: $(O)utility.tag $(DATABASE) $(subst /,\,$(U)makedefs -d) @@ -1212,9 +1206,7 @@ ifneq "$(W_GAMEDIR)" "" if exist $(W_GAMEDIR)\nhdat$(NHV) del $(W_GAMEDIR)\nhdat$(NHV) endif ifneq "$(W_SRC)" "" - if exist $(W_SRC)\vis_tab.c del $(W_SRC)\vis_tab.c if exist $(W_SRC)\tile.c del $(W_SRC)\tile.c - if exist $(W_SRC)\vis_tab.c del $(W_SRC)\vis_tab.c if exist $(W_SRC)\nhdat$(NHV). del $(W_SRC)\nhdat$(NHV). endif ifneq "$(W_DAT)" "" @@ -1265,7 +1257,6 @@ ifneq "$(W_INCL)" "" if exist $(W_INCL)\date.h del $(W_INCL)\date.h if exist $(W_INCL)\onames.h del $(W_INCL)\onames.h if exist $(W_INCL)\pm.h del $(W_INCL)\pm.h - if exist $(W_INCL)\vis_tab.h del $(W_INCL)\vis_tab.h endif ifeq "$(ADD_CURSES)" "Y" ifneq "$(W_OBJ)" "" @@ -1607,7 +1598,7 @@ $(O)qt_yndlg.o: ../win/Qt/qt_yndlg.cpp $(HACK_H) ../win/Qt/qt_pre.h \ ../win/Qt/qt_str.h # $(CXX) $(CXXFLAGS) -c -o $@ ../win/Qt/qt_yndlg.cpp #--- -$(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h +$(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(O)allmain.o: allmain.c $(HACK_H) $(O)alloc.o: alloc.c $(CONFIG_H) $(O)apply.o: apply.c $(HACK_H) @@ -1715,7 +1706,7 @@ $(O)u_init.o: u_init.c $(HACK_H) $(O)uhitm.o: uhitm.c $(HACK_H) $(O)vault.o: vault.c $(HACK_H) $(O)version.o: version.c $(HACK_H) $(INCL)/date.h -$(O)vision.o: vision.c $(HACK_H) $(INCL)/vis_tab.h +$(O)vision.o: vision.c $(HACK_H) $(O)weapon.o: weapon.c $(HACK_H) $(O)were.o: were.c $(HACK_H) $(O)wield.o: wield.c $(HACK_H) diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc index 22b9c2d5a..01cd6f595 100644 --- a/sys/winnt/Makefile.msc +++ b/sys/winnt/Makefile.msc @@ -315,9 +315,9 @@ VOBJ22 = $(O)sit.o $(O)sounds.o $(O)sp_lev.o $(O)spell.o VOBJ23 = $(O)steal.o $(O)steed.o $(O)symbols.o $(O)sys.o VOBJ24 = $(O)teleport.o $(O)timeout.o $(O)topten.o $(O)track.o VOBJ25 = $(O)trap.o $(O)u_init.o $(O)uhitm.o $(O)vault.o -VOBJ26 = $(O)vis_tab.o $(O)vision.o $(O)weapon.o $(O)were.o -VOBJ27 = $(O)wield.o $(O)windows.o $(O)wizard.o $(O)worm.o -VOBJ28 = $(O)worn.o $(O)write.o $(O)zap.o +VOBJ26 = $(O)vision.o $(O)weapon.o $(O)were.o $(O)wield.o +VOBJ27 = $(O)windows.o $(O)wizard.o $(O)worm.o $(O)worn.o +VOBJ28 = $(O)write.o $(O)zap.o LUAOBJ = $(O)nhlua.o $(O)nhlsel.o $(O)nhlobj.o @@ -1030,7 +1030,7 @@ $(O)sp_lev.tag: echo sp_levs done > $(O)sp_lev.tag $(O)utility.tag: $(INCL)\nhlua.h $(INCL)\date.h $(INCL)\onames.h $(INCL)\pm.h \ - $(SRC)\vis_tab.c $(INCL)\vis_tab.h $(TILEUTIL16) + $(TILEUTIL16) @echo utilities made >$@ @echo utilities made. @@ -1096,12 +1096,6 @@ $(INCL)\onames.h : $(U)makedefs.exe $(INCL)\pm.h : $(U)makedefs.exe $(U)makedefs -p -$(INCL)\vis_tab.h: $(U)makedefs.exe - $(U)makedefs -z - -$(SRC)\vis_tab.c: $(U)makedefs.exe - $(U)makedefs -z - #========================================== # uudecode utility and uuencoded targets #========================================== @@ -1630,8 +1624,6 @@ spotless: clean if exist $(INCL)\date.h del $(INCL)\date.h if exist $(INCL)\onames.h del $(INCL)\onames.h if exist $(INCL)\pm.h del $(INCL)\pm.h - if exist $(INCL)\vis_tab.h del $(INCL)\vis_tab.h - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c if exist $(SRC)\tile.c del $(SRC)\tile.c if exist $(U)*.lnk del $(U)*.lnk if exist $(U)*.map del $(U)*.map @@ -1643,7 +1635,6 @@ spotless: clean if exist $(DAT)\dlb.lst del $(DAT)\dlb.lst if exist $(DAT)\porthelp del $(DAT)\porthelp if exist $(O)sp_lev.tag del $(O)sp_lev.tag - if exist $(SRC)\vis_tab.c del $(SRC)\vis_tab.c if exist nhdat$(NHV). del nhdat$(NHV). if exist $(O)obj.tag del $(O)obj.tag if exist $(O)gamedir.tag del $(O)gamedir.tag @@ -1937,7 +1928,6 @@ $(O)wc_chainout.o: ..\win\chain\wc_chainout.c $(HACK_H) # @$(cc) $(cflagsBuild) -Fo$@ ..\win\chain\wc_chainout.c $(O)wc_trace.o: ..\win\chain\wc_trace.c $(HACK_H) $(INCL)\func_tab.h # @$(cc) $(cflagsBuild) -Fo$@ ..\win\chain\wc_trace.c -$(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)\vis_tab.h $(O)allmain.o: allmain.c $(HACK_H) $(O)alloc.o: alloc.c $(CONFIG_H) $(O)apply.o: apply.c $(HACK_H) @@ -2055,7 +2045,7 @@ $(O)uhitm.o: uhitm.c $(HACK_H) $(O)vault.o: vault.c $(HACK_H) $(O)version.o: version.c $(HACK_H) $(INCL)\dlb.h $(INCL)\date.h @$(cc) $(cflagsBuild) $(CROSSCOMPILE) $(CROSSCOMPILE_TARGET) -Fo$@ version.c -$(O)vision.o: vision.c $(HACK_H) $(INCL)\vis_tab.h +$(O)vision.o: vision.c $(HACK_H) $(O)weapon.o: weapon.c $(HACK_H) $(O)were.o: were.c $(HACK_H) $(O)wield.o: wield.c $(HACK_H) diff --git a/win/win32/vs/NetHackW.vcxproj b/win/win32/vs/NetHackW.vcxproj index 994b7213e..ff9571efd 100644 --- a/win/win32/vs/NetHackW.vcxproj +++ b/win/win32/vs/NetHackW.vcxproj @@ -190,7 +190,6 @@ - @@ -313,7 +312,6 @@ - diff --git a/win/win32/vs/aftermakedefs.proj b/win/win32/vs/aftermakedefs.proj index af5fd489c..4ce136bb9 100644 --- a/win/win32/vs/aftermakedefs.proj +++ b/win/win32/vs/aftermakedefs.proj @@ -7,7 +7,6 @@ - diff --git a/win/win32/vs/files.props b/win/win32/vs/files.props index c388b6898..5aeae719e 100644 --- a/win/win32/vs/files.props +++ b/win/win32/vs/files.props @@ -8,9 +8,6 @@ - - - From 9c6a65f49b45dbdc81768b9b510f4d768bcfce4b Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 29 Dec 2020 14:34:37 -0800 Subject: [PATCH 703/708] fix github issue #432 - bad sanity check The block of sanity check code that is causing impossible warnings about the Wizard mimicking a monster was initially only used for furniture and objects specifically because of the Wizard. When it got extended to check for mimicking monsters, an exception for the Wizard was needed but not added. Fixes #432 --- doc/fixes37.0 | 3 ++- src/mon.c | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index a50894cb1..cacc868b0 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.402 $ $NHDT-Date: 1608933417 2020/12/25 21:56:57 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.410 $ $NHDT-Date: 1609281273 2020/12/29 22:34:33 $ General Fixes and Modified Features ----------------------------------- @@ -465,6 +465,7 @@ tilemap.c wasn't building if STATUES_LOOK_LIKE_MONSTERS wasn't defined; also, ensure that monster female name variation ends up as a female during ^G arbitrate when there is a conflict between gender term (male or female) and a gender-tied monster name (cavewoman) during ^G; gender term wins +wizard mode sanity check complained about Wizard's clone mimicking a monster curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support diff --git a/src/mon.c b/src/mon.c index 1b13ddbd6..346b21c0f 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mon.c $NHDT-Date: 1609075599 2020/12/27 13:26:39 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.363 $ */ +/* NetHack 3.7 mon.c $NHDT-Date: 1609281168 2020/12/29 22:32:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.364 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -150,9 +150,12 @@ const char *msg; impossible( "mimic%s concealed as %s despite Prot-from-shape-changers %s", is_mimic ? "" : "ker", what, msg); - /* pet's quickmimic can take on furniture and object shapes, - but only until the pet finishes eating a mimic corpse */ - if (!(is_mimic || mtmp->meating)) + /* the Wizard's clone after "double trouble" starts out mimicking + some other monster; pet's quickmimic effect can temporarily take + on furniture, object, or monster shape, but only until the pet + finishes eating a mimic corpse */ + if (!(is_mimic || mtmp->meating + || (mtmp->iswiz && M_AP_TYPE(mtmp) == M_AP_MONSTER))) impossible("non-mimic (%s) posing as %s (%s)", mptr->pmnames[NEUTRAL], what, msg); #if 0 /* mimics who end up in strange locations do still hide while there */ From 00c9277cfeb2c5be72845ae332e8820c1f1101f8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 29 Dec 2020 17:49:30 -0500 Subject: [PATCH 704/708] usage of whichpm in new gender code required a null ptr guard --- src/read.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/read.c b/src/read.c index a6fa79b1a..fa790026f 100644 --- a/src/read.c +++ b/src/read.c @@ -2591,7 +2591,8 @@ struct _create_particular_data *d; if (d->genderconf == -1) { /* no confict exists between explicit gender term and the specified monster name */ - if (d->fem != -1 && !is_male(whichpm) && !is_female(whichpm)) + if (d->fem != -1 + && (!whichpm || (!is_male(whichpm) && !is_female(whichpm)))) mmflags |= (d->fem == FEMALE) ? MM_FEMALE : (d->fem == MALE) ? MM_MALE : 0; } else { From a1678d62f362f3d5dc9a7740e5ce17a5737aa119 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 29 Dec 2020 18:02:01 -0500 Subject: [PATCH 705/708] fixes entry for PR #433 Closes #433 --- doc/fixes37.0 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes37.0 b/doc/fixes37.0 index cacc868b0..1e7d25d56 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -466,6 +466,8 @@ ensure that monster female name variation ends up as a female during ^G arbitrate when there is a conflict between gender term (male or female) and a gender-tied monster name (cavewoman) during ^G; gender term wins wizard mode sanity check complained about Wizard's clone mimicking a monster +new ^G gender-naming handling code required a guard against null permonst + pointer which could occur under some circumstances curses: 'msg_window' option wasn't functional for curses unless the binary also included tty support From b735122c2ccb8a704d838c689bb08e65d2b42894 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 29 Dec 2020 15:44:06 -0800 Subject: [PATCH 706/708] ^G prompting Make the initial prompt for ^G be less verbose. Only expand to the verbose form if a second or further try is needed. Also, remove an orphan comment about is_male() and is_female(). --- src/read.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/read.c b/src/read.c index fa790026f..5d2c47bb3 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1608846072 2020/12/24 21:41:12 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.207 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1609285441 2020/12/29 23:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.213 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2625,7 +2625,6 @@ struct _create_particular_data *d; continue; } mx = mtmp->mx, my = mtmp->my; - /* 'is_FOO()' ought to be called 'always_FOO()' */ if (d->maketame) { (void) tamedog(mtmp, (struct obj *) 0); } else if (d->makepeaceful || d->makehostile) { @@ -2691,12 +2690,15 @@ struct _create_particular_data *d; boolean create_particular() { - char buf[BUFSZ] = DUMMY, *bufp; - int tryct = 5; +#define CP_TRYLIM 5 struct _create_particular_data d; + char *bufp, buf[BUFSZ], prompt[QBUFSZ]; + int tryct = CP_TRYLIM; + buf[0] = '\0'; /* for EDIT_GETLIN */ + Strcpy(prompt, "Create what kind of monster?"); do { - getlin("Create what kind of monster? [type the name or symbol]", buf); + getlin(prompt, buf); bufp = mungspaces(buf); if (*bufp == '\033') return FALSE; @@ -2706,6 +2708,9 @@ create_particular() /* no good; try again... */ pline("I've never heard of such monsters."); + /* when a second try is needed, expand the prompt */ + if (tryct == CP_TRYLIM - 1) + Strcat(prompt, " [type name or symbol]"); } while (--tryct > 0); if (!tryct) From a4e7646f4c8bc92bf4bd2e53df6cf363a146419d Mon Sep 17 00:00:00 2001 From: Dean Luick Date: Mon, 28 Dec 2020 19:16:34 -0600 Subject: [PATCH 707/708] Remove src and unix VISION_TABLES Remove all references to the unused vision tables in the main source and unix build. Leave makedefs able to generate the vision tables. makdefs will be cleaned up in a different commit, once all ports are clear of dependencies. --- include/config.h | 15 +- include/extern.h | 6 - src/vision.c | 715 +----------------------------------------- sys/unix/Makefile.src | 17 +- sys/unix/Makefile.utl | 4 - 5 files changed, 13 insertions(+), 744 deletions(-) diff --git a/include/config.h b/include/config.h index 1d762d99e..d9e4fbb25 100644 --- a/include/config.h +++ b/include/config.h @@ -457,24 +457,15 @@ typedef unsigned char uchar; /* #define STRNCMPI */ /* compiler/library has the strncmpi function */ /* - * There are various choices for the NetHack vision system. There is a - * choice of two algorithms with the same behavior. Defining VISION_TABLES - * creates huge (60K) tables at compile time, drastically increasing data - * size, but runs slightly faster than the alternate algorithm. (MSDOS in - * particular cannot tolerate the increase in data size; other systems can - * flip a coin weighted to local conditions.) + * Vision choices. * - * If VISION_TABLES is not defined, things will be faster if you can use - * MACRO_CPATH. Some cpps, however, cannot deal with the size of the - * functions that have been macroized. + * Things will be faster if you can use MACRO_CPATH. Some cpps, however, + * cannot deal with the size of the functions that have been macroized. */ -/* #define VISION_TABLES */ /* use vision tables generated at compile time */ -#ifndef VISION_TABLES #ifndef NO_MACRO_CPATH #define MACRO_CPATH /* use clear_path macros instead of functions */ #endif -#endif #if !defined(MAC) #if !defined(NOCLIPPING) diff --git a/include/extern.h b/include/extern.h index 0d9b86a52..7b1c7800b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2852,12 +2852,6 @@ E int FDECL(assign_videoshades, (char *)); E int FDECL(assign_videocolors, (char *)); #endif -/* ### vis_tab.c ### */ - -#ifdef VISION_TABLES -E void NDECL(vis_tab_init); -#endif - /* ### vision.c ### */ E void NDECL(vision_init); diff --git a/src/vision.c b/src/vision.c index 3136cf0e3..9d291ae40 100644 --- a/src/vision.c +++ b/src/vision.c @@ -127,15 +127,8 @@ vision_init() g.vision_full_recalc = 0; (void) memset((genericptr_t) could_see, 0, sizeof(could_see)); - /* Initialize the vision algorithm (currently C or D). */ + /* Initialize the vision algorithm (currently C). */ view_init(); - -#ifdef VISION_TABLES - /* Note: this initializer doesn't do anything except guarantee that - * we're linked properly. - */ - vis_tab_init(); -#endif } /* @@ -1083,11 +1076,9 @@ int row, col; /*==========================================================================*/ /*==========================================================================*/ -/* Use either algorithm C or D. See the config.h for more details. - * =========*/ /* - * Variables local to both Algorithms C and D. + * Variables local to Algorithm C. */ static int start_row; static int start_col; @@ -1100,7 +1091,7 @@ static void FDECL((*vis_func), (int, int, genericptr_t)); static genericptr_t varg; /* - * Both Algorithms C and D use the following macros. + * Algorithm C uses the following macros: * * good_row(z) - Return TRUE if the argument is a legal row. * set_cs(rowp,col) - Set the local could see array. @@ -1583,704 +1574,6 @@ cleardone: return (boolean) result; } -#ifdef VISION_TABLES -/*==========================================================================*\ - GENERAL LINE OF SIGHT - Algorithm D -\*==========================================================================*/ - -/* - * Indicate caller for the shadow routines. - */ -#define FROM_RIGHT 0 -#define FROM_LEFT 1 - -/* - * Include the table definitions. - */ -#include "vis_tab.h" - -/* 3D table pointers. */ -static close2d *close_dy[CLOSE_MAX_BC_DY]; -static far2d *far_dy[FAR_MAX_BC_DY]; - -static void FDECL(right_side, (int, int, int, int, int, - int, int, const xchar *)); -static void FDECL(left_side, (int, int, int, int, int, int, int, - const xchar *)); -static int FDECL(close_shadow, (int, int, int, int)); -static int FDECL(far_shadow, (int, int, int, int)); - -/* - * Initialize algorithm D's table pointers. If we don't have these, - * then we do 3D table lookups. Verrrry slow. - */ -static void -view_init() -{ - int i; - - for (i = 0; i < CLOSE_MAX_BC_DY; i++) - close_dy[i] = &close_table[i]; - - for (i = 0; i < FAR_MAX_BC_DY; i++) - far_dy[i] = &far_table[i]; -} - -/* - * If the far table has an entry of OFF_TABLE, then the far block prevents - * us from seeing the location just above/below it. I.e. the first visible - * location is one *before* the block. - */ -#define OFF_TABLE 0xff - -static int -close_shadow(side, this_row, block_row, block_col) -int side, this_row, block_row, block_col; -{ - register int sdy, sdx, pdy, offset; - - /* - * If on the same column (block_row = -1), then we can see it. - */ - if (block_row < 0) - return block_col; - - /* Take explicit absolute values. Adjust. */ - if ((sdy = (start_row - block_row)) < 0) - sdy = -sdy; - --sdy; /* src dy */ - if ((sdx = (start_col - block_col)) < 0) - sdx = -sdx; /* src dx */ - if ((pdy = (block_row - this_row)) < 0) - pdy = -pdy; /* point dy */ - - if (sdy < 0 || sdy >= CLOSE_MAX_SB_DY || sdx >= CLOSE_MAX_SB_DX - || pdy >= CLOSE_MAX_BC_DY) { - impossible("close_shadow: bad value"); - return block_col; - } - offset = close_dy[sdy]->close[sdx][pdy]; - if (side == FROM_RIGHT) - return block_col + offset; - - return block_col - offset; -} - -static int -far_shadow(side, this_row, block_row, block_col) -int side, this_row, block_row, block_col; -{ - register int sdy, sdx, pdy, offset; - - /* - * Take care of a bug that shows up only on the borders. - * - * If the block is beyond the border, then the row is negative. Return - * the block's column number (should be 0 or COLNO-1). - * - * Could easily have the column be -1, but then wouldn't know if it was - * the left or right border. - */ - if (block_row < 0) - return block_col; - - /* Take explicit absolute values. Adjust. */ - if ((sdy = (start_row - block_row)) < 0) - sdy = -sdy; /* src dy */ - if ((sdx = (start_col - block_col)) < 0) - sdx = -sdx; - --sdx; /* src dx */ - if ((pdy = (block_row - this_row)) < 0) - pdy = -pdy; - --pdy; /* point dy */ - - if (sdy >= FAR_MAX_SB_DY || sdx < 0 || sdx >= FAR_MAX_SB_DX || pdy < 0 - || pdy >= FAR_MAX_BC_DY) { - impossible("far_shadow: bad value"); - return block_col; - } - if ((offset = far_dy[sdy]->far_q[sdx][pdy]) == OFF_TABLE) - offset = -1; - if (side == FROM_RIGHT) - return block_col + offset; - - return block_col - offset; -} - -/* - * right_side() - * - * Figure out what could be seen on the right side of the source. - */ -static void -right_side(row, cb_row, cb_col, fb_row, fb_col, left, right_mark, limits) -int row; /* current row */ -int cb_row, cb_col; /* close block row and col */ -int fb_row, fb_col; /* far block row and col */ -int left; /* left mark of the previous row */ -int right_mark; /* right mark of previous row */ -xchar *limits; /* points at range limit for current row, or NULL */ -{ - register int i; - register char *rowp = NULL; - int hit_stone = 0; - int left_shadow, right_shadow, loc_right; - int lblock_col; /* local block column (current row) */ - int nrow, deeper; - char *row_min = NULL; /* left most */ - char *row_max = NULL; /* right most */ - int lim_max; /* right most limit of circle */ - - nrow = row + step; - deeper = good_row(nrow) && (!limits || (*limits >= *(limits + 1))); - if (!vis_func) { - rowp = cs_rows[row]; - row_min = &cs_left[row]; - row_max = &cs_right[row]; - } - if (limits) { - lim_max = start_col + *limits; - if (lim_max > COLNO - 1) - lim_max = COLNO - 1; - if (right_mark > lim_max) - right_mark = lim_max; - limits++; /* prepare for next row */ - } else - lim_max = COLNO - 1; - - /* - * Get the left shadow from the close block. This value could be - * illegal. - */ - left_shadow = close_shadow(FROM_RIGHT, row, cb_row, cb_col); - - /* - * Mark all stone walls as seen before the left shadow. All this work - * for a special case. - * - * NOTE. With the addition of this code in here, it is now *required* - * for the algorithm to work correctly. If this is commented out, - * change the above assignment so that left and not left_shadow is the - * variable that gets the shadow. - */ - while (left <= right_mark) { - loc_right = right_ptrs[row][left]; - if (loc_right > lim_max) - loc_right = lim_max; - if (viz_clear_rows[row][left]) { - if (loc_right >= left_shadow) { - left = left_shadow; /* opening ends beyond shadow */ - break; - } - left = loc_right; - loc_right = right_ptrs[row][left]; - if (loc_right > lim_max) - loc_right = lim_max; - if (left == loc_right) - return; /* boundary */ - - /* Shadow covers opening, beyond right mark */ - if (left == right_mark && left_shadow > right_mark) - return; - } - - if (loc_right > right_mark) /* can't see stone beyond the mark */ - loc_right = right_mark; - - if (vis_func) { - for (i = left; i <= loc_right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = left; i <= loc_right; i++) - set_cs(rowp, i); - set_min(left); - set_max(loc_right); - } - - if (loc_right == right_mark) - return; /* all stone */ - if (loc_right >= left_shadow) - hit_stone = 1; - left = loc_right + 1; - } - - /* - * At this point we are at the first visible clear spot on or beyond - * the left shadow, unless the left shadow is an illegal value. If we - * have "hit stone" then we have a stone wall just to our left. - */ - - /* - * Get the right shadow. Make sure that it is a legal value. - */ - if ((right_shadow = far_shadow(FROM_RIGHT, row, fb_row, fb_col)) >= COLNO) - right_shadow = COLNO - 1; - /* - * Make vertical walls work the way we want them. In this case, we - * note when the close block blocks the column just above/beneath - * it (right_shadow < fb_col [actually right_shadow == fb_col-1]). If - * the location is filled, then we want to see it, so we put the - * right shadow back (same as fb_col). - */ - if (right_shadow < fb_col && !viz_clear_rows[row][fb_col]) - right_shadow = fb_col; - if (right_shadow > lim_max) - right_shadow = lim_max; - - /* - * Main loop. Within the range of sight of the previous row, mark all - * stone walls as seen. Follow open areas recursively. - */ - while (left <= right_mark) { - /* Get the far right of the opening or wall */ - loc_right = right_ptrs[row][left]; - if (loc_right > lim_max) - loc_right = lim_max; - - if (!viz_clear_rows[row][left]) { - hit_stone = 1; /* use stone on this row as close block */ - /* - * We can see all of the wall until the next open spot or the - * start of the shadow caused by the far block (right). - * - * Can't see stone beyond the right mark. - */ - if (loc_right > right_mark) - loc_right = right_mark; - - if (vis_func) { - for (i = left; i <= loc_right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = left; i <= loc_right; i++) - set_cs(rowp, i); - set_min(left); - set_max(loc_right); - } - - if (loc_right == right_mark) - return; /* hit the end */ - left = loc_right + 1; - loc_right = right_ptrs[row][left]; - if (loc_right > lim_max) - loc_right = lim_max; - /* fall through... we know at least one position is visible */ - } - - /* - * We are in an opening. - * - * If this is the first open spot since the could see area (this is - * true if we have hit stone), get the shadow generated by the wall - * just to our left. - */ - if (hit_stone) { - lblock_col = left - 1; /* local block column */ - left = close_shadow(FROM_RIGHT, row, row, lblock_col); - if (left > lim_max) - break; /* off the end */ - } - - /* - * Check if the shadow covers the opening. If it does, then - * move to end of the opening. A shadow generated on from a - * wall on this row does *not* cover the wall on the right - * of the opening. - */ - if (left >= loc_right) { - if (loc_right == lim_max) { /* boundary */ - if (left == lim_max) { - if (vis_func) - (*vis_func)(lim_max, row, varg); - else { - set_cs(rowp, lim_max); /* last pos */ - set_max(lim_max); - } - } - return; /* done */ - } - left = loc_right; - continue; - } - - /* - * If the far wall of the opening (loc_right) is closer than the - * shadow limit imposed by the far block (right) then use the far - * wall as our new far block when we recurse. - * - * If the limits are the same, and the far block really exists - * (fb_row >= 0) then do the same as above. - * - * Normally, the check would be for the far wall being closer OR EQUAL - * to the shadow limit. However, there is a bug that arises from the - * fact that the clear area pointers end in an open space (if it - * exists) on a boundary. This then makes a far block exist where it - * shouldn't --- on a boundary. To get around that, I had to - * introduce the concept of a non-existent far block (when the - * row < 0). Next I have to check for it. Here is where that check - * exists. - */ - if ((loc_right < right_shadow) - || (fb_row >= 0 && loc_right == right_shadow)) { - if (vis_func) { - for (i = left; i <= loc_right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = left; i <= loc_right; i++) - set_cs(rowp, i); - set_min(left); - set_max(loc_right); - } - - if (deeper) { - if (hit_stone) - right_side(nrow, row, lblock_col, row, loc_right, left, - loc_right, limits); - else - right_side(nrow, cb_row, cb_col, row, loc_right, left, - loc_right, limits); - } - - /* - * The following line, setting hit_stone, is needed for those - * walls that are only 1 wide. If hit stone is *not* set and - * the stone is only one wide, then the close block is the old - * one instead one on the current row. A way around having to - * set it here is to make left = loc_right (not loc_right+1) and - * let the outer loop take care of it. However, if we do that - * then we then have to check for boundary conditions here as - * well. - */ - hit_stone = 1; - - left = loc_right + 1; - - /* - * The opening extends beyond the right mark. This means that - * the next far block is the current far block. - */ - } else { - if (vis_func) { - for (i = left; i <= right_shadow; i++) - (*vis_func)(i, row, varg); - } else { - for (i = left; i <= right_shadow; i++) - set_cs(rowp, i); - set_min(left); - set_max(right_shadow); - } - - if (deeper) { - if (hit_stone) - right_side(nrow, row, lblock_col, fb_row, fb_col, left, - right_shadow, limits); - else - right_side(nrow, cb_row, cb_col, fb_row, fb_col, left, - right_shadow, limits); - } - - return; /* we're outta here */ - } - } -} - -/* - * left_side() - * - * This routine is the mirror image of right_side(). Please see right_side() - * for blow by blow comments. - */ -static void -left_side(row, cb_row, cb_col, fb_row, fb_col, left_mark, right, limits) -int row; /* the current row */ -int cb_row, cb_col; /* close block row and col */ -int fb_row, fb_col; /* far block row and col */ -int left_mark; /* left mark of previous row */ -int right; /* right mark of the previous row */ -const xchar *limits; -{ - register int i; - register char *rowp = NULL; - int hit_stone = 0; - int left_shadow, right_shadow, loc_left; - int lblock_col; /* local block column (current row) */ - int nrow, deeper; - char *row_min = NULL; /* left most */ - char *row_max = NULL; /* right most */ - int lim_min; - - nrow = row + step; - deeper = good_row(nrow) && (!limits || (*limits >= *(limits + 1))); - if (!vis_func) { - rowp = cs_rows[row]; - row_min = &cs_left[row]; - row_max = &cs_right[row]; - } - if (limits) { - lim_min = start_col - *limits; - if (lim_min < 0) - lim_min = 0; - if (left_mark < lim_min) - left_mark = lim_min; - limits++; /* prepare for next row */ - } else - lim_min = 0; - - /* This value could be illegal. */ - right_shadow = close_shadow(FROM_LEFT, row, cb_row, cb_col); - - while (right >= left_mark) { - loc_left = left_ptrs[row][right]; - if (loc_left < lim_min) - loc_left = lim_min; - if (viz_clear_rows[row][right]) { - if (loc_left <= right_shadow) { - right = right_shadow; /* opening ends beyond shadow */ - break; - } - right = loc_left; - loc_left = left_ptrs[row][right]; - if (loc_left < lim_min) - loc_left = lim_min; - if (right == loc_left) - return; /* boundary */ - } - - if (loc_left < left_mark) /* can't see beyond the left mark */ - loc_left = left_mark; - - if (vis_func) { - for (i = loc_left; i <= right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = loc_left; i <= right; i++) - set_cs(rowp, i); - set_min(loc_left); - set_max(right); - } - - if (loc_left == left_mark) - return; /* all stone */ - if (loc_left <= right_shadow) - hit_stone = 1; - right = loc_left - 1; - } - - /* At first visible clear spot on or beyond the right shadow. */ - - if ((left_shadow = far_shadow(FROM_LEFT, row, fb_row, fb_col)) < 0) - left_shadow = 0; - - /* Do vertical walls as we want. */ - if (left_shadow > fb_col && !viz_clear_rows[row][fb_col]) - left_shadow = fb_col; - if (left_shadow < lim_min) - left_shadow = lim_min; - - while (right >= left_mark) { - loc_left = left_ptrs[row][right]; - - if (!viz_clear_rows[row][right]) { - hit_stone = 1; /* use stone on this row as close block */ - - /* We can only see walls until the left mark */ - if (loc_left < left_mark) - loc_left = left_mark; - - if (vis_func) { - for (i = loc_left; i <= right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = loc_left; i <= right; i++) - set_cs(rowp, i); - set_min(loc_left); - set_max(right); - } - - if (loc_left == left_mark) - return; /* hit end */ - right = loc_left - 1; - loc_left = left_ptrs[row][right]; - if (loc_left < lim_min) - loc_left = lim_min; - /* fall through...*/ - } - - /* We are in an opening. */ - if (hit_stone) { - lblock_col = right + 1; /* stone block (local) */ - right = close_shadow(FROM_LEFT, row, row, lblock_col); - if (right < lim_min) - return; /* off the end */ - } - - /* Check if the shadow covers the opening. */ - if (right <= loc_left) { - /* Make a boundary condition work. */ - if (loc_left == lim_min) { /* at boundary */ - if (right == lim_min) { - if (vis_func) - (*vis_func)(lim_min, row, varg); - else { - set_cs(rowp, lim_min); /* caught the last pos */ - set_min(lim_min); - } - } - return; /* and break out the loop */ - } - - right = loc_left; - continue; - } - - /* If the far wall of the opening is closer than the shadow limit. */ - if ((loc_left > left_shadow) - || (fb_row >= 0 && loc_left == left_shadow)) { - if (vis_func) { - for (i = loc_left; i <= right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = loc_left; i <= right; i++) - set_cs(rowp, i); - set_min(loc_left); - set_max(right); - } - - if (deeper) { - if (hit_stone) - left_side(nrow, row, lblock_col, row, loc_left, loc_left, - right, limits); - else - left_side(nrow, cb_row, cb_col, row, loc_left, loc_left, - right, limits); - } - - hit_stone = 1; /* needed for walls of width 1 */ - right = loc_left - 1; - - /* The opening extends beyond the left mark. */ - } else { - if (vis_func) { - for (i = left_shadow; i <= right; i++) - (*vis_func)(i, row, varg); - } else { - for (i = left_shadow; i <= right; i++) - set_cs(rowp, i); - set_min(left_shadow); - set_max(right); - } - - if (deeper) { - if (hit_stone) - left_side(nrow, row, lblock_col, fb_row, fb_col, - left_shadow, right, limits); - else - left_side(nrow, cb_row, cb_col, fb_row, fb_col, - left_shadow, right, limits); - } - - return; /* we're outta here */ - } - } -} - -/* - * view_from - * - * Calculate a view from the given location. Initialize and fill a - * ROWNOxCOLNO array (could_see) with all the locations that could be - * seen from the source location. Initialize and fill the left most - * and right most boundaries of what could be seen. - */ -static void -view_from(srow, scol, loc_cs_rows, left_most, right_most, range, func, arg) -int srow, scol; /* source row and column */ -xchar **loc_cs_rows; /* could_see array (row pointers) */ -xchar *left_most, *right_most; /* limits of what could be seen */ -int range; /* 0 if unlimited */ -void FDECL((*func), (int, int, genericptr_t)); -genericptr_t arg; -{ - register int i; - char *rowp; - int nrow, left, right, left_row, right_row; - char *limits; - - /* Set globals for near_shadow(), far_shadow(), etc. to use. */ - start_col = scol; - start_row = srow; - cs_rows = loc_cs_rows; - cs_left = left_most; - cs_right = right_most; - vis_func = func; - varg = arg; - - /* Find the left and right limits of sight on the starting row. */ - if (viz_clear_rows[srow][scol]) { - left = left_ptrs[srow][scol]; - right = right_ptrs[srow][scol]; - } else { - left = (!scol) ? 0 : (viz_clear_rows[srow][scol - 1] - ? left_ptrs[srow][scol - 1] - : scol - 1); - right = (scol == COLNO - 1) ? COLNO - 1 - : (viz_clear_rows[srow][scol + 1] - ? right_ptrs[srow][scol + 1] - : scol + 1); - } - - if (range) { - if (range > MAX_RADIUS || range < 1) - panic("view_from called with range %d", range); - limits = circle_ptr(range) + 1; /* start at next row */ - if (left < scol - range) - left = scol - range; - if (right > scol + range) - right = scol + range; - } else - limits = (char *) 0; - - if (func) { - for (i = left; i <= right; i++) - (*func)(i, srow, arg); - } else { - /* Row optimization */ - rowp = cs_rows[srow]; - - /* We know that we can see our row. */ - for (i = left; i <= right; i++) - set_cs(rowp, i); - cs_left[srow] = left; - cs_right[srow] = right; - } - - /* The far block has a row number of -1 if we are on an edge. */ - right_row = (right == COLNO - 1) ? -1 : srow; - left_row = (!left) ? -1 : srow; - - /* - * Check what could be seen in quadrants. - */ - if ((nrow = srow + 1) < ROWNO) { - step = 1; /* move down */ - if (scol < COLNO - 1) - right_side(nrow, -1, scol, right_row, right, scol, right, limits); - if (scol) - left_side(nrow, -1, scol, left_row, left, left, scol, limits); - } - - if ((nrow = srow - 1) >= 0) { - step = -1; /* move up */ - if (scol < COLNO - 1) - right_side(nrow, -1, scol, right_row, right, scol, right, limits); - if (scol) - left_side(nrow, -1, scol, left_row, left, left, scol, limits); - } -} - -#else /*===== End of algorithm D =====*/ - /*==========================================================================*\ GENERAL LINE OF SIGHT Algorithm C @@ -2723,7 +2016,7 @@ genericptr_t arg; } } -#endif /*===== End of algorithm C =====*/ +/*===== End of algorithm C =====*/ /* * AREA OF EFFECT "ENGINE" diff --git a/sys/unix/Makefile.src b/sys/unix/Makefile.src index 76631e60f..315d7dd28 100644 --- a/sys/unix/Makefile.src +++ b/sys/unix/Makefile.src @@ -534,7 +534,7 @@ SYSCSRC = ../sys/share/pcmain.c ../sys/share/pcsys.c \ SYSCXXSRC = ../sys/share/cppregex.cpp # generated source files (tile.c is handled separately via WINxxxSRC) -GENCSRC = vis_tab.c #tile.c +GENCSRC = #tile.c # all windowing-system-dependent .c (for dependencies and such) WINCSRC = $(WINTTYSRC) $(WINCURSESSRC) $(WINX11SRC) $(WINGNOMESRC) $(WINGEMSRC) $(WINSHIMSRC) @@ -554,7 +554,7 @@ VERSOURCES = $(HACKCSRC) $(SYSSRC) $(WINSRC) $(CHAINSRC) $(GENCSRC) CSOURCES = $(HACKCSRC) $(SYSCSRC) $(WINCSRC) $(CHAINSRC) $(GENCSRC) -# all .h files except date.h, onames.h, pm.h, and vis_tab.h which would +# all .h files except date.h, onames.h, and pm.h which would # cause dependency loops if run through "make depend" # and dgn_file.h, special level & dungeon files. # @@ -569,7 +569,7 @@ HACKINCL = align.h artifact.h artilist.h attrib.h botl.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 -HSOURCES = $(HACKINCL) date.h onames.h pm.h vis_tab.h dgn_file.h +HSOURCES = $(HACKINCL) date.h onames.h pm.h dgn_file.h # the following .o's _must_ be made before any others (for makedefs) FIRSTOBJ = monst.o objects.o @@ -610,7 +610,7 @@ HOBJ = $(TARGETPFX)allmain.o $(TARGETPFX)alloc.o \ $(TARGETPFX)steed.o $(TARGETPFX)teleport.o $(TARGETPFX)timeout.o \ $(TARGETPFX)topten.o $(TARGETPFX)track.o $(TARGETPFX)trap.o \ $(TARGETPFX)u_init.o $(TARGETPFX)uhitm.o $(TARGETPFX)vault.o \ - $(TARGETPFX)vision.o $(TARGETPFX)vis_tab.o $(TARGETPFX)weapon.o \ + $(TARGETPFX)vision.o $(TARGETPFX)weapon.o \ $(TARGETPFX)were.o $(TARGETPFX)wield.o $(TARGETPFX)windows.o \ $(TARGETPFX)wizard.o $(TARGETPFX)worm.o $(TARGETPFX)worn.o \ $(TARGETPFX)write.o $(TARGETPFX)zap.o \ @@ -753,10 +753,6 @@ $(MAKEDEFS): $(FIRSTOBJ) \ @( cd ../util ; $(MAKE) ../include/onames.h ) ../include/pm.h: $(MAKEDEFS) ../include/onames.h @( cd ../util ; $(MAKE) ../include/pm.h ) -../include/vis_tab.h: $(MAKEDEFS) ../include/pm.h - @( cd ../util ; $(MAKE) ../include/vis_tab.h ) -# makedefs -z makes both vis_tab.h and vis_tab.c, but writes the .h first -vis_tab.c: ../include/vis_tab.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) @@ -804,7 +800,7 @@ spotless: clean -rm -f a.out core $(GAMEBIN) Sys* -rm -f ../lib/lua/liblua.a ../include/nhlua.h -rm -f ../include/date.h ../include/onames.h ../include/pm.h - -rm -f ../include/vis_tab.h vis_tab.c tile.c *.moc + -rm -f tile.c *.moc -rm -f ../win/gnome/gn_rip.h package: @@ -1065,7 +1061,6 @@ $(TARGETPFX)wc_chainout.o: ../win/chain/wc_chainout.c $(HACK_H) $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_chainout.c $(TARGETPFX)wc_trace.o: ../win/chain/wc_trace.c $(HACK_H) ../include/func_tab.h $(TARGET_CC) $(TARGET_CFLAGS) -c -o $@ ../win/chain/wc_trace.c -$(TARGETPFX)vis_tab.o: vis_tab.c $(CONFIG_H) ../include/vis_tab.h $(TARGETPFX)allmain.o: allmain.c $(HACK_H) $(TARGETPFX)alloc.o: alloc.c $(CONFIG_H) $(TARGETPFX)apply.o: apply.c $(HACK_H) @@ -1187,7 +1182,7 @@ $(TARGETPFX)u_init.o: u_init.c $(HACK_H) $(TARGETPFX)uhitm.o: uhitm.c $(HACK_H) $(TARGETPFX)vault.o: vault.c $(HACK_H) $(TARGETPFX)version.o: version.c $(HACK_H) ../include/dlb.h ../include/date.h -$(TARGETPFX)vision.o: vision.c $(HACK_H) ../include/vis_tab.h +$(TARGETPFX)vision.o: vision.c $(HACK_H) $(TARGETPFX)weapon.o: weapon.c $(HACK_H) $(TARGETPFX)were.o: were.c $(HACK_H) $(TARGETPFX)wield.o: wield.c $(HACK_H) diff --git a/sys/unix/Makefile.utl b/sys/unix/Makefile.utl index 0e763c62c..38ef8bebf 100644 --- a/sys/unix/Makefile.utl +++ b/sys/unix/Makefile.utl @@ -221,10 +221,6 @@ mdgreph: mdgrep.pl ./makedefs -o ../include/pm.h: makedefs ./makedefs -p -../include/vis_tab.h: makedefs - ./makedefs -z -# makedefs -z makes both vis_tab.h and vis_tab.c, but writes the .h first -../src/vis_tab.c: ../include/vis_tab.h lintdefs: @lint -axbh -I../include -DLINT $(MAKESRC) $(CMONOBJ) | sed '/_flsbuf/d' From ef4efdb1256b8ef68d3009ac144817e46ef75ecd Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 30 Dec 2020 02:24:59 -0800 Subject: [PATCH 708/708] ^G prompting revisited CP_TRYLIM-1 was the right value when the prompt augmentation was at the top of the loop before the first prompt, but should been changed to CP_TRYLIM when that got moved to the bottom of the loop. First prompt: |Create what kind of monster? Second and subsequent prompts if first attempt is unsuccessful: |Create what kind of monster? [type name or symbol] Prior to this fix, the shorter prompt was being used on the first and second tries and not switching to the longer one until the third. --- src/read.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/read.c b/src/read.c index 5d2c47bb3..130259ee3 100644 --- a/src/read.c +++ b/src/read.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 read.c $NHDT-Date: 1609285441 2020/12/29 23:44:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.213 $ */ +/* NetHack 3.7 read.c $NHDT-Date: 1609323865 2020/12/30 10:24:25 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.214 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2709,7 +2709,7 @@ create_particular() /* no good; try again... */ pline("I've never heard of such monsters."); /* when a second try is needed, expand the prompt */ - if (tryct == CP_TRYLIM - 1) + if (tryct == CP_TRYLIM) Strcat(prompt, " [type name or symbol]"); } while (--tryct > 0);