Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drawbridge jams #76

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/extern.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 ### */

Expand Down
22 changes: 12 additions & 10 deletions include/rm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Comment on lines +204 to +208
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously, DB_UNDER = DB_LAVA | DB_ICE | DB_FLOOR. In this change, DB_UNDER = DB_FLOOR. Does this not introduce bugs in code that uses DB_UNDER?

Copy link
Contributor Author

@entrez entrez Dec 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still DB_MOAT | DB_LAVA | DB_ICE | DB_FLOOR (0x0 | 0x4 | 0x8 | 0xc is 0xc), it's just that because they are mutually exclusive states, there can be overlap -- in other words, the checks are always (flags & DB_UNDER) == DB_MOAT, never (flags & DB_MOAT) != 0 (which would be impossible even in the current arrangement, since one of them is 0). So it's not necessary to give each one a unique bit; as long as the values themselves are unique and distinguishable all the existing code works fine.

But this hack to save a bit is also not really necessary if you've expanded flags.


#define DB_JAM 0x10

/*
* Wall information. Nondiggable also applies to iron bars.
Expand Down
50 changes: 50 additions & 0 deletions src/dbridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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*/
12 changes: 5 additions & 7 deletions src/music.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,14 +757,12 @@ 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 = is_jammed_db(x, y);
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);
Expand Down
5 changes: 4 additions & 1 deletion src/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down