extern void acid_damage(struct obj *);
extern int water_damage(struct obj *, const char *, boolean);
extern void water_damage_chain(struct obj *, boolean);
+extern boolean rnd_nextto_goodpos(coordxy *, coordxy *, struct monst *);
extern boolean drown(void);
extern void drain_en(int);
extern int dountrap(void);
return TRUE;
}
+/* pick a random goodpos() next to x,y for monster mtmp.
+ mtmp could be &g.youmonst, uses then crawl_destination().
+ returns TRUE if any good position found, with the coord in x,y */
+boolean
+rnd_nextto_goodpos(coordxy *x, coordxy *y, struct monst *mtmp)
+{
+ int i, j, k, dirs[N_DIRS];
+ boolean is_u = (mtmp == &g.youmonst);
+ coordxy nx, ny;
+
+ for (i = 0; i < N_DIRS; ++i)
+ dirs[i] = i;
+ for (i = N_DIRS; i > 0; --i) {
+ j = rn2(i);
+ k = dirs[j];
+ dirs[j] = dirs[i - 1];
+ dirs[i - 1] = k;
+ }
+ for (i = 0; i < N_DIRS; ++i) {
+ nx = *x + xdir[dirs[i]];
+ ny = *y + ydir[dirs[i]];
+ /* crawl_destination and goodpos both include an isok() check */
+ if (is_u ? crawl_destination(nx, ny) : goodpos(nx, ny, mtmp, 0)) {
+ *x = nx;
+ *y = ny;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
/* return TRUE iff player relocated */
boolean
/* can't crawl if unable to move (crawl_ok flag stays false) */
if (g.multi < 0 || (Upolyd && !g.youmonst.data->mmove))
goto crawl;
- /* look around for a place to crawl to */
-#if 0
- for (i = 0; i < 100; i++) {
- x = rn1(3, u.ux - 1);
- y = rn1(3, u.uy - 1);
- if (crawl_destination(x, y)) {
- crawl_ok = TRUE;
- goto crawl;
- }
- }
- /* one more scan */
- for (x = u.ux - 1; x <= u.ux + 1; x++)
- for (y = u.uy - 1; y <= u.uy + 1; y++)
- if (crawl_destination(x, y)) {
- crawl_ok = TRUE;
- goto crawl;
- }
-#else
- {
- int j, k, dirs[N_DIRS];
-
- /* instead of picking a random direction up to 100 times, try each
- of the eight directions at most once after shuffling their order */
- for (i = 0; i < N_DIRS; ++i)
- dirs[i] = i;
- for (i = N_DIRS; i > 0; --i) {
- j = rn2(i);
- k = dirs[j];
- dirs[j] = dirs[i - 1];
- dirs[i - 1] = k;
- }
- for (i = 0; i < N_DIRS; ++i) {
- x = u.ux + xdir[dirs[i]];
- y = u.uy + ydir[dirs[i]];
- /* note: crawl_dest calls goodpos() which performs isok() check */
- if (crawl_destination(x, y)) {
- crawl_ok = TRUE;
- break;
- }
- }
- }
-#endif
+ x = u.ux, y = u.uy;
+ if (rnd_nextto_goodpos(&x, &y, &g.youmonst))
+ crawl_ok = TRUE;
crawl:
if (crawl_ok) {
boolean lost = FALSE;
new_tail->wy = y;
while (curr) {
- int nx = 0, ny = 0;
-#if 0 /* old code */
- int trycnt = 0;
-
- /* pick a random direction from x, y and test for goodpos() */
- do {
- random_dir(ox, oy, &nx, &ny);
- } while (!goodpos(nx, ny, worm, 0) && ++tryct <= 50);
-
- if (tryct <= 50)
-#else /* new code */
- int i, j, k, dirs[N_DIRS];
-
- /* instead of picking a random direction up to 50 times, try each
- of the eight directions at most once after shuffling their order */
- for (i = 0; i < N_DIRS; ++i)
- dirs[i] = i;
- for (i = N_DIRS; i > 0; --i) {
- j = rn2(i);
- k = dirs[j];
- dirs[j] = dirs[i - 1];
- dirs[i - 1] = k;
- }
- for (i = 0; i < N_DIRS; ++i) {
- nx = ox + xdir[dirs[i]];
- ny = oy + ydir[dirs[i]];
- if (goodpos(nx, ny, worm, 0)) /* includes an isok() check */
- break;
- }
+ coordxy nx = ox, ny = oy;
- if (i < N_DIRS)
-#endif
- {
+ if (rnd_nextto_goodpos(&nx, &ny, worm)) {
place_worm_seg(worm, nx, ny);
curr->wx = (coordxy) (ox = nx);
curr->wy = (coordxy) (oy = ny);