diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 3a543bfe9..06097ca17 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1,11 +1,11 @@ -.\" $NHDT-Branch: master $:$NHDT-Revision: 1.164 $ $NHDT-Date: 1432473674 2015/05/24 13:21:14 $ +.\" $NHDT-Branch: master $:$NHDT-Revision: 1.170 $ $NHDT-Date: 1433125736 2015/06/01 02:28:56 $ .ds h0 "NetHack Guidebook .ds h1 .ds h2 % .ds vr "NetHack 3.6 .ds f0 "\*(vr .ds f1 -.ds f2 "May 30, 2015 +.ds f2 "May 31, 2015 .\" labeled paragraph start (should be part of tmac.n, but I don't want to .\" make changes to that file) .\" .PS word @@ -56,8 +56,15 @@ A Guide to the Mazes of Menace (Guidebook for NetHack) .au -Eric S. Raymond -(Edited and expanded for 3.6) +Original version - Eric S. Raymond +(Edited and expanded for 3.6 by Michael Allison, Mike Stephenson) +.hn 1 +Preface - Version 3.6 +\fBThis version of the game is special in a particular way. Near the end of +the development of 3.6, one of the significant inspirations for many of the +humorous and fun features found in the game, author \fBTerry Pratchett\fP, +passed away. We have dedicated this version of the game in his memory. +.pg .hn 1 Introduction @@ -3330,16 +3337,17 @@ joined the NetHack development team. .pg In September 2014, an interim snapshot of the code under development was released publicly by other parties. Since that code was a work-in-progress -and had not gone through a period of debugging, 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 -devteam'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. +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 devteam'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. .pg -In January 2015, preparation began for the release of NetHack 3.6. The 3.6 -version merges work done by the development team since the previous release with -some of the beloved community patches. Many bugs were fixed and some code was -restructured. +In November 2014, preparation began for the release of NetHack 3.6. The 3.6 +version merges work done by the development team since the previous release +with some of the beloved community patches. Many bugs were fixed and a +large amount of code was restructured. .pg \fBThe development team, as well as \fBSteve VanDevender\fP and \fBKevin Smolkowski\fP ensured that NetHack 3.6.0 continued to operate on @@ -3352,11 +3360,6 @@ maintained the port of NetHack 3.6.0 for Mac. \fBAlex Kompel\fP, and \fBDion Nicolaas\fP maintained the port of NetHack 3.6.0 for Microsoft Windows. .pg -\fBThis version of the game is special in a particular way. Near the end of -the development of 3.6, one of the significant inspirations for many of the -humorous and fun features found in the game, author \fBTerry Pratchett\fP, -passed away. This version of the game is dedicated to him. -.pg The official NetHack web site is maintained by \fBKen Lorber\fP at http://www.nethack.org/. .pg SHOUT-OUTS diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index fd92b1ce4..80cbac507 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -44,12 +44,21 @@ \Large Guidebook for {\it NetHack\/}} %.au -\author{Eric S. Raymond\\ -(Edited and expanded for 3.6)} -\date{May 30, 2015} +\author{Original version - Eric S. Raymond\\ +(Edited and expanded for 3.6 by Michael Allison, Mike Stephenson)} +\date{May 31, 2015} \maketitle +%.hn 1 +\section{Preface - Version 3.6} +%.pg +This version of the game is special in a particular way. Near the end of +the development of 3.6, one of the significant inspirations for many of the +humorous and fun features found in the game, author {\it Terry Pratchett}, +passed away. We have dedicated this version of the game in his memory. + +%.pg %.hn 1 \section{Introduction} @@ -4021,18 +4030,20 @@ joined the NetHack development team. \medskip In September 2014, an interim snapshot of the code under development was released publicly by other parties. Since that code was a work-in-progress -and had not gone through a period of debugging, 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 -devteam'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. +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 devteam'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. %.pg \medskip -In January 2015, preparation began for the release of NetHack 3.6. -The 3.6 version merges work done by the development team since the previous -release with some of the beloved community patches. Many bugs were fixed -and some code was restructured. +In November 2014, preparation began for the release of NetHack 3.6. The 3.6 +version merges work done by the development team since the previous release +with some of the beloved community patches. Many bugs were fixed and a +large amount of code was restructured. + %.pg \medskip @@ -4050,13 +4061,6 @@ maintained the port of NetHack 3.6.0 for Mac. {\it Alex Kompel}, and {\it Dion Nicolaas} maintained the port of NetHack 3.6.0 for Microsoft Windows. -%.pg -\medskip -This version of the game is special in a particular way. Near the end of -the development of 3.6, one of the significant inspirations for many of the -humorous and fun features found in the game, author {\it Terry Pratchett}, -passed away. This version of the game is dedicated to him. - %.pg \medskip \nd The official NetHack web site is maintained by {\it Ken Lorber} at diff --git a/include/artifact.h b/include/artifact.h index 6bdfab945..4b7f55d6d 100644 --- a/include/artifact.h +++ b/include/artifact.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 artifact.h $NHDT-Date: 1432512779 2015/05/25 00:12:59 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 artifact.h $NHDT-Date: 1433050871 2015/05/31 05:41:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -52,6 +52,7 @@ struct artifact { short role; /* character role associated with */ short race; /* character race associated with */ long cost; /* price when sold to hero (default 100 x base cost) */ + char acolor; /* color to use if artifact 'glows' */ }; /* invoked properties with special powers */ diff --git a/include/artilist.h b/include/artilist.h index bde9d5b52..b3510386c 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -1,19 +1,19 @@ -/* NetHack 3.6 artilist.h $NHDT-Date: 1432946531 2015/05/30 00:42:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */ +/* NetHack 3.6 artilist.h $NHDT-Date: 1433050874 2015/05/31 05:41:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.16 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ #ifdef MAKEDEFS_C /* in makedefs.c, all we care about is the list of names */ -#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, cost) nam +#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, cost, clr) nam static const char *artifact_names[] = { #else /* in artifact.c, set up the actual artifact list structure */ -#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, cost) \ - { \ - typ, nam, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, cost \ +#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, cost, clr) \ + { \ + typ, nam, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, cost, clr \ } /* clang-format off */ @@ -41,29 +41,30 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { /* dummy element #0, so that all interesting indices are non-zero */ A("", STRANGE_OBJECT, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, - NON_PM, NON_PM, 0L), + NON_PM, NON_PM, 0L, NO_COLOR), A("Excalibur", LONG_SWORD, (SPFX_NOGEN | SPFX_RESTR | SPFX_SEEK | SPFX_DEFN | SPFX_INTEL | SPFX_SEARCH), 0, 0, PHYS(5, 10), DRLI(0, 0), NO_CARY, 0, A_LAWFUL, PM_KNIGHT, NON_PM, - 4000L), + 4000L, NO_COLOR), /* * Stormbringer only has a 2 because it can drain a level, * providing 8 more. */ A("Stormbringer", RUNESWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN | SPFX_INTEL | SPFX_DRLI), 0, 0, - DRLI(5, 2), DRLI(0, 0), NO_CARY, 0, A_CHAOTIC, NON_PM, NON_PM, 8000L), + DRLI(5, 2), DRLI(0, 0), NO_CARY, 0, A_CHAOTIC, NON_PM, NON_PM, 8000L, + NO_COLOR), /* * Mjollnir will return to the hand of the wielder when thrown * if the wielder is a Valkyrie wearing Gauntlets of Power. */ A("Mjollnir", WAR_HAMMER, /* Mjo:llnir */ (SPFX_RESTR | SPFX_ATTK), 0, 0, ELEC(5, 24), NO_DFNS, NO_CARY, 0, - A_NEUTRAL, PM_VALKYRIE, NON_PM, 4000L), + A_NEUTRAL, PM_VALKYRIE, NON_PM, 4000L, NO_COLOR), A("Cleaver", BATTLE_AXE, SPFX_RESTR, 0, 0, PHYS(3, 6), NO_DFNS, NO_CARY, - 0, A_NEUTRAL, PM_BARBARIAN, NON_PM, 1500L), + 0, A_NEUTRAL, PM_BARBARIAN, NON_PM, 1500L, NO_COLOR), /* * Grimtooth glows in warning when elves are present, but its @@ -72,7 +73,7 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { */ A("Grimtooth", ORCISH_DAGGER, (SPFX_RESTR | SPFX_WARN | SPFX_DFLAG2), 0, M2_ELF, PHYS(2, 6), NO_DFNS, - NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ORC, 300L), + NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ORC, 300L, CLR_RED), /* * Orcrist and Sting have same alignment as elves. * @@ -81,51 +82,62 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { * Sting and Orcrist will warn of M2_ORC monsters. */ A("Orcrist", ELVEN_BROADSWORD, (SPFX_WARN | SPFX_DFLAG2), 0, M2_ORC, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 2000L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 2000L, + CLR_BRIGHT_BLUE), /* bright blue is actually light blue */ A("Sting", ELVEN_DAGGER, (SPFX_WARN | SPFX_DFLAG2), 0, M2_ORC, PHYS(5, 0), - NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 800L), + NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 800L, CLR_BRIGHT_BLUE), /* * Magicbane is a bit different! Its magic fanfare * unbalances victims in addition to doing some damage. */ A("Magicbane", ATHAME, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0, STUN(3, 4), DFNS(AD_MAGM), NO_CARY, 0, A_NEUTRAL, PM_WIZARD, NON_PM, - 3500L), + 3500L, NO_COLOR), A("Frost Brand", LONG_SWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0, - COLD(5, 0), COLD(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L), + COLD(5, 0), COLD(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L, + NO_COLOR), A("Fire Brand", LONG_SWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0, - FIRE(5, 0), FIRE(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L), + FIRE(5, 0), FIRE(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L, + NO_COLOR), A("Dragonbane", BROADSWORD, (SPFX_RESTR | SPFX_DCLAS), 0, S_DRAGON, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 500L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 500L, + NO_COLOR), A("Demonbane", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_DEMON, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 2500L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 2500L, + NO_COLOR), A("Werebane", SILVER_SABER, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_WERE, - PHYS(5, 0), DFNS(AD_WERE), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 1500L), + PHYS(5, 0), DFNS(AD_WERE), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 1500L, + NO_COLOR), A("Grayswandir", SILVER_SABER, (SPFX_RESTR | SPFX_HALRES), 0, 0, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 8000L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 8000L, + NO_COLOR), A("Giantslayer", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_GIANT, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 200L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 200L, + NO_COLOR), A("Ogresmasher", WAR_HAMMER, (SPFX_RESTR | SPFX_DCLAS), 0, S_OGRE, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L, + NO_COLOR), A("Trollsbane", MORNING_STAR, (SPFX_RESTR | SPFX_DCLAS), 0, S_TROLL, - PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L), + PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L, + NO_COLOR), /* * Two problems: 1) doesn't let trolls regenerate heads, * 2) doesn't give unusual message for 2-headed monsters (but * allowing those at all causes more problems than worth the effort). */ A("Vorpal Blade", LONG_SWORD, (SPFX_RESTR | SPFX_BEHEAD), 0, 0, - PHYS(5, 1), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 4000L), + PHYS(5, 1), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 4000L, + NO_COLOR), /* * Ah, never shall I forget the cry, * or the shriek that shrieked he, @@ -135,10 +147,11 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { * (From Sir W.S. Gilbert's "The Mikado") */ A("Snickersnee", KATANA, SPFX_RESTR, 0, 0, PHYS(0, 8), NO_DFNS, NO_CARY, - 0, A_LAWFUL, PM_SAMURAI, NON_PM, 1200L), + 0, A_LAWFUL, PM_SAMURAI, NON_PM, 1200L, NO_COLOR), A("Sunsword", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_UNDEAD, - PHYS(5, 0), DFNS(AD_BLND), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 1500L), + PHYS(5, 0), DFNS(AD_BLND), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 1500L, + NO_COLOR), /* * The artifacts for the quest dungeon, all self-willed. @@ -147,81 +160,84 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { A("The Orb of Detection", CRYSTAL_BALL, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), (SPFX_ESP | SPFX_HSPDAM), 0, NO_ATTK, NO_DFNS, CARY(AD_MAGM), INVIS, A_LAWFUL, PM_ARCHEOLOGIST, - NON_PM, 2500L), + NON_PM, 2500L, NO_COLOR), A("The Heart of Ahriman", LUCKSTONE, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), SPFX_STLTH, 0, /* this stone does double damage if used as a projectile weapon */ PHYS(5, 0), NO_DFNS, NO_CARY, LEVITATION, A_NEUTRAL, PM_BARBARIAN, - NON_PM, 2500L), + NON_PM, 2500L, NO_COLOR), 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_CAVEMAN, NON_PM, 2500L, + NO_COLOR), #if 0 /* OBSOLETE */ A("The Palantir of Westernesse", CRYSTAL_BALL, (SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL), (SPFX_ESP|SPFX_REGEN|SPFX_HSPDAM), 0, NO_ATTK, NO_DFNS, NO_CARY, - TAMING, A_CHAOTIC, NON_PM , PM_ELF, 8000L ), + TAMING, A_CHAOTIC, NON_PM , PM_ELF, 8000L, NO_COLOR ), #endif A("The Staff of Aesculapius", QUARTERSTAFF, (SPFX_NOGEN | SPFX_RESTR | SPFX_ATTK | SPFX_INTEL | SPFX_DRLI | SPFX_REGEN), 0, 0, DRLI(0, 0), DRLI(0, 0), NO_CARY, HEALING, A_NEUTRAL, PM_HEALER, - NON_PM, 5000L), + NON_PM, 5000L, NO_COLOR), A("The Magic Mirror of Merlin", MIRROR, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK), SPFX_ESP, 0, - NO_ATTK, NO_DFNS, CARY(AD_MAGM), 0, A_LAWFUL, PM_KNIGHT, NON_PM, 1500L), + NO_ATTK, NO_DFNS, CARY(AD_MAGM), 0, A_LAWFUL, PM_KNIGHT, NON_PM, 1500L, + NO_COLOR), A("The Eyes of the Overworld", LENSES, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_XRAY), 0, 0, NO_ATTK, DFNS(AD_MAGM), NO_CARY, ENLIGHTENING, A_NEUTRAL, PM_MONK, NON_PM, - 2500L), + 2500L, NO_COLOR), 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), + PM_PRIEST, NON_PM, 2000L, NO_COLOR), A("The Longbow of Diana", BOW, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_REFLECT), SPFX_ESP, 0, PHYS(5, 0), NO_DFNS, NO_CARY, CREATE_AMMO, A_CHAOTIC, PM_RANGER, NON_PM, - 4000L), + 4000L, NO_COLOR), A("The Master Key of Thievery", SKELETON_KEY, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK), (SPFX_WARN | SPFX_TCTRL | SPFX_HPHDAM), 0, NO_ATTK, NO_DFNS, NO_CARY, - UNTRAP, A_CHAOTIC, PM_ROGUE, NON_PM, 3500L), + UNTRAP, A_CHAOTIC, PM_ROGUE, NON_PM, 3500L, NO_COLOR), A("The Tsurugi of Muramasa", TSURUGI, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_BEHEAD | SPFX_LUCK | SPFX_PROTECT), 0, 0, PHYS(0, 8), NO_DFNS, NO_CARY, 0, A_LAWFUL, PM_SAMURAI, NON_PM, - 4500L), + 4500L, NO_COLOR), A("The Platinum Yendorian Express Card", CREDIT_CARD, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DEFN), (SPFX_ESP | SPFX_HSPDAM), 0, NO_ATTK, NO_DFNS, CARY(AD_MAGM), - CHARGE_OBJ, A_NEUTRAL, PM_TOURIST, NON_PM, 7000L), + CHARGE_OBJ, A_NEUTRAL, PM_TOURIST, NON_PM, 7000L, NO_COLOR), A("The Orb of Fate", CRYSTAL_BALL, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_LUCK), (SPFX_WARN | SPFX_HSPDAM | SPFX_HPHDAM), 0, NO_ATTK, NO_DFNS, NO_CARY, - LEV_TELE, A_NEUTRAL, PM_VALKYRIE, NON_PM, 3500L), + LEV_TELE, A_NEUTRAL, PM_VALKYRIE, NON_PM, 3500L, NO_COLOR), A("The Eye of the Aethiopica", AMULET_OF_ESP, (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), (SPFX_EREGEN | SPFX_HSPDAM), 0, NO_ATTK, DFNS(AD_MAGM), NO_CARY, CREATE_PORTAL, A_NEUTRAL, PM_WIZARD, - NON_PM, 4000L), + NON_PM, 4000L, NO_COLOR), /* * terminator; otyp must be zero */ - A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L) + A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L, + 0) /* 0 is CLR_BLACK rather than NO_COLOR but it doesn't matter here */ }; /* artilist[] (or artifact_names[]) */ diff --git a/include/extern.h b/include/extern.h index 7be7d667f..9df9080e9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -88,6 +88,7 @@ E long FDECL(spec_m2, (struct obj *)); E boolean FDECL(artifact_has_invprop, (struct obj *, UCHAR_P)); E long FDECL(arti_cost, (struct obj *)); E struct obj *FDECL(what_gives, (long *)); +E const char *FDECL(glow_color, (int)); E void FDECL(Sting_effects, (int)); E int FDECL(retouch_object, (struct obj **, BOOLEAN_P)); E void FDECL(retouch_equipment, (int)); @@ -1631,6 +1632,7 @@ E void FDECL(parsesymbols, (char *)); E struct symparse *FDECL(match_sym, (char *)); E void NDECL(set_playmode); E int FDECL(sym_val, (char *)); +E const char *FDECL(clr2colorname, (int)); E boolean FDECL(add_menu_coloring, (char *)); E boolean FDECL(get_menu_coloring, (char *, int *, int *)); E void NDECL(free_menu_coloring); diff --git a/src/artifact.c b/src/artifact.c index 89ca6109a..0377c3ac8 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 artifact.c $NHDT-Date: 1432946531 2015/05/30 00:42:11 $ $NHDT-Branch: master $:$NHDT-Revision: 1.89 $ */ +/* NetHack 3.6 artifact.c $NHDT-Date: 1433060653 2015/05/31 08:24:13 $ $NHDT-Branch: master $:$NHDT-Revision: 1.91 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1784,10 +1784,12 @@ long *abil; unsigned long spfx; long wornbits; long wornmask = - (W_ARM | W_ARMC | W_ARMH | W_ARMS | W_ARMG | W_ARMF | W_WEP | W_QUIVER - | W_SWAPWEP | W_ART | W_ARTI | W_AMUL | W_RINGL | W_RINGR | W_TOOL - | W_BALL | W_CHAIN | W_SADDLE | W_ARMU); + (W_ARM | W_ARMC | W_ARMH | W_ARMS | W_ARMG | W_ARMF | W_ARMU + | W_AMUL | W_RINGL | W_RINGR | W_TOOL | W_ART | W_ARTI); + /* [do W_ART and W_ARTI actually belong here?] */ + if (u.twoweap) + wornmask |= W_SWAPWEP; dtyp = abil_to_adtyp(abil); spfx = abil_to_spfx(abil); wornbits = (wornmask & *abil); @@ -1795,14 +1797,21 @@ long *abil; for (obj = invent; obj; obj = obj->nobj) { if (obj->oartifact && ((abil != &EWarn_of_mon) || context.warntype.obj)) { - register const struct artifact *art = get_artifact(obj); + const struct artifact *art = get_artifact(obj); + if (art) { - if (dtyp - && (art->cary.adtyp == dtyp || art->defn.adtyp == dtyp)) - return obj; - if (spfx && ((art->cspfx & spfx) == spfx - || (art->spfx & spfx) == spfx)) - return obj; + if (dtyp) { + if (art->cary.adtyp == dtyp || art->defn.adtyp == dtyp) + return obj; + } + if (spfx) { + /* property conferred when carried */ + if ((art->cspfx & spfx) == spfx) + return obj; + /* property conferred when wielded or worn */ + if ((art->spfx & spfx) == spfx && obj->owornmask) + return obj; + } } } else { if (wornbits && wornbits == (wornmask & obj->owornmask)) @@ -1812,32 +1821,39 @@ long *abil; return (struct obj *) 0; } +const char * +glow_color(arti_indx) +int arti_indx; +{ + int colornum = artilist[arti_indx].acolor; + const char *colorstr = clr2colorname(colornum); + + return hcolor(colorstr); +} + /* use for warning "glow" for Sting, Orcrist, and Grimtooth */ void Sting_effects(orc_count) -int orc_count; +int orc_count; /* new count (warn_obj_cnt is old count); -1 is a flag value */ { if (uwep && (uwep->oartifact == ART_STING || uwep->oartifact == ART_ORCRIST || uwep->oartifact == ART_GRIMTOOTH)) { - /* - * Toggling blindness in between warning messages can result in - * Sting glows light blue! [...] Sting stops quivering. - * or - * Sting quivers slightly. [...] Sting stops glowing. - * but addressing that is far more trouble than it's worth. - */ - if (orc_count > 0 && warn_obj_cnt == 0) { + if (orc_count == -1 && warn_obj_cnt > 0) { + /* -1 means that blindess has just been toggled; give a + 'continue' message that eventual 'stop' message will match */ + pline("%s is %s.", bare_artifactname(uwep), + !Blind ? "glowing" : "quivering"); + } else if (orc_count > 0 && warn_obj_cnt == 0) { + /* 'start' message */ if (!Blind) pline("%s %s %s!", bare_artifactname(uwep), - otense(uwep, "glow"), - hcolor((uwep->oartifact == ART_GRIMTOOTH) - ? NH_RED - : NH_LIGHT_BLUE)); + otense(uwep, "glow"), glow_color(uwep->oartifact)); else pline("%s quivers slightly.", bare_artifactname(uwep)); } else if (orc_count == 0 && warn_obj_cnt > 0) { + /* 'stop' message */ pline("%s stops %s.", bare_artifactname(uwep), !Blind ? "glowing" : "quivering"); } diff --git a/src/cmd.c b/src/cmd.c index 15200c504..a56c9491e 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1432512764 2015/05/25 00:12:44 $ $NHDT-Branch: master $:$NHDT-Revision: 1.192 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1433050877 2015/05/31 05:41:17 $ $NHDT-Branch: master $:$NHDT-Revision: 1.193 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1952,10 +1952,9 @@ int final; you_are("warned", from_what(WARNING)); if (Warn_of_mon && context.warntype.obj) { Sprintf(buf, "aware of the presence of %s", - (context.warntype.obj & M2_ORC) - ? "orcs" - : (context.warntype.obj & M2_DEMON) ? "demons" - : something); + (context.warntype.obj & M2_ORC) ? "orcs" + : (context.warntype.obj & M2_ELF) ? "elves" + : (context.warntype.obj & M2_DEMON) ? "demons" : something); you_are(buf, from_what(WARN_OF_MON)); } if (Warn_of_mon && context.warntype.polyd) { diff --git a/src/makemon.c b/src/makemon.c index ea0ca262c..242675340 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -697,7 +697,7 @@ register struct monst *mtmp; } break; case S_GNOME: - if (!rn2((In_mines(&u.uz) ? 5 : 10))) { + if (!rn2((In_mines(&u.uz) && in_mklev) ? 20 : 60)) { otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE, TRUE, FALSE); otmp->quan = 1; otmp->owt = weight(otmp); diff --git a/src/mondata.c b/src/mondata.c index 55bc459a3..40c0ed81b 100644 --- a/src/mondata.c +++ b/src/mondata.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mondata.c $NHDT-Date: 1432512762 2015/05/25 00:12:42 $ $NHDT-Branch: master $:$NHDT-Revision: 1.53 $ */ +/* NetHack 3.6 mondata.c $NHDT-Date: 1433117881 2015/06/01 00:18:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.54 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -6,6 +6,7 @@ /* These routines provide basic data for any type of monster. */ +/* set up an individual monster's base type (initial creation, shapechange) */ void set_mon_data(mon, ptr, flag) struct monst *mon; @@ -23,6 +24,7 @@ int flag; return; } +/* does monster-type have any attack for a specific type of damage? */ struct attack * attacktype_fordmg(ptr, atyp, dtyp) struct permonst *ptr; @@ -33,10 +35,10 @@ int atyp, dtyp; for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++) if (a->aatyp == atyp && (dtyp == AD_ANY || a->adtyp == dtyp)) return a; - return (struct attack *) 0; } +/* does monster-type have a paricular type of attack */ boolean attacktype(ptr, atyp) struct permonst *ptr; @@ -45,7 +47,7 @@ int atyp; return attacktype_fordmg(ptr, atyp, AD_ANY) ? TRUE : FALSE; } -/* returns TRUE if monster doesn't attack, FALSE if it does */ +/* returns True if monster doesn't attack, False if it does */ boolean noattacks(ptr) struct permonst *ptr; @@ -62,34 +64,40 @@ struct permonst *ptr; if (mattk[i].aatyp) return FALSE; } - return TRUE; } +/* does monster-type transform into something else when petrified? */ boolean poly_when_stoned(ptr) struct permonst *ptr; { - return ((boolean)(is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] - && !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD))); + /* non-stone golems turn into stone golems unless latter is genocided */ + return (boolean) (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] + && !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD)); /* allow G_EXTINCT */ } +/* returns True if monster is drain-life resistant */ boolean -resists_drli(mon) /* returns TRUE if monster is drain-life resistant */ +resists_drli(mon) struct monst *mon; { struct permonst *ptr = mon->data; - struct obj *wep = ((mon == &youmonst) ? uwep : MON_WEP(mon)); + struct obj *wep; - return (boolean)(is_undead(ptr) || is_demon(ptr) || is_were(ptr) || - /* is_were() doesn't handle hero in human form */ - (mon == &youmonst && u.ulycn >= LOW_PM) - || ptr == &mons[PM_DEATH] || is_vampshifter(mon) - || (wep && wep->oartifact && defends(AD_DRLI, wep))); + if (is_undead(ptr) || is_demon(ptr) || is_were(ptr) + /* is_were() doesn't handle hero in human form */ + || (mon == &youmonst && u.ulycn >= LOW_PM) + || ptr == &mons[PM_DEATH] || is_vampshifter(mon)) + return TRUE; + wep = (mon == &youmonst) ? uwep : MON_WEP(mon); + return (boolean) (wep && wep->oartifact && defends(AD_DRLI, wep)); } -boolean resists_magm(mon) /* TRUE if monster is magic-missile resistant */ +/* True if monster is magic-missile (actually, general magic) resistant */ +boolean +resists_magm(mon) struct monst *mon; { struct permonst *ptr = mon->data; @@ -121,7 +129,7 @@ struct monst *mon; return FALSE; } -/* TRUE iff monster is resistant to light-induced blindness */ +/* True iff monster is resistant to light-induced blindness */ boolean resists_blnd(mon) struct monst *mon; @@ -159,8 +167,8 @@ struct monst *mon; return FALSE; } -/* TRUE iff monster can be blinded by the given attack */ -/* Note: may return TRUE when mdef is blind (e.g. new cream-pie attack) */ +/* True iff monster can be blinded by the given attack; + note: may return True when mdef is blind (e.g. new cream-pie attack) */ boolean can_blnd(magr, mdef, aatyp, obj) struct monst *magr; /* NULL == no specific aggressor */ @@ -248,7 +256,9 @@ struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */ return TRUE; } -boolean ranged_attk(ptr) /* returns TRUE if monster can attack at range */ +/* returns True if monster can attack at range */ +boolean +ranged_attk(ptr) struct permonst *ptr; { register int i, atyp; @@ -267,39 +277,41 @@ struct permonst *ptr; if ((atk_mask & (1L << atyp)) != 0L) return TRUE; } - return FALSE; } +/* True if specific monster is especially affected by silver weapons */ boolean mon_hates_silver(mon) struct monst *mon; { - return (is_vampshifter(mon) || hates_silver(mon->data)); + return (boolean) (is_vampshifter(mon) || hates_silver(mon->data)); } -/* TRUE if monster is especially affected by silver weapons */ +/* True if monster-type is especially affected by silver weapons */ boolean hates_silver(ptr) register struct permonst *ptr; { - return (boolean)(is_were(ptr) || ptr->mlet == S_VAMPIRE || is_demon(ptr) - || ptr == &mons[PM_SHADE] - || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU])); + return (boolean) (is_were(ptr) || ptr->mlet == S_VAMPIRE || is_demon(ptr) + || ptr == &mons[PM_SHADE] + || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU])); } -/* true iff the type of monster pass through iron bars */ +/* True iff the type of monster pass through iron bars */ boolean passes_bars(mptr) 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) - || (slithy(mptr) && !bigmonst(mptr))); + return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr) + || is_whirly(mptr) || verysmall(mptr) + || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST) + || (slithy(mptr) && !bigmonst(mptr))); } -boolean can_blow(mtmp) /* returns TRUE if monster can blow (whistle, etc) */ +/* returns True if monster can blow (whistle, etc) */ +boolean +can_blow(mtmp) register struct monst *mtmp; { if ((is_silent(mtmp->data) || mtmp->data->msound == MS_BUZZ) @@ -311,7 +323,9 @@ register struct monst *mtmp; return TRUE; } -boolean can_be_strangled(mon) /* TRUE if mon is vulnerable to strangulation */ +/* True if mon is vulnerable to strangulation */ +boolean +can_be_strangled(mon) struct monst *mon; { struct obj *mamul; @@ -339,41 +353,54 @@ struct monst *mon; || ((mamul = which_armor(mon, W_AMUL)) != 0 && (mamul->otyp == AMULET_OF_MAGICAL_BREATHING))); } - return (boolean)(!nobrainer || !nonbreathing); + return (boolean) (!nobrainer || !nonbreathing); } -boolean can_track(ptr) /* returns TRUE if monster can track well */ +/* returns True if monster can track well */ +boolean +can_track(ptr) register struct permonst *ptr; { if (uwep && uwep->oartifact == ART_EXCALIBUR) return TRUE; else - return ((boolean) haseyes(ptr)); + return (boolean) haseyes(ptr); } -boolean sliparm(ptr) /* creature will slide out of armor */ +/* creature will slide out of armor */ +boolean +sliparm(ptr) register struct permonst *ptr; { - return ((boolean)(is_whirly(ptr) || ptr->msize <= MZ_SMALL - || noncorporeal(ptr))); + return (boolean) (is_whirly(ptr) || ptr->msize <= MZ_SMALL + || noncorporeal(ptr)); } -boolean breakarm(ptr) /* creature will break out of armor */ +/* creature will break out of armor */ +boolean +breakarm(ptr) register struct permonst *ptr; { - return ((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr)) || - /* special cases of humanoids that cannot wear body armor */ - ptr == &mons[PM_MARILITH] || ptr == &mons[PM_WINGED_GARGOYLE]) - && !sliparm(ptr)); + if (sliparm(ptr)) + return FALSE; + + return (boolean) (bigmonst(ptr) + || (ptr->msize > MZ_SMALL && !humanoid(ptr)) + /* special cases of humanoids that cannot wear suits */ + || ptr == &mons[PM_MARILITH] + || ptr == &mons[PM_WINGED_GARGOYLE]); } -boolean sticks(ptr) /* creature sticks other creatures it hits */ +/* creature sticks other creatures it hits */ +boolean +sticks(ptr) register struct permonst *ptr; { - return ((boolean)(dmgtype(ptr, AD_STCK) || dmgtype(ptr, AD_WRAP) - || attacktype(ptr, AT_HUGS))); + return (boolean) (dmgtype(ptr, AD_STCK) || dmgtype(ptr, AD_WRAP) + || attacktype(ptr, AT_HUGS)); } +/* some monster-types can't vomit */ boolean cantvomit(ptr) struct permonst *ptr; @@ -408,6 +435,8 @@ struct permonst *ptr; return 0; } +/* does monster-type deal out a particular type of damage from a particular + type of attack? */ struct attack * dmgtype_fromattack(ptr, dtyp, atyp) struct permonst *ptr; @@ -418,10 +447,10 @@ int dtyp, atyp; for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++) if (a->adtyp == dtyp && (atyp == AT_ANY || a->aatyp == atyp)) return a; - return (struct attack *) 0; } +/* does monster-type deal out a particular type of damage from any attack */ boolean dmgtype(ptr, dtyp) struct permonst *ptr; @@ -431,7 +460,7 @@ int dtyp; } /* returns the maximum damage a defender can do to the attacker via - * a passive defense */ + a passive defense */ int max_passive_dmg(mdef, magr) register struct monst *mdef, *magr; @@ -552,8 +581,8 @@ struct permonst *pm1, *pm2; return (let2 == S_GHOST); } else if (is_undead(pm2)) return FALSE; - /* check for monsters--mainly animals--which grow into more mature forms - */ + + /* check for monsters which grow into more mature forms */ if (let1 == let2) { int m1 = monsndx(pm1), m2 = monsndx(pm2), prv, nxt; @@ -575,6 +604,7 @@ struct permonst *pm1, *pm2; || pm2 == &mons[PM_WINGED_GARGOYLE]); if (pm1 == &mons[PM_KILLER_BEE] || pm1 == &mons[PM_QUEEN_BEE]) return (pm2 == &mons[PM_KILLER_BEE] || pm2 == &mons[PM_QUEEN_BEE]); + if (is_longworm(pm1)) return is_longworm(pm2); /* handles tail */ /* [currently there's no reason to bother matching up @@ -583,7 +613,9 @@ struct permonst *pm1, *pm2; return FALSE; } -int monsndx(ptr) /* return an index into the mons array */ +/* return an index into the mons array */ +int +monsndx(ptr) struct permonst *ptr; { register int i; @@ -594,8 +626,7 @@ struct permonst *ptr; fmt_ptr((genericptr_t) ptr)); return NON_PM; /* will not get here */ } - - return (i); + return i; } /* for handling alternate spellings */ @@ -675,7 +706,7 @@ const char *in_str; { "invisible stalker", PM_STALKER }, { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */ { "halfling", PM_HOBBIT }, /* potential guess for polyself */ - /* Hyphenated names */ + /* Hyphenated names */ { "ki rin", PM_KI_RIN }, { "uruk hai", PM_URUK_HAI }, { "orc captain", PM_ORC_CAPTAIN }, @@ -710,11 +741,13 @@ const char *in_str; for (len = 0, i = LOW_PM; i < NUMMONS; i++) { register int m_i_len = strlen(mons[i].mname); + if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) { if (m_i_len == slen) { return i; /* exact match */ } else if (slen > m_i_len - && (str[m_i_len] == ' ' || !strcmpi(&str[m_i_len], "s") + && (str[m_i_len] == ' ' + || !strcmpi(&str[m_i_len], "s") || !strncmpi(&str[m_i_len], "s ", 2) || !strcmpi(&str[m_i_len], "'") || !strncmpi(&str[m_i_len], "' ", 2) @@ -834,8 +867,8 @@ register struct monst *mtmp; return mtmp->female; } -/* Like gender(), but lower animals and such are still "it". */ -/* This is the one we want to use when printing messages. */ +/* Like gender(), but lower animals and such are still "it". + This is the one we want to use when printing messages. */ int pronoun_gender(mtmp) register struct monst *mtmp; @@ -843,9 +876,7 @@ register struct monst *mtmp; if (is_neuter(mtmp->data) || !canspotmon(mtmp)) return 2; return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ) - || type_is_pname(mtmp->data)) - ? (int) mtmp->female - : 2; + || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2; } /* used for nearby monsters when you go to another level */ @@ -859,15 +890,13 @@ struct monst *mtmp; /* Wizard with Amulet won't bother trying to follow across levels */ if (mtmp->iswiz && mon_has_amulet(mtmp)) return FALSE; - /* some monsters will follow even while intending to flee from you */ if (mtmp->mtame || mtmp->iswiz || is_fshk(mtmp)) return TRUE; - /* stalking types follow, but won't when fleeing unless you hold the Amulet */ - return (boolean)((mtmp->data->mflags2 & M2_STALK) - && (!mtmp->mflee || u.uhave.amulet)); + return (boolean) ((mtmp->data->mflags2 & M2_STALK) + && (!mtmp->mflee || u.uhave.amulet)); } static const short grownups[][2] = { @@ -947,29 +976,14 @@ int little_to_big(montype) int montype; { -#ifndef AIXPS2_BUG register int i; for (i = 0; grownups[i][0] >= LOW_PM; i++) - if (montype == grownups[i][0]) - return grownups[i][1]; + if (montype == grownups[i][0]) { + montype = grownups[i][1]; + break; + } return montype; -#else - /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop, - * and causes segmentation faults at runtime. (The problem does not - * occur if -O is not used.) - * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990 - */ - int i; - int monvalue; - - monvalue = montype; - for (i = 0; grownups[i][0] >= LOW_PM; i++) - if (montype == grownups[i][0]) - monvalue = grownups[i][1]; - - return monvalue; -#endif } int @@ -979,8 +993,10 @@ int montype; register int i; for (i = 0; grownups[i][0] >= LOW_PM; i++) - if (montype == grownups[i][1]) - return grownups[i][0]; + if (montype == grownups[i][1]) { + montype = grownups[i][0]; + break; + } return montype; } @@ -994,9 +1010,9 @@ raceptr(mtmp) struct monst *mtmp; { if (mtmp == &youmonst && !Upolyd) - return (&mons[urace.malenum]); + return &mons[urace.malenum]; else - return (mtmp->data); + return mtmp->data; } static const char *levitate[4] = { "float", "Float", "wobble", "Wobble" }; @@ -1014,21 +1030,14 @@ const char *def; { int capitalize = (*def == highc(*def)); - return (is_floater(ptr) - ? levitate[capitalize] - : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) - ? flys[capitalize] - : (is_flyer(ptr) && ptr->msize > MZ_SMALL) - ? flyl[capitalize] - : slithy(ptr) - ? slither[capitalize] - : amorphous(ptr) - ? ooze[capitalize] - : !ptr->mmove - ? immobile[capitalize] - : nolimbs(ptr) - ? crawl[capitalize] - : def); + return (is_floater(ptr) ? levitate[capitalize] + : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize] + : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize] + : slithy(ptr) ? slither[capitalize] + : amorphous(ptr) ? ooze[capitalize] + : !ptr->mmove ? immobile[capitalize] + : nolimbs(ptr) ? crawl[capitalize] + : def); } const char * @@ -1038,25 +1047,17 @@ const char *def; { int capitalize = 2 + (*def == highc(*def)); - return (is_floater(ptr) - ? levitate[capitalize] - : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) - ? flys[capitalize] - : (is_flyer(ptr) && ptr->msize > MZ_SMALL) - ? flyl[capitalize] - : slithy(ptr) - ? slither[capitalize] - : amorphous(ptr) - ? ooze[capitalize] - : !ptr->mmove - ? immobile[capitalize] - : nolimbs(ptr) - ? crawl[capitalize] - : def); + return (is_floater(ptr) ? levitate[capitalize] + : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize] + : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize] + : slithy(ptr) ? slither[capitalize] + : amorphous(ptr) ? ooze[capitalize] + : !ptr->mmove ? immobile[capitalize] + : nolimbs(ptr) ? crawl[capitalize] + : def); } -/* return a phrase describing the effect of fire attack on a type of monster - */ +/* return phrase describing the effect of fire attack on a type of monster */ const char * on_fire(mptr, mattk) struct permonst *mptr; @@ -1098,8 +1099,8 @@ struct attack *mattk; /* * Returns: - * TRUE if monster is presumed to have a sense of smell. - * FALSE if monster definitely does not have a sense of smell. + * True if monster is presumed to have a sense of smell. + * False if monster definitely does not have a sense of smell. * * Do not base this on presence of a head or nose, since many * creatures sense smells other ways (feelers, forked-tongues, etc.) @@ -1109,12 +1110,13 @@ boolean olfaction(mdat) struct permonst *mdat; { - if (mdat && (is_golem(mdat) || mdat->mlet == S_EYE || /* spheres */ - mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING - || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX - || mdat->mlet == S_ELEMENTAL || mdat->mlet == S_FUNGUS - || /* mushrooms and fungi */ - mdat->mlet == S_LIGHT)) + if (is_golem(mdat) + || mdat->mlet == S_EYE /* spheres */ + || mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING + || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX + || mdat->mlet == S_ELEMENTAL + || mdat->mlet == S_FUNGUS /* mushrooms and fungi */ + || mdat->mlet == S_LIGHT) return FALSE; return TRUE; } diff --git a/src/objnam.c b/src/objnam.c index 03b640c76..134f784e8 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1432722918 2015/05/27 10:35:18 $ $NHDT-Branch: master $:$NHDT-Revision: 1.137 $ */ +/* NetHack 3.6 objnam.c $NHDT-Date: 1433058272 2015/05/31 07:44:32 $ $NHDT-Branch: master $:$NHDT-Revision: 1.141 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -550,9 +550,9 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */ /* similar to simple_typename but minimal_xname operates on a particular object rather than its general type; it formats the most basic info: - potion -- if description not known - brown potion -- if oc_name_known not set - potion of object detection -- if discovered + potion -- if description not known + brown potion -- if oc_name_known not set + potion of object detection -- if discovered */ static char * minimal_xname(obj) @@ -945,6 +945,14 @@ boolean with_price; if (bimanual(obj)) hand_s = makeplural(hand_s); Sprintf(eos(bp), " (weapon in %s)", hand_s); + + if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) { + /* presumeably can be felt when blind */ + Strcat(bp, " (glowing"); + if (!Blind) + Sprintf(eos(bp), " %s", glow_color(obj->oartifact)); + Strcat(bp, ")"); + } } } if (obj->owornmask & W_SWAPWEP) { @@ -991,6 +999,7 @@ boolean with_price; quotedprice, currency(quotedprice)); } else if (with_price) { long price = get_cost_of_shop_item(obj); + if (price > 0) Sprintf(eos(bp), " (%ld %s)", price, currency(price)); } diff --git a/src/options.c b/src/options.c index f3b921f9e..cbbd2c0a0 100644 --- a/src/options.c +++ b/src/options.c @@ -503,7 +503,6 @@ STATIC_OVL boolean FDECL(wc2_supported, (const char *)); STATIC_DCL void FDECL(remove_autopickup_exception, (struct autopickup_exception *)); STATIC_OVL int FDECL(count_ape_maps, (int *, int *)); -STATIC_DCL const char *FDECL(clr2colorname, (int)); STATIC_DCL const char *FDECL(attr2attrname, (int)); STATIC_DCL int NDECL(query_color); STATIC_DCL int NDECL(query_msgtype); diff --git a/src/pickup.c b/src/pickup.c index ce8c6f49a..7e1fcb0cc 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -2688,27 +2688,59 @@ dotip() /* check floor container(s) first; at most one will be accessed */ if ((boxes = container_at(cc.x, cc.y, TRUE)) > 0) { - if (flags.verbose) - pline("There %s here.", - (boxes > 1) ? "are containers" : "is a container"); Sprintf(buf, "You can't tip %s while carrying so much.", !flags.verbose ? "a container" : (boxes > 1) ? "one" : "it"); if (!check_capacity(buf) && able_to_loot(cc.x, cc.y, FALSE)) { - for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) { - nobj = cobj->nexthere; - if (!Is_container(cobj)) - continue; - c = ynq(safe_qbuf(qbuf, "There is ", " here, tip it?", cobj, - doname, ansimpleoname, "container")); - if (c == 'q') + if (boxes > 1) { + /* use menu to pick a container to tip */ + int n, i; + winid win; + anything any; + menu_item *pick_list = NULL; + any = zeroany; + win = create_nhwindow(NHW_MENU); + start_menu(win); + + for (cobj = level.objects[cc.x][cc.y]; cobj; + cobj = cobj->nexthere) + if (Is_container(cobj)) { + any.a_obj = cobj; + add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, + doname(cobj), MENU_UNSELECTED); + } + end_menu(win, "Tip which container?"); + n = select_menu(win, PICK_ONE, &pick_list); + destroy_nhwindow(win); + + if (n > 0) { + for (i = 0; i < n; i++) { + tipcontainer(pick_list[i].item.a_obj); + free((genericptr_t) pick_list); + return 1; + } + } + if (pick_list) + free((genericptr_t) pick_list); + if (n == -1) return 0; - if (c == 'n') - continue; + } else { + for (cobj = level.objects[cc.x][cc.y]; cobj; cobj = nobj) { + nobj = cobj->nexthere; + if (!Is_container(cobj)) + continue; - tipcontainer(cobj); - return 1; - } /* next cobj */ + c = ynq(safe_qbuf(qbuf, "There is ", " here, tip it?", cobj, + doname, ansimpleoname, "container")); + if (c == 'q') + return 0; + if (c == 'n') + continue; + + tipcontainer(cobj); + return 1; + } + } } } diff --git a/src/potion.c b/src/potion.c index 7cee10f31..661b30c47 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 potion.c $NHDT-Date: 1432512769 2015/05/25 00:12:49 $ $NHDT-Branch: master $:$NHDT-Revision: 1.115 $ */ +/* NetHack 3.6 potion.c $NHDT-Date: 1433060654 2015/05/31 08:24:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.116 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -304,6 +304,14 @@ boolean talk; if (Blind_telepat || Infravision) see_monsters(); + /* avoid either of the sequences + "Sting starts glowing", [become blind], "Sting stops quivering" or + "Sting starts quivering", [regain sight], "Sting stops glowing" + by giving "Sting is quivering" when becoming blind or + "Sting is glowing" when regaining sight so that the eventual + "stops" message matches */ + if (warn_obj_cnt && uwep && (EWarn_of_mon & W_WEP) != 0L) + Sting_effects(-1); /* update dknown flag for inventory picked up while blind */ if (can_see_now) learn_unseen_invent();