| 216 | #ifdef NEW_ENEXTO |
| 217 | |
| 218 | boolean |
| 219 | enexto_core( |
| 220 | coord *cc, /* output; <cc.x,cc.y> as close as feasible to <xx,yy> */ |
| 221 | coordxy xx, coordxy yy, /* input coordinates */ |
| 222 | struct permonst *mdat, /* type of monster; affects whether water or |
| 223 | * lava or boulder spots will be considered */ |
| 224 | mmflags_nht entflags) /* flags for goodpos() */ |
| 225 | { |
| 226 | coord candy[ROWNO * (COLNO - 1)]; /* enough room for every location */ |
| 227 | int i, nearcandyct, allcandyct; |
| 228 | struct monst fakemon; /* dummy monster */ |
| 229 | boolean allow_xx_yy = (boolean) ((entflags & GP_ALLOW_XY) != 0); |
| 230 | /* note: GP_ALLOW_XY isn't used by goodpos(); old enext_core() used to |
| 231 | mask it off to hide it from goodpos but that isn't required and we |
| 232 | want to keep it in case the debugpline4() gets called */ |
| 233 | |
| 234 | if (!mdat) { |
| 235 | debugpline0("enexto() called with null mdat"); |
| 236 | /* default to player's original monster type */ |
| 237 | mdat = &mons[u.umonster]; |
| 238 | } |
| 239 | fakemon = cg.zeromonst; |
| 240 | set_mon_data(&fakemon, mdat); /* set up for goodpos() */ |
| 241 | |
| 242 | /* gather candidate coordinates within 3 steps, those 1 step away in |
| 243 | random order first, then those 2 steps away in random order, then 3; |
| 244 | this will usually find a good spot without scanning the whole map */ |
| 245 | nearcandyct = collect_coords(candy, xx, yy, 3, CC_NO_FLAGS, |
| 246 | (boolean (*)(coordxy, coordxy)) 0); |
| 247 | for (i = 0; i < nearcandyct; ++i) { |
| 248 | *cc = candy[i]; |
| 249 | if (goodpos(cc->x, cc->y, &fakemon, entflags)) |
| 250 | return TRUE; |
| 251 | } |
| 252 | |
| 253 | /* didn't find a spot; gather coordinates for the whole map except |
| 254 | for <xx,yy> itself, ordered in expanding distance from <xx,yy> |
| 255 | (subsets of equal distance grouped together with order randomized) */ |
| 256 | allcandyct = collect_coords(candy, xx, yy, 0, CC_NO_FLAGS, |
| 257 | (boolean (*)(coordxy, coordxy)) 0); |
| 258 | /* skip first 'nearcandyct' spots, they have already been rejected; |
| 259 | they will occur in different random order but same overall total */ |
| 260 | for (i = nearcandyct; i < allcandyct; ++i) { |
| 261 | *cc = candy[i]; |
| 262 | if (goodpos(cc->x, cc->y, &fakemon, entflags)) |
| 263 | return TRUE; |
| 264 | } |
| 265 | |
| 266 | /* still didn't find a spot; maybe try <xx,yy> itself */ |
| 267 | cc->x = xx, cc->y = yy; /* final value for 'cc' in case we return False */ |
| 268 | if (allow_xx_yy && goodpos(cc->x, cc->y, &fakemon, entflags)) |
| 269 | return TRUE; |
| 270 | |
| 271 | /* failed to find any acceptable spot */ |
| 272 | debugpline4("enexto(\"%s\",%d,%d,0x%08lx) failed", |
| 273 | mdat->pmnames[NEUTRAL], (int) xx, (int) yy, |
| 274 | (unsigned long) entflags); |
| 275 | return FALSE; |
no test coverage detected