From fee66f29059e1297522fb25aa5a0b76c2e14c003 Mon Sep 17 00:00:00 2001 From: nhmall Date: Thu, 15 Jun 2023 09:29:41 -0400 Subject: [PATCH] don't hide under statues, statue trap or not Unlike ground clutter, statues are typically in pretty tight contact with the ground; statue traps are sometimes proclaimed as "monsters posing as statues". --- include/extern.h | 1 + src/mon.c | 10 ++++++---- src/monmove.c | 18 +++++++++++++++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 9cbc33bf2..6104ef938 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1730,6 +1730,7 @@ extern boolean can_fog(struct monst *); extern boolean should_displace(struct monst *, coord *, long *, int, coordxy, coordxy); extern boolean undesirable_disp(struct monst *, coordxy, coordxy); +extern boolean can_hide_under_obj(struct obj *); /* ### monst.c ### */ diff --git a/src/mon.c b/src/mon.c index 2039f59e4..9cc190b62 100644 --- a/src/mon.c +++ b/src/mon.c @@ -4196,7 +4196,9 @@ maybe_unhide_at(coordxy x, coordxy y) } if (undetected - && ((hides_under(mtmp->data) && (!OBJ_AT(x, y) || trapped)) + && ((hides_under(mtmp->data) + && (!OBJ_AT(x, y) || trapped + || !can_hide_under_obj(gl.level.objects[x][y]))) || (mtmp->data->mlet == S_EEL && !is_pool(x, y)))) (void) hideunder(mtmp); } @@ -4210,6 +4212,7 @@ hideunder(struct monst *mtmp) int seeit = canseemon(mtmp); boolean oldundetctd, undetected = FALSE, is_u = (mtmp == &gy.youmonst); coordxy x = is_u ? u.ux : mtmp->mx, y = is_u ? u.uy : mtmp->my; + struct obj *otmp; if (mtmp == u.ustuck) { ; /* undetected==FALSE; can't hide if holding you or held by you */ @@ -4221,9 +4224,8 @@ hideunder(struct monst *mtmp) undetected = (is_pool(x, y) && !Is_waterlevel(&u.uz)); if (seeit) seenobj = "the water"; - } else if (hides_under(mtmp->data) && OBJ_AT(x, y)) { - struct obj *otmp = gl.level.objects[x][y]; - + } else if (hides_under(mtmp->data) && OBJ_AT(x, y) + && (otmp = gl.level.objects[x][y]) != 0 && can_hide_under_obj(otmp)) { if (seeit) seenobj = ansimpleoname(otmp); /* most monsters won't hide under cockatrice corpse but they diff --git a/src/monmove.c b/src/monmove.c index 547260bdd..369feb279 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1312,7 +1312,8 @@ m_move(register struct monst *mtmp, int after) finish_meating(mtmp); return MMOVE_DONE; /* still eating */ } - if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10)) + if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) + && can_hide_under_obj(gl.level.objects[mtmp->mx][mtmp->my]) && rn2(10)) return MMOVE_NOTHING; /* do not leave hiding place */ /* Where does 'mtmp' think you are? Not necessary if m_move() called @@ -1893,6 +1894,21 @@ m_move_aggress(struct monst *mtmp, coordxy x, coordxy y) return MMOVE_DONE; } +/* returns TRUE if a mon can hide under the obj */ +boolean +can_hide_under_obj(struct obj *obj) +{ + struct trap *t; + + if (!obj || (obj->otyp == STATUE + /* uncomment this next line for just statue traps */ + /* && (t = t_at(obj->ox, obj->oy)) != 0 && t->ttyp == STATUE_TRAP */ + )) + return FALSE; + return TRUE; + nhUse(t); +} + void dissolve_bars(coordxy x, coordxy y) {