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.
This commit is contained in:
cohrs
2003-10-10 23:01:42 +00:00
parent 219e091d82
commit 8ee1ecd2ea
10 changed files with 45 additions and 37 deletions

View File

@@ -34,6 +34,7 @@ grammar, spelling and other typos
oracle and rumor regarding priestly donations oracle and rumor regarding priestly donations
keep various delayed killers separate to avoid mixed up messages keep various delayed killers separate to avoid mixed up messages
don't place randomly-placed aquatic monsters in lava on special levels 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 Platform- and/or Interface-Specific Fixes

View File

@@ -1148,6 +1148,7 @@ E void FDECL(seemimic, (struct monst *));
E void NDECL(rescham); E void NDECL(rescham);
E void NDECL(restartcham); E void NDECL(restartcham);
E void FDECL(restore_cham, (struct monst *)); E void FDECL(restore_cham, (struct monst *));
E boolean FDECL(hideunder, (struct monst*));
E void FDECL(mon_animal_list, (BOOLEAN_P)); E void FDECL(mon_animal_list, (BOOLEAN_P));
E int FDECL(newcham, (struct monst *,struct permonst *,BOOLEAN_P,BOOLEAN_P)); E int FDECL(newcham, (struct monst *,struct permonst *,BOOLEAN_P,BOOLEAN_P));
E int FDECL(can_be_hatched, (int)); E int FDECL(can_be_hatched, (int));

View File

@@ -1339,12 +1339,9 @@ domove()
nomul(0); nomul(0);
} }
if (hides_under(youmonst.data)) if (hides_under(youmonst.data) || (youmonst.data->mlet == S_EEL) ||
u.uundetected = OBJ_AT(u.ux, u.uy); u.dx || u.dy)
else if (youmonst.data->mlet == S_EEL) (void) hideunder(&youmonst);
u.uundetected = is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz);
else if (u.dx || u.dy)
u.uundetected = 0;
/* /*
* Mimics (or whatever) become noticeable if they move and are * Mimics (or whatever) become noticeable if they move and are

View File

@@ -2506,7 +2506,7 @@ long numused;
} }
delobj(otmp); delobj(otmp);
if (at_u && u.uundetected && hides_under(youmonst.data)) if (at_u && u.uundetected && hides_under(youmonst.data))
u.uundetected = OBJ_AT(u.ux, u.uy); (void) hideunder(&youmonst);
} }
/* /*

View File

@@ -924,8 +924,7 @@ register int mmflags;
if(in_mklev) if(in_mklev)
if(x && y) if(x && y)
(void) mkobj_at(0, x, y, TRUE); (void) mkobj_at(0, x, y, TRUE);
if(hides_under(ptr) && OBJ_AT(x, y)) (void) hideunder(mtmp);
mtmp->mundetected = TRUE;
break; break;
case S_LIGHT: case S_LIGHT:
case S_ELEMENTAL: case S_ELEMENTAL:
@@ -935,8 +934,7 @@ register int mmflags;
} }
break; break;
case S_EEL: case S_EEL:
if (is_pool(x, y)) (void) hideunder(mtmp);
mtmp->mundetected = TRUE;
break; break;
case S_LEPRECHAUN: case S_LEPRECHAUN:
mtmp->msleeping = 1; mtmp->msleeping = 1;

View File

@@ -2248,6 +2248,32 @@ register struct monst *mtmp;
return(FALSE); 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 */ short *animal_list = 0; /* list of PM values for animal monsters */
int animal_list_count; int animal_list_count;
@@ -2444,9 +2470,7 @@ boolean msg; /* "The oldmon turns into a newmon!" */
if (!mtmp->perminvis || pm_invisible(olddata)) if (!mtmp->perminvis || pm_invisible(olddata))
mtmp->perminvis = pm_invisible(mdat); mtmp->perminvis = pm_invisible(mdat);
mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis; mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis;
if (!(hides_under(mdat) && OBJ_AT(mtmp->mx, mtmp->my)) && if (mtmp->mundetected) (void) hideunder(mtmp);
!(mdat->mlet == S_EEL && is_pool(mtmp->mx, mtmp->my)))
mtmp->mundetected = 0;
if (u.ustuck == mtmp) { if (u.ustuck == mtmp) {
if(u.uswallow) { if(u.uswallow) {
if(!attacktype(mdat,AT_ENGL)) { if(!attacktype(mdat,AT_ENGL)) {

View File

@@ -1181,9 +1181,7 @@ postmov:
usually set mundetected unless monster can't move. */ usually set mundetected unless monster can't move. */
if (mtmp->mundetected || if (mtmp->mundetected ||
(mtmp->mcanmove && !mtmp->msleeping && rn2(5))) (mtmp->mcanmove && !mtmp->msleeping && rn2(5)))
mtmp->mundetected = (ptr->mlet != S_EEL) ? (void) hideunder(mtmp);
OBJ_AT(mtmp->mx, mtmp->my) :
(is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz));
newsym(mtmp->mx, mtmp->my); newsym(mtmp->mx, mtmp->my);
} }
if (mtmp->isshk) { if (mtmp->isshk) {

View File

@@ -585,13 +585,13 @@ end_query:
} }
if (!u.uswallow) { 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) */ /* position may need updating (invisible hero) */
if (n_picked) newsym(u.ux,u.uy); if (n_picked) newsym(u.ux,u.uy);
/* see whether there's anything else here, after auto-pickup is done */ /* check if there's anything else here after auto-pickup is done */
if (autopickup) check_here(n_picked > 0); if (autopickup) check_here(n_picked > 0);
} }
return (n_tried > 0); return (n_tried > 0);
} }

View File

@@ -458,12 +458,7 @@ int mntmp;
skinback(FALSE); skinback(FALSE);
break_armor(); break_armor();
drop_weapon(1); drop_weapon(1);
if (hides_under(youmonst.data)) (void) hideunder(&youmonst);
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;
if (u.utraptype == TT_PIT) { if (u.utraptype == TT_PIT) {
if (could_pass_walls && !Passes_walls) { if (could_pass_walls && !Passes_walls) {

View File

@@ -274,15 +274,9 @@ boolean allow_drag;
u.ux0 = u.ux; u.ux0 = u.ux;
u.uy0 = u.uy; u.uy0 = u.uy;
if (hides_under(youmonst.data)) if (!hideunder(&youmonst) && youmonst.data->mlet == S_MIMIC) {
u.uundetected = OBJ_AT(nux, nuy); /* mimics stop being unnoticed */
else if (youmonst.data->mlet == S_EEL) youmonst.m_ap_type = M_AP_NOTHING;
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 (u.uswallow) { if (u.uswallow) {