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:
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
|
||||
30
src/mon.c
30
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)) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
10
src/pickup.c
10
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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user