]> granicus.if.org Git - nethack/commitdiff
Fix vibrating square
authorPasi Kallinen <paxed@alt.org>
Thu, 19 Jan 2023 10:12:26 +0000 (12:12 +0200)
committerPasi Kallinen <paxed@alt.org>
Thu, 19 Jan 2023 10:15:46 +0000 (12:15 +0200)
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.

dat/hellfill.lua
include/extern.h
src/mkmaze.c
src/nhlua.c
src/sp_lev.c

index 964b4a24ee4db4b2bf7e6157c61ab0fc31ca0e9a..646939e067e9f99b893d4c0a2b438beed08208ad 100644 (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();
index cb35482bc771c4d11ad130e78613e936a2164584..d32d22899d781dc3716186e7302dd7db736ec0c0 100644 (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 *);
index e2aa636a2b7d00ff83a7b32f135ed1dd7f3b2012..ba5e74ecf60900085c91564e07dfcf4c2bac7b74 100644 (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 */
index 3b3ba0582209284d563b51713e37fb7c0b493baf..1d4224eb211df8dab91c3a9afa2122fe56551b4a 100644 (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");
index 61af4c58ebae9fd3c6d464a0ae16f336775e9b72..bf7ca8c05f4550eceb872ff166b312f0c2486d92 100644 (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;