wizard mode terrain wishing at drawbridge spot

When trying to reproduce the wand of striking "interesting effect (0)"
report, I tried wishing for lava under the castle drawbridge.  That
wasn't handling drawbridges properly.  This fixes wishing for moat,
lava, ice, or floor at a drawbridge span location whether the bridge
is currently open of closed.  It also allows wishing for room or floor
or ground at room spots; that hasn't had much testing.

Wishing for furniture, pool|moat|water, or lava at an ice location
wasn't cancelling any pending melt timer.

ice_descr() was declared as returning const but returns its non-const
output buffer argument.  Change to 'char *' so that wizterrainwish()
can capitilize that output without jumping through any hoops.
This commit is contained in:
PatR
2023-12-11 19:54:20 -08:00
parent e9e444d109
commit 4bd7f265f1
3 changed files with 104 additions and 27 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 extern.h $NHDT-Date: 1698264776 2023/10/25 20:12:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1296 $ */
/* NetHack 3.7 extern.h $NHDT-Date: 1702349265 2023/12/12 02:47:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1328 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2106,7 +2106,7 @@ extern char *monhealthdescr(struct monst *mon, boolean, char *);
extern void mhidden_description(struct monst *, boolean, char *);
extern boolean object_from_map(int, coordxy, coordxy, struct obj **);
extern const char *waterbody_name(coordxy, coordxy);
extern const char *ice_descr(coordxy, coordxy, char *);
extern char *ice_descr(coordxy, coordxy, char *);
extern boolean ia_checkfile(struct obj *);
extern int do_screen_description(coord, boolean, int, char *, const char **,
struct permonst **);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 objnam.c $NHDT-Date: 1698264786 2023/10/25 20:13:06 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.398 $ */
/* NetHack 3.7 objnam.c $NHDT-Date: 1702349266 2023/12/12 02:47:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.407 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -49,6 +49,7 @@ static boolean wishymatch(const char *, const char *, boolean);
static short rnd_otyp_by_wpnskill(schar);
static short rnd_otyp_by_namedesc(const char *, char, int);
static struct obj *wizterrainwish(struct _readobjnam_data *);
static void dbterrainmesg(const char *, coordxy, coordxy);
static void readobjnam_init(char *, struct _readobjnam_data *);
static int readobjnam_preparse(struct _readobjnam_data *);
static void readobjnam_parse_charges(struct _readobjnam_data *);
@@ -3253,8 +3254,9 @@ static struct obj *
wizterrainwish(struct _readobjnam_data *d)
{
struct rm *lev;
boolean madeterrain = FALSE, badterrain = FALSE, didblock;
int trap, oldtyp;
boolean madeterrain = FALSE, badterrain = FALSE, didblock, is_dbridge;
int trap;
unsigned oldtyp, ltyp;
coordxy x = u.ux, y = u.uy;
char *bp = d->bp, *p = d->p;
@@ -3273,8 +3275,9 @@ wizterrainwish(struct _readobjnam_data *d)
tname = trapname(trap, TRUE);
pline("%s%s.", An(tname),
(trap != MAGIC_PORTAL) ? "" : " to nowhere");
} else
} else {
pline("Creation of %s failed.", an(tname));
}
return &hands_obj;
}
@@ -3282,6 +3285,7 @@ wizterrainwish(struct _readobjnam_data *d)
or place furniture on existing traps which shouldn't be allowed) */
lev = &levl[x][y];
oldtyp = lev->typ;
is_dbridge = (oldtyp == DRAWBRIDGE_DOWN || oldtyp == DRAWBRIDGE_UP);
didblock = does_block(x, y, lev);
p = eos(bp);
if (!BSTRCMPI(bp, p - 8, "fountain")) {
@@ -3312,39 +3316,76 @@ wizterrainwish(struct _readobjnam_data *d)
long save_prop;
const char *new_water;
lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL
: !BSTRCMPI(bp, p - 4, "moat") ? MOAT
: WATER;
lev->flags = 0;
ltyp = !BSTRCMPI(bp, p - 4, "pool") ? POOL
: !BSTRCMPI(bp, p - 4, "moat") ? MOAT
: WATER;
if (!is_dbridge) {
lev->typ = ltyp;
lev->flags = 0;
} else {
/* drawbridgemask overloads flags */
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= DB_MOAT;
}
del_engr_at(x, y);
save_prop = EHalluc_resistance;
EHalluc_resistance = 1;
new_water = waterbody_name(x, y);
EHalluc_resistance = save_prop;
pline("%s.", An(new_water));
/* Must manually make kelp! */
if (!is_dbridge) {
save_prop = EHalluc_resistance;
EHalluc_resistance = 1;
new_water = waterbody_name(x, y);
EHalluc_resistance = save_prop;
pline("%s.", An(new_water));
/* Must manually make kelp! */
} else {
dbterrainmesg("Moat", x, y);
}
water_damage_chain(gl.level.objects[x][y], TRUE);
madeterrain = TRUE;
/* also matches "molten lava" */
} else if (!BSTRCMPI(bp, p - 4, "lava")
|| !BSTRCMPI(bp, p - 12, "wall of lava")) {
lev->typ = !BSTRCMPI(bp, p - 12, "wall of lava") ? LAVAWALL : LAVAPOOL;
lev->flags = 0;
ltyp = !BSTRCMPI(bp, p - 12, "wall of lava") ? LAVAWALL : LAVAPOOL;
if (!is_dbridge) {
lev->typ = ltyp;
lev->flags = 0;
} else {
/* drawbridgemask overloads flags */
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= DB_LAVA;
}
del_engr_at(x, y);
pline("A pool of molten lava.");
if (!(Levitation || Flying) || lev->typ == LAVAWALL)
pooleffects(FALSE);
if (!is_dbridge) {
pline("A %s of molten lava.",
(lev->typ == LAVAPOOL) ? "pool" : "wall");
if (!(Levitation || Flying) || lev->typ == LAVAWALL)
pooleffects(FALSE);
} else {
dbterrainmesg("Lava", x, y);
}
fire_damage_chain(gl.level.objects[x][y], TRUE, TRUE, x, y);
madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 3, "ice")) {
lev->typ = ICE;
lev->flags = 0;
if (!is_dbridge) {
lev->typ = ICE;
/* icedpool overloads flags; specifies what ice will melt into */
lev->icedpool = (oldtyp == ROOM) ? ICED_POOL : ICED_MOAT;
} else {
/* drawbridgemask overloads flags */
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= DB_ICE;
}
del_engr_at(x, y);
if (!strncmpi(bp, "melting ", 8))
start_melt_ice_timeout(x, y, 0L);
pline("Ice.");
if (!is_dbridge) {
char icebuf[40];
pline("%s.", upstart(ice_descr(x, y, icebuf)));
} else {
dbterrainmesg("Ice", x, y);
}
madeterrain = TRUE;
} else if (!BSTRCMPI(bp, p - 5, "altar")) {
aligntyp al;
@@ -3500,6 +3541,30 @@ wizterrainwish(struct _readobjnam_data *d)
pline("Secret corridor requires corridor location.");
badterrain = TRUE;
}
} else if (!BSTRCMPI(bp, p - 4, "room")
|| !BSTRCMPI(bp, p - 5, "floor")
|| !BSTRCMPI(bp, p - 6, "ground")) {
if (oldtyp == ROOM
|| (IS_FURNITURE(oldtyp) && CAN_OVERWRITE_TERRAIN(oldtyp))
|| oldtyp == ICE || is_pool_or_lava(x, y)) {
struct trap *t;
lev->typ = ROOM;
pline("Room floor.");
if (IS_FURNITURE(oldtyp))
count_level_features();
if ((t = t_at(x, y)) != 0 && t->ttyp != MAGIC_PORTAL)
deltrap(t);
madeterrain = TRUE;
} else if (is_dbridge) {
lev->drawbridgemask &= ~DB_UNDER;
lev->drawbridgemask |= DB_FLOOR;
dbterrainmesg("Floor", x, y);
madeterrain = TRUE;
} else {
pline("Room|floor|ground not allowed here.");
badterrain = TRUE;
}
}
if (madeterrain) {
@@ -3510,7 +3575,7 @@ wizterrainwish(struct _readobjnam_data *d)
if (u.uinwater && !is_pool(u.ux, u.uy)) {
set_uinwater(0); /* u.uinwater = 0; leave the water */
docrt();
/* [block/unblock_point was handled by docrt -> vision_recalc] */
/* [block/unblock_point handled by docrt -> vision_recalc] */
} else {
if (u.utrap && u.utraptype == TT_LAVA && !is_lava(u.ux, u.uy))
reset_utrap(FALSE);
@@ -3527,6 +3592,8 @@ wizterrainwish(struct _readobjnam_data *d)
/* fixups for replaced terrain that aren't handled above */
if (IS_FOUNTAIN(oldtyp) || IS_SINK(oldtyp))
count_level_features(); /* update level.flags.nfountains,nsinks */
if (!is_ice(x, y))
spot_stop_timers(x, y, MELT_ICE_AWAY);
/* horizontal is overlaid by fountain->blessedftn, grave->disturbed */
if (IS_FOUNTAIN(oldtyp) || IS_GRAVE(oldtyp)
|| IS_WALL(oldtyp) || oldtyp == IRONBARS
@@ -3553,6 +3620,16 @@ wizterrainwish(struct _readobjnam_data *d)
return (struct obj *) 0;
}
/* message common to several wizterrainwish() results */
static void
dbterrainmesg(
const char *newtype,
coordxy x, coordxy y)
{
pline("%s %s the drawbridge.", newtype,
(levl[x][y].typ == DRAWBRIDGE_UP) ? "in front of" : "under");
}
#define TIN_UNDEFINED 0
#define TIN_EMPTY 1
#define TIN_SPINACH 2

View File

@@ -1,4 +1,4 @@
/* NetHack 3.7 pager.c $NHDT-Date: 1698264788 2023/10/25 20:13:08 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.252 $ */
/* NetHack 3.7 pager.c $NHDT-Date: 1702349268 2023/12/12 02:47:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.266 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2018. */
/* NetHack may be freely redistributed. See license for details. */
@@ -532,7 +532,7 @@ waterbody_name(coordxy x, coordxy y)
return "water"; /* don't hallucinate this as some other liquid */
}
const char *
char *
ice_descr(coordxy x, coordxy y, char *outbuf)
{
static const char *const icetyp[] = {