flipping current level with #wizlevelflip
Give wizard mode player control over how a level gets transposed by prompting for the desired outcome. Refreshing the screen showed that remembered, no longer in view wall corners and T walls were shown with their old orientation instead of being transposed along with the level. This fixes that, but does so by adding a chunk of code that will be irrelevant for normal play.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1582321542 2020/02/21 21:45:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.801 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1582592780 2020/02/25 01:06:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.804 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -2466,33 +2466,38 @@ E void FDECL(sysopt_seduce_set, (int));
|
||||
|
||||
/* ### sp_lev.c ### */
|
||||
#if !defined(CROSSCOMPILE) || defined(CROSSCOMPILE_TARGET)
|
||||
E void FDECL(flip_level, (int, BOOLEAN_P));
|
||||
E void FDECL(flip_level_rnd, (int, BOOLEAN_P));
|
||||
E boolean FDECL(check_room, (xchar *, xchar *, xchar *, xchar *, BOOLEAN_P));
|
||||
E boolean FDECL(create_room, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P,
|
||||
XCHAR_P, XCHAR_P, XCHAR_P));
|
||||
E void FDECL(create_secret_door, (struct mkroom *, XCHAR_P));
|
||||
E boolean
|
||||
FDECL(dig_corridor, (coord *, coord *, BOOLEAN_P, SCHAR_P, SCHAR_P));
|
||||
E boolean FDECL(dig_corridor, (coord *, coord *, BOOLEAN_P, SCHAR_P, SCHAR_P));
|
||||
E void FDECL(fill_room, (struct mkroom *, BOOLEAN_P));
|
||||
E boolean FDECL(load_special, (const char *));
|
||||
E xchar FDECL(selection_getpoint, (int, int, struct selectionvar *));
|
||||
E struct selectionvar *NDECL(selection_new);
|
||||
E void FDECL(selection_free, (struct selectionvar *, BOOLEAN_P));
|
||||
#if !defined(IN_SP_LEV_C)
|
||||
E void FDECL(set_selection_floodfillchk, (int FDECL((*), (int,int))));
|
||||
#endif
|
||||
E void FDECL(selection_floodfill, (struct selectionvar *, int, int, BOOLEAN_P));
|
||||
E void FDECL(get_location_coord, (schar *, schar *, int, struct mkroom *, long));
|
||||
E void FDECL(selection_floodfill, (struct selectionvar *, int, int,
|
||||
BOOLEAN_P));
|
||||
E void FDECL(get_location_coord, (schar *, schar *, int, struct mkroom *,
|
||||
long));
|
||||
E void FDECL(selection_setpoint, (int, int, struct selectionvar *, XCHAR_P));
|
||||
E struct selectionvar * FDECL(selection_not, (struct selectionvar *));
|
||||
E void FDECL(selection_filter_percent, (struct selectionvar *, int));
|
||||
E int FDECL(selection_rndcoord, (struct selectionvar *, schar *, schar *, BOOLEAN_P));
|
||||
E int FDECL(selection_rndcoord, (struct selectionvar *, schar *, schar *,
|
||||
BOOLEAN_P));
|
||||
E void FDECL(selection_do_grow, (struct selectionvar *, int));
|
||||
E void FDECL(selection_do_line, (SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P, struct selectionvar *));
|
||||
E void FDECL(selection_do_randline, (SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P, struct selectionvar *));
|
||||
E struct selectionvar *FDECL(selection_filter_mapchar, (struct selectionvar *, XCHAR_P, int));
|
||||
E void FDECL(selection_do_line, (SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P,
|
||||
struct selectionvar *));
|
||||
E void FDECL(selection_do_randline, (SCHAR_P, SCHAR_P, SCHAR_P, SCHAR_P,
|
||||
SCHAR_P, SCHAR_P, struct selectionvar *));
|
||||
E struct selectionvar *FDECL(selection_filter_mapchar, (struct selectionvar *,
|
||||
XCHAR_P, int));
|
||||
E void FDECL(set_floodfillchk_match_under, (XCHAR_P));
|
||||
E void FDECL(selection_do_ellipse, (struct selectionvar *, int, int, int, int, int));
|
||||
E void FDECL(selection_do_ellipse, (struct selectionvar *,
|
||||
int, int, int, int, int));
|
||||
E void NDECL(update_croom);
|
||||
E const char *FDECL(get_trapname_bytype, (int));
|
||||
E void FDECL(l_register_des, (lua_State *));
|
||||
|
||||
35
src/cmd.c
35
src/cmd.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1582321487 2020/02/21 21:44:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.403 $ */
|
||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1582592803 2020/02/25 01:06:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.405 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1019,14 +1019,37 @@ wiz_level_tele(VOID_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* #wizlevelflip - randomly flip the current level.
|
||||
Does not handle vision, monst mtrack, levregions,
|
||||
as flipping is normally done only during level creation.
|
||||
*/
|
||||
/* #wizlevelflip - flip the current level */
|
||||
static int
|
||||
wiz_level_flip(VOID_ARGS)
|
||||
{
|
||||
if (wizard) flip_level_rnd(3, TRUE);
|
||||
static const char choices[] = "0123",
|
||||
prmpt[] = "Flip 0=randomly, 1=vertically, 2=horizonally, 3=both:";
|
||||
|
||||
/*
|
||||
* Does not handle
|
||||
* levregions,
|
||||
* monster mtrack,
|
||||
* migrating monsters aimed at returning to specific coordinates
|
||||
* on the this level
|
||||
* as flipping is normally done only during level creation.
|
||||
*/
|
||||
if (wizard) {
|
||||
char c = yn_function(prmpt, choices, '\0');
|
||||
|
||||
if (c && index(choices, c)) {
|
||||
c -= '0';
|
||||
|
||||
if (!c)
|
||||
flip_level_rnd(3, TRUE);
|
||||
else
|
||||
flip_level((int) c, TRUE);
|
||||
|
||||
docrt();
|
||||
} else {
|
||||
pline("%s", Never_mind);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
136
src/sp_lev.c
136
src/sp_lev.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1581562593 2020/02/13 02:56:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.157 $ */
|
||||
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1582592810 2020/02/25 01:06:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.162 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -30,7 +30,6 @@ static void FDECL(lvlfill_solid, (SCHAR_P, SCHAR_P));
|
||||
static void FDECL(flip_drawbridge_horizontal, (struct rm *));
|
||||
static void FDECL(flip_drawbridge_vertical, (struct rm *));
|
||||
static int FDECL(flip_encoded_direction_bits, (int, int));
|
||||
static void FDECL(flip_level, (int, BOOLEAN_P));
|
||||
static void FDECL(set_wall_property, (XCHAR_P, XCHAR_P, XCHAR_P, XCHAR_P,
|
||||
int));
|
||||
static void NDECL(count_features);
|
||||
@@ -246,6 +245,49 @@ struct rm *lev;
|
||||
}
|
||||
}
|
||||
|
||||
/* for #wizlevelflip; not needed when flipping during level creation;
|
||||
update seen vector for whole level and glyph for walls */
|
||||
static void
|
||||
flip_visuals(flp)
|
||||
int flp;
|
||||
{
|
||||
struct rm *lev;
|
||||
int x, y, seenv;
|
||||
|
||||
for (y = 0; y < ROWNO; ++y) {
|
||||
for (x = 1; x < COLNO; ++x) {
|
||||
lev = &levl[x][y];
|
||||
seenv = lev->seenv & 0xff;
|
||||
/* locations which haven't been seen can be skipped */
|
||||
if (seenv == 0)
|
||||
continue;
|
||||
/* flip <x,y>'s seen vector; not necessary for locations seen
|
||||
from all directions (the whole level after magic mapping) */
|
||||
if (seenv != SVALL) {
|
||||
/* SV2 SV1 SV0 *
|
||||
* SV3 -+- SV7 *
|
||||
* SV4 SV5 SV6 */
|
||||
if (flp & 1) { /* swap top and bottom */
|
||||
seenv = swapbits(seenv, 2, 4);
|
||||
seenv = swapbits(seenv, 1, 5);
|
||||
seenv = swapbits(seenv, 0, 6);
|
||||
}
|
||||
if (flp & 2) { /* swap left and right */
|
||||
seenv = swapbits(seenv, 2, 0);
|
||||
seenv = swapbits(seenv, 3, 7);
|
||||
seenv = swapbits(seenv, 4, 6);
|
||||
}
|
||||
lev->seenv = (uchar) seenv;
|
||||
}
|
||||
/* if <x,y> is displayed as a wall, reset its display glyph so
|
||||
that remembered, out of view T's and corners get flipped */
|
||||
if ((IS_WALL(lev->typ) || lev->typ == SDOOR)
|
||||
&& glyph_is_cmap(lev->glyph))
|
||||
lev->glyph = back_to_glyph(x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
flip_encoded_direction_bits(int flp, int val)
|
||||
{
|
||||
@@ -267,12 +309,14 @@ flip_encoded_direction_bits(int flp, int val)
|
||||
#define FlipX(val) ((maxx - (val)) + minx)
|
||||
#define FlipY(val) ((maxy - (val)) + miny)
|
||||
|
||||
static void
|
||||
/* transpose top with bottom or left with right or both; sometimes called
|
||||
for new special levels, or for any level via the #wizlevelflip command */
|
||||
void
|
||||
flip_level(flp, extras)
|
||||
int flp;
|
||||
boolean extras;
|
||||
{
|
||||
int x, y, i;
|
||||
int x, y, i, itmp;
|
||||
int minx, miny, maxx, maxy;
|
||||
struct rm trm;
|
||||
struct trap *ttmp;
|
||||
@@ -283,10 +327,14 @@ boolean extras;
|
||||
|
||||
get_level_extends(&minx, &miny, &maxx, &maxy);
|
||||
/* get_level_extends() returns -1,-1 to COLNO,ROWNO at max */
|
||||
if (miny < 0) miny = 0;
|
||||
if (minx < 0) minx = 0;
|
||||
if (maxx >= COLNO) maxx = (COLNO - 1);
|
||||
if (maxy >= ROWNO) maxy = (ROWNO - 1);
|
||||
if (miny < 0)
|
||||
miny = 0;
|
||||
if (minx < 0)
|
||||
minx = 0;
|
||||
if (maxx >= COLNO)
|
||||
maxx = (COLNO - 1);
|
||||
if (maxy >= ROWNO)
|
||||
maxy = (ROWNO - 1);
|
||||
|
||||
/* stairs and ladders */
|
||||
if (flp & 1) {
|
||||
@@ -312,7 +360,8 @@ boolean extras;
|
||||
ttmp->launch.y = FlipY(ttmp->launch.y);
|
||||
ttmp->launch2.y = FlipY(ttmp->launch2.y);
|
||||
} else if (is_pit(ttmp->ttyp) && ttmp->conjoined) {
|
||||
ttmp->conjoined = flip_encoded_direction_bits(flp, ttmp->conjoined);
|
||||
ttmp->conjoined = flip_encoded_direction_bits(flp,
|
||||
ttmp->conjoined);
|
||||
}
|
||||
}
|
||||
if (flp & 2) {
|
||||
@@ -321,7 +370,8 @@ boolean extras;
|
||||
ttmp->launch.x = FlipX(ttmp->launch.x);
|
||||
ttmp->launch2.x = FlipX(ttmp->launch2.x);
|
||||
} else if (is_pit(ttmp->ttyp) && ttmp->conjoined) {
|
||||
ttmp->conjoined = flip_encoded_direction_bits(flp, ttmp->conjoined);
|
||||
ttmp->conjoined = flip_encoded_direction_bits(flp,
|
||||
ttmp->conjoined);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -382,34 +432,34 @@ boolean extras;
|
||||
g.lregions[i].inarea.y1 = FlipY(g.lregions[i].inarea.y1);
|
||||
g.lregions[i].inarea.y2 = FlipY(g.lregions[i].inarea.y2);
|
||||
if (g.lregions[i].inarea.y1 > g.lregions[i].inarea.y2) {
|
||||
int tmp = g.lregions[i].inarea.y1;
|
||||
itmp = g.lregions[i].inarea.y1;
|
||||
g.lregions[i].inarea.y1 = g.lregions[i].inarea.y2;
|
||||
g.lregions[i].inarea.y2 = tmp;
|
||||
g.lregions[i].inarea.y2 = itmp;
|
||||
}
|
||||
|
||||
g.lregions[i].delarea.y1 = FlipY(g.lregions[i].delarea.y1);
|
||||
g.lregions[i].delarea.y2 = FlipY(g.lregions[i].delarea.y2);
|
||||
if (g.lregions[i].delarea.y1 > g.lregions[i].delarea.y2) {
|
||||
int tmp = g.lregions[i].delarea.y1;
|
||||
itmp = g.lregions[i].delarea.y1;
|
||||
g.lregions[i].delarea.y1 = g.lregions[i].delarea.y2;
|
||||
g.lregions[i].delarea.y2 = tmp;
|
||||
g.lregions[i].delarea.y2 = itmp;
|
||||
}
|
||||
}
|
||||
if (flp & 2) {
|
||||
g.lregions[i].inarea.x1 = FlipX(g.lregions[i].inarea.x1);
|
||||
g.lregions[i].inarea.x2 = FlipX(g.lregions[i].inarea.x2);
|
||||
if (g.lregions[i].inarea.x1 > g.lregions[i].inarea.x2) {
|
||||
int tmp = g.lregions[i].inarea.x1;
|
||||
itmp = g.lregions[i].inarea.x1;
|
||||
g.lregions[i].inarea.x1 = g.lregions[i].inarea.x2;
|
||||
g.lregions[i].inarea.x2 = tmp;
|
||||
g.lregions[i].inarea.x2 = itmp;
|
||||
}
|
||||
|
||||
g.lregions[i].delarea.x1 = FlipX(g.lregions[i].delarea.x1);
|
||||
g.lregions[i].delarea.x2 = FlipX(g.lregions[i].delarea.x2);
|
||||
if (g.lregions[i].delarea.x1 > g.lregions[i].delarea.x2) {
|
||||
int tmp = g.lregions[i].delarea.x1;
|
||||
itmp = g.lregions[i].delarea.x1;
|
||||
g.lregions[i].delarea.x1 = g.lregions[i].delarea.x2;
|
||||
g.lregions[i].delarea.x2 = tmp;
|
||||
g.lregions[i].delarea.x2 = itmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -422,40 +472,41 @@ boolean extras;
|
||||
sroom->ly = FlipY(sroom->ly);
|
||||
sroom->hy = FlipY(sroom->hy);
|
||||
if (sroom->ly > sroom->hy) {
|
||||
int tmp = sroom->ly;
|
||||
itmp = sroom->ly;
|
||||
sroom->ly = sroom->hy;
|
||||
sroom->hy = tmp;
|
||||
sroom->hy = itmp;
|
||||
}
|
||||
}
|
||||
if (flp & 2) {
|
||||
sroom->lx = FlipX(sroom->lx);
|
||||
sroom->hx = FlipX(sroom->hx);
|
||||
if (sroom->lx > sroom->hx) {
|
||||
int tmp = sroom->lx;
|
||||
itmp = sroom->lx;
|
||||
sroom->lx = sroom->hx;
|
||||
sroom->hx = tmp;
|
||||
sroom->hx = itmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (sroom->nsubrooms)
|
||||
for (i = 0; i < sroom->nsubrooms; i++) {
|
||||
struct mkroom *rroom = sroom->sbrooms[i];
|
||||
|
||||
if (flp & 1) {
|
||||
rroom->ly = FlipY(rroom->ly);
|
||||
rroom->hy = FlipY(rroom->hy);
|
||||
if (rroom->ly > rroom->hy) {
|
||||
int tmp = rroom->ly;
|
||||
itmp = rroom->ly;
|
||||
rroom->ly = rroom->hy;
|
||||
rroom->hy = tmp;
|
||||
rroom->hy = itmp;
|
||||
}
|
||||
}
|
||||
if (flp & 2) {
|
||||
rroom->lx = FlipX(rroom->lx);
|
||||
rroom->hx = FlipX(rroom->hx);
|
||||
if (rroom->lx > rroom->hx) {
|
||||
int tmp = rroom->lx;
|
||||
itmp = rroom->lx;
|
||||
rroom->lx = rroom->hx;
|
||||
rroom->hx = tmp;
|
||||
rroom->hx = itmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -472,7 +523,7 @@ boolean extras;
|
||||
/* the map */
|
||||
if (flp & 1) {
|
||||
for (x = minx; x <= maxx; x++)
|
||||
for (y = miny; y < (miny + ((maxy-miny+1) / 2)); y++) {
|
||||
for (y = miny; y < (miny + ((maxy - miny + 1) / 2)); y++) {
|
||||
int ny = FlipY(y);
|
||||
|
||||
flip_drawbridge_vertical(&levl[x][y]);
|
||||
@@ -492,7 +543,7 @@ boolean extras;
|
||||
}
|
||||
}
|
||||
if (flp & 2) {
|
||||
for (x = minx; x < (minx + ((maxx-minx+1) / 2)); x++)
|
||||
for (x = minx; x < (minx + ((maxx - minx + 1) / 2)); x++)
|
||||
for (y = miny; y <= maxy; y++) {
|
||||
int nx = FlipX(x);
|
||||
|
||||
@@ -514,28 +565,43 @@ boolean extras;
|
||||
}
|
||||
|
||||
if (extras) {
|
||||
if (flp & 1) u.uy = FlipY(u.uy);
|
||||
if (flp & 2) u.ux = FlipX(u.ux);
|
||||
if (flp & 1)
|
||||
u.uy = FlipY(u.uy), u.uy0 = FlipY(u.uy0);
|
||||
if (flp & 2)
|
||||
u.ux = FlipX(u.ux), u.ux0 = FlipX(u.ux0);
|
||||
}
|
||||
|
||||
fix_wall_spines(1, 0, COLNO-1, ROWNO-1);
|
||||
|
||||
fix_wall_spines(1, 0, COLNO - 1, ROWNO - 1);
|
||||
if (extras && flp) {
|
||||
set_wall_state();
|
||||
flip_visuals(flp); /* after wall_spines; flips seenv and wall joins */
|
||||
}
|
||||
vision_reset();
|
||||
}
|
||||
|
||||
#undef FlipX
|
||||
#undef FlipY
|
||||
|
||||
/* randomly transpose top with bottom or left with right or both;
|
||||
caller controls which transpositions are allowed */
|
||||
void
|
||||
flip_level_rnd(flp, extras)
|
||||
int flp;
|
||||
boolean extras;
|
||||
{
|
||||
int c = 0;
|
||||
if ((flp & 1) && rn2(2)) c |= 1;
|
||||
if ((flp & 2) && rn2(2)) c |= 2;
|
||||
|
||||
if (c) flip_level(c, extras);
|
||||
/* TODO?
|
||||
* Might change rn2(2) to !rn2(3) or (rn2(5) < 2) in order to bias
|
||||
* the outcome towards the traditional orientation.
|
||||
*/
|
||||
if ((flp & 1) && rn2(2))
|
||||
c |= 1;
|
||||
if ((flp & 2) && rn2(2))
|
||||
c |= 2;
|
||||
|
||||
if (c)
|
||||
flip_level(c, extras);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user