fix for breaking unreachable statue
Reported almost 9 years ago: if an adjacent statue was in a pit, you could use a pick-axe to break it even though if you managed to move to the pit location without falling in, you wouldn't be able to reach objects there including the statue. Allow a pick to reach if hero is in a conjoined pit, or if it is a mattock rather than an ordinary pick-axe. Otherwise you'll get the "you swing at thin air" result. Similarly when hero is in a pit and and adjacent statue or boulder is on the floor: mattock will work but pick-axe now yields "you can't reach".
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1393 $ $NHDT-Date: 1709388534 2024/03/02 14:08:54 $
|
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1396 $ $NHDT-Date: 1709928001 2024/03/08 20:00:01 $
|
||||||
|
|
||||||
General Fixes and Modified Features
|
General Fixes and Modified Features
|
||||||
-----------------------------------
|
-----------------------------------
|
||||||
@@ -1371,6 +1371,8 @@ when a spellbook was polymorphed into a novel and then incrementing spestudied
|
|||||||
field turned it into a blank spellbook, the novel's title would stick:
|
field turned it into a blank spellbook, the novel's title would stick:
|
||||||
"{spellbook of blank paper|plain spellbook} named <Discworld title>"
|
"{spellbook of blank paper|plain spellbook} named <Discworld title>"
|
||||||
walking on ice can make you slide in a random direction
|
walking on ice can make you slide in a random direction
|
||||||
|
if an adjacent statue was a in a pit, you could break it with a pick-axe even
|
||||||
|
though you're conceptually at the wrong elevation to reach it
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||||
|
|||||||
73
src/dig.c
73
src/dig.c
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.7 dig.c $NHDT-Date: 1702206282 2023/12/10 11:04:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.204 $ */
|
/* NetHack 3.7 dig.c $NHDT-Date: 1709928001 2024/03/08 20:00:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.211 $ */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/*-Copyright (c) Michael Allison, 2012. */
|
/*-Copyright (c) Michael Allison, 2012. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
static boolean rm_waslit(void);
|
static boolean rm_waslit(void);
|
||||||
static void mkcavepos(coordxy, coordxy, int, boolean, boolean);
|
static void mkcavepos(coordxy, coordxy, int, boolean, boolean);
|
||||||
static void mkcavearea(boolean);
|
static void mkcavearea(boolean);
|
||||||
|
static boolean pick_can_reach(struct obj *, coordxy, coordxy) NONNULLARG1;
|
||||||
static int dig(void);
|
static int dig(void);
|
||||||
static void dig_up_grave(coord *);
|
static void dig_up_grave(coord *);
|
||||||
static boolean watchman_canseeu(struct monst *) NONNULLARG1;
|
static boolean watchman_canseeu(struct monst *) NONNULLARG1;
|
||||||
@@ -135,6 +136,34 @@ mkcavearea(boolean rockit)
|
|||||||
gv.vision_full_recalc = 1; /* everything changed */
|
gv.vision_full_recalc = 1; /* everything changed */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called when attempting to break a statue or boulder with a pick */
|
||||||
|
static boolean
|
||||||
|
pick_can_reach(struct obj *pick, coordxy x, coordxy y)
|
||||||
|
{
|
||||||
|
struct trap *t = t_at(x, y);
|
||||||
|
/* tseen: pit only affects item positioning when it is known */
|
||||||
|
boolean target_in_pit = t && is_pit(t->ttyp) && t->tseen;
|
||||||
|
|
||||||
|
/* if hero is in a pit, pick can only reach if the statue is too and
|
||||||
|
the two pits are conjoined or the statue isn't and pick is two-handed;
|
||||||
|
this applies to hero in pit trying to reach an adjcacent boulder too */
|
||||||
|
if (u.utrap && u.utraptype == TT_PIT) {
|
||||||
|
if (target_in_pit)
|
||||||
|
return conjoined_pits(t, t_at(u.ux, u.uy), FALSE);
|
||||||
|
return bimanual(pick);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* when hero isn't in a pit, a mattock or flying hero w/ pick can reach
|
||||||
|
whether or not the statue is in a pit */
|
||||||
|
if (bimanual(pick) || Flying)
|
||||||
|
return TRUE;
|
||||||
|
/* one-handed pick-axe can reach if statue isn't in a pit */
|
||||||
|
if (!target_in_pit)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* When digging into location <x,y>, what are you actually digging into? */
|
/* When digging into location <x,y>, what are you actually digging into? */
|
||||||
int
|
int
|
||||||
dig_typ(struct obj *otmp, coordxy x, coordxy y)
|
dig_typ(struct obj *otmp, coordxy x, coordxy y)
|
||||||
@@ -147,9 +176,11 @@ dig_typ(struct obj *otmp, coordxy x, coordxy y)
|
|||||||
if (!ispick && !is_axe(otmp))
|
if (!ispick && !is_axe(otmp))
|
||||||
return DIGTYP_UNDIGGABLE;
|
return DIGTYP_UNDIGGABLE;
|
||||||
|
|
||||||
return ((ispick && sobj_at(STATUE, x, y))
|
return ((ispick && sobj_at(STATUE, x, y)
|
||||||
|
&& pick_can_reach(otmp, x, y))
|
||||||
? DIGTYP_STATUE
|
? DIGTYP_STATUE
|
||||||
: (ispick && sobj_at(BOULDER, x, y))
|
: (ispick && sobj_at(BOULDER, x, y)
|
||||||
|
&& pick_can_reach(otmp, x, y))
|
||||||
? DIGTYP_BOULDER
|
? DIGTYP_BOULDER
|
||||||
: closed_door(x, y)
|
: closed_door(x, y)
|
||||||
? DIGTYP_DOOR
|
? DIGTYP_DOOR
|
||||||
@@ -1112,6 +1143,8 @@ use_pick_axe2(struct obj *obj)
|
|||||||
return ECMD_TIME;
|
return ECMD_TIME;
|
||||||
dig_target = dig_typ(obj, rx, ry);
|
dig_target = dig_typ(obj, rx, ry);
|
||||||
if (dig_target == DIGTYP_UNDIGGABLE) {
|
if (dig_target == DIGTYP_UNDIGGABLE) {
|
||||||
|
struct obj *boulder;
|
||||||
|
|
||||||
/* ACCESSIBLE or POOL */
|
/* ACCESSIBLE or POOL */
|
||||||
trap = t_at(rx, ry);
|
trap = t_at(rx, ry);
|
||||||
if (trap && trap->ttyp == WEB) {
|
if (trap && trap->ttyp == WEB) {
|
||||||
@@ -1137,17 +1170,28 @@ use_pick_axe2(struct obj *obj)
|
|||||||
You("need an axe to cut down a tree.");
|
You("need an axe to cut down a tree.");
|
||||||
} else if (IS_ROCK(lev->typ)) {
|
} else if (IS_ROCK(lev->typ)) {
|
||||||
You("need a pick to dig rock.");
|
You("need a pick to dig rock.");
|
||||||
} else if (!ispick && (sobj_at(STATUE, rx, ry)
|
} else if ((boulder = sobj_at(BOULDER, rx, ry)) != 0
|
||||||
|| sobj_at(BOULDER, rx, ry))) {
|
|| sobj_at(STATUE, rx, ry)) {
|
||||||
boolean vibrate = !rn2(3);
|
/* if both boulders and statues are present, the topmost
|
||||||
|
boulder will be shown on the map so treat it as target */
|
||||||
|
const char *what = boulder ? "boulder" : "statue";
|
||||||
|
|
||||||
pline("Sparks fly as you whack the %s.%s",
|
if (!ispick) {
|
||||||
sobj_at(STATUE, rx, ry) ? "statue" : "boulder",
|
boolean vibrate = !rn2(3);
|
||||||
vibrate ? " The axe-handle vibrates violently!" : "");
|
|
||||||
if (vibrate)
|
pline("Sparks fly as you whack the %s.%s", what,
|
||||||
losehp(Maybe_Half_Phys(2), "axing a hard object",
|
vibrate ? " The axe-handle vibrates violently!"
|
||||||
KILLED_BY);
|
: "");
|
||||||
wake_nearby();
|
if (vibrate)
|
||||||
|
losehp(Maybe_Half_Phys(2), "axing a hard object",
|
||||||
|
KILLED_BY);
|
||||||
|
wake_nearby();
|
||||||
|
} else {
|
||||||
|
/* using a pick but dig_target is DIGTYPE_UNDIGGABLE
|
||||||
|
and there is at least one boulder or statue or both
|
||||||
|
present; pick_can_reach() returned false */
|
||||||
|
You_cant("reach the %s.", what);
|
||||||
|
}
|
||||||
} else if (u.utrap && u.utraptype == TT_PIT && trap
|
} else if (u.utrap && u.utraptype == TT_PIT && trap
|
||||||
&& (trap_with_u = t_at(u.ux, u.uy))
|
&& (trap_with_u = t_at(u.ux, u.uy))
|
||||||
&& is_pit(trap->ttyp)
|
&& is_pit(trap->ttyp)
|
||||||
@@ -1177,7 +1221,8 @@ use_pick_axe2(struct obj *obj)
|
|||||||
|
|
||||||
gd.did_dig_msg = FALSE;
|
gd.did_dig_msg = FALSE;
|
||||||
gc.context.digging.quiet = FALSE;
|
gc.context.digging.quiet = FALSE;
|
||||||
if (gc.context.digging.pos.x != rx || gc.context.digging.pos.y != ry
|
if (gc.context.digging.pos.x != rx
|
||||||
|
|| gc.context.digging.pos.y != ry
|
||||||
|| !on_level(&gc.context.digging.level, &u.uz)
|
|| !on_level(&gc.context.digging.level, &u.uz)
|
||||||
|| gc.context.digging.down) {
|
|| gc.context.digging.down) {
|
||||||
if (flags.autodig && dig_target == DIGTYP_ROCK
|
if (flags.autodig && dig_target == DIGTYP_ROCK
|
||||||
|
|||||||
Reference in New Issue
Block a user