From ed18ebc5459505f6bbf2e9104a59abb4941999a3 Mon Sep 17 00:00:00 2001 From: PatR Date: Sat, 27 Jul 2019 16:12:24 -0700 Subject: [PATCH 1/6] timer validations Add the contributed code that checks for attempting to start a duplicate timer. It's based on a comment which must have been there at least 25 years and doesn't solve any known problems, but it is conceptually similar to the large amount of sanity checking which has gone into 3.6.x. It didn't work as is because it was comparing two unions with '=='. I don't know offhand whether C++ supports that but C doesn't (through C11 at least; don't know about C17). The union ('anything') is simple enough that two instances can be compared without jumping through hoops. I've also added another check for timer 'kind' (level, object, monster, or global). --- doc/fixes36.3 | 4 +++- include/timeout.h | 11 ++++++----- src/timeout.c | 32 +++++++++++++++++++++++++------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 909dbd345..a20fc650e 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.94 $ $NHDT-Date: 1562838835 2019/07/11 09:53:55 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.95 $ $NHDT-Date: 1564269131 2019/07/27 23:12:11 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -105,6 +105,8 @@ when farlook describes a monster at a visible spot as trapped, reveal the trap fix theft when poly'd into nymph form; 3.6.2 change made that anger the victim hero poly'd into nymph would steal gold along with other items change wizard mode #panic to require "yes" if 'paranoid_confirm:quit' is set +add some additional validation checks when setting up a new timer (triggered + by an ancient source comment rather than by any observed problems) Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/include/timeout.h b/include/timeout.h index 0cb4c706a..0ac85a3c8 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.h $NHDT-Date: 1432512775 2015/05/25 00:12:55 $ $NHDT-Branch: master $:$NHDT-Revision: 1.10 $ */ +/* NetHack 3.6 timeout.h $NHDT-Date: 1564269131 2019/07/27 23:12:11 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.12 $ */ /* Copyright 1994, Dean Luick */ /* NetHack may be freely redistributed. See license for details. */ @@ -10,10 +10,11 @@ typedef void FDECL((*timeout_proc), (ANY_P *, long)); /* kind of timer */ enum timer_type { - TIMER_LEVEL = 0, /* event specific to level */ - TIMER_GLOBAL, /* event follows current play */ - TIMER_OBJECT, /* event follows a object */ - TIMER_MONSTER /* event follows a monster */ + TIMER_LEVEL = 0, /* event specific to level [melting ice] */ + TIMER_GLOBAL = 1, /* event follows current play [not used] */ + TIMER_OBJECT = 2, /* event follows an object [various] */ + TIMER_MONSTER = 3, /* event follows a monster [not used] */ + NUM_TIMER_KINDS /* 4 */ }; /* save/restore timer ranges */ diff --git a/src/timeout.c b/src/timeout.c index 54a2943c3..3d820b0fb 100644 --- a/src/timeout.c +++ b/src/timeout.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 timeout.c $NHDT-Date: 1559664953 2019/06/04 16:15:53 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.90 $ */ +/* NetHack 3.6 timeout.c $NHDT-Date: 1564269133 2019/07/27 23:12:13 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.91 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2018. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1868,13 +1868,32 @@ short kind; short func_index; anything *arg; { - timer_element *gnu; + timer_element *gnu, *dup; - if (func_index < 0 || func_index >= NUM_TIME_FUNCS) - panic("start_timer"); + if (kind < 0 || kind >= NUM_TIMER_KINDS + || func_index < 0 || func_index >= NUM_TIME_FUNCS) + panic("start_timer (%s: %d)", kind_name(kind), (int) func_index); - gnu = (timer_element *) alloc(sizeof(timer_element)); - (void) memset((genericptr_t)gnu, 0, sizeof(timer_element)); + /* fail if already has a timer running */ + for (dup = timer_base; dup; dup = dup->next) + if (dup->kind == kind + && dup->func_index == func_index + && dup->arg.a_void == arg->a_void) + break; + if (dup) { + char idbuf[QBUFSZ]; + +#ifdef VERBOSE_TIMER + Sprintf(idbuf, "%s timer", timeout_funcs[func_index].name); +#else + Sprintf(idbuf, "%s timer (%d)", kind_name(kind), (int) func_index); +#endif + impossible("Attempted to start duplicate %s, aborted.", idbuf); + return FALSE; + } + + gnu = (timer_element *) alloc(sizeof *gnu); + (void) memset((genericptr_t) gnu, 0, sizeof *gnu); gnu->next = 0; gnu->tid = timer_id++; gnu->timeout = monstermoves + when; @@ -1887,7 +1906,6 @@ anything *arg; if (kind == TIMER_OBJECT) /* increment object's timed count */ (arg->a_obj)->timed++; - /* should check for duplicates and fail if any */ return TRUE; } From c4a2f20af0280f6889819bea2f7f18e243a30c2a Mon Sep 17 00:00:00 2001 From: PatR Date: Sun, 28 Jul 2019 15:06:02 -0700 Subject: [PATCH 2/6] Mjollnir comment in artilist[] The description of Mjollnir's behavior when thrown was incomplete and slightly inaccurate. --- include/artilist.h | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/include/artilist.h b/include/artilist.h index 8948e521a..d1b1ef624 100644 --- a/include/artilist.h +++ b/include/artilist.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 artilist.h $NHDT-Date: 1433050874 2015/05/31 05:41:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.16 $ */ +/* NetHack 3.6 artilist.h $NHDT-Date: 1564351548 2019/07/28 22:05:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.20 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2017. */ /* NetHack may be freely redistributed. See license for details. */ @@ -57,8 +57,16 @@ STATIC_OVL NEARDATA struct artifact artilist[] = { 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. + * Mjollnir can be thrown when wielded if hero has 25 Strength + * (usually via gauntlets of power but possible with rings of + * gain strength). If the thrower is a Valkyrie, Mjollnir will + * usually (99%) return and then usually (separate 99%) be caught + * and automatically be re-wielded. When returning Mjollnir is + * not caught, there is a 50:50 chance of hitting hero for damage + * and its lightning shock might destroy some wands and/or rings. + * + * Monsters don't throw Mjollnir regardless of strength (not even + * fake-player valkyries). */ A("Mjollnir", WAR_HAMMER, /* Mjo:llnir */ (SPFX_RESTR | SPFX_ATTK), 0, 0, ELEC(5, 24), NO_DFNS, NO_CARY, 0, From 6dffe52a27adf9659e830667e868e34d992754fd Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 30 Jul 2019 17:24:33 -0700 Subject: [PATCH 3/6] Glory of Arioch vs spellbook From the newsgroup (reported for slash'em but applies to nethack too): a chaotic monk was crowned and told he or she had been "chosen to steal souls for My Glory!" while being given a spellbook of restore ability which has nothing whatever to do with soul stealing. There's alternate wording for when Stormbringer can't be given because it already exists; also use that for when it's not going to be given because the character is discouraged against wielding weapons. --- doc/fixes36.3 | 5 ++++- src/pray.c | 35 +++++++++++++++++++---------------- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index a20fc650e..1eeb0de1b 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.95 $ $NHDT-Date: 1564269131 2019/07/27 23:12:11 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.96 $ $NHDT-Date: 1564532667 2019/07/31 00:24:27 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -107,6 +107,9 @@ hero poly'd into nymph would steal gold along with other items change wizard mode #panic to require "yes" if 'paranoid_confirm:quit' is set add some additional validation checks when setting up a new timer (triggered by an ancient source comment rather than by any observed problems) +if a chaotic monk or wizard gets crowned and is given a spellbook rather than + Stormbringer as the crowning gift, don't describe the hero as having + been "chosen to steal souls for [Arioch's] glory" Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/pray.c b/src/pray.c index d40bb933c..42e5f8be8 100644 --- a/src/pray.c +++ b/src/pray.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pray.c $NHDT-Date: 1562462064 2019/07/07 01:14:24 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.116 $ */ +/* NetHack 3.6 pray.c $NHDT-Date: 1564532667 2019/07/31 00:24:27 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.117 $ */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -771,6 +771,20 @@ gcrownu() HPoison_resistance |= FROMOUTSIDE; godvoice(u.ualign.type, (char *) 0); + class_gift = STRANGE_OBJECT; + /* 3.3.[01] had this in the A_NEUTRAL case, + preventing chaotic wizards from receiving a spellbook */ + if (Role_if(PM_WIZARD) + && (!uwep || (uwep->oartifact != ART_VORPAL_BLADE + && uwep->oartifact != ART_STORMBRINGER)) + && !carrying(SPE_FINGER_OF_DEATH)) { + class_gift = SPE_FINGER_OF_DEATH; + } else if (Role_if(PM_MONK) && (!uwep || !uwep->oartifact) + && !carrying(SPE_RESTORE_ABILITY)) { + /* monks rarely wield a weapon */ + class_gift = SPE_RESTORE_ABILITY; + } + obj = ok_wep(uwep) ? uwep : 0; already_exists = in_hand = FALSE; /* lint suppression */ switch (u.ualign.type) { @@ -791,19 +805,13 @@ gcrownu() already_exists = exist_artifact(RUNESWORD, artiname(ART_STORMBRINGER)); verbalize("Thou art chosen to %s for My Glory!", - already_exists && !in_hand ? "take lives" : "steal souls"); + ((already_exists && !in_hand) + || class_gift != STRANGE_OBJECT) ? "take lives" + : "steal souls"); break; } - class_gift = STRANGE_OBJECT; - /* 3.3.[01] had this in the A_NEUTRAL case below, - preventing chaotic wizards from receiving a spellbook */ - if (Role_if(PM_WIZARD) - && (!uwep || (uwep->oartifact != ART_VORPAL_BLADE - && uwep->oartifact != ART_STORMBRINGER)) - && !carrying(SPE_FINGER_OF_DEATH)) { - class_gift = SPE_FINGER_OF_DEATH; - make_splbk: + if (objects[class_gift].oc_class == SPBOOK_CLASS) { obj = mksobj(class_gift, TRUE, FALSE); bless(obj); obj->bknown = 1; /* ok to skip set_bknown() */ @@ -818,11 +826,6 @@ gcrownu() obj = uwep; /* to be blessed,&c */ break; } - } else if (Role_if(PM_MONK) && (!uwep || !uwep->oartifact) - && !carrying(SPE_RESTORE_ABILITY)) { - /* monks rarely wield a weapon */ - class_gift = SPE_RESTORE_ABILITY; - goto make_splbk; } switch (u.ualign.type) { From 31c80383447ad3332f893724deff600efb648132 Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 31 Jul 2019 14:22:09 -0700 Subject: [PATCH 4/6] bad weapon check for monster multi-shot shooting A typo caused the bow and arrow check when a monster was wielding an elven box to test the hero's weapon with monster's ammo. [I looked at the old slash'em code where I think this came from and it doesn't have the typo but does have a different bug. A monster could get a multi-shot volley by wielding an elven bow when throwing darts or spears. The extra bow and arrow check is intended to prevent that. The typo was probably by me but I have no memory of that code....] Elves with bows (or other monsters who manage to pick up and wield an elven bow) will shoot bigger volleys after this fix. That will make them more dangerous but also cause them to run out of arrows more quickly. --- doc/fixes36.3 | 4 +++- src/mthrowu.c | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 1eeb0de1b..2ff46966a 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.96 $ $NHDT-Date: 1564532667 2019/07/31 00:24:27 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.97 $ $NHDT-Date: 1564608120 2019/07/31 21:22:00 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -110,6 +110,8 @@ add some additional validation checks when setting up a new timer (triggered if a chaotic monk or wizard gets crowned and is given a spellbook rather than Stormbringer as the crowning gift, don't describe the hero as having been "chosen to steal souls for [Arioch's] glory" +for multi-shot shooting by monsters, a typo checked hero's weapon for + compatibility with ammo when monster was wielding an elven bow Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/mthrowu.c b/src/mthrowu.c index d10d2f1f1..7cb178ed4 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mthrowu.c $NHDT-Date: 1542765360 2018/11/21 01:56:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.78 $ */ +/* NetHack 3.6 mthrowu.c $NHDT-Date: 1564608121 2019/07/31 21:22:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.84 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -183,7 +183,10 @@ struct obj *otmp, *mwep; /* Elven Craftsmanship makes for light, quick bows */ if (otmp->otyp == ELVEN_ARROW && !otmp->cursed) multishot++; - if (ammo_and_launcher(otmp, uwep) && mwep->otyp == ELVEN_BOW + /* for arrow, we checked bow&arrow at start of block, but for + bow, so far we've only validated that otmp is a weapon stack; + need to verify that it's a stack of arrows rather than darts */ + if (mwep->otyp == ELVEN_BOW && ammo_and_launcher(otmp, mwep) && !mwep->cursed) multishot++; /* 1/3 of launcher enchantment */ From 55e166ba08cbeab621055fa8bf80284289283c54 Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 2 Aug 2019 10:42:26 -0700 Subject: [PATCH 5/6] fix #H9082 - post-3.6.2 monster throwing crash Changing if (ammo_and_launcher(otmp, uwep) && mwep->otyp == ELVEN_BOW) (with 'uwep' typo) to if (mwep->otyp == ELVEN_BOW && ammo_and_launcher(otmp, mwep)) (with fixed 'mwep') moved ammo_and_launcher()'s hidden non-null test to after 'mwep->otyp'. If mwep was Null (so monster must be throwing non-ammo such as darts or daggers rather than shooting with a launcher), a crash occurred. (Throwing such things while the monster is wielding any weapon doesn't have this problem.) I don't think 3.6.2 can crash here. If hero's uwep is a bow, otmp must be arrows to get past pre-3.6.3's incorrect ammo_and_launcher() check. And a monster won't shoot arrows unless wielding a bow, so monster's mwep would be non-Null regardless of what uwep is. I tested a kobold with darts and an elven bow. But I also gave it one elven arrow to provoke it into wielding the bow and my test didn't throw darts with nothing wielded.... --- doc/fixes36.3 | 4 +++- src/mthrowu.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index 2ff46966a..bf9e7a39f 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.97 $ $NHDT-Date: 1564608120 2019/07/31 21:22:00 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.98 $ $NHDT-Date: 1564767725 2019/08/02 17:42:05 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -128,6 +128,8 @@ fix for feedback when a monster plays a fire horn at self to cure green slime ended up being used for zapping a wand of fire at self too wizard mode ^I "not carrying anything" still claimed "not carrying anything" if "(all items are already identified)" was given +monster throwing from stack of missiles (darts, daggers, spears) would cause + crash if it wasn't wielding a weapon (bug in multi-shot shooting fix) curses: sometimes the message window would show a blank line after a prompt curses: the change to show map in columns 1..79 instead of 2..80 made the highlight for '@' show up in the wrong place if clipped map had been diff --git a/src/mthrowu.c b/src/mthrowu.c index 7cb178ed4..1c65e2488 100644 --- a/src/mthrowu.c +++ b/src/mthrowu.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mthrowu.c $NHDT-Date: 1564608121 2019/07/31 21:22:01 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.84 $ */ +/* NetHack 3.6 mthrowu.c $NHDT-Date: 1564767726 2019/08/02 17:42:06 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.85 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Pasi Kallinen, 2016. */ /* NetHack may be freely redistributed. See license for details. */ @@ -183,10 +183,10 @@ struct obj *otmp, *mwep; /* Elven Craftsmanship makes for light, quick bows */ if (otmp->otyp == ELVEN_ARROW && !otmp->cursed) multishot++; - /* for arrow, we checked bow&arrow at start of block, but for + /* for arrow, we checked bow&arrow when entering block, but for bow, so far we've only validated that otmp is a weapon stack; need to verify that it's a stack of arrows rather than darts */ - if (mwep->otyp == ELVEN_BOW && ammo_and_launcher(otmp, mwep) + if (mwep && mwep->otyp == ELVEN_BOW && ammo_and_launcher(otmp, mwep) && !mwep->cursed) multishot++; /* 1/3 of launcher enchantment */ From 508af05e422126ac38b31b157b89699437b5c05c Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 2 Aug 2019 11:51:26 -0700 Subject: [PATCH 6/6] fix #H9084 - teleported boulder left stale screen Report was for Sokoban but it applied anywhere: if a teleported boulder landed in a pit or trap door or hole and flooreffects() used it up (so returned True), rloco() didn't update the location it was teleported from and it appeared not to have moved. (Line of sight was updated to reflect its absence but map spot wasn't redrawn without it.) --- doc/fixes36.3 | 5 ++++- src/teleport.c | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index bf9e7a39f..00745966a 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.98 $ $NHDT-Date: 1564767725 2019/08/02 17:42:05 $ +$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.99 $ $NHDT-Date: 1564771880 2019/08/02 18:51:20 $ This fixes36.3 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.2 in May 2019. Please note, however, @@ -112,6 +112,9 @@ if a chaotic monk or wizard gets crowned and is given a spellbook rather than been "chosen to steal souls for [Arioch's] glory" for multi-shot shooting by monsters, a typo checked hero's weapon for compatibility with ammo when monster was wielding an elven bow +when a boulder was teleported, if it landed in a pit or trap door or hole its + former location wasn't updated to show that it wasn't there anymore + (noticed in Sokoban but not limited to there) Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/teleport.c b/src/teleport.c index 100a74d3b..9c2bd66f5 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 teleport.c $NHDT-Date: 1561336020 2019/06/24 00:27:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.89 $ */ +/* NetHack 3.6 teleport.c $NHDT-Date: 1564771880 2019/08/02 18:51:20 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.92 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1450,6 +1450,9 @@ register struct obj *obj; dndest.nhx, dndest.nhy))); if (flooreffects(obj, tx, ty, "fall")) { + /* update old location since flooreffects() couldn't; + unblock_point() for boulder handled by obj_extract_self() */ + newsym(otx, oty); return FALSE; } else if (otx == 0 && oty == 0) { ; /* fell through a trap door; no update of old loc needed */ @@ -1466,6 +1469,7 @@ register struct obj *obj; newsym(otx, oty); /* update old location */ } place_object(obj, tx, ty); + /* note: block_point() for boulder handled by place_object() */ newsym(tx, ty); return TRUE; }