more wizard mode wishing for terrain
Try a lot harder to keep terrain/level flags in a sane state. They're overloaded so it's not simple. Creating a fountain or sink incremented the corresponding counter (for controlling ambient sounds) but removing one by wishing for something else in its place didn't decrement. Allow wish for "disturbed grave" to create a grave with the 'disturbed' flag set, similar to existing "magic fountain" and 'blessedftn' flag. (I didn't add "looted throne", "looted tree", and several other things that use the 'looted' overload of 'rm.flags'.) Automate block_point (tree, cloud, secret corridor, or secret door in open doorway) and add unblock_point (use Pass_wall to move into wall or tree or stone, or just walk onto a cloud, then make iron bars or almost any other wishable terrain to replace the blocking feature).
This commit is contained in:
23
include/rm.h
23
include/rm.h
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 rm.h $NHDT-Date: 1578258722 2020/01/05 21:12:02 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.77 $ */
|
||||
/* NetHack 3.6 rm.h $NHDT-Date: 1580070206 2020/01/26 20:23:26 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.78 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2017. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -528,16 +528,19 @@ struct rm {
|
||||
#define SV7 0x80
|
||||
#define SVALL 0xFF
|
||||
|
||||
#define doormask flags
|
||||
#define altarmask flags
|
||||
#define wall_info flags
|
||||
#define ladder flags
|
||||
#define drawbridgemask flags
|
||||
#define looted flags
|
||||
#define icedpool flags
|
||||
|
||||
/* if these get changed or expanded, make sure wizard-mode wishing becomes
|
||||
aware of the new usage */
|
||||
#define doormask flags /* door, sdoor (note conflict with wall_info) */
|
||||
#define altarmask flags /* alignment and maybe temple */
|
||||
#define wall_info flags /* wall, sdoor (note conflict with doormask) */
|
||||
#define ladder flags /* up or down */
|
||||
#define drawbridgemask flags /* what's underneath when the span is open */
|
||||
#define looted flags /* used for throne, tree, fountain, sink, door */
|
||||
#define icedpool flags /* used for ice (in case it melts) */
|
||||
/* horizonal applies to walls, doors (including sdoor); also to iron bars
|
||||
even though they don't have separate symbols for horizontal and vertical */
|
||||
#define blessedftn horizontal /* a fountain that grants attribs */
|
||||
#define disturbed horizontal /* a grave that has been disturbed */
|
||||
#define disturbed horizontal /* a grave that has been disturbed */
|
||||
|
||||
struct damage {
|
||||
struct damage *next;
|
||||
|
||||
92
src/objnam.c
92
src/objnam.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1579261291 2020/01/17 11:41:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1580070220 2020/01/26 20:23:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.291 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2952,8 +2952,8 @@ char *bp, *p;
|
||||
int locked, trapped;
|
||||
{
|
||||
struct rm *lev;
|
||||
boolean madeterrain = FALSE, badterrain = FALSE;
|
||||
int trap, x = u.ux, y = u.uy;
|
||||
boolean madeterrain = FALSE, badterrain = FALSE, didblock;
|
||||
int trap, oldtyp, x = u.ux, y = u.uy;
|
||||
|
||||
for (trap = NO_TRAP + 1; trap < TRAPNUM; trap++) {
|
||||
struct trap *t;
|
||||
@@ -2978,21 +2978,25 @@ int locked, trapped;
|
||||
/* furniture and terrain (use at your own risk; can clobber stairs
|
||||
or place furniture on existing traps which shouldn't be allowed) */
|
||||
lev = &levl[x][y];
|
||||
oldtyp = lev->typ;
|
||||
didblock = does_block(x, y, lev);
|
||||
p = eos(bp);
|
||||
if (!BSTRCMPI(bp, p - 8, "fountain")) {
|
||||
lev->typ = FOUNTAIN;
|
||||
g.level.flags.nfountains++;
|
||||
if (!strncmpi(bp, "magic ", 6))
|
||||
lev->blessedftn = 1;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
lev->blessedftn = !strncmpi(bp, "magic ", 6);
|
||||
pline("A %sfountain.", lev->blessedftn ? "magic " : "");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 6, "throne")) {
|
||||
lev->typ = THRONE;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
pline("A throne.");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 4, "sink")) {
|
||||
lev->typ = SINK;
|
||||
g.level.flags.nsinks++;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
pline("A sink.");
|
||||
madeterrain = TRUE;
|
||||
|
||||
@@ -3000,6 +3004,7 @@ int locked, trapped;
|
||||
} else if (!BSTRCMPI(bp, p - 4, "pool")
|
||||
|| !BSTRCMPI(bp, p - 4, "moat")) {
|
||||
lev->typ = !BSTRCMPI(bp, p - 4, "pool") ? POOL : MOAT;
|
||||
lev->flags = 0;
|
||||
del_engr_at(x, y);
|
||||
pline("A %s.", (lev->typ == POOL) ? "pool" : "moat");
|
||||
/* Must manually make kelp! */
|
||||
@@ -3009,6 +3014,7 @@ int locked, trapped;
|
||||
/* also matches "molten lava" */
|
||||
} else if (!BSTRCMPI(bp, p - 4, "lava")) {
|
||||
lev->typ = LAVAPOOL;
|
||||
lev->flags = 0;
|
||||
del_engr_at(x, y);
|
||||
pline("A pool of molten lava.");
|
||||
if (!(Levitation || Flying))
|
||||
@@ -3028,34 +3034,51 @@ int locked, trapped;
|
||||
al = A_NONE;
|
||||
else /* -1 - A_CHAOTIC, 0 - A_NEUTRAL, 1 - A_LAWFUL */
|
||||
al = !rn2(6) ? A_NONE : (rn2((int) A_LAWFUL + 2) - 1);
|
||||
lev->altarmask = Align2amask(al);
|
||||
lev->altarmask = Align2amask(al); /* overlays 'flags' */
|
||||
pline("%s altar.", An(align_str(al)));
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 5, "grave")
|
||||
|| !BSTRCMPI(bp, p - 9, "headstone")) {
|
||||
make_grave(x, y, (char *) 0);
|
||||
pline("%s.", IS_GRAVE(lev->typ) ? "A grave"
|
||||
: "Can't place a grave here");
|
||||
madeterrain = TRUE;
|
||||
if (IS_GRAVE(lev->typ)) {
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
lev->disturbed = !strncmpi(bp, "disturbed ", 10);
|
||||
pline("A %sgrave.", lev->disturbed ? "disturbed " : "");
|
||||
madeterrain = TRUE;
|
||||
} else {
|
||||
pline("Can't place a grave here");
|
||||
badterrain = TRUE;
|
||||
}
|
||||
} else if (!BSTRCMPI(bp, p - 4, "tree")) {
|
||||
lev->typ = TREE;
|
||||
lev->looted = 0; /* overlays 'flags' */
|
||||
pline("A tree.");
|
||||
block_point(x, y);
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 4, "bars")) {
|
||||
lev->typ = IRONBARS;
|
||||
lev->flags = 0;
|
||||
/* [FIXME: if this isn't a wall or door location where 'horizontal'
|
||||
is already set up, that should be calculated for this spot.
|
||||
Unforutnately, it can be tricky; placing one in open space
|
||||
and then another adjacent might need to recalculate first one.] */
|
||||
pline("Iron bars.");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 5, "cloud")) {
|
||||
lev->typ = CLOUD;
|
||||
block_point(x, y);
|
||||
lev->flags = 0;
|
||||
pline("A cloud.");
|
||||
madeterrain = TRUE;
|
||||
} else if (!BSTRCMPI(bp, p - 11, "secret door")) {
|
||||
if (lev->typ == DOOR
|
||||
|| (IS_WALL(lev->typ) && lev->typ != DBWALL)) {
|
||||
/* require door or wall so that the 'horizontal' flag will
|
||||
already have the correct value (it will matter once the
|
||||
secret door is discovered and becomes a regular door);
|
||||
player might choose to put SDOOR on top of existing SDOOR
|
||||
to control its trapped state; iron bars are surrogate walls */
|
||||
if (lev->typ == DOOR || lev->typ == SDOOR
|
||||
|| (IS_WALL(lev->typ) && lev->typ != DBWALL)
|
||||
|| lev->typ == IRONBARS) {
|
||||
lev->typ = SDOOR;
|
||||
lev->wall_info = 0;
|
||||
lev->wall_info = 0; /* overlays 'flags' */
|
||||
/* lev->horizontal stays as-is */
|
||||
/* no special handling for rogue level is necessary;
|
||||
exposing a secret door there yields a doorless doorway */
|
||||
@@ -3073,7 +3096,6 @@ int locked, trapped;
|
||||
#endif
|
||||
if (trapped)
|
||||
lev->doormask |= D_TRAPPED;
|
||||
block_point(x, y);
|
||||
pline("Secret door.");
|
||||
madeterrain = TRUE;
|
||||
} else {
|
||||
@@ -3083,7 +3105,7 @@ int locked, trapped;
|
||||
} else if (!BSTRCMPI(bp, p - 15, "secret corridor")) {
|
||||
if (lev->typ == CORR) {
|
||||
lev->typ = SCORR;
|
||||
block_point(x, y);
|
||||
/* neither CORR nor SCORR uses 'flags' or 'horizontal' */
|
||||
pline("Secret corridor.");
|
||||
madeterrain = TRUE;
|
||||
} else {
|
||||
@@ -3099,11 +3121,41 @@ int locked, trapped;
|
||||
if (u.uinwater && !is_pool(u.ux, u.uy)) {
|
||||
u.uinwater = 0; /* leave the water */
|
||||
docrt();
|
||||
g.vision_full_recalc = 1;
|
||||
} else if (u.utrap && u.utraptype == TT_LAVA
|
||||
&& !is_lava(u.ux, u.uy)) {
|
||||
reset_utrap(FALSE);
|
||||
/* [block/unblock_point was handled by docrt -> vision_recalc] */
|
||||
} else {
|
||||
if (u.utrap && u.utraptype == TT_LAVA && !is_lava(u.ux, u.uy))
|
||||
reset_utrap(FALSE);
|
||||
|
||||
if (does_block(x, y, lev)) {
|
||||
if (!didblock)
|
||||
block_point(x, y);
|
||||
} else {
|
||||
if (didblock)
|
||||
unblock_point(x, y);
|
||||
}
|
||||
}
|
||||
/* fixups for replaced terrain that aren't handled above;
|
||||
for fountain placed on fountain or sink placed on sink, the
|
||||
increment above gets canceled out by the decrement here;
|
||||
otherwise if fountain or sink was replaced, there's one less */
|
||||
if (IS_FOUNTAIN(oldtyp))
|
||||
g.level.flags.nfountains--;
|
||||
else if (IS_SINK(oldtyp))
|
||||
g.level.flags.nsinks--;
|
||||
/* horizontal is overlaid by fountain->blessedftn, grave->disturbed */
|
||||
if (IS_FOUNTAIN(oldtyp) || IS_GRAVE(oldtyp)
|
||||
|| IS_WALL(oldtyp) || oldtyp == IRONBARS
|
||||
|| IS_DOOR(oldtyp) || oldtyp == SDOOR) {
|
||||
/* when new terrain is a fountain, 'blessedftn' was explicitly
|
||||
set above; likewise for grave and 'disturbed'; when it's a
|
||||
secret door, the old type was a wall or a door and we retain
|
||||
the 'horizontal' value from those */
|
||||
if (!IS_FOUNTAIN(lev->typ) && !IS_GRAVE(lev->typ)
|
||||
&& lev->typ != SDOOR)
|
||||
lev->horizontal = 0; /* also clears blessedftn, disturbed */
|
||||
}
|
||||
/* note: lev->lit and lev->nondiggable retain their values even
|
||||
though those might not make sense with the new terrain */
|
||||
}
|
||||
if (madeterrain || badterrain) {
|
||||
/* cast 'const' away; caller won't modify this */
|
||||
|
||||
Reference in New Issue
Block a user