show trapped doors,chests as themselves \
instead of as fake bear traps Use the new traps and their tiles when confused gold detection finds trapped doors and trapped chests. (Large boxes can be trapped too; they use the trapped chest trap and corresponding tile rather than have their own.) Usually these pseudo-traps go away when as soon as they are within line of sight. (While testing, I noticed that seeing a trapped door from outside its room rather than inside didn't behave that way. The door was created by wizard mode wishing; I don't know whether that was a factor.) I also discovered that secret doors weren't being handled correctly. They can't be trapped because of their use of both the doormask and wall_info overlays of levl[][].flags, but I had a secret door be falsely displayed as a trap. This fixes that. We should have obj->tknown and rm->D_TRAPKNOWN so that the hero won't forget about these traps after declining to attempt to untrap them. But that's more work than I care to tackle.
This commit is contained in:
@@ -894,6 +894,8 @@ inventory #adjust for !fixinv, after picking 'from' slot the prompt for 'to'
|
||||
where x is last letter used (despite that, y could still be picked)
|
||||
with two-weapon combat or Cleaver attacking multiple targets, hero kept going
|
||||
with next attack after being paralyzed by passive counter-attack
|
||||
trap detection could falsely find trapped secret doors; those can't be trapped
|
||||
due to details of how they use overlaid fields in the rm structure
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
|
||||
@@ -1595,6 +1597,8 @@ pets are more likely to follow you closely if you are carrying something they
|
||||
really like to eat; behave as if you are carrying such whenever you
|
||||
are standing on stairs so that pets will try harder to come to you
|
||||
allow setting msgtype in SOUND line
|
||||
display detected door traps and chest traps as trapped doors and trapped
|
||||
chests rather than as fake bear traps
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
57
src/detect.c
57
src/detect.c
@@ -28,6 +28,12 @@ static void openone(int, int, genericptr_t);
|
||||
static int mfind0(struct monst *, boolean);
|
||||
static int reveal_terrain_getglyph(int, int, int, unsigned, int, int);
|
||||
|
||||
/* dummytrap: used when detecting traps finds a door or chest trap; the
|
||||
couple of fields that matter are always re-initialized during use so
|
||||
this does not need to be part of 'struct instance_globals g'; fields
|
||||
that aren't used are compile-/link-/load-time initialized to 0 */
|
||||
static struct trap dummytrap;
|
||||
|
||||
/* wildcard class for clear_stale_map - this used to be used as a getobj()
|
||||
input but it's no longer used for that function */
|
||||
#define ALL_CLASSES (MAXOCLASSES + 1)
|
||||
@@ -111,7 +117,7 @@ trapped_chest_at(int ttyp, int x, int y)
|
||||
|
||||
if (!glyph_is_trap(glyph_at(x, y)))
|
||||
return FALSE;
|
||||
if (ttyp != BEAR_TRAP || (Hallucination && rn2(20)))
|
||||
if (ttyp != TRAPPED_CHEST || (Hallucination && rn2(20)))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
@@ -153,7 +159,7 @@ trapped_door_at(int ttyp, int x, int y)
|
||||
|
||||
if (!glyph_is_trap(glyph_at(x, y)))
|
||||
return FALSE;
|
||||
if (ttyp != BEAR_TRAP || (Hallucination && rn2(20)))
|
||||
if (ttyp != TRAPPED_DOOR || (Hallucination && rn2(20)))
|
||||
return FALSE;
|
||||
lev = &levl[x][y];
|
||||
if (!IS_DOOR(lev->typ))
|
||||
@@ -851,14 +857,16 @@ sense_trap(struct trap *trap, xchar x, xchar y, int src_cursed)
|
||||
} else if (trap) {
|
||||
map_trap(trap, 1);
|
||||
trap->tseen = 1;
|
||||
} else { /* trapped door or trapped chest */
|
||||
struct trap temp_trap; /* fake trap */
|
||||
|
||||
(void) memset((genericptr_t) &temp_trap, 0, sizeof temp_trap);
|
||||
temp_trap.tx = x;
|
||||
temp_trap.ty = y;
|
||||
temp_trap.ttyp = BEAR_TRAP; /* some kind of trap */
|
||||
map_trap(&temp_trap, 1);
|
||||
} else {
|
||||
/*
|
||||
* OBSOLETE; this was for trapped door or trapped chest
|
||||
* but those are handled by 'if (trap) {map_trap()}' now
|
||||
* and this block of code shouldn't be reachable anymore.
|
||||
*/
|
||||
dummytrap.tx = x;
|
||||
dummytrap.ty = y;
|
||||
dummytrap.ttyp = BEAR_TRAP; /* some kind of trap */
|
||||
map_trap(&dummytrap, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,8 +878,10 @@ sense_trap(struct trap *trap, xchar x, xchar y, int src_cursed)
|
||||
2 if found at some other spot, 3 if both, 0 otherwise; optionally
|
||||
update the map to show where such traps were found */
|
||||
static int
|
||||
detect_obj_traps(struct obj *objlist, boolean show_them,
|
||||
int how) /* 1 for misleading map feedback */
|
||||
detect_obj_traps(
|
||||
struct obj *objlist,
|
||||
boolean show_them,
|
||||
int how) /* 1 for misleading map feedback */
|
||||
{
|
||||
struct obj *otmp;
|
||||
xchar x, y;
|
||||
@@ -882,12 +892,15 @@ detect_obj_traps(struct obj *objlist, boolean show_them,
|
||||
* If so, should they be displayed as objects or as traps?
|
||||
*/
|
||||
|
||||
dummytrap.ttyp = TRAPPED_CHEST;
|
||||
for (otmp = objlist; otmp; otmp = otmp->nobj) {
|
||||
if (Is_box(otmp) && otmp->otrapped
|
||||
&& get_obj_location(otmp, &x, &y, BURIED_TOO | CONTAINED_TOO)) {
|
||||
result |= u_at(x, y) ? OTRAP_HERE : OTRAP_THERE;
|
||||
if (show_them)
|
||||
sense_trap((struct trap *) 0, x, y, how);
|
||||
if (show_them) {
|
||||
dummytrap.tx = x, dummytrap.ty = y;
|
||||
sense_trap(&dummytrap, x, y, how);
|
||||
}
|
||||
}
|
||||
if (Has_contents(otmp))
|
||||
result |= detect_obj_traps(otmp->cobj, show_them, how);
|
||||
@@ -950,6 +963,11 @@ trap_detect(struct obj *sobj) /* null if crystal ball,
|
||||
/* door traps */
|
||||
for (door = 0; door < g.doorindex; door++) {
|
||||
cc = g.doors[door];
|
||||
/* levl[][].doormask and .wall_info both overlay levl[][].flags;
|
||||
the bit in doormask for D_TRAPPED is also a bit in wall_info;
|
||||
secret doors use wall_info so can't be marked as trapped */
|
||||
if (levl[cc.x][cc.y].typ == SDOOR)
|
||||
continue;
|
||||
if (levl[cc.x][cc.y].doormask & D_TRAPPED) {
|
||||
if (cc.x != u.ux || cc.y != u.uy)
|
||||
goto outtrapmap;
|
||||
@@ -986,10 +1004,15 @@ trap_detect(struct obj *sobj) /* null if crystal ball,
|
||||
for (ttmp = g.ftrap; ttmp; ttmp = ttmp->ntrap)
|
||||
sense_trap(ttmp, 0, 0, cursed_src);
|
||||
|
||||
dummytrap.ttyp = TRAPPED_DOOR;
|
||||
for (door = 0; door < g.doorindex; door++) {
|
||||
cc = g.doors[door];
|
||||
if (levl[cc.x][cc.y].doormask & D_TRAPPED)
|
||||
sense_trap((struct trap *) 0, cc.x, cc.y, cursed_src);
|
||||
if (levl[cc.x][cc.y].typ == SDOOR) /* see above */
|
||||
continue;
|
||||
if (levl[cc.x][cc.y].doormask & D_TRAPPED) {
|
||||
dummytrap.tx = cc.x, dummytrap.ty = cc.y;
|
||||
sense_trap(&dummytrap, cc.x, cc.y, cursed_src);
|
||||
}
|
||||
}
|
||||
|
||||
/* redisplay hero unless sense_trap() revealed something at <ux,uy> */
|
||||
@@ -1575,6 +1598,8 @@ openone(int zx, int zy, genericptr_t num)
|
||||
}
|
||||
/* let it fall to the next cases. could be on trap. */
|
||||
}
|
||||
/* note: secret doors can't be trapped; they use levl[][].wall_info;
|
||||
see rm.h for the troublesome overlay of doormask and wall_info */
|
||||
if (levl[zx][zy].typ == SDOOR
|
||||
|| (levl[zx][zy].typ == DOOR
|
||||
&& (levl[zx][zy].doormask & (D_CLOSED | D_LOCKED)))) {
|
||||
|
||||
18
src/pager.c
18
src/pager.c
@@ -145,11 +145,10 @@ monhealthdescr(struct monst *mon, boolean addspace, char *outbuf)
|
||||
static void
|
||||
trap_description(char *outbuf, int tnum, int x, int y)
|
||||
{
|
||||
/* Trap detection displays a bear trap at locations having
|
||||
* a trapped door or trapped container or both.
|
||||
*
|
||||
* TODO: we should create actual trap types for doors and
|
||||
* chests so that they can have their own glyphs and tiles.
|
||||
/*
|
||||
* Trap detection used to display a bear trap at locations having
|
||||
* a trapped door or trapped container or both. They're semi-real
|
||||
* traps now (defined trap types but not part of ftrap chain).
|
||||
*/
|
||||
if (trapped_chest_at(tnum, x, y))
|
||||
Strcpy(outbuf, "trapped chest"); /* might actually be a large box */
|
||||
@@ -1908,9 +1907,14 @@ doidtrap(void)
|
||||
x = u.ux + u.dx;
|
||||
y = u.uy + u.dy;
|
||||
|
||||
/* check fake bear trap from confused gold detection */
|
||||
/* trapped doors and chests used to be shown as fake bear traps;
|
||||
they have their own trap types now but aren't part of the ftrap
|
||||
chain; usually they revert to normal door or chest when the hero
|
||||
sees them but player might be using '^' while the hero is blind */
|
||||
glyph = glyph_at(x, y);
|
||||
if (glyph_is_trap(glyph) && (tt = glyph_to_trap(glyph)) == BEAR_TRAP) {
|
||||
if (glyph_is_trap(glyph)
|
||||
&& ((tt = glyph_to_trap(glyph)) == BEAR_TRAP
|
||||
|| tt == TRAPPED_DOOR || tt == TRAPPED_CHEST)) {
|
||||
boolean chesttrap = trapped_chest_at(tt, x, y);
|
||||
|
||||
if (chesttrap || trapped_door_at(tt, x, y)) {
|
||||
|
||||
Reference in New Issue
Block a user