From 0171345aadd2f483d4d492c23670cd01796ab1e3 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 30 May 2015 22:41:30 -0700 Subject: [PATCH 1/7] more Sting,&c Add "(glowing light blue)" to the formatted object description when Sting or Orcrist is glowing due to presence of orcs or "(glowing red)" if Grimtooth is glowing due to elves. Use "(glowing)" if blind; assumes that some aspect of the glow (perhaps warmth or vibration) can be noticed via touch. Make enlightenment's "you are warned about because of " catch up with Orcrist and Grimtooth. It was attributing Orcrist's warning against orcs to Sting, and Grimtooth's warning was against "something" rather than elves. The glow color is now a new field in artilist[], so the biggest part of this patch is adding an extra value to each artifact's definition. --- include/artifact.h | 3 +- include/artilist.h | 98 +++++++++++++++++++++++++++------------------- include/extern.h | 4 +- src/artifact.c | 46 +++++++++++++++------- src/cmd.c | 9 ++--- src/objnam.c | 16 ++++++-- src/options.c | 3 +- 7 files changed, 110 insertions(+), 69 deletions(-) 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 901326707..a4f355a09 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1432890461 2015/05/29 09:07:41 $ $NHDT-Branch: master $:$NHDT-Revision: 1.498 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1433050874 2015/05/31 05:41:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.499 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -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)); @@ -1636,6 +1637,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..4928e755e 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: 1433050876 2015/05/31 05:41:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.90 $ */ /* 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,6 +1821,16 @@ 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) @@ -1831,10 +1850,7 @@ int orc_count; if (orc_count > 0 && warn_obj_cnt == 0) { 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) { 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/objnam.c b/src/objnam.c index 03b640c76..8972ede19 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: 1433050879 2015/05/31 05:41:19 $ $NHDT-Branch: master $:$NHDT-Revision: 1.140 $ */ /* 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,13 @@ boolean with_price; if (bimanual(obj)) hand_s = makeplural(hand_s); Sprintf(eos(bp), " (weapon in %s)", hand_s); + if (obj == uwep && obj->oartifact && warn_obj_cnt) { + /* 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 +998,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 e418add02..93aa19704 100644 --- a/src/options.c +++ b/src/options.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 options.c $NHDT-Date: 1432974335 2015/05/30 08:25:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.207 $ */ +/* NetHack 3.6 options.c $NHDT-Date: 1433050879 2015/05/31 05:41:19 $ $NHDT-Branch: master $:$NHDT-Revision: 1.208 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -502,7 +502,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); From 36f00f98eb795fd28cb6c176db331417c9b33246 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sun, 31 May 2015 10:13:49 +0300 Subject: [PATCH 2/7] Use a menu to pick a container to tip If there is more than one container, the #tip command will show a menu; if there's just one container, prompt for tipping. As per Boudewijn's suggestion, remove the superfluous "There is a container here" message. --- src/pickup.c | 62 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 15 deletions(-) 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; + } + } } } From a70599b0cd76ebdf2688e0a3e526b4dd486236ed Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 31 May 2015 00:44:40 -0700 Subject: [PATCH 3/7] Sting again When formatting uwep, verify that warning comes from wielded weapon before appending "(glowing )". --- src/objnam.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/objnam.c b/src/objnam.c index 8972ede19..134f784e8 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 objnam.c $NHDT-Date: 1433050879 2015/05/31 05:41:19 $ $NHDT-Branch: master $:$NHDT-Revision: 1.140 $ */ +/* 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. */ @@ -945,7 +945,8 @@ boolean with_price; if (bimanual(obj)) hand_s = makeplural(hand_s); Sprintf(eos(bp), " (weapon in %s)", hand_s); - if (obj == uwep && obj->oartifact && warn_obj_cnt) { + + if (warn_obj_cnt && obj == uwep && (EWarn_of_mon & W_WEP) != 0L) { /* presumeably can be felt when blind */ Strcat(bp, " (glowing"); if (!Blind) From 3a5304c49eea282ba02d8b2ba43b338a39e73dec Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 31 May 2015 01:24:19 -0700 Subject: [PATCH 4/7] last? Sting If Sting is glowing when blindness gets toggled, give a new "glowing" message. So instead of Sting glows blue! [...] You can't see! [...] Sting stops quivering. if you're still blind when the last orc goes away, or Sting quivers slightly. [...] You can see again. [...] Sting stops glowing. if you were blind when the first orc arrived, now you'll get an intermediate message between the second and third ones. 'Sting is quivering' for the first case, 'Sting is glowing' for the second. No matter how many times blindness toggles back and forth, the final "stops glowing" or "stops quivering" will be consistent with the most recent "is glowing" or "is quivering". --- src/artifact.c | 20 ++++++++++---------- src/potion.c | 10 +++++++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/artifact.c b/src/artifact.c index 4928e755e..0377c3ac8 100644 --- a/src/artifact.c +++ b/src/artifact.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 artifact.c $NHDT-Date: 1433050876 2015/05/31 05:41:16 $ $NHDT-Branch: master $:$NHDT-Revision: 1.90 $ */ +/* 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. */ @@ -1834,26 +1834,26 @@ int arti_indx; /* 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"), 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/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(); From 92ec573fbb6c1a24b60bd482393fdacb4f4b161a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 31 May 2015 17:18:06 -0700 Subject: [PATCH 5/7] mondata.c formatting cleanup, ancient AIX PS/2 bug When looking to see whether the monsndx() panic could provide any more useful information [if a pointer that's supposed to point into the mons[] array doesn't, I don't think that there's a whole lot of other information available aside from whether it is null or not, and that's implicitly provided already], I went through the whole file cleaning up the formatting and making sure every routine was preceded by a short (usually one line) comment. There were a few bits of code reorganization. I changed little_to_big to have a single point of return. The 25 year old workaround for a compiler bug on a defunct platform may or may not still be applicable; I took that out. If we get segfault reports for AIX on PS/2, this is the first place to look. (big_to_little is nearly identical and didn't have the same workaround. Not needed, or not called often enough for any AIX PS/2 user to be affected?) --- src/mondata.c | 254 +++++++++++++++++++++++++------------------------- 1 file changed, 128 insertions(+), 126 deletions(-) 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; } From be4c2b2fd6de899b08fb0546a5b08ccb21112549 Mon Sep 17 00:00:00 2001 From: karnov Date: Sun, 31 May 2015 22:29:08 -0400 Subject: [PATCH 6/7] Guidebook updates (misc). --- doc/Guidebook.mn | 39 +++++++++++++++++++++------------------ doc/Guidebook.tex | 42 +++++++++++++++++++++++------------------- 2 files changed, 44 insertions(+), 37 deletions(-) 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 From 13ef4962fd2f6a943d3f9c21cb52ac930c71e514 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 1 Jun 2015 15:56:23 +0300 Subject: [PATCH 7/7] Reduce the number of gnomes with candles Gnomes in mines during level generation have 1/20 chance of getting a candle (should give approximately 4 candles in all of the mines total), and every randomly generated gnome has 1/60 chance. --- src/makemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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);