From ad7310bec69d6c330f1082bbe5b69cc2c57be022 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 2 Jun 2015 16:57:42 -0700 Subject: [PATCH 01/13] breaking blind-from-birth conduct OPTIONS:blind starts the hero off blind, but putting on the Eyes of the Overworld confers sight. Make that break the blind-from-birth conduct. Sight persists after removing the Eyes even though they aren't intended to cure anything. It doesn't make sense to restore the blind-from-birth flag when taking the Eyes off, but we may want to add another flag, or make u.uroleplay.blind into a bit mask that can track both can't-see-now for play and could-never-see for conduct. (Actually, u.uroleplay.blind should track only the conduct, and starting the game with it enabled should set one of the extra bits in u.uprops[BLINDED].intrinsic. The Eyes already override that, and taking them off would restore blindness since the bit would still be set. As a bonus, the expression in the macro 'Blind' could be simplified.) --- src/do_wear.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/do_wear.c b/src/do_wear.c index df039ec1f..a79046319 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1432512763 2015/05/25 00:12:43 $ $NHDT-Branch: master $:$NHDT-Revision: 1.81 $ */ +/* NetHack 3.6 do_wear.c $NHDT-Date: 1433289458 2015/06/02 23:57:38 $ $NHDT-Branch: master $:$NHDT-Revision: 1.82 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1084,7 +1084,14 @@ register struct obj *otmp; } else if (already_blind && !Blind) { changed = TRUE; /* "You are now wearing the Eyes of the Overworld." */ - You("can see!"); + if (u.uroleplay.blind) { + /* this can only happen by putting on the Eyes of the Overworld; + that shouldn't actually produce a permanent cure, but we + can't let the "blind from birth" conduct remain intact */ + pline("For the first time in your life, you can see!"); + u.uroleplay.blind = FALSE; + } else + You("can see!"); } if (changed) { /* blindness has just been toggled */ From a1aebc336c21b60b1eddb8a6caea6bb666fc1c15 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 2 Jun 2015 17:30:16 -0700 Subject: [PATCH 02/13] blind-from-birth fix The Blindfolded_only macro didn't track u.uroleplay.blind so would give a false positive if wearing a blindfold, not able to see due to the blind option, and not afflicted with any other blindness factors. Dipping a worn blindfold into holy or unholy water is supposed to reveal a glow if that blindfold is the only reason for blindness but the glow was described even when blind-from-birth. There's no feedback at all when the glow isn't seen. I'm punting on that one. (This change didn't introduce that, just added one extra situation where it happens.) --- include/youprop.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/youprop.h b/include/youprop.h index 5dc91b89d..f1c1d9d00 100644 --- a/include/youprop.h +++ b/include/youprop.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 youprop.h $NHDT-Date: 1432512778 2015/05/25 00:12:58 $ $NHDT-Branch: master $:$NHDT-Revision: 1.22 $ */ +/* NetHack 3.6 youprop.h $NHDT-Date: 1433291407 2015/06/03 00:30:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.23 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -91,10 +91,10 @@ && !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) /* ...the Eyes operate even when you really are blind or don't have any eyes */ -#define Blindfolded_only \ - (!Blinded && haseyes(youmonst.data) && Blindfolded \ - && !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD)) -/* blind because of a blindfold, and *only* that */ +#define Blindfolded_only \ + (Blindfolded && ublindf->oartifact != ART_EYES_OF_THE_OVERWORLD \ + && !u.uroleplay.blind && !Blinded && haseyes(youmonst.data)) +/* ...blind because of a blindfold, and *only* that */ #define Sick u.uprops[SICK].intrinsic #define Stoned u.uprops[STONED].intrinsic From 64e0c99b62da2044b303838ac3c98652ac1ac59f Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 2 Jun 2015 17:39:19 -0700 Subject: [PATCH 03/13] enlightenment for unarmored, also blindness Augment the existing enlightenment feedback for blindness: "innately" blind if poly'd into something without eyes, "permanently" blind if using the blind-from-birth option, "deliberately" blind if blindness is solely due to a blindfold, or "temporarily" blind otherwise. Add status of "not wearing any armor" when applicable, with slightly different phrasing if it's due to adhering the OPTIONS:nudist conduct. --- src/cmd.c | 65 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index a56c9491e..8ca41387d 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1433050877 2015/05/31 05:41:17 $ $NHDT-Branch: master $:$NHDT-Revision: 1.193 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1433291955 2015/06/03 00:39:15 $ $NHDT-Branch: master $:$NHDT-Revision: 1.194 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1604,11 +1604,10 @@ int final; int cap; char buf[BUFSZ], youtoo[BUFSZ]; boolean Riding = (u.usteed - && /* if hero dies while dismounting, u.usteed will still be set; we want to ignore steed in that situation */ - !(final == ENL_GAMEOVERDEAD - && !strcmp(killer.name, "riding accident"))); + && !(final == ENL_GAMEOVERDEAD + && !strcmp(killer.name, "riding accident"))); const char *steedname = !Riding ? (char *) 0 @@ -1650,13 +1649,10 @@ int final; you_are(Swimming ? "swimming" : "in water", from_what(SWIMMING)); } else if (walking_on_water()) { /* show active Wwalking here, potential Wwalking elsewhere */ - Sprintf( - buf, "walking on %s", - is_pool(u.ux, u.uy) - ? "water" - : is_lava(u.ux, u.uy) - ? "lava" - : surface(u.ux, u.uy)); /* catchall; shouldn't happen */ + Sprintf(buf, "walking on %s", + is_pool(u.ux, u.uy) ? "water" + : is_lava(u.ux, u.uy) ? "lava" + : surface(u.ux, u.uy)); /* catchall; shouldn't happen */ you_are(buf, from_what(WWALKING)); } if (Upolyd && (u.uundetected || youmonst.m_ap_type != M_AP_NOTHING)) @@ -1692,8 +1688,21 @@ int final; you_are("confused", ""); if (Hallucination) you_are("hallucinating", ""); - if (Blind) - you_are("blind", from_what(BLINDED)); + if (Blind) { + /* from_what() (currently wizard-mode only) checks !haseyes() + before u.uroleplay.blind, so we should too */ + Sprintf(buf, "%s blind", + !haseyes(youmonst.data) ? "innately" + : u.uroleplay.blind ? "permanently" + /* better phrasing desparately wanted... */ + : Blindfolded_only ? "deliberately" + : "temporarily"); + if (wizard && (Blinded & TIMEOUT) != 0L + && !u.uroleplay.blind && haseyes(youmonst.data)) + Sprintf(eos(buf), " (%ld)", (Blinded & TIMEOUT)); + /* !haseyes: avoid "you are innately blind innately" */ + you_are(buf, !haseyes(youmonst.data) ? "" : from_what(BLINDED)); + } if (Deaf) you_are("deaf", from_what(DEAF)); @@ -1823,26 +1832,27 @@ int final; (cap < OVERLOADED) ? " slowed" : ""); you_are(buf, ""); } else { - /* last resort entry, guarantees Status section is non-empty */ + /* last resort entry, guarantees Status section is non-empty + (no longer needed for that purpose since weapon status added; + still useful though) */ you_are("unencumbered", ""); } /* report being weaponless; distinguish whether gloves are worn */ - if (!uwep) - you_are(uarmg ? "empty handed" : /* gloves imply hands */ - /* no weapon and no gloves */ - humanoid(youmonst.data) - ? "bare handed" - : - /* alternate phrasing for paws or lack of hands */ - "not wielding anything", + if (!uwep) { + you_are(uarmg ? "empty handed" /* gloves imply hands */ + /* no weapon and no gloves */ + : humanoid(youmonst.data) + ? "bare handed" + /* alternate phrasing for paws or lack of hands */ + : "not wielding anything", ""); /* two-weaponing implies a weapon (not other odd stuff) in each hand */ - else if (u.twoweap) + } else if (u.twoweap) { you_are("wielding two weapons at once", ""); /* report most weapons by their skill class (so a katana will be described as a long sword, for instance; mattock and hook are exceptions), or wielded non-weapon item by its object class */ - else { + } else { const char *what = weapon_descr(uwep); if (!strcmpi(what, "armor") || !strcmpi(what, "food") @@ -1853,6 +1863,13 @@ int final; (uwep->quan == 1L) ? an(what) : makeplural(what)); you_are(buf, ""); } + /* report 'nudity' */ + if (!uarm && !uarmu && !uarmc && !uarmg && !uarmf && !uarmh) { + if (u.uroleplay.nudist) + enl_msg(You_, "do", "did", " not wear any armor", ""); + else + you_are("not wearing any armor", ""); + } } /* attributes: intrinsics and the like, other non-obvious capabilities */ From cf28b8ad71f9b258cf0e89b87314effc560a8c28 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 3 Jun 2015 17:27:36 +0300 Subject: [PATCH 04/13] Fix Rogue-level lighting bugs caused by dark room Found by Boudewijn --- src/display.c | 12 ++++++++++-- src/options.c | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index 70d88ef82..f08748b29 100644 --- a/src/display.c +++ b/src/display.c @@ -577,7 +577,7 @@ xchar x, y; if (lev->typ != ROOM && lev->seenv) { map_background(x, y, 1); } else { - lev->glyph = flags.dark_room + lev->glyph = (flags.dark_room && !Is_rogue_level(&u.uz)) ? cmap_to_glyph(S_darkroom) : (lev->waslit ? cmap_to_glyph(S_room) : cmap_to_glyph(S_stone)); @@ -586,7 +586,7 @@ xchar x, y; } else if ((lev->glyph >= cmap_to_glyph(S_stone) && lev->glyph < cmap_to_glyph(S_darkroom)) || glyph_is_invisible(levl[x][y].glyph)) { - lev->glyph = flags.dark_room + lev->glyph = (flags.dark_room && !Is_rogue_level(&u.uz)) ? cmap_to_glyph(S_darkroom) : (lev->waslit ? cmap_to_glyph(S_room) : cmap_to_glyph(S_stone)); @@ -799,6 +799,14 @@ register int x, y; * These checks and changes must be here and not in back_to_glyph(). * They are dependent on the position being out of sight. */ + else if (Is_rogue_level(&u.uz)) { + if (lev->glyph == cmap_to_glyph(S_litcorr) && lev->typ == CORR) + show_glyph(x, y, lev->glyph = cmap_to_glyph(S_corr)); + else if (lev->glyph == cmap_to_glyph(S_room) && lev->typ == ROOM && !lev->waslit) + show_glyph(x, y, lev->glyph = cmap_to_glyph(S_stone)); + else + goto show_mem; + } else if (!lev->waslit || (flags.dark_room && iflags.use_color)) { if (lev->glyph == cmap_to_glyph(S_litcorr) && lev->typ == CORR) show_glyph(x, y, lev->glyph = cmap_to_glyph(S_corr)); diff --git a/src/options.c b/src/options.c index 0c89826cd..d6c7b9553 100644 --- a/src/options.c +++ b/src/options.c @@ -524,7 +524,7 @@ reglyph_darkroom() for (y = 0; y < ROWNO; y++) { struct rm *lev = &levl[x][y]; - if (!flags.dark_room) { + if (!flags.dark_room || Is_rogue_level(&u.uz)) { if (lev->glyph == cmap_to_glyph(S_darkroom)) lev->glyph = lev->waslit ? cmap_to_glyph(S_room) : cmap_to_glyph(S_stone); From 19fe4ece8c3c5d95fcdb1a368f8fc678a18ea46c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 3 Jun 2015 17:41:01 +0300 Subject: [PATCH 05/13] Move struct istat_s above prototypes using it --- src/botl.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/botl.c b/src/botl.c index 210a21e13..527fe5669 100644 --- a/src/botl.c +++ b/src/botl.c @@ -285,17 +285,6 @@ char *buf; #ifdef STATUS_VIA_WINDOWPORT /* =======================================================================*/ -STATIC_DCL void NDECL(init_blstats); -STATIC_DCL char *FDECL(anything_to_s, (char *, anything *, int)); -STATIC_DCL void FDECL(s_to_anything, (anything *, char *, int)); -STATIC_OVL int FDECL(percentage, (struct istat_s *, struct istat_s *)); -STATIC_OVL int FDECL(compare_blstats, (struct istat_s *, struct istat_s *)); - -#ifdef STATUS_HILITES -STATIC_DCL boolean FDECL(assign_hilite, (char *, char *, char *, char *, BOOLEAN_P)); -STATIC_DCL const char *FDECL(clridx_to_s, (char *, int)); -#endif - /* structure that tracks the status details in the core */ struct istat_s { long time; @@ -307,6 +296,18 @@ struct istat_s { enum statusfields fld; }; + +STATIC_DCL void NDECL(init_blstats); +STATIC_DCL char *FDECL(anything_to_s, (char *, anything *, int)); +STATIC_DCL void FDECL(s_to_anything, (anything *, char *, int)); +STATIC_OVL int FDECL(percentage, (struct istat_s *, struct istat_s *)); +STATIC_OVL int FDECL(compare_blstats, (struct istat_s *, struct istat_s *)); + +#ifdef STATUS_HILITES +STATIC_DCL boolean FDECL(assign_hilite, (char *, char *, char *, char *, BOOLEAN_P)); +STATIC_DCL const char *FDECL(clridx_to_s, (char *, int)); +#endif + /* If entries are added to this, botl.h will require updating too */ STATIC_DCL struct istat_s initblstats[MAXBLSTATS] = { { 0L, ANY_STR, {(genericptr_t)0L}, (char *)0, 80, 0, BL_TITLE}, From 61447ef8c8ed953f66fb062a3e03513e1582eae2 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 3 Jun 2015 18:13:00 +0300 Subject: [PATCH 06/13] Minor Guidebook fixage --- doc/Guidebook.mn | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 9615cc6e3..27693556f 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2770,7 +2770,7 @@ The pattern should be a POSIX extended regular expression. .hn 2 Configuring Status Hilites .pg -Your copy of NetHack may have been compiled with support for {\tStatus Hilites}. +Your copy of NetHack may have been compiled with support for ``Status Hilites''. If so, you can customize your game display by setting thresholds to change the color or appearance of fields in the status display. .pg @@ -2778,14 +2778,15 @@ For example, the following line in your config file will cause the hitpoints field to display in the color red if your hitpoints drop to or below a threshold of 30%: .si -.lp OPTION=hilite_status: hitpoints/30%/red/normal +.lp "OPTION=hilite_status: hitpoints/30%/red/normal" .ei .pg For another example, the following line in your config file will cause wisdom to be displayed red if it drops and green if it rises. .si -.lp OPTION=hilite_status: wisdom/updown/red/green +.lp "OPTION=hilite_status: wisdom/updown/red/green" .ei +.pg You can adjust the display of the following status fields: .TS S center; @@ -2810,10 +2811,10 @@ Note that the platform used may interpret the attributes any way it wants. .lp "" Behaviours can occur based on percentage thresholds, updown, or absolute values. -The in-game options menu can help you determine the correct syntax for a +The in-game options menu can help you determine the correct syntax for a config file. .lp "" -The whole feature can be disable by setting option statushilites off. +The whole feature can be disabled by setting option statushilites off. .pg .hn 2 Modifying NetHack Symbols From 014547beb2f8c48b34a89cf5d5b61c36916a1603 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 4 Jun 2015 15:36:26 +0300 Subject: [PATCH 07/13] Fix looking around when swallowed From Boudewijn: > I am currently swallowed by an ice vortex, and used the ; command > to identify the \ on my top right. > > It said: "\ an opulent throne (interior of a monster)" Now, when you're swallowed, and look at anything else than yourself, you'll get "\ the interior of a monster (interior of an ice vortex)". Based on the comment in the code, it seems this was the original intention anyway. --- src/pager.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/pager.c b/src/pager.c index aa7e7ecbd..9fe15d724 100644 --- a/src/pager.c +++ b/src/pager.c @@ -544,6 +544,22 @@ const char **firstmatch; * When all have been checked then the string is printed. */ + /* + * Special case: if identifying from the screen, and we're swallowed, + * and looking at something other than our own symbol, then just say + * "the interior of a monster". + */ + if (u.uswallow && (looked) && (is_swallow_sym(sym) || (int)showsyms[S_stone] == sym)) { + if (!found) { + Sprintf(out_str, "%s%s", prefix, mon_interior); + *firstmatch = mon_interior; + } else { + found += append_str(out_str, mon_interior); + } + need_to_look = TRUE; + goto didlook; + } + /* Check for monsters */ for (i = 0; i < MAXMCLASSES; i++) { if (sym == ((looked) ? showsyms[i + SYM_OFF_M] : def_monsyms[i].sym) @@ -567,21 +583,6 @@ const char **firstmatch; && !(Race_if(PM_HUMAN) || Race_if(PM_ELF)) && !Upolyd) found += append_str(out_str, "you"); /* tack on "or you" */ - /* - * Special case: if identifying from the screen, and we're swallowed, - * and looking at something other than our own symbol, then just say - * "the interior of a monster". - */ - if (u.uswallow && (looked) && is_swallow_sym(sym)) { - if (!found) { - Sprintf(out_str, "%s%s", prefix, mon_interior); - *firstmatch = mon_interior; - } else { - found += append_str(out_str, mon_interior); - } - need_to_look = TRUE; - } - /* Now check for objects */ for (i = 1; i < MAXOCLASSES; i++) { if (sym @@ -696,6 +697,7 @@ const char **firstmatch; * If we are looking at the screen, follow multiple possibilities or * an ambiguous explanation by something more detailed. */ + didlook: if (looked) { if (found > 1 || need_to_look) { char monbuf[BUFSZ]; From 86b84568ea7dff0af185641d0fac33855e6d339f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 4 Jun 2015 17:39:21 +0300 Subject: [PATCH 08/13] Monster detection shows pets with the correct glyph Make pets hilited when detected with uncursed potion of monster detection and hilite_pet is on. Noticed by Raisse. --- src/detect.c | 3 ++- src/worm.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/detect.c b/src/detect.c index ee25935f4..c149cac69 100644 --- a/src/detect.c +++ b/src/detect.c @@ -637,7 +637,8 @@ int mclass; /* monster class, 0 for all */ show_glyph(mtmp->mx, mtmp->my, detected_mon_to_glyph(mtmp)); else - show_glyph(mtmp->mx, mtmp->my, mon_to_glyph(mtmp)); + show_glyph(mtmp->mx, mtmp->my, + mtmp->mtame ? pet_to_glyph(mtmp) : mon_to_glyph(mtmp)); /* don't be stingy - display entire worm */ if (mtmp->data == &mons[PM_LONG_WORM]) detect_wsegs(mtmp, 0); diff --git a/src/worm.c b/src/worm.c index c4ad029fc..cb3dc4922 100644 --- a/src/worm.c +++ b/src/worm.c @@ -465,8 +465,10 @@ boolean use_detection_glyph; while (curr != wheads[worm->wormno]) { num = use_detection_glyph - ? detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)) - : monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)); + ? detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)) + : (worm->mtame + ? petnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)) + : monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL))); show_glyph(curr->wx, curr->wy, num); curr = curr->nseg; } From f86bbca9b648d10a772d73100d8272648a97a7e6 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 4 Jun 2015 18:02:20 +0300 Subject: [PATCH 09/13] Show detected pets with correct glyph When detecting monsters with blessed potion of monster detection, show pets with the correct glyph; highlights them if hilite_pet is on. --- src/display.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/display.c b/src/display.c index f08748b29..b3ea39ce8 100644 --- a/src/display.c +++ b/src/display.c @@ -431,7 +431,7 @@ register xchar worm_tail; /* mon is actually a worm tail */ /* [ALI] Only use detected glyphs when monster wouldn't be * visible by any other means. */ - if (sightflags == DETECTED) { + if (sightflags == DETECTED && !mon->mtame) { if (worm_tail) num = detected_monnum_to_glyph(what_mon(PM_LONG_WORM_TAIL)); else @@ -768,10 +768,10 @@ register int x, y; && ((see_it = (tp_sensemon(mon) || MATCH_WARN_OF_MON(mon) || (see_with_infrared(mon) && mon_visible(mon)))) - || Detect_monsters) && !is_worm_tail(mon)) { + || Detect_monsters)) { /* Monsters are printed every time. */ /* This also gets rid of any invisibility glyph */ - display_monster(x, y, mon, see_it ? 0 : DETECTED, 0); + display_monster(x, y, mon, see_it ? 0 : DETECTED, is_worm_tail(mon) ? TRUE : FALSE); } else if ((mon = m_at(x, y)) && mon_warning(mon) && !is_worm_tail(mon)) { display_warning(mon); From 8d1e49f094c9ebc240519579bc7d99e15e0949ef Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 4 Jun 2015 21:01:36 +0300 Subject: [PATCH 10/13] Dwarves may be generated with dwarvish spears --- src/makemon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/makemon.c b/src/makemon.c index 242675340..a1fc167fe 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -325,7 +325,7 @@ register struct monst *mtmp; if (rn2(2)) (void) mongets(mtmp, DWARVISH_MATTOCK); else { - (void) mongets(mtmp, AXE); + (void) mongets(mtmp, rn2(2) ? AXE : DWARVISH_SPEAR); (void) mongets(mtmp, DWARVISH_ROUNDSHIELD); } (void) mongets(mtmp, DWARVISH_IRON_HELM); From 2de17b059c609c9ba1efe6afd8bfb031bdbafa32 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 4 Jun 2015 21:27:36 +0300 Subject: [PATCH 11/13] Make priest door opening check match dog_move --- src/priest.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/priest.c b/src/priest.c index a50b93ef7..fba265259 100644 --- a/src/priest.c +++ b/src/priest.c @@ -76,8 +76,8 @@ register xchar omx, omy, gx, gy; allowflags |= ALLOW_DIG; if (!nohands(mtmp->data) && !verysmall(mtmp->data)) { allowflags |= OPENDOOR; - if (m_carrying(mtmp, SKELETON_KEY)) - allowflags |= BUSTDOOR; + if (monhaskey(mtmp, TRUE)) + allowflags |= UNLOCKDOOR; } if (is_giant(mtmp->data)) allowflags |= BUSTDOOR; From def25495924245669a128ca30ee7628d29f5668f Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Jun 2015 15:31:25 -0700 Subject: [PATCH 12/13] shapeshifting on rogue level Limit vampire shapeshifting on rogue level to vampire bats (only choice represented by uppercase letter) and have other shapeshifting try for uppercase. The latter isn't rigorous because shapeshifters (chameleon=':', doppelganger='@', sandestin='&') aren't uppercase themselves, so won't be created there under ordinary circumstances. It applies to the "summon nasties" monster spell and post-invocation/ post-Wizard's-death harassment effect too. --- src/makemon.c | 21 ++++++++------------- src/mon.c | 32 ++++++++++++++++++++++++++------ src/wizard.c | 16 +++++++++++++--- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/makemon.c b/src/makemon.c index a1fc167fe..5aea3392d 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makemon.c $NHDT-Date: 1432685497 2015/05/27 00:11:37 $ $NHDT-Branch: master $:$NHDT-Revision: 1.89 $ */ +/* NetHack 3.6 makemon.c $NHDT-Date: 1433457069 2015/06/04 22:31:09 $ $NHDT-Branch: master $:$NHDT-Revision: 1.92 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1134,23 +1134,18 @@ register int mmflags; mtmp->cham = NON_PM; /* default is "not a shapechanger" */ if ((mcham = pm_to_cham(mndx)) != NON_PM) { /* this is a shapechanger after all */ - if (Protection_from_shape_changers) { + if (Protection_from_shape_changers + || mtmp->cham == PM_VLAD_THE_IMPALER) { ; /* stuck in its natural form (NON_PM) */ } else { /* Note: shapechanger's initial form used to be - chosen with rndmonst(), yielding a monster + chosen here with rndmonst(), yielding a monster which was approriate to the level's difficulty but ignored the changer's usual type selection - so would be inppropriate for vampshifters. */ - mtmp->cham = mcham; /* remember base form */ - if (mcham != PM_VLAD_THE_IMPALER && - /* select initial shape */ - (mcham = select_newcham_form(mtmp)) != NON_PM) { - /* take on initial shape; if successful, - avoid giving that shape's usual inventory */ - if (newcham(mtmp, &mons[mcham], FALSE, FALSE)) - allow_minvent = FALSE; - } + so would be inppropriate for vampshifters. + Let newcham() pick the shape. */ + if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE)) + allow_minvent = FALSE; } } else if (mndx == PM_WIZARD_OF_YENDOR) { mtmp->iswiz = TRUE; diff --git a/src/mon.c b/src/mon.c index cf168fd82..8ca8d16a1 100644 --- a/src/mon.c +++ b/src/mon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mon.c $NHDT-Date: 1432512774 2015/05/25 00:12:54 $ $NHDT-Branch: master $:$NHDT-Revision: 1.177 $ */ +/* NetHack 3.6 mon.c $NHDT-Date: 1433457072 2015/06/04 22:31:12 $ $NHDT-Branch: master $:$NHDT-Revision: 1.178 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2667,10 +2667,18 @@ boolean construct; STATIC_OVL int pick_animal() { + int res; + if (!animal_list) mon_animal_list(TRUE); - return animal_list[rn2(animal_list_count)]; + res = animal_list[rn2(animal_list_count)]; + /* rogue level should use monsters represented by uppercase letters + only, but since chameleons aren't generated there (not uppercase!) + we don't perform a lot of retries */ + if (Is_rogue_level(&u.uz) && !isupper((uchar) mons[res].mlet)) + res = animal_list[rn2(animal_list_count)]; + return res; } void @@ -2710,6 +2718,9 @@ pickvampshape(mon) struct monst *mon; { int mndx = mon->cham; + /* avoid picking monsters with lowercase display symbols ('d' for wolf + and 'v' for fog cloud) on rogue level*/ + boolean uppercase_only = Is_rogue_level(&u.uz); switch (mndx) { case PM_VLAD_THE_IMPALER: @@ -2718,13 +2729,13 @@ struct monst *mon; break; /* leave mndx as is */ /*FALLTHRU*/ case PM_VAMPIRE_LORD: /* vampire lord or Vlad can become wolf */ - if (!rn2(10)) { + if (!rn2(10) && !uppercase_only) { mndx = PM_WOLF; break; } /*FALLTHRU*/ case PM_VAMPIRE: /* any vampire can become fog or bat */ - mndx = !rn2(4) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; + mndx = (!rn2(4) && !uppercase_only) ? PM_FOG_CLOUD : PM_VAMPIRE_BAT; break; } return mndx; @@ -2786,7 +2797,8 @@ int *mndx_p, monclass; *mndx_p = PM_VLAD_THE_IMPALER; return TRUE; } - /* basic vampires can't become wolves; any can become fog or bat */ + /* basic vampires can't become wolves; any can become fog or bat + (we don't enforce upper-case only for rogue level here) */ if (*mndx_p == PM_WOLF) return (mon->cham != PM_VAMPIRE); if (*mndx_p == PM_FOG_CLOUD || *mndx_p == PM_VAMPIRE_BAT) @@ -2916,7 +2928,10 @@ struct monst *mon; tryct = 50; do { mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM); - } while (--tryct > 0 && !validspecmon(mon, mndx)); + } while (--tryct > 0 && !validspecmon(mon, mndx) + /* try harder to select uppercase monster on rogue level */ + && (tryct > 40 && Is_rogue_level(&u.uz) + && !isupper((uchar) mons[mndx].mlet))); } return mndx; } @@ -2995,6 +3010,11 @@ boolean msg; /* "The oldmon turns into a newmon!" */ do { mndx = select_newcham_form(mtmp); mdat = accept_newcham_form(mndx); + /* for the first several tries we require upper-case on + the rogue level (after that, we take whatever we get) */ + if (tryct > 15 && Is_rogue_level(&u.uz) + && !isupper((uchar) mdat->mlet)) + mdat = 0; if (mdat) break; } while (--tryct > 0); diff --git a/src/wizard.c b/src/wizard.c index 261c831b1..d0a6c371c 100644 --- a/src/wizard.c +++ b/src/wizard.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wizard.c $NHDT-Date: 1432512766 2015/05/25 00:12:46 $ $NHDT-Branch: master $:$NHDT-Revision: 1.37 $ */ +/* NetHack 3.6 wizard.c $NHDT-Date: 1433457074 2015/06/04 22:31:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.38 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -428,9 +428,19 @@ clonewiz() int pick_nasty() { + int res = nasties[rn2(SIZE(nasties))]; + /* To do? Possibly should filter for appropriate forms when - in the elemental planes or surrounded by water or lava. */ - return nasties[rn2(SIZE(nasties))]; + * in the elemental planes or surrounded by water or lava. + * + * We want monsters represented by uppercase on rogue level, + * but we don't try very hard. + */ + if (Is_rogue_level(&u.uz) + && !('A' <= mons[res].mlet && mons[res].mlet <= 'Z')) + res = nasties[rn2(SIZE(nasties))]; + + return res; } /* create some nasty monsters, aligned or neutral with the caster */ From 159b29a85ba10339149986fcb66039d5ec80f7fa Mon Sep 17 00:00:00 2001 From: nhmall Date: Fri, 5 Jun 2015 06:36:00 -0400 Subject: [PATCH 13/13] ensure dummy obj owornmask is clear (from Alex) Another minor oddity (did not have time to trace it). Charges for damaged weapon refer to it as "weapon in hand": -- As you read the scroll, it disappears. Being confused, you mispronounce the magic words... Demirci's long sword is covered by a mottled purple glow! "You degrade that long sword, you pay for it!" Call a scroll labeled VERR YED HORRE: What do you want to wield? [- ajrw or ?*] j j - a rustproof athame named Magicbane (weapon in hand) (10 aum). What do you want to drop? [$a-df-rtwxM or ?*] r You drop a long sword (40 aum). Demirci offers 8 gold pieces for your long sword. Sell it? [ynaq] (y) y You sold a long sword (40 aum) for 8 gold pieces. You see here a scale mail (250 aum). You see here a ring mail (250 aum). A rustproof long sword (weapon in hand) (40 aum) for 15 zorkmids. Pay? [yn] (n) You paid for a rustproof long sword (weapon in hand) (40 aum) at a cost of 15 gold pieces. "Thank you for shopping in Demirci's used armor dealership!" -- --- src/mkobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/mkobj.c b/src/mkobj.c index 337d6d9fe..16c839ffc 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1432512771 2015/05/25 00:12:51 $ $NHDT-Branch: master $:$NHDT-Revision: 1.101 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1433500549 2015/06/05 10:35:49 $ $NHDT-Branch: master $:$NHDT-Revision: 1.102 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -520,6 +520,7 @@ register struct obj *otmp; free_omid(dummy); /* only one association with m_id*/ if (Is_candle(dummy)) dummy->lamplit = 0; + dummy->owornmask = 0L; /* dummy object is not worn */ addtobill(dummy, FALSE, TRUE, TRUE); if (cost) alter_cost(dummy, -cost);