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
This commit is contained in:
PatR
2025-02-26 12:15:13 -08:00
parent 1fd3bb661f
commit 6c42180cfc
2 changed files with 31 additions and 30 deletions

View File

@@ -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

View File

@@ -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))