From e92445810f7ec8b9d5afc7730e2cf3d26e209b43 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 8 Oct 2019 19:44:51 +0300 Subject: [PATCH 1/4] Fix ball and chain sanity Scatter did not consider the ball or chain, and moved them around, causing ball and chain sanity error. One way to trigger was being punished, with chain on a land mine and having a monster trigger the mine. Now the chain will shatter, unpunishing the hero. --- doc/fixes36.3 | 1 + src/explode.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/doc/fixes36.3 b/doc/fixes36.3 index f9781a9a8..71572a441 100644 --- a/doc/fixes36.3 +++ b/doc/fixes36.3 @@ -177,6 +177,7 @@ avoid 'object lost' panic when polymorph causes loss of levitation boots or over but buffered output didn't show it until hero stopped, so it wasn't possible to tell where they were, unlike all other forms of multiple movement; stop running if/when an engraving is reached +fix exploding land mine moving ball or chain and causing a sanity error Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository diff --git a/src/explode.c b/src/explode.c index 941d22201..2c46178fd 100644 --- a/src/explode.c +++ b/src/explode.c @@ -621,6 +621,13 @@ struct obj *obj; /* only scatter this obj */ obj->ox, obj->oy, sx, sy); while ((otmp = (individual_object ? obj : level.objects[sx][sy])) != 0) { + if (otmp == uball || otmp == uchain) { + boolean waschain = (otmp == uchain); + pline_The("chain shatters!"); + unpunish(); + if (waschain) + continue; + } if (otmp->quan > 1L) { qtmp = otmp->quan - 1L; if (qtmp > LARGEST_INT) From ba3004d6e2ded6de9f16439ab3847dafbc543284 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Oct 2019 13:26:39 -0700 Subject: [PATCH 2/4] W_WEAPON -> W_WEAPONS Report #H9243 misinterpreted W_WEAPON as W_WEP and attributed a hypothetical ball and chain sanity checking problem to that. Rename the former to W_WEAPONS to emphasize that it includes alternate/secondary weapon and quivered stack as well as wielded weapon. --- include/prop.h | 4 ++-- src/ball.c | 4 ++-- src/do_wear.c | 8 ++++---- src/invent.c | 4 ++-- src/mkobj.c | 6 +++--- src/pickup.c | 5 +++-- src/steal.c | 4 ++-- 7 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/prop.h b/include/prop.h index ba0dc0863..570f3f2fa 100644 --- a/include/prop.h +++ b/include/prop.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 prop.h $NHDT-Date: 1547514641 2019/01/15 01:10:41 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.20 $ */ +/* NetHack 3.6 prop.h $NHDT-Date: 1570566360 2019/10/08 20:26:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.21 $ */ /* Copyright (c) 1989 Mike Threepoint */ /* NetHack may be freely redistributed. See license for details. */ @@ -106,7 +106,7 @@ struct prop { #define W_WEP 0x00000100L /* Wielded weapon */ #define W_QUIVER 0x00000200L /* Quiver for (f)iring ammo */ #define W_SWAPWEP 0x00000400L /* Secondary weapon */ -#define W_WEAPON (W_WEP | W_SWAPWEP | W_QUIVER) +#define W_WEAPONS (W_WEP | W_SWAPWEP | W_QUIVER) #define W_ART 0x00001000L /* Carrying artifact (not really worn) */ #define W_ARTI 0x00002000L /* Invoked artifact (not really worn) */ /* Amulets, rings, tools, and other items */ diff --git a/src/ball.c b/src/ball.c index 81e2d6dd2..9a309676a 100644 --- a/src/ball.c +++ b/src/ball.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 ball.c $NHDT-Date: 1559601027 2019/06/03 22:30:27 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.40 $ */ +/* NetHack 3.6 ball.c $NHDT-Date: 1570566373 2019/10/08 20:26:13 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.43 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) David Cohrs, 2006. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1074,7 +1074,7 @@ bc_sanity_check() && uball->where != OBJ_FREE) || (freeball ^ freechain) || (uball->owornmask & W_BALL) == 0L - || (uball->owornmask & ~(W_BALL | W_WEAPON)) != 0L)) { + || (uball->owornmask & ~(W_BALL | W_WEAPONS)) != 0L)) { otyp = uball->otyp; onam = safe_typename(otyp); impossible("uball: type %d (%s), where %d, wornmask=0x%08lx", diff --git a/src/do_wear.c b/src/do_wear.c index 78262cba0..edf4d6faf 100644 --- a/src/do_wear.c +++ b/src/do_wear.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 do_wear.c $NHDT-Date: 1559670603 2019/06/04 17:50:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.109 $ */ +/* NetHack 3.6 do_wear.c $NHDT-Date: 1570566377 2019/10/08 20:26:17 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.111 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1101,7 +1101,7 @@ struct obj *otmp; boolean already_blind = Blind, changed = FALSE; /* blindfold might be wielded; release it for wearing */ - if (otmp->owornmask & W_WEAPON) + if (otmp->owornmask & W_WEAPONS) remove_worn_item(otmp, FALSE); setworn(otmp, W_TOOL); on_msg(otmp); @@ -1919,7 +1919,7 @@ struct obj *obj; /* if the armor is wielded, release it for wearing (won't be welded even if cursed; that only happens for weapons/weptools) */ - if (obj->owornmask & W_WEAPON) + if (obj->owornmask & W_WEAPONS) remove_worn_item(obj, FALSE); /* * Setting obj->known=1 is done because setworn() causes hero's AC @@ -2545,7 +2545,7 @@ doddoremarm() possibly combined with weapons */ (void) strncpy(context.takeoff.disrobing, "disrobing", CONTEXTVERBSZ); /* specific activity when handling weapons only */ - if (!(context.takeoff.mask & ~W_WEAPON)) + if (!(context.takeoff.mask & ~W_WEAPONS)) (void) strncpy(context.takeoff.disrobing, "disarming", CONTEXTVERBSZ); (void) take_off(); diff --git a/src/invent.c b/src/invent.c index 01c252b89..be2a24497 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1570232224 2019/10/04 23:37:04 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.263 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1570566378 2019/10/08 20:26:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.264 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1889,7 +1889,7 @@ boolean is_worn(otmp) struct obj *otmp; { - return (otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE | W_WEAPON)) + return (otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE | W_WEAPONS)) ? TRUE : FALSE; } diff --git a/src/mkobj.c b/src/mkobj.c index 4a5e7f0dc..d3cede639 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1561588627 2019/06/26 22:37:07 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.151 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1570566379 2019/10/08 20:26:19 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.152 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2572,7 +2572,7 @@ struct obj *obj; } if (n == 2 && carried(obj) && obj == uball && (owornmask & W_BALL) != 0L - && (owornmask & W_WEAPON) != 0L) { + && (owornmask & W_WEAPONS) != 0L) { /* chained ball can be wielded/alt-wielded/quivered; if so, pretend it's not chained in order to check the weapon pointer (we've already verified the ball pointer by successfully passing @@ -2681,7 +2681,7 @@ struct obj *obj; becoming embedded in poly'd hero's skin */ if (embedded && !Is_dragon_scales(obj)) what = "skin"; - } else if (owornmask & W_WEAPON) { + } else if (owornmask & W_WEAPONS) { /* monsters don't maintain alternate weapon or quiver */ if (mcarried(obj) && (owornmask & (W_SWAPWEP | W_QUIVER)) != 0L) what = (owornmask & W_SWAPWEP) != 0L ? "monst alt weapon?" diff --git a/src/pickup.c b/src/pickup.c index 16473747e..4c789f38a 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 pickup.c $NHDT-Date: 1570142736 2019/10/03 22:45:36 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.234 $ */ +/* NetHack 3.6 pickup.c $NHDT-Date: 1570566381 2019/10/08 20:26:21 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.235 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1206,7 +1206,8 @@ int qflags; for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { if (curr->oclass == *pack) { if ((qflags & WORN_TYPES) - && !(curr->owornmask & (W_ARMOR | W_ACCESSORY | W_WEAPON))) + && !(curr->owornmask & (W_ARMOR | W_ACCESSORY + | W_WEAPONS))) continue; if (!counted_category) { ccount++; diff --git a/src/steal.c b/src/steal.c index 2686a5392..86933c73a 100644 --- a/src/steal.c +++ b/src/steal.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 steal.c $NHDT-Date: 1562806584 2019/07/11 00:56:24 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.74 $ */ +/* NetHack 3.6 steal.c $NHDT-Date: 1570566382 2019/10/08 20:26:22 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.75 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -218,7 +218,7 @@ boolean unchain_ball; /* whether to unpunish or just unwield */ Ring_gone(obj); } else if (obj->owornmask & W_TOOL) { Blindf_off(obj); - } else if (obj->owornmask & W_WEAPON) { + } else if (obj->owornmask & W_WEAPONS) { if (obj == uwep) uwepgone(); if (obj == uswapwep) From 3c6303b34e43faf2f8044d84fbc22b418ce8d89f Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 8 Oct 2019 14:23:27 -0700 Subject: [PATCH 3/4] fix #H9266 - redundant obj init Sword given to angels used obj->spe = max(obj->spe, rn2(4)) [except using a temporary to sanely work with max() macro]. But the obj was explicitly created as no-init, so obj->spe was always 0 and the max() was pointless. Shield given to angels was manipulating bless/curse state directly instead of using the functions intended for that, a no-no and also pointless to be clearing 'cursed' for a no-init item. Mace for priests had useless handling for object creation failure. Object creation failure could only happen if the mksobj() call had a valid entry in objects[] (or out of bounds access that didn't crash) for an object class that it doesn't know how to handle. That can't happen unless somebody screws up big time. If it ever did happen, it would have produced a memory leak. --- src/makemon.c | 19 ++++++++----------- src/mkobj.c | 3 ++- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/makemon.c b/src/makemon.c index 2350e77a0..6d3635cd2 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 makemon.c $NHDT-Date: 1561236435 2019/06/22 20:47:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.138 $ */ +/* NetHack 3.6 makemon.c $NHDT-Date: 1570569787 2019/10/08 21:23:07 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.140 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -166,7 +166,7 @@ register struct monst *mtmp; register struct permonst *ptr = mtmp->data; register int mm = monsndx(ptr); struct obj *otmp; - int bias, spe2, w1, w2; + int bias, w1, w2; if (Is_rogue_level(&u.uz)) return; @@ -259,12 +259,10 @@ register struct monst *mtmp; } else if (ptr->msound == MS_PRIEST || quest_mon_represents_role(ptr, PM_PRIEST)) { otmp = mksobj(MACE, FALSE, FALSE); - if (otmp) { - otmp->spe = rnd(3); - if (!rn2(2)) - curse(otmp); - (void) mpickobj(mtmp, otmp); - } + otmp->spe = rnd(3); + if (!rn2(2)) + curse(otmp); + (void) mpickobj(mtmp, otmp); } else if (mm == PM_NINJA) { /* extra quest villains */ (void) mongets(mtmp, rn2(4) ? SHURIKEN : DART); (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE); @@ -336,14 +334,13 @@ register struct monst *mtmp; artiname(rn2(2) ? ART_DEMONBANE : ART_SUNSWORD)); bless(otmp); otmp->oerodeproof = TRUE; - spe2 = rn2(4); - otmp->spe = max(otmp->spe, spe2); + otmp->spe = rn2(4); (void) mpickobj(mtmp, otmp); otmp = mksobj(!rn2(4) || is_lord(ptr) ? SHIELD_OF_REFLECTION : LARGE_SHIELD, FALSE, FALSE); - otmp->cursed = FALSE; + /* uncurse(otmp); -- mksobj(,FALSE,) item is always uncursed */ otmp->oerodeproof = TRUE; otmp->spe = 0; (void) mpickobj(mtmp, otmp); diff --git a/src/mkobj.c b/src/mkobj.c index d3cede639..24124f706 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 mkobj.c $NHDT-Date: 1570566379 2019/10/08 20:26:19 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.152 $ */ +/* NetHack 3.6 mkobj.c $NHDT-Date: 1570569798 2019/10/08 21:23:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.153 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1064,6 +1064,7 @@ boolean artif; default: impossible("impossible mkobj %d, sym '%c'.", otmp->otyp, objects[otmp->otyp].oc_class); + dealloc_obj(otmp); /* free() would suffice here */ return (struct obj *) 0; } } From bab05ea680c289c0b79228b643a5dd49fbc17cf8 Mon Sep 17 00:00:00 2001 From: nhmall Date: Tue, 8 Oct 2019 20:17:01 -0400 Subject: [PATCH 4/4] remove one band from a recent attempted warning correction --- win/curses/cursmisc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index 80ff91c65..e435f2211 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -377,6 +377,7 @@ curses_str_remainder(const char *str, int width, int line_num) int strsize = strlen(str) + 1; #if __STDC_VERSION__ >= 199901L char substr[strsize]; + char curstr[strsize]; char tmpstr[strsize]; strcpy(substr, str); @@ -385,6 +386,7 @@ curses_str_remainder(const char *str, int width, int line_num) #define BUFSZ 256 #endif char substr[BUFSZ * 2]; + char curstr[BUFSZ * 2]; char tmpstr[BUFSZ * 2]; if (strsize > (BUFSZ * 2) - 1) { @@ -412,6 +414,10 @@ curses_str_remainder(const char *str, int width, int line_num) if (last_space == 0) { /* No spaces found */ last_space = count - 1; } + for (count = 0; count < last_space; count++) { + curstr[count] = substr[count]; + } + curstr[count] = '\0'; if (substr[count] == '\0') { break; }