From 99ef5550ee13ee24c2513404596517ca1f488896 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Tue, 19 Jul 2022 21:57:00 -0400 Subject: [PATCH 01/11] Add some missing ceiling_exists calls --- src/muse.c | 1 + src/zap.c | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/muse.c b/src/muse.c index 2fdb3bb4b2..81eb829c8e 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1443,6 +1443,7 @@ find_offensive(struct monst *mtmp) || !rn2(10)) && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 && mtmp->mcansee && haseyes(mtmp->data) + && ceiling_exists() && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { gm.m.offensive = obj; gm.m.has_offense = MUSE_SCR_EARTH; diff --git a/src/zap.c b/src/zap.c index 881a7c15e1..721a778c84 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3225,9 +3225,8 @@ zap_updown(struct obj *obj) /* wand or spell */ else destroy_drawbridge(xx, yy); disclose = TRUE; - } else if (striking && u.dz < 0 && rn2(3) && !Is_airlevel(&u.uz) - && !Is_waterlevel(&u.uz) && !Underwater - && !Is_qstart(&u.uz)) { + } else if (striking && u.dz < 0 && rn2(3) + && ceiling_exists() && !Underwater) { int dmg; /* similar to zap_dig() */ pline("A rock is dislodged from the %s and falls on your %s.", From 631f8b71416655060d0b5db072731458e85a8538 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 9 Jun 2023 14:26:20 -0400 Subject: [PATCH 02/11] Lay groundwork for des.add_ceiling() Add the function, make it work (once a bit is defined to be used with it), make it accessible from level files. --- include/rm.h | 3 +++ src/sp_lev.c | 31 ++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/rm.h b/include/rm.h index 50a6f95914..703109ea73 100644 --- a/include/rm.h +++ b/include/rm.h @@ -174,6 +174,9 @@ enum door_states { #define TREE_LOOTED 1 #define TREE_SWARM 2 +#define BECEILINGED 0x01 /* FIXME not real value (or name) */ +#define HAS_CEILING(x, y) ((levl[x][y].flags & BECEILINGED) != 0) + /* * Fountains have limits, and special warnings. */ diff --git a/src/sp_lev.c b/src/sp_lev.c index 9a15c99c47..862c879c6e 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -29,6 +29,7 @@ static int flip_encoded_direction_bits(int, int); static void flip_vault_guard(int, struct monst *, coordxy, coordxy, coordxy, coordxy); static void sel_set_wall_property(coordxy, coordxy, genericptr_t); +static void sel_set_flags(coordxy, coordxy, genericptr_t); static void set_wall_property(coordxy, coordxy, coordxy, coordxy, int); static void count_features(void); static void remove_boundary_syms(void); @@ -102,6 +103,7 @@ static void get_table_xy_or_coord(lua_State *, lua_Integer *, lua_Integer *); static int get_table_region(lua_State *, const char *, lua_Integer *, lua_Integer *, lua_Integer *, lua_Integer *, boolean); static void set_wallprop_in_selection(lua_State *, int); +static void set_prop_in_selection(lua_State *, select_iter_func, int); static coordxy random_wdir(void); static int floodfillchk_match_under(coordxy, coordxy); static int floodfillchk_match_accessible(coordxy, coordxy); @@ -144,6 +146,7 @@ int lspo_mineralize(lua_State *); int lspo_monster(lua_State *); int lspo_non_diggable(lua_State *); int lspo_non_passwall(lua_State *); +int lspo_add_ceiling(lua_State *); int lspo_object(lua_State *); int lspo_portal(lua_State *); int lspo_random_corridors(lua_State *); @@ -963,6 +966,14 @@ sel_set_wall_property(coordxy x, coordxy y, genericptr_t arg) levl[x][y].wall_info |= prop; } +static void +sel_set_flags(coordxy x, coordxy y, genericptr_t arg) +{ + int prop = *(int *)arg; + + levl[x][y].flags |= prop; +} + /* * Make walls of the area (x1, y1, x2, y2) non diggable/non passwall-able */ @@ -6668,6 +6679,12 @@ lspo_wall_property(lua_State *L) static void set_wallprop_in_selection(lua_State *L, int prop) +{ + set_prop_in_selection(L, sel_set_wall_property, prop); +} + +static void +set_prop_in_selection(lua_State *L, select_iter_func set, int prop) { int argc = lua_gettop(L); boolean freesel = FALSE; @@ -6684,7 +6701,7 @@ set_wallprop_in_selection(lua_State *L, int prop) } if (sel) { - selection_iterate(sel, sel_set_wall_property, (genericptr_t) &prop); + selection_iterate(sel, set, (genericptr_t) &prop); if (freesel) selection_free(sel, TRUE); } @@ -6708,6 +6725,17 @@ lspo_non_passwall(lua_State *L) return 0; } +/* should be used for 'outdoors' flagged levels, to specify areas which have + * ceilings */ +/* add_ceiling(selection); */ +/* add_ceiling(); */ +int +lspo_add_ceiling(lua_State *L) +{ + set_prop_in_selection(L, sel_set_flags, BECEILINGED); + return 0; +} + #if 0 /*ARGSUSED*/ static void @@ -7173,6 +7201,7 @@ static const struct luaL_Reg nhl_functions[] = { { "wall_property", lspo_wall_property }, { "non_diggable", lspo_non_diggable }, { "non_passwall", lspo_non_passwall }, + { "add_ceiling", lspo_add_ceiling }, { "teleport_region", lspo_teleport_region }, { "reset_level", lspo_reset_level }, { "finalize_level", lspo_finalize_level }, From a7760ed720f5195183cfac6634c9474260c00ad4 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 9 Jun 2023 14:31:03 -0400 Subject: [PATCH 03/11] Check for ceiling existing at a specific spot... ...instead of a level-wide ceiling/no-ceiling, when appropriate. --- include/extern.h | 1 + src/dothrow.c | 2 +- src/dungeon.c | 32 ++++++++++++++++++++++++++++++++ src/mklev.c | 8 ++++++-- src/mon.c | 16 ++++++++-------- src/muse.c | 6 ++++-- src/polyself.c | 2 +- src/potion.c | 2 +- src/read.c | 5 +++-- src/zap.c | 2 +- 10 files changed, 58 insertions(+), 18 deletions(-) diff --git a/include/extern.h b/include/extern.h index ce90664bae..6500bbff18 100644 --- a/include/extern.h +++ b/include/extern.h @@ -742,6 +742,7 @@ extern boolean Is_botlevel(d_level *); extern boolean Can_fall_thru(d_level *); extern boolean Can_dig_down(d_level *); extern boolean Can_rise_up(coordxy, coordxy, d_level *); +extern boolean ceiling_exists(coordxy, coordxy, boolean); extern boolean has_ceiling(d_level *); extern boolean avoid_ceiling(d_level *); extern const char *surface(coordxy, coordxy); diff --git a/src/dothrow.c b/src/dothrow.c index ce9734e0de..8eabadf11d 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1309,7 +1309,7 @@ toss_up(struct obj *obj, boolean hitsroof) && touch_petrifies(&mons[obj->corpsenm])); /* note: obj->quan == 1 */ - if (!has_ceiling(&u.uz)) { + if (!ceiling_exists(u.ux, u.uy, FALSE)) { action = "flies up into"; /* into "the sky" or "the water above" */ } else if (hitsroof) { if (breaktest(obj)) { diff --git a/src/dungeon.c b/src/dungeon.c index 22ca20ee84..8503acca0d 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1864,6 +1864,38 @@ surface(coordxy x, coordxy y) return "ground"; } +boolean +ceiling_exists(coordxy x, coordxy y, boolean check_surroundings) +{ + /* no exceptions on certain levels */ + if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) + return FALSE; + if (!gl.level.flags.outdoors) + return TRUE; + + /* if we're given 0,0 or similar out-of-bounds candidate, just return + the default ceiling state for the level -- after previous checks it + must be no-ceiling */ + if (!isok(x, y)) + return FALSE; + + /* now check for exceptions */ + if (HAS_CEILING(x, y)) + return TRUE; + + if (check_surroundings) { + int xx, yy; + for (xx = x - 1; xx <= x + 1; ++xx) { + for (yy = y - 1; yy <= y + 1; ++yy) { + if (isok(xx, yy) && HAS_CEILING(xx, yy)) + return TRUE; + } + } + } + + return FALSE; +} + /* * It is expected that the second argument of get_level is a depth value, * either supplied by the user (teleport control) or randomly generated. diff --git a/src/mklev.c b/src/mklev.c index d80263b6fc..b92562ba76 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1963,11 +1963,15 @@ mktrap( kind = NO_TRAP; break; case RUST_TRAP: - case ROCKTRAP: + case ROCKTRAP: { /* certain traps that rely on a ceiling to make sense */ - if (!has_ceiling(&u.uz)) + int x = 0, y = 0; + if (tm) + x = tm->x, y = tm->y; + if (!ceiling_exists(x, y, FALSE)) kind = NO_TRAP; } + } } while (kind == NO_TRAP); } diff --git a/src/mon.c b/src/mon.c index a1f4c73e21..2966d5b02d 100644 --- a/src/mon.c +++ b/src/mon.c @@ -159,14 +159,14 @@ sanity_check_single_mon( if (ceiling_hider(mptr) /* normally !accessible would be overridable with passes_walls, but not for hiding on the ceiling */ - && (!has_ceiling(&u.uz) || - !(levl[mx][my].typ == POOL - || levl[mx][my].typ == MOAT - || levl[mx][my].typ == LAVAPOOL - || accessible(mx, my)))) + && (!ceiling_exists(mx, my, FALSE) + || !(levl[mx][my].typ == POOL + || levl[mx][my].typ == MOAT + || levl[mx][my].typ == LAVAPOOL + || accessible(mx, my)))) impossible("ceiling hider hiding %s (%s)", - !has_ceiling(&u.uz) ? "without ceiling" - : "in solid stone", + !ceiling_exists(mx, my, FALSE) ? "without ceiling" + : "in solid stone", msg); if (mtmp->mtrapped && (t = t_at(mx, my)) != 0 && !is_pit(t->ttyp)) impossible("hiding while trapped in a non-pit (%s)", msg); @@ -4634,7 +4634,7 @@ restrap(struct monst *mtmp) set_mimic_sym(mtmp); return TRUE; } else if (levl[mtmp->mx][mtmp->my].typ == ROOM - && has_ceiling(&u.uz)) { + && ceiling_exists(mtmp->mx, mtmp->my, FALSE)) { mtmp->mundetected = 1; return TRUE; } diff --git a/src/muse.c b/src/muse.c index 81eb829c8e..8ce65204c4 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1443,7 +1443,7 @@ find_offensive(struct monst *mtmp) || !rn2(10)) && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 && mtmp->mcansee && haseyes(mtmp->data) - && ceiling_exists() + && ceiling_exists(mtmp->mx, mtmp->my, TRUE) && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { gm.m.offensive = obj; gm.m.has_offense = MUSE_SCR_EARTH; @@ -1784,6 +1784,7 @@ use_offensive(struct monst *mtmp) for (y = mmy - 1; y <= mmy + 1; y++) { /* Is this a suitable spot? */ if (isok(x, y) && !closed_door(x, y) + && ceiling_exists(x, y, FALSE) && !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ) && (((x == mmx) && (y == mmy)) ? !is_blessed : !is_cursed) && (x != u.ux || y != u.uy)) { @@ -1792,7 +1793,8 @@ use_offensive(struct monst *mtmp) } } /* Attack the player */ - if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !is_cursed) { + if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !is_cursed + && ceiling_exists(u.ux, u.uy, FALSE)) { drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE); } diff --git a/src/polyself.c b/src/polyself.c index d232b2bd57..0f4501be74 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1851,7 +1851,7 @@ dohide(void) } } /* Planes of Air and Water */ - if (on_ceiling && !has_ceiling(&u.uz)) { + if (on_ceiling && !ceiling_exists(u.ux, u.uy, FALSE)) { There("is nowhere to hide above you."); u.uundetected = 0; return ECMD_OK; diff --git a/src/potion.c b/src/potion.c index bd0697188e..1027af80b0 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1400,7 +1400,7 @@ peffect_levitation(struct obj *otmp) /* in case we're already Levitating, which would have resulted in incrementing 'nothing' */ gp.potion_nothing = 0; /* not nothing after all */ - } else if (has_ceiling(&u.uz)) { + } else if (ceiling_exists(u.ux, u.uy, FALSE)) { int dmg = rnd(!uarmh ? 10 : !is_hard(uarmh) ? 6 : 3); You("hit your %s on the %s.", body_part(HEAD), diff --git a/src/read.c b/src/read.c index b722c90e69..747a0a24bb 100644 --- a/src/read.c +++ b/src/read.c @@ -1984,7 +1984,7 @@ seffect_earth(struct obj **sobjp) } pline("The earth moves around you!"); } - else if (has_ceiling(&u.uz) + else if (ceiling_exists(u.ux, u.uy, !scursed) && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { coordxy x, y; int nboulders = 0; @@ -2016,6 +2016,7 @@ seffect_earth(struct obj **sobjp) for (y = u.uy - 1; y <= u.uy + 1; y++) { /* Is this a suitable spot? */ if (isok(x, y) && !closed_door(x, y) + && ceiling_exists(x, y, FALSE) && !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ) && (x != u.ux || y != u.uy)) { @@ -2025,7 +2026,7 @@ seffect_earth(struct obj **sobjp) } } /* Attack the player */ - if (!sblessed) { + if (!sblessed && ceiling_exists(u.ux, u.uy, FALSE)) { drop_boulder_on_player(FALSE, !scursed, TRUE, FALSE); } else if (!nboulders) pline("But nothing else happens."); diff --git a/src/zap.c b/src/zap.c index 721a778c84..8e87a5d600 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3226,7 +3226,7 @@ zap_updown(struct obj *obj) /* wand or spell */ destroy_drawbridge(xx, yy); disclose = TRUE; } else if (striking && u.dz < 0 && rn2(3) - && ceiling_exists() && !Underwater) { + && ceiling_exists(x, y, FALSE) && !Underwater) { int dmg; /* similar to zap_dig() */ pline("A rock is dislodged from the %s and falls on your %s.", From 0632d29aaac41bbdf7454834aa48f89a39e5a594 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Tue, 19 Jul 2022 23:11:23 -0400 Subject: [PATCH 04/11] Improve(?) on ceiling-required trap generation This is arguably a better approach than the previous one, in that it allows for rock traps to generate randomly indoors (or under some other kind of ceiling) even on levels that are flagged 'outdoors'. However, it's a bit wasteful since any outdoors level without 'indoor' areas will spend a bunch of cycles trying to place the trap before finally giving up. Maybe not that big a deal in the big picture though. --- include/trap.h | 1 + src/mklev.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/trap.h b/include/trap.h index 68346b8008..cca9639f85 100644 --- a/include/trap.h +++ b/include/trap.h @@ -121,6 +121,7 @@ enum { Trap_Effect_Finished = 0, || (ttyp) == MAGIC_TRAP \ || (ttyp) == ANTI_MAGIC \ || (ttyp) == POLY_TRAP) +#define is_ceiling_trap(ttyp) ((ttyp) == ROCKTRAP || (ttyp) == RUST_TRAP) /* "transportation" traps */ #define is_xport(ttyp) ((ttyp) >= TELEP_TRAP && (ttyp) <= MAGIC_PORTAL) diff --git a/src/mklev.c b/src/mklev.c index b92562ba76..551dd8e7af 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1963,15 +1963,11 @@ mktrap( kind = NO_TRAP; break; case RUST_TRAP: - case ROCKTRAP: { + case ROCKTRAP: /* certain traps that rely on a ceiling to make sense */ - int x = 0, y = 0; - if (tm) - x = tm->x, y = tm->y; - if (!ceiling_exists(x, y, FALSE)) + if (tm && !ceiling_exists(tm->x, tm->y, FALSE)) kind = NO_TRAP; } - } } while (kind == NO_TRAP); } @@ -1982,7 +1978,8 @@ mktrap( m = *tm; } else { register int tryct = 0; - boolean avoid_boulder = (is_pit(kind) || is_hole(kind)); + boolean avoid_boulder = (is_pit(kind) || is_hole(kind)), + need_ceiling = is_ceiling_trap(kind); /* Try up to 200 times to find a random coordinate for the trap. */ do { @@ -1993,7 +1990,8 @@ mktrap( else if (!somexyspace(croom, &m)) return; } while (occupied(m.x, m.y) - || (avoid_boulder && sobj_at(BOULDER, m.x, m.y))); + || (avoid_boulder && sobj_at(BOULDER, m.x, m.y)) + || (need_ceiling && !ceiling_exists(m.x, m.y, FALSE))); } t = maketrap(m.x, m.y, kind); From 17787a1e4669bc1f892af751523ff47993f673f0 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 9 Jun 2023 14:34:47 -0400 Subject: [PATCH 05/11] Require ceiling directly above for scroll of earth Instead of checking for any adjacent ceiling, require ceiling directly above the hero or monster reading the scroll. This avoids the need for more complicated feedback (e.g. "the ceiling rumbles nearby" or similar when there's no ceiling directly above you), and I think it probably makes sense anyway... This also allows us to drop the boolean param from ceiling_exists. --- include/extern.h | 2 +- src/dothrow.c | 2 +- src/dungeon.c | 16 ++-------------- src/mklev.c | 4 ++-- src/mon.c | 8 ++++---- src/muse.c | 6 +++--- src/polyself.c | 2 +- src/potion.c | 2 +- src/read.c | 6 +++--- src/zap.c | 2 +- 10 files changed, 19 insertions(+), 31 deletions(-) diff --git a/include/extern.h b/include/extern.h index 6500bbff18..dc22cf76e4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -742,7 +742,7 @@ extern boolean Is_botlevel(d_level *); extern boolean Can_fall_thru(d_level *); extern boolean Can_dig_down(d_level *); extern boolean Can_rise_up(coordxy, coordxy, d_level *); -extern boolean ceiling_exists(coordxy, coordxy, boolean); +extern boolean ceiling_exists(coordxy, coordxy); extern boolean has_ceiling(d_level *); extern boolean avoid_ceiling(d_level *); extern const char *surface(coordxy, coordxy); diff --git a/src/dothrow.c b/src/dothrow.c index 8eabadf11d..ec372beee6 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1309,7 +1309,7 @@ toss_up(struct obj *obj, boolean hitsroof) && touch_petrifies(&mons[obj->corpsenm])); /* note: obj->quan == 1 */ - if (!ceiling_exists(u.ux, u.uy, FALSE)) { + if (!ceiling_exists(u.ux, u.uy)) { action = "flies up into"; /* into "the sky" or "the water above" */ } else if (hitsroof) { if (breaktest(obj)) { diff --git a/src/dungeon.c b/src/dungeon.c index 8503acca0d..e6a342432a 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1803,7 +1803,7 @@ ceiling(coordxy x, coordxy y) else if (Is_waterlevel(&u.uz)) /* water plane has no surface; its air bubbles aren't below sky */ what = "water above"; - else if (!has_ceiling(&u.uz)) + else if (!ceiling_exists(x, y)) what = "sky"; else if (Is_firelevel(&u.uz)) what = "flames above"; @@ -1865,34 +1865,22 @@ surface(coordxy x, coordxy y) } boolean -ceiling_exists(coordxy x, coordxy y, boolean check_surroundings) +ceiling_exists(coordxy x, coordxy y) { /* no exceptions on certain levels */ if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)) return FALSE; if (!gl.level.flags.outdoors) return TRUE; - /* if we're given 0,0 or similar out-of-bounds candidate, just return the default ceiling state for the level -- after previous checks it must be no-ceiling */ if (!isok(x, y)) return FALSE; - /* now check for exceptions */ if (HAS_CEILING(x, y)) return TRUE; - if (check_surroundings) { - int xx, yy; - for (xx = x - 1; xx <= x + 1; ++xx) { - for (yy = y - 1; yy <= y + 1; ++yy) { - if (isok(xx, yy) && HAS_CEILING(xx, yy)) - return TRUE; - } - } - } - return FALSE; } diff --git a/src/mklev.c b/src/mklev.c index 551dd8e7af..3cf71e17ed 100644 --- a/src/mklev.c +++ b/src/mklev.c @@ -1965,7 +1965,7 @@ mktrap( case RUST_TRAP: case ROCKTRAP: /* certain traps that rely on a ceiling to make sense */ - if (tm && !ceiling_exists(tm->x, tm->y, FALSE)) + if (tm && !ceiling_exists(tm->x, tm->y)) kind = NO_TRAP; } } while (kind == NO_TRAP); @@ -1991,7 +1991,7 @@ mktrap( return; } while (occupied(m.x, m.y) || (avoid_boulder && sobj_at(BOULDER, m.x, m.y)) - || (need_ceiling && !ceiling_exists(m.x, m.y, FALSE))); + || (need_ceiling && !ceiling_exists(m.x, m.y))); } t = maketrap(m.x, m.y, kind); diff --git a/src/mon.c b/src/mon.c index 2966d5b02d..39e22b9835 100644 --- a/src/mon.c +++ b/src/mon.c @@ -159,14 +159,14 @@ sanity_check_single_mon( if (ceiling_hider(mptr) /* normally !accessible would be overridable with passes_walls, but not for hiding on the ceiling */ - && (!ceiling_exists(mx, my, FALSE) + && (!ceiling_exists(mx, my) || !(levl[mx][my].typ == POOL || levl[mx][my].typ == MOAT || levl[mx][my].typ == LAVAPOOL || accessible(mx, my)))) impossible("ceiling hider hiding %s (%s)", - !ceiling_exists(mx, my, FALSE) ? "without ceiling" - : "in solid stone", + !ceiling_exists(mx, my) ? "without ceiling" + : "in solid stone", msg); if (mtmp->mtrapped && (t = t_at(mx, my)) != 0 && !is_pit(t->ttyp)) impossible("hiding while trapped in a non-pit (%s)", msg); @@ -4634,7 +4634,7 @@ restrap(struct monst *mtmp) set_mimic_sym(mtmp); return TRUE; } else if (levl[mtmp->mx][mtmp->my].typ == ROOM - && ceiling_exists(mtmp->mx, mtmp->my, FALSE)) { + && ceiling_exists(mtmp->mx, mtmp->my)) { mtmp->mundetected = 1; return TRUE; } diff --git a/src/muse.c b/src/muse.c index 8ce65204c4..e687885f2b 100644 --- a/src/muse.c +++ b/src/muse.c @@ -1443,7 +1443,7 @@ find_offensive(struct monst *mtmp) || !rn2(10)) && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 2 && mtmp->mcansee && haseyes(mtmp->data) - && ceiling_exists(mtmp->mx, mtmp->my, TRUE) + && ceiling_exists(mtmp->mx, mtmp->my) && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { gm.m.offensive = obj; gm.m.has_offense = MUSE_SCR_EARTH; @@ -1784,7 +1784,7 @@ use_offensive(struct monst *mtmp) for (y = mmy - 1; y <= mmy + 1; y++) { /* Is this a suitable spot? */ if (isok(x, y) && !closed_door(x, y) - && ceiling_exists(x, y, FALSE) + && ceiling_exists(x, y) && !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ) && (((x == mmx) && (y == mmy)) ? !is_blessed : !is_cursed) && (x != u.ux || y != u.uy)) { @@ -1794,7 +1794,7 @@ use_offensive(struct monst *mtmp) } /* Attack the player */ if (distmin(mmx, mmy, u.ux, u.uy) == 1 && !is_cursed - && ceiling_exists(u.ux, u.uy, FALSE)) { + && ceiling_exists(u.ux, u.uy)) { drop_boulder_on_player(confused, !is_cursed, FALSE, TRUE); } diff --git a/src/polyself.c b/src/polyself.c index 0f4501be74..1cfdd57e91 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1851,7 +1851,7 @@ dohide(void) } } /* Planes of Air and Water */ - if (on_ceiling && !ceiling_exists(u.ux, u.uy, FALSE)) { + if (on_ceiling && !ceiling_exists(u.ux, u.uy)) { There("is nowhere to hide above you."); u.uundetected = 0; return ECMD_OK; diff --git a/src/potion.c b/src/potion.c index 1027af80b0..a0ad52335a 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1400,7 +1400,7 @@ peffect_levitation(struct obj *otmp) /* in case we're already Levitating, which would have resulted in incrementing 'nothing' */ gp.potion_nothing = 0; /* not nothing after all */ - } else if (ceiling_exists(u.ux, u.uy, FALSE)) { + } else if (ceiling_exists(u.ux, u.uy)) { int dmg = rnd(!uarmh ? 10 : !is_hard(uarmh) ? 6 : 3); You("hit your %s on the %s.", body_part(HEAD), diff --git a/src/read.c b/src/read.c index 747a0a24bb..e7a4ca2224 100644 --- a/src/read.c +++ b/src/read.c @@ -1984,7 +1984,7 @@ seffect_earth(struct obj **sobjp) } pline("The earth moves around you!"); } - else if (ceiling_exists(u.ux, u.uy, !scursed) + else if (ceiling_exists(u.ux, u.uy) && (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { coordxy x, y; int nboulders = 0; @@ -2016,7 +2016,7 @@ seffect_earth(struct obj **sobjp) for (y = u.uy - 1; y <= u.uy + 1; y++) { /* Is this a suitable spot? */ if (isok(x, y) && !closed_door(x, y) - && ceiling_exists(x, y, FALSE) + && ceiling_exists(x, y) && !IS_ROCK(levl[x][y].typ) && !IS_AIR(levl[x][y].typ) && (x != u.ux || y != u.uy)) { @@ -2026,7 +2026,7 @@ seffect_earth(struct obj **sobjp) } } /* Attack the player */ - if (!sblessed && ceiling_exists(u.ux, u.uy, FALSE)) { + if (!sblessed && ceiling_exists(u.ux, u.uy)) { drop_boulder_on_player(FALSE, !scursed, TRUE, FALSE); } else if (!nboulders) pline("But nothing else happens."); diff --git a/src/zap.c b/src/zap.c index 8e87a5d600..b0303ab53b 100644 --- a/src/zap.c +++ b/src/zap.c @@ -3226,7 +3226,7 @@ zap_updown(struct obj *obj) /* wand or spell */ destroy_drawbridge(xx, yy); disclose = TRUE; } else if (striking && u.dz < 0 && rn2(3) - && ceiling_exists(x, y, FALSE) && !Underwater) { + && ceiling_exists(x, y) && !Underwater) { int dmg; /* similar to zap_dig() */ pline("A rock is dislodged from the %s and falls on your %s.", From 7e0a4826f840b61d3c8b7cb9e9333aea5b9b01fe Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Tue, 19 Jul 2022 23:00:04 -0400 Subject: [PATCH 06/11] Test the ceiling thing --- dat/Arc-strt.lua | 8 ++++++++ include/rm.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dat/Arc-strt.lua b/dat/Arc-strt.lua index abc4814c72..dc919c053d 100644 --- a/dat/Arc-strt.lua +++ b/dat/Arc-strt.lua @@ -114,6 +114,14 @@ for i = 1,2 do end des.object("tinning kit", bookrooms:rndcoord(1)) des.object("grappling hook", bookrooms:rndcoord(1)) +-- Interiors +des.add_ceiling(selection.area(5,0,12,5) | selection.area(3,2,4,5)) +des.add_ceiling(selection.area(20,0,32,2)) +des.add_ceiling(selection.area(8,17,18,19) | selection.area(12,15,18,16) | selection.area(19,18,22,19)) +des.add_ceiling(selection.area(23,8,30,14) | selection.area(28,4,35,8) | selection.area(31,9,42,11) | selection.area(39,6,42,8)) +des.add_ceiling(selection.area(27,17,39,19) | selection.area(32,15,42,18)) +des.add_ceiling(selection.area(63,0,67,5) | selection.area(68,0,76,3) | selection.area(66,4,71,7)) +des.add_ceiling(selection.area(61,9,66,12) | selection.area(58,10,64,14)) -- Small cemetery des.grave(73,18, "Dr. Carter -- Died to a mummy's curse") des.grave(75,19, "Under NO circumstances are students to dig up this grave!") diff --git a/include/rm.h b/include/rm.h index 703109ea73..9fbe0df626 100644 --- a/include/rm.h +++ b/include/rm.h @@ -174,7 +174,7 @@ enum door_states { #define TREE_LOOTED 1 #define TREE_SWARM 2 -#define BECEILINGED 0x01 /* FIXME not real value (or name) */ +#define BECEILINGED 0x20 /* FIXME not real value (or name) */ #define HAS_CEILING(x, y) ((levl[x][y].flags & BECEILINGED) != 0) /* From 6aef050de76f395bc5aedab762515343ef72d9d1 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 20 Jul 2022 12:10:10 -0400 Subject: [PATCH 07/11] Add ceilings to outdoors levels --- dat/Arc-loca.lua | 3 +++ dat/Arc-strt.lua | 13 +++++-------- dat/Bar-goal.lua | 5 +++++ dat/Bar-loca.lua | 5 +++++ dat/Bar-strt.lua | 3 +++ dat/Hea-loca.lua | 2 ++ dat/Hea-strt.lua | 2 ++ dat/Kni-strt.lua | 3 +++ dat/Mon-loca.lua | 4 ++++ dat/Mon-strt.lua | 5 +++++ dat/Pri-loca.lua | 2 ++ dat/Pri-strt.lua | 3 +++ dat/Sam-loca.lua | 4 ++++ dat/Sam-strt.lua | 3 +++ dat/Tou-strt.lua | 4 ++++ dat/Val-strt.lua | 2 ++ dat/Wiz-loca.lua | 2 ++ dat/Wiz-strt.lua | 6 +++++- 18 files changed, 62 insertions(+), 9 deletions(-) diff --git a/dat/Arc-loca.lua b/dat/Arc-loca.lua index 2336a7c6f3..9a335f5542 100644 --- a/dat/Arc-loca.lua +++ b/dat/Arc-loca.lua @@ -33,6 +33,9 @@ local outside = selection.floodfill(00,00) local inside = outside:clone():negate():filter_mapchar('.') des.region(outside, "lit") +-- Ceilings +des.add_ceiling(inside:clone():grow() | selection.area(70,13, 76,19)) + -- Non diggable walls (but leave all trees diggable) local nondig = selection.area(00,00,75,19) ~ selection.area(00,00,50,19):filter_mapchar('T') des.non_diggable(nondig) diff --git a/dat/Arc-strt.lua b/dat/Arc-strt.lua index dc919c053d..633346fad9 100644 --- a/dat/Arc-strt.lua +++ b/dat/Arc-strt.lua @@ -37,6 +37,11 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,76,19), "lit") +-- Ceilings +local exterior = selection.area(00,00, 76,19):filter_mapchar(',') | selection.floodfill(02,06, true) + | selection.area(71,15, 76,19) | selection.area(34,12, 41,14) +local interior = exterior:clone():negate():filter_mapchar('.'):grow() +des.add_ceiling(interior) -- Stairs des.stair("down",76,05) -- Portal arrival point @@ -114,14 +119,6 @@ for i = 1,2 do end des.object("tinning kit", bookrooms:rndcoord(1)) des.object("grappling hook", bookrooms:rndcoord(1)) --- Interiors -des.add_ceiling(selection.area(5,0,12,5) | selection.area(3,2,4,5)) -des.add_ceiling(selection.area(20,0,32,2)) -des.add_ceiling(selection.area(8,17,18,19) | selection.area(12,15,18,16) | selection.area(19,18,22,19)) -des.add_ceiling(selection.area(23,8,30,14) | selection.area(28,4,35,8) | selection.area(31,9,42,11) | selection.area(39,6,42,8)) -des.add_ceiling(selection.area(27,17,39,19) | selection.area(32,15,42,18)) -des.add_ceiling(selection.area(63,0,67,5) | selection.area(68,0,76,3) | selection.area(66,4,71,7)) -des.add_ceiling(selection.area(61,9,66,12) | selection.area(58,10,64,14)) -- Small cemetery des.grave(73,18, "Dr. Carter -- Died to a mummy's curse") des.grave(75,19, "Under NO circumstances are students to dig up this grave!") diff --git a/dat/Bar-goal.lua b/dat/Bar-goal.lua index 8c7c58e9d8..7b6ba80c22 100644 --- a/dat/Bar-goal.lua +++ b/dat/Bar-goal.lua @@ -41,6 +41,11 @@ des.teleport_region({ region = {00,00,75,19}, exclude = {06,00,75,19}, dir="down -- and active at the same time. des.teleport_region({ region = {00,00,75,19}, exclude = {41,00,75,19}, dir="up" }) +-- Ceilings +local exterior = selection.floodfill(00,00) + selection.floodfill(57,08) +local covered = exterior:clone():negate():filter_mapchar('.'):grow() +des.add_ceiling(covered) + -- Stair local leftedge = selection.line(00,00, 00,19) des.stair("up", leftedge:rndcoord(1)) diff --git a/dat/Bar-loca.lua b/dat/Bar-loca.lua index 82a855e679..4833a458ac 100644 --- a/dat/Bar-loca.lua +++ b/dat/Bar-loca.lua @@ -37,6 +37,11 @@ des.region(selection.area(35,14,37,15), "unlit") des.region(selection.area(39,03,54,08), "lit") des.region(selection.area(56,00,75,08), "unlit") des.region(selection.area(64,09,75,16), "unlit") +-- Ceilings +local covered = selection.floodfill(00,00, true):negate():filter_mapchar('.') +-- only needed if the caves to the right should actually be uncovered: +-- covered = covered - selection.floodfill(66,05) +des.add_ceiling(covered:grow()) -- Doors des.door("open",23,03) des.door("open",30,08) diff --git a/dat/Bar-strt.lua b/dat/Bar-strt.lua index 5bc69348b2..1b688fdf3e 100644 --- a/dat/Bar-strt.lua +++ b/dat/Bar-strt.lua @@ -55,6 +55,9 @@ des.region(selection.area(26,10,28,11), "lit") des.region(selection.area(04,13,06,14), "lit") des.region(selection.area(15,13,17,14), "lit") des.region(selection.area(22,14,24,15), "lit") +-- Ceilings +local covered = selection.floodfill(00,00):negate():filter_mapchar('.'):grow() +des.add_ceiling(covered) -- Stairs des.stair("down", 09,09) -- Portal arrival point diff --git a/dat/Hea-loca.lua b/dat/Hea-loca.lua index 5f6373944a..44eac910ab 100644 --- a/dat/Hea-loca.lua +++ b/dat/Hea-loca.lua @@ -24,6 +24,8 @@ PPPPPPPPPPP........PPPPPPPPPPPP -- Dungeon Description des.region(selection.area(00,00,30,09), "lit") des.region({ region={12,03, 20,06}, lit=1, type="temple", filled=1 }) +-- Ceilings +des.add_ceiling(selection.area(09,02, 21,07)) -- Doors des.door("closed",09,04) des.door("closed",09,05) diff --git a/dat/Hea-strt.lua b/dat/Hea-strt.lua index 6c25b1841f..02373b73d5 100644 --- a/dat/Hea-strt.lua +++ b/dat/Hea-strt.lua @@ -40,6 +40,8 @@ des.replace_terrain({ region={01,01, 74,18}, fromterrain="P", toterrain=".", cha -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") +-- Ceilings +des.add_ceiling(selection.area(24,07, 50,13)) -- Stairs des.stair("down", 37,9) -- Portal arrival point diff --git a/dat/Kni-strt.lua b/dat/Kni-strt.lua index 59fca9303a..3f31973b6b 100644 --- a/dat/Kni-strt.lua +++ b/dat/Kni-strt.lua @@ -40,6 +40,9 @@ des.region({ region={06,06,22,09}, lit=1, type="throne", filled=2 }) des.region(selection.area(27,06,43,09), "lit") -- Portal arrival point des.levregion({ region = {20,14,20,14}, type="branch" }) +-- Ceilings +local interior = selection.floodfill(00,00):negate():filter_mapchar('.'):grow() +des.add_ceiling(interior) -- Stairs des.stair("down", 40,7) -- Doors diff --git a/dat/Mon-loca.lua b/dat/Mon-loca.lua index 93d24ea94d..8e563d0087 100644 --- a/dat/Mon-loca.lua +++ b/dat/Mon-loca.lua @@ -39,6 +39,10 @@ des.region(selection.area(62,03,72,11), "unlit") des.teleport_region({ region={00,00,06,04}, dir="down" }) des.teleport_region({ region={62,03,72,11}, dir="up" }) +-- Ceilings +local covered = selection.floodfill(67, 4):grow() + selection.floodfill(67, 7) +des.add_ceiling(covered) + -- Stairs des.stair("up", 00,00) des.stair("down", 67,07) diff --git a/dat/Mon-strt.lua b/dat/Mon-strt.lua index 689539bcb5..aab6a0452b 100644 --- a/dat/Mon-strt.lua +++ b/dat/Mon-strt.lua @@ -41,6 +41,11 @@ des.region(selection.area(00,00,75,19), "lit") local spacelocs = selection.floodfill(05,04); +-- Ceilings +local covered = selection.area(55,14, 65,19) | selection.area(54,15, 66,18) + | selection.floodfill(40,09):grow() +des.add_ceiling(covered) + -- Portal arrival point des.levregion({ region = {02,10,02,10}, type="branch" }) diff --git a/dat/Pri-loca.lua b/dat/Pri-loca.lua index 984a04b9a0..99361d6486 100644 --- a/dat/Pri-loca.lua +++ b/dat/Pri-loca.lua @@ -31,6 +31,8 @@ des.region({ region={09,00, 30,01}, lit=0, type="morgue", filled=1 }) des.region({ region={09,12, 30,13}, lit=0, type="morgue", filled=1 }) des.region({ region={31,00, 39,13}, lit=0, type="morgue", filled=1 }) des.region({ region={11,03, 29,10}, lit=1, type="temple", filled=1, irregular=1 }) +-- Ceilings +des.add_ceiling(selection.area(10, 2, 30, 11)) -- The altar inside the temple des.altar({ x=20,y=07, align="noalign", type="shrine" }) des.monster({ id = "aligned cleric", x=20, y=07, align="noalign", peaceful = 0 }) diff --git a/dat/Pri-strt.lua b/dat/Pri-strt.lua index 457949ccbb..68c25b5eec 100644 --- a/dat/Pri-strt.lua +++ b/dat/Pri-strt.lua @@ -47,6 +47,9 @@ local spacelocs = selection.floodfill(05,04); -- Portal arrival point des.levregion({ region = {05,04,05,04}, type="branch" }) +-- Ceilings +local covered = selection.area(20,03, 55,16) | selection.area(18,08, 20,11) +des.add_ceiling(covered) -- Stairs des.stair("down", 52,09) -- Doors diff --git a/dat/Sam-loca.lua b/dat/Sam-loca.lua index 87c08e0cf2..41d489e75a 100644 --- a/dat/Sam-loca.lua +++ b/dat/Sam-loca.lua @@ -31,6 +31,10 @@ des.map([[ ]]); -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") +-- Ceiling +local covered = selection.floodfill(00,00, true):negate():filter_mapchar('.') +covered = covered - selection.area(24,07,51,12) +des.add_ceiling(covered:grow()) -- Doors des.door("locked",22,04) des.door("locked",22,15) diff --git a/dat/Sam-strt.lua b/dat/Sam-strt.lua index cfc04083b7..6db56d54bb 100644 --- a/dat/Sam-strt.lua +++ b/dat/Sam-strt.lua @@ -38,6 +38,9 @@ des.map([[ -- Dungeon Description des.region(selection.area(00,00,75,19), "lit") des.region({ region={18,03, 26,07}, lit=1, type="throne", filled=2 }) +-- Ceilings +local covered = selection.area(10,02,60,11) | selection.area(42,12,60,17) +des.add_ceiling(covered) -- Portal arrival zone des.levregion({ region = {62,12,70,17}, type="branch" }) -- Stairs diff --git a/dat/Tou-strt.lua b/dat/Tou-strt.lua index bac7845f80..5aeef544ee 100644 --- a/dat/Tou-strt.lua +++ b/dat/Tou-strt.lua @@ -45,6 +45,10 @@ des.region(selection.area(34,02,39,04), "unlit") des.region(selection.area(41,02,53,04), "unlit") des.region(selection.area(55,02,60,04), "unlit") des.region(selection.area(62,02,67,04), "lit") +-- Ceilings +local covered = selection.area(06,09, 12,13) | selection.area(03,15, 09,19) + | selection.area(16,15, 22,19) | selection.area(24,00, 72,07) +des.add_ceiling(covered) -- Stairs des.stair("down", 66,03) -- Portal arrival point diff --git a/dat/Val-strt.lua b/dat/Val-strt.lua index 13dfccdcb5..76648fb88a 100644 --- a/dat/Val-strt.lua +++ b/dat/Val-strt.lua @@ -42,6 +42,8 @@ local inside = selection.floodfill(34,10) + selection.floodfill(34,06) + selecti local outside = (everything:filter_mapchar('.') + alltheice) - inside local init_monster_area = outside & selection.area(17,00,75,19):grow() des.region(everything, "lit") +-- Ceilings +des.add_ceiling(inside:clone():grow()) -- Lava vents surrounded by water local pools = selection.new() local function growths() diff --git a/dat/Wiz-loca.lua b/dat/Wiz-loca.lua index 33460d92a1..acb3fd51ce 100644 --- a/dat/Wiz-loca.lua +++ b/dat/Wiz-loca.lua @@ -72,6 +72,8 @@ des.region({ region={48,10,54,10}, lit=0, type="ordinary", irregular=1, end }) +-- Ceilings +des.add_ceiling(selection.area(36,03, 66,17)) -- Doors des.door("locked",55,08) des.door("locked",55,12) diff --git a/dat/Wiz-strt.lua b/dat/Wiz-strt.lua index 285530774a..f49e3ba4ad 100644 --- a/dat/Wiz-strt.lua +++ b/dat/Wiz-strt.lua @@ -35,7 +35,11 @@ des.map([[ ......................CCC.C................................................. ]]); --- first do cloud everywhere +-- Add ceilings before anything else, so floodfill will work +local covered = selection.floodfill(00,00):negate():filter_mapchar('.'):grow() + | selection.area(11,08, 35,12) +des.add_ceiling(covered) +-- do cloud everywhere des.replace_terrain({ region={0,0, 75,19}, fromterrain=".", toterrain="C", chance=10 }) -- then replace clouds inside the tower back to floor des.replace_terrain({ region={13,5, 33,15}, fromterrain="C", toterrain=".", chance=100 }) From 8938d1f69a007387bc7fecfdb75e35ead317faa5 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 9 Jun 2023 14:35:50 -0400 Subject: [PATCH 08/11] Use separate field in struct rm for ceiling Storing it in 'flags' was causing it to be overwritten when a door or other furniture was added to a square. It should be consistent even when furniture, etc, changes. --- include/rm.h | 6 ++---- src/dungeon.c | 2 +- src/sp_lev.c | 20 ++++++++++---------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/include/rm.h b/include/rm.h index 9fbe0df626..af636a95ed 100644 --- a/include/rm.h +++ b/include/rm.h @@ -174,9 +174,6 @@ enum door_states { #define TREE_LOOTED 1 #define TREE_SWARM 2 -#define BECEILINGED 0x20 /* FIXME not real value (or name) */ -#define HAS_CEILING(x, y) ((levl[x][y].flags & BECEILINGED) != 0) - /* * Fountains have limits, and special warnings. */ @@ -254,7 +251,8 @@ struct rm { Bitfield(candig, 1); /* Exception to Can_dig_down; was a trapdoor */ Bitfield(uvisited, 1); /* player has visited this space */ - Bitfield(unused, 6); /* currently unused - take bits out of this rather + Bitfield(ceiling, 1); /* special ceiling status */ + Bitfield(unused, 5); /* currently unused - take bits out of this rather than overloading it as if it were a second flags field! */ }; diff --git a/src/dungeon.c b/src/dungeon.c index e6a342432a..79f9a79ce0 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -1878,7 +1878,7 @@ ceiling_exists(coordxy x, coordxy y) if (!isok(x, y)) return FALSE; /* now check for exceptions */ - if (HAS_CEILING(x, y)) + if (levl[x][y].ceiling) return TRUE; return FALSE; diff --git a/src/sp_lev.c b/src/sp_lev.c index 862c879c6e..af2bdb4b02 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -29,7 +29,6 @@ static int flip_encoded_direction_bits(int, int); static void flip_vault_guard(int, struct monst *, coordxy, coordxy, coordxy, coordxy); static void sel_set_wall_property(coordxy, coordxy, genericptr_t); -static void sel_set_flags(coordxy, coordxy, genericptr_t); static void set_wall_property(coordxy, coordxy, coordxy, coordxy, int); static void count_features(void); static void remove_boundary_syms(void); @@ -104,6 +103,7 @@ static int get_table_region(lua_State *, const char *, lua_Integer *, lua_Integer *, lua_Integer *, lua_Integer *, boolean); static void set_wallprop_in_selection(lua_State *, int); static void set_prop_in_selection(lua_State *, select_iter_func, int); +static void sel_set_ceiling(coordxy, coordxy, genericptr_t); static coordxy random_wdir(void); static int floodfillchk_match_under(coordxy, coordxy); static int floodfillchk_match_accessible(coordxy, coordxy); @@ -966,14 +966,6 @@ sel_set_wall_property(coordxy x, coordxy y, genericptr_t arg) levl[x][y].wall_info |= prop; } -static void -sel_set_flags(coordxy x, coordxy y, genericptr_t arg) -{ - int prop = *(int *)arg; - - levl[x][y].flags |= prop; -} - /* * Make walls of the area (x1, y1, x2, y2) non diggable/non passwall-able */ @@ -6725,6 +6717,14 @@ lspo_non_passwall(lua_State *L) return 0; } +static void +sel_set_ceiling(coordxy x, coordxy y, genericptr_t arg) +{ + int val = *(int *)arg; + + levl[x][y].ceiling = val; +} + /* should be used for 'outdoors' flagged levels, to specify areas which have * ceilings */ /* add_ceiling(selection); */ @@ -6732,7 +6732,7 @@ lspo_non_passwall(lua_State *L) int lspo_add_ceiling(lua_State *L) { - set_prop_in_selection(L, sel_set_flags, BECEILINGED); + set_prop_in_selection(L, sel_set_ceiling, 1); return 0; } From 9e8fec4b48a642d4feacb57a2a269ed8ce8c50a1 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 20 Jul 2022 16:25:48 -0400 Subject: [PATCH 09/11] Add roof to Sam-loca courtyard aosdict pointed out there's no definitive indication that it's a courtyard, and players who consider the possibility of a courtyard may waste scrolls of earth standing in it, which would be frustrating. --- dat/Sam-loca.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dat/Sam-loca.lua b/dat/Sam-loca.lua index 41d489e75a..0e5ecc977f 100644 --- a/dat/Sam-loca.lua +++ b/dat/Sam-loca.lua @@ -33,7 +33,9 @@ des.map([[ des.region(selection.area(00,00,75,19), "lit") -- Ceiling local covered = selection.floodfill(00,00, true):negate():filter_mapchar('.') -covered = covered - selection.area(24,07,51,12) +-- interior courtyard: roofed over out of concern players will waste scrolls of +-- earth not realizing it's a roofless area +-- covered = covered - selection.area(24,07,51,12) des.add_ceiling(covered:grow()) -- Doors des.door("locked",22,04) From b9015b69e4dde49913897f60fc333db50c9716a2 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Fri, 9 Jun 2023 14:38:48 -0400 Subject: [PATCH 10/11] Add another missing ceiling_exists call --- src/dig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dig.c b/src/dig.c index 7cfe54ad86..ebdd3a7264 100644 --- a/src/dig.c +++ b/src/dig.c @@ -1497,7 +1497,7 @@ zap_dig(void) if (u.dz) { if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz) && !Underwater) { if ((u.dz < 0 || On_stairs(u.ux, u.uy)) - && !gl.level.flags.outdoors) { + && ceiling_exists(u.ux, u.uy)) { int dmg; if (On_stairs(u.ux, u.uy)) { stairway *stway = stairway_at(u.ux, u.uy); From de07adc5876a627f10d9343911e3a06434413941 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Thu, 21 Jul 2022 17:52:52 -0400 Subject: [PATCH 11/11] Add wizmode option to highlight ceilings I wouldn't include this in the actual release/master branch, since it sloppily relies on overwriting the color and piggybacking off the inverse video effect of object piles, but it's useful for testing purposes. If this were to be a permanent addition to the game I'd add some new flag like MG_CEILING that could be used for this purpose, but I doubt it's worth it. I'm including it in this branch just so that others can use it for testing if desired, because it's convenient. --- include/flag.h | 1 + include/optlist.h | 3 +++ src/display.c | 5 +++++ src/options.c | 1 + 4 files changed, 10 insertions(+) diff --git a/include/flag.h b/include/flag.h index 63c232eb7d..fb730c9292 100644 --- a/include/flag.h +++ b/include/flag.h @@ -331,6 +331,7 @@ struct instance_flags { boolean fireassist; /* autowield launcher when using fire-command */ boolean time_botl; /* context.botl for 'time' (moves) only */ boolean wizmgender; /* test gender info from core in window port */ + boolean wizceiling; /* highlight ceilngs */ boolean invweight; /* display weights of items in inventory */ boolean msg_is_alert; /* suggest windowport should grab player's attention * and request acknowlegement */ diff --git a/include/optlist.h b/include/optlist.h index daa5fc8333..7d0726f9a3 100644 --- a/include/optlist.h +++ b/include/optlist.h @@ -823,6 +823,9 @@ static int optfn_##a(int, int, boolean, char *, char *); No, Yes, No, No, NoAlias, "the foreground/background colors of windows") /* NHOPTC(windowtype) -- moved to top */ + NHOPTB(wizceiling, Advanced, 0, opt_in, set_wizonly, + Off, Yes, No, No, NoAlias, &iflags.wizceiling, Term_False, + (char *) 0) NHOPTB(wizmgender, Advanced, 0, opt_in, set_wizonly, Off, Yes, No, No, NoAlias, &iflags.wizmgender, Term_False, (char *)0) diff --git a/src/display.c b/src/display.c index 12551469bf..2dc1a1c39f 100644 --- a/src/display.c +++ b/src/display.c @@ -2613,6 +2613,11 @@ map_glyphinfo( ? CLR_GRAY : CLR_WHITE; } } + if (iflags.wizceiling && wizard && isok(x, y) && levl[x][y].ceiling) { + glyphinfo->gm.sym.color = CLR_RED; + /* glyphinfo->gm.sym.symidx */ + glyphinfo->gm.glyphflags |= MG_OBJPILE; + } #endif /* TEXTCOLOR */ glyphinfo->ttychar = gs.showsyms[glyphinfo->gm.sym.symidx]; glyphinfo->glyph = glyph; diff --git a/src/options.c b/src/options.c index 2b66e325b4..fa562bb8f9 100644 --- a/src/options.c +++ b/src/options.c @@ -5004,6 +5004,7 @@ optfn_boolean(int optidx, int req, boolean negated, char *opts, char *op) if (iflags.use_color) go.opt_need_redraw = TRUE; /* darkroom refresh */ break; + case opt_wizceiling: case opt_wizmgender: case opt_showrace: case opt_use_inverse: