]> granicus.if.org Git - nethack/commitdiff
hiding under a cockatrice corpse
authorcohrs <cohrs>
Fri, 10 Oct 2003 23:01:42 +0000 (23:01 +0000)
committercohrs <cohrs>
Fri, 10 Oct 2003 23:01:42 +0000 (23:01 +0000)
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.

doc/fixes35.0
include/extern.h
src/hack.c
src/invent.c
src/makemon.c
src/mon.c
src/monmove.c
src/pickup.c
src/polyself.c
src/teleport.c

index df8bff49fa4d1247bc7aec47e226af342bd65dc1..df5c4aa526ab07e3ca45b297d3826beaf35fd866 100644 (file)
@@ -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
index b628d1d41c47b6870e5b4669490f1b762765a101..1eec667326e7461f603e0fcc535b410aecfa89cb 100644 (file)
@@ -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));
index 6f2a15440356ad1de09b672c4576a023d0004f2c..7c118f627c2d6ad629a728d102591ad51ecef454 100644 (file)
@@ -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
index f0578167fed386b54313fe7261f02cd4c7d31844..07822ba6f92d7485dea0fd49d9a0ae23ba3bb0d2 100644 (file)
@@ -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);
 }
 
 /*
index 70aec1ffe9e6fa58b27e4955e6a62b287f472934..123de5da1abf93db8fe4eaa476190bda655c0ca2 100644 (file)
@@ -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;
index be20c45c537bf64b7b04659fac0042824c91f1f7..e877526563f24e60a48d4794a56c7f14f9a1aaf3 100644 (file)
--- 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)) {
index c4f64b0b6a6458dcb6b7d2d2c70c07486e8d0db4..ff4546f86e9b5f26703e239bc72da020d51d7dcd 100644 (file)
@@ -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) {
index bbb9cbd9ee040f4ac48063982a64aac6e5fc7b92..bb44bf5ecc3227032c5e3847775b447a18c44ff0 100644 (file)
@@ -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);
 }
index 3952f8125bfaec8c43f329a7764aa1bb98f38f93..4b7bf73572556b68f7968c1b94a909508f1430b5 100644 (file)
@@ -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) {
index 2cd31322ac7972c3da00fed7163273d0955256d4..1c15e69a215181db3dba6d05be1c00a7e7013732 100644 (file)
@@ -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) {