From 6c42180cfcc7e9a07a7498d7d11c67ef579af65a Mon Sep 17 00:00:00 2001 From: PatR Date: Wed, 26 Feb 2025 12:15:13 -0800 Subject: [PATCH] fix issue #1383 - chopping boulder at tree spot Reported by k21971: applying an axe toward a location that contained both a tree and a boulder (or statue) would use the axe to break the boulder/statue rather than chop down the tree. Different code is used to finish the dig/chop than is used to decide whether the tool is appropriate for its target. Fixes #1383 --- doc/fixes3-7-0.txt | 4 +++- src/dig.c | 57 +++++++++++++++++++++++----------------------- 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index e54ab8cf7..a9f4960d9 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1533 $ $NHDT-Date: 1738638877 2025/02/03 19:14:37 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1535 $ $NHDT-Date: 1740629713 2025/02/26 20:15:13 $ General Fixes and Modified Features ----------------------------------- @@ -1504,6 +1504,8 @@ since introduction in 3.1.0, the definition for Mitre of Holiness has specified that carrying it provides fire resistance, but that had never been implemented; wearing it didn't confer fire resistance either--there is no 'defends' capability for it since carrying should encompass that +if a tree and a boulder or statue were at the same location, applying an axe + would break the boulder or statue rather than chop the tree Fixes to 3.7.0-x General Problems Exposed Via git Repository diff --git a/src/dig.c b/src/dig.c index c0c341248..195222235 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dig.c $NHDT-Date: 1736530208 2025/01/10 09:30:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.225 $ */ +/* NetHack 3.7 dig.c $NHDT-Date: 1740629713 2025/02/26 20:15:13 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Michael Allison, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -168,29 +168,27 @@ pick_can_reach(struct obj *pick, coordxy x, coordxy y) int dig_typ(struct obj *otmp, coordxy x, coordxy y) { - boolean ispick; + int ltyp; - if (!otmp) - return DIGTYP_UNDIGGABLE; - ispick = is_pick(otmp); - if (!ispick && !is_axe(otmp)) + if (!isok(x, y) || !otmp || (!is_pick(otmp) && !is_axe(otmp))) return DIGTYP_UNDIGGABLE; - return ((ispick && sobj_at(STATUE, x, y) - && pick_can_reach(otmp, x, y)) - ? DIGTYP_STATUE - : (ispick && sobj_at(BOULDER, x, y) - && pick_can_reach(otmp, x, y)) - ? DIGTYP_BOULDER - : closed_door(x, y) - ? DIGTYP_DOOR - : IS_TREE(levl[x][y].typ) - ? (ispick ? DIGTYP_UNDIGGABLE : DIGTYP_TREE) - : (ispick && IS_OBSTRUCTED(levl[x][y].typ) - && (!svl.level.flags.arboreal - || IS_WALL(levl[x][y].typ))) - ? DIGTYP_ROCK - : DIGTYP_UNDIGGABLE); + ltyp = levl[x][y].typ; + if (is_axe(otmp)) + return closed_door(x, y) ? DIGTYP_DOOR + : IS_TREE(ltyp) ? DIGTYP_TREE /* axe vs tree */ + : DIGTYP_UNDIGGABLE; + /*assert(is_pick(otmp));*/ + return (sobj_at(STATUE, x, y) && pick_can_reach(otmp, x, y)) + ? DIGTYP_STATUE + : (sobj_at(BOULDER, x, y) && pick_can_reach(otmp, x, y)) + ? DIGTYP_BOULDER + : closed_door(x, y) ? DIGTYP_DOOR + : IS_TREE(ltyp) ? DIGTYP_UNDIGGABLE /* pick vs tree */ + : (IS_OBSTRUCTED(ltyp) + && (!svl.level.flags.arboreal || IS_WALL(ltyp))) + ? DIGTYP_ROCK + : DIGTYP_UNDIGGABLE; } boolean @@ -441,21 +439,22 @@ dig(void) if (svc.context.digging.effort > 100) { const char *digtxt, *dmgtxt = (const char *) 0; - struct obj *obj; + struct obj *obj, *bobj; boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE); + int digtyp = dig_typ(uwep, dpx, dpy); - if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) { + if (digtyp == DIGTYP_STATUE + && (obj = sobj_at(STATUE, dpx, dpy)) != 0) { if (break_statue(obj)) digtxt = "The statue shatters."; else /* it was a statue trap; break_statue() - * printed a message and updated the screen - */ + printed a message and updated the screen */ digtxt = (char *) 0; - } else if ((obj = sobj_at(BOULDER, dpx, dpy)) != 0) { - struct obj *bobj; - + } else if (digtyp == DIGTYP_BOULDER + && (obj = sobj_at(BOULDER, dpx, dpy)) != 0) { fracture_rock(obj); + /*[3.7: this probably isn't necessary anymore]*/ if ((bobj = sobj_at(BOULDER, dpx, dpy)) != 0) { /* another boulder here, restack it to the top */ obj_extract_self(bobj); @@ -474,7 +473,7 @@ dig(void) goto cleanup; } } - if (IS_TREE(lev->typ)) { + if (digtyp == DIGTYP_TREE) { digtxt = "You cut down the tree."; lev->typ = ROOM, lev->flags = 0; if (!rn2(5))