]> granicus.if.org Git - nethack/commitdiff
pets and tripe
authorarromdee <arromdee>
Fri, 18 Jan 2002 03:15:10 +0000 (03:15 +0000)
committerarromdee <arromdee>
Fri, 18 Jan 2002 03:15:10 +0000 (03:15 +0000)
This fixes a very, very, old bug.  I don't think there's been a version
since pets were introduced that doesn't have it.
--Ken A

doc/buglist
doc/fixes33.2
src/dogmove.c

index 860f45a1b4c62b8af8773b1dd075980b1d196346..eacdf8cdcb87c72245af8937b74ae73c771dcdd5 100644 (file)
@@ -133,10 +133,6 @@ Reported but unconfirmed bugs:
    catching a signal.
 -- Reported problem with loss of hit points for no apparent reason until
    player was left with 1 out of 1 hit points.
--- Walking around in the Gnomish Town, when I suddenly noticed my cat
-   wasn't following me around anymore. It appeared to be hanging around
-   somewhere near an outer wall of a food shop, on the other side of which
-   was lying a tripe ration and would not move. [Boudewijn Waijers]
 -- Monsters were displayed as 'I' (unseen monster) but were referred to by
    name.  [Irina]
 -- A wand of secret door detection self-identified while engraving even
index ecf4f37fe6275e6329ac6ddc0c6264dd208d6c39..431a8411738cf995831f65504cbabcbc4c562d4f 100644 (file)
@@ -393,6 +393,7 @@ blessed full healing can reciver at most half of other lost levels
 golden glow when praying will recover lost level if blessed full healing could
 gaining a level while polymorphed increases current monst hit points as well
        as latent human (or whatever) hit points
+pets should not try to go after food that they can't reach
 
 
 Platform- and/or Interface-Specific Fixes
index 5ace67462859e4755ef4536977074d03b766bad8..ed2236062bf3c1a86425d4fff38c2e13a8c14618 100644 (file)
@@ -16,6 +16,8 @@ STATIC_DCL int FDECL(dog_invent,(struct monst *,struct edog *,int));
 STATIC_DCL int FDECL(dog_goal,(struct monst *,struct edog *,int,int,int));
 
 STATIC_DCL struct obj *FDECL(DROPPABLES, (struct monst *));
+STATIC_DCL boolean can_reach_food(struct monst *,XCHAR_P,XCHAR_P,XCHAR_P,
+    XCHAR_P);
 
 STATIC_OVL struct obj *
 DROPPABLES(mon)
@@ -381,7 +383,8 @@ int after, udist, whappr;
                        continue;
                    if (cursed_object_at(nx, ny))
                        continue;
-                   if (otyp < MANFOOD) {
+                   if (otyp < MANFOOD &&
+                           can_reach_food(mtmp, mtmp->mx, mtmp->my, nx, ny)) {
                        if (otyp < gtyp || DDIST(nx,ny) < DDIST(gx,gy)) {
                            gx = nx;
                            gy = ny;
@@ -778,6 +781,50 @@ dognext:
        return(1);
 }
 
+/* Hack to prevent a dog from being endlessly stuck near a piece of food that
+ * it can't reach, such as caught in a teleport scroll niche.  It recursively
+ * checks to see if the squares inbetween are good.  The checking could be a
+ * little smarter; a full check would probably be useful in m_move() too.
+ * Since the maximum food distance is 5, this should never be more than 5 calls
+ * deep.
+ */
+STATIC_OVL  boolean
+can_reach_food(mon, mx, my, fx, fy)
+struct monst *mon;
+xchar mx, my, fx, fy;
+{
+    int i, j;
+    int dist;
+
+    if (mx == fx && my == fy) return TRUE;
+    if (!isok(mx, my)) return FALSE; /* should not happen */
+    
+    dist = dist2(mx, my, fx, fy);
+    for(i=mx-1; i<=mx+1; i++) {
+       for(j=my-1; j<=my+1; j++) {
+           if (!isok(i, j))
+               continue;
+           if (dist2(i, j, fx, fy) >= dist)
+               continue;
+           if (IS_ROCK(levl[i][j].typ) && !passes_walls(mon->data) &&
+                                   (!may_dig(i,j) || !tunnels(mon->data)))
+               continue;
+           if (IS_DOOR(levl[i][j].typ) &&
+                               (levl[i][j].doormask & (D_CLOSED | D_LOCKED)))
+               continue;
+           if (is_pool(i, j) && !is_swimmer(mon->data))
+               continue;
+           if (is_lava(i, j) && !likes_lava(mon->data))
+               continue;
+           if (sobj_at(BOULDER,i,j) && !throws_rocks(mon->data))
+               continue;
+           if (can_reach_food(mon, i, j, fx, fy))
+               return TRUE;
+       }
+    }
+    return FALSE;
+}
+
 #endif /* OVL0 */
 #ifdef OVLB