It does now. Simply adding old position for monster and checking if the old position is the first step on the straight path (in this case using pathfinding code instead) did the job. I tested with a char inside and outside a permawalled vault, and each time Morgoth was able to find the @ without getting stuck.
Code below (from PWMAngband) if interested (this replaces monster_near_permwall):
Code below (from PWMAngband) if interested (this replaces monster_near_permwall):
Code:
/* * Find whether a PASS_WALL or KILL_WALL monster has a clear path to the player. * * This is a modified/simplified version of project_path(). */ static bool can_path_player(struct player *p, const struct monster *mon, struct chunk *c) { int y, x; int y1 = mon->fy; int x1 = mon->fx; int y2 = p->py; int x2 = p->px; /* Absolute */ int ay, ax; /* Offsets */ int sy, sx; /* Fractions */ int frac; /* Scale factors */ int full, half; /* Slope */ int m; /* If player is in LOS, there's no need to go around walls */ if (projectable_wall(c, y1, x1, y2, x2)) return true; /* Analyze "dy" */ if (y2 < y1) { ay = (y1 - y2); sy = -1; } else { ay = (y2 - y1); sy = 1; } /* Analyze "dx" */ if (x2 < x1) { ax = (x1 - x2); sx = -1; } else { ax = (x2 - x1); sx = 1; } /* Number of "units" in one "half" grid */ half = (ay * ax); /* Number of "units" in one "full" grid */ full = half << 1; /* Vertical */ if (ay > ax) { /* Start at tile edge */ frac = ax * ax; /* Let m = ((dx/dy) * full) = (dx * dx * 2) = (frac * 2) */ m = frac << 1; /* Start */ y = y1 + sy; x = x1; /* Never go back from whence we came */ if ((x == mon->old_fx) && (y == mon->old_fy)) return false; /* Create the projection path */ while (1) { /* Stop at destination grid */ if ((x == x2) && (y == y2)) return true; /* Stop at permawall grids */ if (square_isperm(c, y, x)) return false; /* Slant */ if (m) { /* Advance (X) part 1 */ frac += m; /* Horizontal change */ if (frac >= half) { /* Advance (X) part 2 */ x += sx; /* Advance (X) part 3 */ frac -= full; } } /* Advance (Y) */ y += sy; } } /* Horizontal */ else if (ax > ay) { /* Start at tile edge */ frac = ay * ay; /* Let m = ((dy/dx) * full) = (dy * dy * 2) = (frac * 2) */ m = frac << 1; /* Start */ y = y1; x = x1 + sx; /* Never go back from whence we came */ if ((x == mon->old_fx) && (y == mon->old_fy)) return false; /* Create the projection path */ while (1) { /* Stop at destination grid */ if ((x == x2) && (y == y2)) return true; /* Stop at permawall grids */ if (square_isperm(c, y, x)) return false; /* Slant */ if (m) { /* Advance (Y) part 1 */ frac += m; /* Vertical change */ if (frac >= half) { /* Advance (Y) part 2 */ y += sy; /* Advance (Y) part 3 */ frac -= full; } } /* Advance (X) */ x += sx; } } /* Diagonal */ else { /* Start */ y = y1 + sy; x = x1 + sx; /* Never go back from whence we came */ if ((x == mon->old_fx) && (y == mon->old_fy)) return false; /* Create the projection path */ while (1) { /* Stop at destination grid */ if ((x == x2) && (y == y2)) return true; /* Stop at permawall grids */ if (square_isperm(c, y, x)) return false; /* Advance (Y) */ y += sy; /* Advance (X) */ x += sx; } } }
Code:
/* If the monster can pass through nearby walls, do that */ if (monster_passes_walls(mon->race) && can_path_player(p, mon, c)) ...
Comment