From a5934470dd472bbb810e982a1065573229761584 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 17 Mar 2023 13:13:19 +0200 Subject: [PATCH] Fix boulder-on-lava sanity error Special level creation could make levels with boulders on top of lava or water; this was caused by mazewalk populating the maze before the rest of the level was created. Add a post-level-creation map cleanup routine, where boulders and traps on liquid terrain are removed. --- src/sp_lev.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/sp_lev.c b/src/sp_lev.c index bfd86cc3b..b68571353 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -20,6 +20,7 @@ extern void mkmap(lev_init *); static boolean match_maptyps(xint16, xint16); static void solidify_map(void); +static void map_cleanup(void); static void lvlfill_maze_grid(int, int, int, int, schar); static void lvlfill_solid(schar, schar); static void lvlfill_swamp(schar, schar, schar); @@ -322,6 +323,34 @@ solidify_map(void) levl[x][y].wall_info |= (W_NONDIGGABLE | W_NONPASSWALL); } +/* do a post-level-creation cleanup of map, such as + removing boulders and traps from lava */ +static void +map_cleanup(void) +{ + struct obj *otmp; + struct trap *ttmp; + coordxy x, y; + + for (x = 0; x < COLNO; x++) + for (y = 0; y < ROWNO; y++) { + schar typ = levl[x][y].typ; + + if (typ == LAVAPOOL || typ == LAVAWALL || IS_POOL(typ)) { + /* in case any boulders are on liquid, delete them */ + while ((otmp = sobj_at(BOULDER, x, y)) != 0) { + obj_extract_self(otmp); + obfree(otmp, (struct obj *)0); + } + + /* traps on liquid? */ + if (((ttmp = t_at(x, y)) != 0) + && !undestroyable_trap(ttmp->ttyp)) + deltrap(ttmp); + } + } +} + static void lvlfill_maze_grid(int x1, int y1, int x2, int y2, schar filling) { @@ -6473,6 +6502,8 @@ lspo_finalize_level(lua_State *L UNUSED) if (L && gc.coder->check_inaccessibles) ensure_way_out(); + map_cleanup(); + /* FIXME: Ideally, we want this call to only cover areas of the map * which were not inserted directly by the special level file (see * the insect legs on Baalzebub's level, for instance). Since that @@ -6947,6 +6978,8 @@ load_special(const char *name) if (gc.coder->check_inaccessibles) ensure_way_out(); + map_cleanup(); + /* FIXME: Ideally, we want this call to only cover areas of the map * which were not inserted directly by the special level file (see * the insect legs on Baalzebub's level, for instance). Since that