Fix vibrating square

The Gehennom changes broke the vibrating square, allowing hero to go
down into the Sanctum via stairs without performing the invocation.

Fix this by making the hellfill lua check for invocation level, and
placing down the vibrating square trap, instead of stairs.
This commit is contained in:
Pasi Kallinen
2023-01-19 12:12:26 +02:00
parent 8952ea9bb5
commit 1113373892
5 changed files with 66 additions and 48 deletions

View File

@@ -257,6 +257,10 @@ hells[hellno]();
--
des.stair("up")
des.stair("down")
if (u.invocation_level) then
des.trap("vibrating square");
else
des.stair("down")
end
populatemaze();

View File

@@ -1411,6 +1411,7 @@ extern void create_maze(int, int, boolean);
extern void wallification(coordxy, coordxy, coordxy, coordxy);
extern void fix_wall_spines(coordxy, coordxy, coordxy, coordxy);
extern void walkfrom(coordxy, coordxy, schar);
extern void pick_vibrasquare_location(void);
extern void makemaz(const char *);
extern void mazexy(coord *);
extern void get_level_extends(coordxy *, coordxy *, coordxy *, coordxy *);

View File

@@ -970,11 +970,61 @@ create_maze(int corrwid, int wallthick, boolean rmdeadends)
}
}
void
pick_vibrasquare_location(void)
{
coordxy x, y;
stairway *stway;
int trycnt = 0;
#define x_maze_min 2
#define y_maze_min 2
/*
* Pick a position where the stairs down to Moloch's Sanctum
* level will ultimately be created. At that time, an area
* will be altered: walls removed, moat and traps generated,
* boulders destroyed. The position picked here must ensure
* that that invocation area won't extend off the map.
*
* We actually allow up to 2 squares around the usual edge of
* the area to get truncated; see mkinvokearea(mklev.c).
*/
#define INVPOS_X_MARGIN (6 - 2)
#define INVPOS_Y_MARGIN (5 - 2)
#define INVPOS_DISTANCE 11
int x_range = gx.x_maze_max - x_maze_min - 2 * INVPOS_X_MARGIN - 1,
y_range = gy.y_maze_max - y_maze_min - 2 * INVPOS_Y_MARGIN - 1;
if (x_range <= INVPOS_X_MARGIN || y_range <= INVPOS_Y_MARGIN
|| (x_range * y_range) <= (INVPOS_DISTANCE * INVPOS_DISTANCE)) {
debugpline2("gi.inv_pos: maze is too small! (%d x %d)",
gx.x_maze_max, gy.y_maze_max);
}
gi.inv_pos.x = gi.inv_pos.y = 0; /*{occupied() => invocation_pos()}*/
do {
x = rn1(x_range, x_maze_min + INVPOS_X_MARGIN + 1);
y = rn1(y_range, y_maze_min + INVPOS_Y_MARGIN + 1);
/* we don't want it to be too near the stairs, nor
to be on a spot that's already in use (wall|trap) */
if (++trycnt > 1000)
break;
} while (((stway = stairway_find_dir(TRUE)) != 0)
&& (x == stway->sx || y == stway->sy /*(direct line)*/
|| abs(x - stway->sx) == abs(y - stway->sy)
|| distmin(x, y, stway->sx, stway->sy) <= INVPOS_DISTANCE
|| !SPACE_POS(levl[x][y].typ) || occupied(x, y)));
gi.inv_pos.x = x;
gi.inv_pos.y = y;
#undef INVPOS_X_MARGIN
#undef INVPOS_Y_MARGIN
#undef INVPOS_DISTANCE
#undef x_maze_min
#undef y_maze_min
}
void
makemaz(const char *s)
{
coordxy x, y;
coordxy x;
char protofile[20];
s_level *sp = Is_special(&u.uz);
coord mm;
@@ -1059,52 +1109,8 @@ makemaz(const char *s)
mazexy(&mm);
mkstairs(mm.x, mm.y, 0, (struct mkroom *) 0, FALSE); /* down */
} else { /* choose "vibrating square" location */
stairway *stway;
int trycnt = 0;
#define x_maze_min 2
#define y_maze_min 2
/*
* Pick a position where the stairs down to Moloch's Sanctum
* level will ultimately be created. At that time, an area
* will be altered: walls removed, moat and traps generated,
* boulders destroyed. The position picked here must ensure
* that that invocation area won't extend off the map.
*
* We actually allow up to 2 squares around the usual edge of
* the area to get truncated; see mkinvokearea(mklev.c).
*/
#define INVPOS_X_MARGIN (6 - 2)
#define INVPOS_Y_MARGIN (5 - 2)
#define INVPOS_DISTANCE 11
int x_range = gx.x_maze_max - x_maze_min - 2 * INVPOS_X_MARGIN - 1,
y_range = gy.y_maze_max - y_maze_min - 2 * INVPOS_Y_MARGIN - 1;
if (x_range <= INVPOS_X_MARGIN || y_range <= INVPOS_Y_MARGIN
|| (x_range * y_range) <= (INVPOS_DISTANCE * INVPOS_DISTANCE)) {
debugpline2("gi.inv_pos: maze is too small! (%d x %d)",
gx.x_maze_max, gy.y_maze_max);
}
gi.inv_pos.x = gi.inv_pos.y = 0; /*{occupied() => invocation_pos()}*/
do {
x = rn1(x_range, x_maze_min + INVPOS_X_MARGIN + 1);
y = rn1(y_range, y_maze_min + INVPOS_Y_MARGIN + 1);
/* we don't want it to be too near the stairs, nor
to be on a spot that's already in use (wall|trap) */
if (++trycnt > 1000)
break;
} while (((stway = stairway_find_dir(TRUE)) != 0)
&& (x == stway->sx || y == stway->sy /*(direct line)*/
|| abs(x - stway->sx) == abs(y - stway->sy)
|| distmin(x, y, stway->sx, stway->sy) <= INVPOS_DISTANCE
|| !SPACE_POS(levl[x][y].typ) || occupied(x, y)));
gi.inv_pos.x = x;
gi.inv_pos.y = y;
pick_vibrasquare_location();
maketrap(gi.inv_pos.x, gi.inv_pos.y, VIBRATING_SQUARE);
#undef INVPOS_X_MARGIN
#undef INVPOS_Y_MARGIN
#undef INVPOS_DISTANCE
#undef x_maze_min
#undef y_maze_min
}
/* place branch stair or portal */

View File

@@ -1573,6 +1573,9 @@ nhl_meta_u_index(lua_State *L)
} else if (!strcmp(tkey, "depth")) {
lua_pushinteger(L, depth(&u.uz));
return 1;
} else if (!strcmp(tkey, "invocation_level")) {
lua_pushboolean(L, Invocation_lev(&u.uz));
return 1;
}
nhl_error(L, "Unknown u table index");

View File

@@ -1776,7 +1776,11 @@ create_trap(spltrap* t, struct mkroom* croom)
coord tm;
int mktrap_flags = MKTRAP_MAZEFLAG;
if (croom) {
if (t->type == VIBRATING_SQUARE) {
pick_vibrasquare_location();
maketrap(gi.inv_pos.x, gi.inv_pos.y, VIBRATING_SQUARE);
return;
} else if (croom) {
get_free_room_loc(&x, &y, croom, t->coord);
} else {
int trycnt = 0;