From: cohrs Date: Fri, 10 Oct 2003 23:01:42 +0000 (+0000) Subject: hiding under a cockatrice corpse X-Git-Tag: MOVE2GIT~1721 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8ee1ecd2eaadfb11c1ddb2bb091da5bcd6aec97b;p=nethack hiding under a cockatrice corpse Reported a while back, a (stonable) hiding monster will hide at a location containing only a cockatrice corpse. While it would be interesting to allow monsters to try, and stone themselves as a result, I chose the simpler fix which is to not have monsters hide in such situations. I found the hiding code was duplicated in several places, so I moved it into a new hideunder() function that works for both the hero and monsters. --- diff --git a/doc/fixes35.0 b/doc/fixes35.0 index df8bff49f..df5c4aa52 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -34,6 +34,7 @@ grammar, spelling and other typos oracle and rumor regarding priestly donations keep various delayed killers separate to avoid mixed up messages don't place randomly-placed aquatic monsters in lava on special levels +hiding monsters don't hide under cockatrice/chickatrice corpses Platform- and/or Interface-Specific Fixes diff --git a/include/extern.h b/include/extern.h index b628d1d41..1eec66732 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1148,6 +1148,7 @@ E void FDECL(seemimic, (struct monst *)); E void NDECL(rescham); E void NDECL(restartcham); E void FDECL(restore_cham, (struct monst *)); +E boolean FDECL(hideunder, (struct monst*)); E void FDECL(mon_animal_list, (BOOLEAN_P)); E int FDECL(newcham, (struct monst *,struct permonst *,BOOLEAN_P,BOOLEAN_P)); E int FDECL(can_be_hatched, (int)); diff --git a/src/hack.c b/src/hack.c index 6f2a15440..7c118f627 100644 --- a/src/hack.c +++ b/src/hack.c @@ -1339,12 +1339,9 @@ domove() nomul(0); } - if (hides_under(youmonst.data)) - u.uundetected = OBJ_AT(u.ux, u.uy); - else if (youmonst.data->mlet == S_EEL) - u.uundetected = is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz); - else if (u.dx || u.dy) - u.uundetected = 0; + if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) || + u.dx || u.dy) + (void) hideunder(&youmonst); /* * Mimics (or whatever) become noticeable if they move and are diff --git a/src/invent.c b/src/invent.c index f0578167f..07822ba6f 100644 --- a/src/invent.c +++ b/src/invent.c @@ -2506,7 +2506,7 @@ long numused; } delobj(otmp); if (at_u && u.uundetected && hides_under(youmonst.data)) - u.uundetected = OBJ_AT(u.ux, u.uy); + (void) hideunder(&youmonst); } /* diff --git a/src/makemon.c b/src/makemon.c index 70aec1ffe..123de5da1 100644 --- a/src/makemon.c +++ b/src/makemon.c @@ -924,8 +924,7 @@ register int mmflags; if(in_mklev) if(x && y) (void) mkobj_at(0, x, y, TRUE); - if(hides_under(ptr) && OBJ_AT(x, y)) - mtmp->mundetected = TRUE; + (void) hideunder(mtmp); break; case S_LIGHT: case S_ELEMENTAL: @@ -935,8 +934,7 @@ register int mmflags; } break; case S_EEL: - if (is_pool(x, y)) - mtmp->mundetected = TRUE; + (void) hideunder(mtmp); break; case S_LEPRECHAUN: mtmp->msleeping = 1; diff --git a/src/mon.c b/src/mon.c index be20c45c5..e87752656 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2248,6 +2248,32 @@ register struct monst *mtmp; return(FALSE); } +/* monster/hero tries to hide under something at the current location */ +boolean +hideunder(mtmp) +struct monst *mtmp; +{ + boolean undetected = FALSE; + xchar x = (mtmp == &youmonst) ? u.ux : mtmp->mx; + xchar y = (mtmp == &youmonst) ? u.uy : mtmp->my; + + if (mtmp->data->mlet == S_EEL) { + undetected = (is_pool(x, y) && !Is_waterlevel(&u.uz)); + } else if (hides_under(mtmp->data) && OBJ_AT(x, y)) { + struct obj *otmp = level.objects[x][y]; + + /* most monsters won't hide under cockatrice corpse */ + if (otmp->nexthere || otmp->otyp != CORPSE || + (mtmp == &youmonst ? Stone_resistance : resists_ston(mtmp)) || + !touch_petrifies(&mons[otmp->corpsenm])) + undetected = TRUE; + } + + if (mtmp == &youmonst) u.uundetected = undetected; + else mtmp->mundetected = undetected; + return undetected; +} + short *animal_list = 0; /* list of PM values for animal monsters */ int animal_list_count; @@ -2444,9 +2470,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */ if (!mtmp->perminvis || pm_invisible(olddata)) mtmp->perminvis = pm_invisible(mdat); mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis; - if (!(hides_under(mdat) && OBJ_AT(mtmp->mx, mtmp->my)) && - !(mdat->mlet == S_EEL && is_pool(mtmp->mx, mtmp->my))) - mtmp->mundetected = 0; + if (mtmp->mundetected) (void) hideunder(mtmp); if (u.ustuck == mtmp) { if(u.uswallow) { if(!attacktype(mdat,AT_ENGL)) { diff --git a/src/monmove.c b/src/monmove.c index c4f64b0b6..ff4546f86 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -1181,9 +1181,7 @@ postmov: usually set mundetected unless monster can't move. */ if (mtmp->mundetected || (mtmp->mcanmove && !mtmp->msleeping && rn2(5))) - mtmp->mundetected = (ptr->mlet != S_EEL) ? - OBJ_AT(mtmp->mx, mtmp->my) : - (is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz)); + (void) hideunder(mtmp); newsym(mtmp->mx, mtmp->my); } if (mtmp->isshk) { diff --git a/src/pickup.c b/src/pickup.c index bbb9cbd9e..bb44bf5ec 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -585,13 +585,13 @@ end_query: } if (!u.uswallow) { - if (!OBJ_AT(u.ux,u.uy)) u.uundetected = 0; + if (hides_under(youmonst.data)) (void) hideunder(&youmonst); - /* position may need updating (invisible hero) */ - if (n_picked) newsym(u.ux,u.uy); + /* position may need updating (invisible hero) */ + if (n_picked) newsym(u.ux,u.uy); - /* see whether there's anything else here, after auto-pickup is done */ - if (autopickup) check_here(n_picked > 0); + /* check if there's anything else here after auto-pickup is done */ + if (autopickup) check_here(n_picked > 0); } return (n_tried > 0); } diff --git a/src/polyself.c b/src/polyself.c index 3952f8125..4b7bf7357 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -458,12 +458,7 @@ int mntmp; skinback(FALSE); break_armor(); drop_weapon(1); - if (hides_under(youmonst.data)) - u.uundetected = OBJ_AT(u.ux, u.uy); - else if (youmonst.data->mlet == S_EEL) - u.uundetected = is_pool(u.ux, u.uy); - else - u.uundetected = 0; + (void) hideunder(&youmonst); if (u.utraptype == TT_PIT) { if (could_pass_walls && !Passes_walls) { diff --git a/src/teleport.c b/src/teleport.c index 2cd31322a..1c15e69a2 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -274,15 +274,9 @@ boolean allow_drag; u.ux0 = u.ux; u.uy0 = u.uy; - if (hides_under(youmonst.data)) - u.uundetected = OBJ_AT(nux, nuy); - else if (youmonst.data->mlet == S_EEL) - u.uundetected = is_pool(nux, nuy); - else { - u.uundetected = 0; - /* mimics stop being unnoticed */ - if (youmonst.data->mlet == S_MIMIC) - youmonst.m_ap_type = M_AP_NOTHING; + if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) { + /* mimics stop being unnoticed */ + youmonst.m_ap_type = M_AP_NOTHING; } if (u.uswallow) {