pets getting "stuck" trying to reach inaccessible objects
Incorporate a slightly modified version of a patch submitted by <Someone> back in June. The basic problem, which I noticed again this past weekend, is that pets with a high apport value can still try to get to objects when there's no path to the object. The patch extends the can_reach_food function to be used for any object, renaming it to can_reach_location, and adds a could_reach_item function for doing point checks. This also removes any chance of a pet dragon, for example, eating something underwater.
This commit is contained in:
@@ -65,6 +65,7 @@ traveling while standing on a trap would sometime step in the wrong direction
|
|||||||
avoid traveling into water/lava, using usual running rules
|
avoid traveling into water/lava, using usual running rules
|
||||||
unchanging iron golem would still rehumanize in a rust trap
|
unchanging iron golem would still rehumanize in a rust trap
|
||||||
fix an impossible rndmonst: bad `mndx' bug
|
fix an impossible rndmonst: bad `mndx' bug
|
||||||
|
pets should not try to go after objects that they can't reach
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ 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 int FDECL(dog_goal,(struct monst *,struct edog *,int,int,int));
|
||||||
|
|
||||||
STATIC_DCL struct obj *FDECL(DROPPABLES, (struct monst *));
|
STATIC_DCL struct obj *FDECL(DROPPABLES, (struct monst *));
|
||||||
STATIC_DCL boolean FDECL(can_reach_food,(struct monst *,XCHAR_P,XCHAR_P,XCHAR_P,
|
STATIC_DCL boolean FDECL(can_reach_location,(struct monst *,XCHAR_P,XCHAR_P,
|
||||||
XCHAR_P));
|
XCHAR_P,XCHAR_P));
|
||||||
|
STATIC_DCL boolean FDECL(could_reach_item,(struct monst *, XCHAR_P,XCHAR_P));
|
||||||
|
|
||||||
STATIC_OVL struct obj *
|
STATIC_OVL struct obj *
|
||||||
DROPPABLES(mon)
|
DROPPABLES(mon)
|
||||||
@@ -285,13 +286,14 @@ int udist;
|
|||||||
){
|
){
|
||||||
int edible = dogfood(mtmp, obj);
|
int edible = dogfood(mtmp, obj);
|
||||||
|
|
||||||
if (edible <= CADAVER ||
|
if ((edible <= CADAVER ||
|
||||||
/* starving pet is more aggressive about eating */
|
/* starving pet is more aggressive about eating */
|
||||||
(edog->mhpmax_penalty && edible == ACCFOOD))
|
(edog->mhpmax_penalty && edible == ACCFOOD)) &&
|
||||||
|
could_reach_item(mtmp, obj->ox, obj->oy))
|
||||||
return dog_eat(mtmp, obj, omx, omy, FALSE);
|
return dog_eat(mtmp, obj, omx, omy, FALSE);
|
||||||
|
|
||||||
if(can_carry(mtmp, obj) && !obj->cursed &&
|
if(can_carry(mtmp, obj) && !obj->cursed &&
|
||||||
!is_pool(mtmp->mx,mtmp->my)) {
|
could_reach_item(mtmp, obj->ox, obj->oy)) {
|
||||||
if(rn2(20) < edog->apport+3) {
|
if(rn2(20) < edog->apport+3) {
|
||||||
if (rn2(udist) || !rn2(edog->apport)) {
|
if (rn2(udist) || !rn2(edog->apport)) {
|
||||||
if (cansee(omx, omy) && flags.verbose)
|
if (cansee(omx, omy) && flags.verbose)
|
||||||
@@ -372,8 +374,11 @@ int after, udist, whappr;
|
|||||||
if (cursed_object_at(nx, ny) &&
|
if (cursed_object_at(nx, ny) &&
|
||||||
!(edog->mhpmax_penalty && otyp < MANFOOD))
|
!(edog->mhpmax_penalty && otyp < MANFOOD))
|
||||||
continue;
|
continue;
|
||||||
if (otyp < MANFOOD &&
|
/* skip completely unreacheable goals */
|
||||||
can_reach_food(mtmp, mtmp->mx, mtmp->my, nx, ny)) {
|
if (!could_reach_item(mtmp, nx, ny) ||
|
||||||
|
!can_reach_location(mtmp, mtmp->mx, mtmp->my, nx, ny))
|
||||||
|
continue;
|
||||||
|
if (otyp < MANFOOD) {
|
||||||
if (otyp < gtyp || DDIST(nx,ny) < DDIST(gx,gy)) {
|
if (otyp < gtyp || DDIST(nx,ny) < DDIST(gx,gy)) {
|
||||||
gx = nx;
|
gx = nx;
|
||||||
gy = ny;
|
gy = ny;
|
||||||
@@ -780,15 +785,28 @@ dognext:
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hack to prevent a dog from being endlessly stuck near a piece of food that
|
/* check if a monster could pick up objects from a location */
|
||||||
|
STATIC_OVL boolean
|
||||||
|
could_reach_item(mon, nx, ny)
|
||||||
|
struct monst *mon;
|
||||||
|
xchar nx, ny;
|
||||||
|
{
|
||||||
|
if ((!is_pool(nx,ny) || is_swimmer(mon->data)) &&
|
||||||
|
(!is_lava(nx,ny) || likes_lava(mon->data)) &&
|
||||||
|
(!sobj_at(BOULDER,nx,ny) || throws_rocks(mon->data)))
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hack to prevent a dog from being endlessly stuck near an object that
|
||||||
* it can't reach, such as caught in a teleport scroll niche. It recursively
|
* 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
|
* checks to see if the squares in between are good. The checking could be a
|
||||||
* little smarter; a full check would probably be useful in m_move() too.
|
* 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
|
* Since the maximum food distance is 5, this should never be more than 5 calls
|
||||||
* deep.
|
* deep.
|
||||||
*/
|
*/
|
||||||
STATIC_OVL boolean
|
STATIC_OVL boolean
|
||||||
can_reach_food(mon, mx, my, fx, fy)
|
can_reach_location(mon, mx, my, fx, fy)
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
xchar mx, my, fx, fy;
|
xchar mx, my, fx, fy;
|
||||||
{
|
{
|
||||||
@@ -811,13 +829,9 @@ xchar mx, my, fx, fy;
|
|||||||
if (IS_DOOR(levl[i][j].typ) &&
|
if (IS_DOOR(levl[i][j].typ) &&
|
||||||
(levl[i][j].doormask & (D_CLOSED | D_LOCKED)))
|
(levl[i][j].doormask & (D_CLOSED | D_LOCKED)))
|
||||||
continue;
|
continue;
|
||||||
if (is_pool(i, j) && !is_swimmer(mon->data))
|
if (!could_reach_item(mon, i, j))
|
||||||
continue;
|
continue;
|
||||||
if (is_lava(i, j) && !likes_lava(mon->data))
|
if (can_reach_location(mon, i, j, fx, fy))
|
||||||
continue;
|
|
||||||
if (sobj_at(BOULDER,i,j) && !throws_rocks(mon->data))
|
|
||||||
continue;
|
|
||||||
if (can_reach_food(mon, i, j, fx, fy))
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user