MCPcopy Create free account
hub / github.com/NetHack/NetHack / enexto_core

Function enexto_core

src/teleport.c:218–276  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

216#ifdef NEW_ENEXTO
217
218boolean
219enexto_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;

Callers 3

enextoFunction · 0.85
enexto_gpflagsFunction · 0.85
makemonFunction · 0.85

Calls 4

set_mon_dataFunction · 0.85
collect_coordsFunction · 0.85
goodposFunction · 0.85
rn2Function · 0.85

Tested by

no test coverage detected