From: Pasi Kallinen Date: Thu, 19 Jan 2023 10:12:26 +0000 (+0200) Subject: Fix vibrating square X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1113373892e0418ad5ac2e3e03d740a7253233ba;p=nethack 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. --- diff --git a/dat/hellfill.lua b/dat/hellfill.lua index 964b4a24e..646939e06 100644 --- a/dat/hellfill.lua +++ b/dat/hellfill.lua @@ -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(); diff --git a/include/extern.h b/include/extern.h index cb35482bc..d32d22899 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *); diff --git a/src/mkmaze.c b/src/mkmaze.c index e2aa636a2..ba5e74ecf 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -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 */ diff --git a/src/nhlua.c b/src/nhlua.c index 3b3ba0582..1d4224eb2 100644 --- a/src/nhlua.c +++ b/src/nhlua.c @@ -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"); diff --git a/src/sp_lev.c b/src/sp_lev.c index 61af4c58e..bf7ca8c05 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -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;