From 7b4482f52b7249c7721c71a631d98abae5825362 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 8 Jun 2022 15:06:25 -0400 Subject: [PATCH 1/2] Allow drawbridges to stay jammed Mentioned in 1654735 and a comment in do_play_instrument(music.c) as something which would be a nice future improvement if there were more bits available in flags/drawbridgemask. Turns out the DB_UNDER states are all mutually exclusive and never overlap, so a bit for the jam can be saved by rearranging those. --- include/rm.h | 22 ++++++++++++---------- src/music.c | 13 ++++++------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/include/rm.h b/include/rm.h index f6d5a46db..31da24d0c 100644 --- a/include/rm.h +++ b/include/rm.h @@ -192,20 +192,22 @@ enum door_states { /* * The four directions for a DrawBridge. */ -#define DB_NORTH 0 -#define DB_SOUTH 1 -#define DB_EAST 2 -#define DB_WEST 3 -#define DB_DIR 3 /* mask for direction */ +#define DB_NORTH 0x0 +#define DB_SOUTH 0x1 +#define DB_EAST 0x2 +#define DB_WEST 0x3 +#define DB_DIR 0x3 /* mask for direction */ /* * What's under a drawbridge. */ -#define DB_MOAT 0 -#define DB_LAVA 4 -#define DB_ICE 8 -#define DB_FLOOR 16 -#define DB_UNDER 28 /* mask for underneath */ +#define DB_MOAT 0x0 +#define DB_LAVA 0x4 +#define DB_ICE 0x8 +#define DB_FLOOR 0xc +#define DB_UNDER 0xc /* mask for underneath */ + +#define DB_JAM 0x10 /* * Wall information. Nondiggable also applies to iron bars. diff --git a/src/music.c b/src/music.c index 3e3f07fd2..015818d42 100644 --- a/src/music.c +++ b/src/music.c @@ -757,14 +757,13 @@ do_play_instrument(struct obj* instr) u.uevent.uheard_tune = 2; record_achievement(ACH_TUNE); if (levl[x][y].typ == DRAWBRIDGE_DOWN) { - if (!rn2(5)) { - /* Future improvement: if flags is ever - * expanded beyond 5 bits, could set a bit - * here to make the mechanism continue to be - * stuck until some condition is met, such - * as opening/closing magic used on it */ - pline("The mechanism seems to get jammed."); + boolean jammed = + (levl[x][y].drawbridgemask & DB_JAM) != 0; + if (!rn2(5) || jammed) { + pline("The mechanism seems to %s jammed.", + jammed ? "be" : "get"); pline("It won't close."); + levl[x][y].drawbridgemask |= DB_JAM; return ECMD_TIME; } close_drawbridge(x, y); From a870a4b312351f59cce51f6ebd848f0071cd02b5 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Wed, 8 Jun 2022 15:28:00 -0400 Subject: [PATCH 2/2] Enable untrapping jammed drawbridge When a drawbridge becomes jammed, it can be unjammed with the #untrap command, on either the drawbridge itself or the portcullis. --- include/extern.h | 2 ++ src/dbridge.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ src/music.c | 3 +-- src/trap.c | 5 ++++- 4 files changed, 57 insertions(+), 3 deletions(-) diff --git a/include/extern.h b/include/extern.h index 7e6f4e1fd..ce52d5f72 100644 --- a/include/extern.h +++ b/include/extern.h @@ -320,11 +320,13 @@ extern boolean is_open_air(int, int); extern schar db_under_typ(int); extern int is_drawbridge_wall(int, int); extern boolean is_db_wall(int, int); +extern boolean is_jammed_db(int, int); extern boolean find_drawbridge(int *, int *); extern boolean create_drawbridge(int, int, int, boolean); extern void open_drawbridge(int, int); extern void close_drawbridge(int, int); extern void destroy_drawbridge(int, int); +extern int unjam_drawbridge(int, int); /* ### decl.c ### */ diff --git a/src/dbridge.c b/src/dbridge.c index 982d7a9b6..2e3d01205 100644 --- a/src/dbridge.c +++ b/src/dbridge.c @@ -181,6 +181,15 @@ is_db_wall(int x, int y) return (boolean) (levl[x][y].typ == DBWALL); } +boolean +is_jammed_db(int x, int y) +{ + if (!find_drawbridge(&x, &y)) + return FALSE; + else + return ((levl[x][y].drawbridgemask & DB_JAM) != 0); +} + /* * Return true with x,y pointing to the drawbridge if x,y initially indicate * a drawbridge or drawbridge wall. @@ -974,4 +983,45 @@ destroy_drawbridge(int x, int y) nokiller(); } +int +unjam_drawbridge(int x, int y) +{ + boolean under_u = (!u.dx && !u.dy); + struct monst *mtmp = m_at(x, y); + + if (!is_jammed_db(x, y)) { + impossible("unjam_drawbridge: clearing nonexistant jam?"); + return 0; + } + + if (mtmp) { + pline("%s is in the way.", Monnam(mtmp)); + return 0; + } + if (sobj_at(BOULDER, x, y) && !Passes_walls && !under_u) { + There("is a boulder in your way."); + return 0; + } + /* duplicate tight-space checks from test_move */ + if (u.dx && u.dy && bad_rock(g.youmonst.data, u.ux, y) + && bad_rock(g.youmonst.data, x, u.uy)) { + if ((g.invent && (inv_weight() + weight_cap() > 600)) + || bigmonst(g.youmonst.data)) { + /* don't allow untrap if they can't get thru to it */ + You("are unable to reach the mechanism!"); + return 0; + } + } + if (rn2(3)) { + You("are having a difficult time clearing the jam."); + return 1; + } + + /* ok, disarm it. */ + You("unjam the mechanism."); + (void) find_drawbridge(&x, &y); + levl[x][y].drawbridgemask &= ~DB_JAM; + return 1; +} + /*dbridge.c*/ diff --git a/src/music.c b/src/music.c index 015818d42..153c13ba4 100644 --- a/src/music.c +++ b/src/music.c @@ -757,8 +757,7 @@ do_play_instrument(struct obj* instr) u.uevent.uheard_tune = 2; record_achievement(ACH_TUNE); if (levl[x][y].typ == DRAWBRIDGE_DOWN) { - boolean jammed = - (levl[x][y].drawbridgemask & DB_JAM) != 0; + boolean jammed = is_jammed_db(x, y); if (!rn2(5) || jammed) { pline("The mechanism seems to %s jammed.", jammed ? "be" : "get"); diff --git a/src/trap.c b/src/trap.c index 97663639f..ad5b56acd 100644 --- a/src/trap.c +++ b/src/trap.c @@ -5449,7 +5449,10 @@ untrap( return 0; } } - } /* end if */ + } + else if (is_jammed_db(x, y)) { + return unjam_drawbridge(x, y); + } if (boxcnt) { /* 3.7: this used to allow searching for traps on multiple