Fix the makemon random coord picking again
This time try random locations up to 50 times, then start going through the map in order to find a good position. First round tries to pick a location not in sight, if that fails, it might try stair or ladder location. If that fails, then it will pick any good position, whether in sight or not. Outside field of vision restriction and trying stair or ladder locations does not happen when the monster is placed from special level code.
This commit is contained in:
@@ -944,6 +944,68 @@ newmextra()
|
||||
return mextra;
|
||||
}
|
||||
|
||||
|
||||
boolean
|
||||
makemon_rnd_goodpos(mon, gpflags, cc)
|
||||
struct monst *mon;
|
||||
unsigned gpflags;
|
||||
coord *cc;
|
||||
{
|
||||
int tryct = 0;
|
||||
int nx,ny;
|
||||
boolean good;
|
||||
do {
|
||||
nx = rn1(COLNO - 3, 2);
|
||||
ny = rn2(ROWNO);
|
||||
if (!in_mklev && cansee(nx,ny)) good = FALSE;
|
||||
else good = goodpos(nx, ny, mon, gpflags);
|
||||
} while ((++tryct < 50) && !good);
|
||||
if (!good) {
|
||||
/* else go through all map positions, twice, first round
|
||||
ignoring positions in sight, and pick first good one.
|
||||
skip first round if we're in special level loader or blind */
|
||||
int xofs = nx;
|
||||
int yofs = ny;
|
||||
int dx,dy;
|
||||
int bl = (in_mklev || Blind) ? 1 : 0;
|
||||
for ( ; bl < 2; bl++) {
|
||||
for (dx = 0; dx < COLNO; dx++)
|
||||
for (dy = 0; dy < ROWNO; dy++) {
|
||||
nx = ((dx + xofs) % (COLNO - 1)) + 1;
|
||||
ny = ((dy + yofs) % (ROWNO - 1)) + 1;
|
||||
if ((bl == 0) && cansee(nx,ny)) continue;
|
||||
if (goodpos(nx, ny, mon, gpflags))
|
||||
goto gotgood;
|
||||
}
|
||||
if (bl == 0 && (!mon || mon->data->mmove)) {
|
||||
/* all map positions are visible (or not good),
|
||||
try to pick something logical */
|
||||
if (dnstair.sx && !rn2(2)) {
|
||||
nx = dnstair.sx;
|
||||
ny = dnstair.sy;
|
||||
} else if (upstair.sx && !rn2(2)) {
|
||||
nx = upstair.sx;
|
||||
ny = upstair.sy;
|
||||
} else if (dnladder.sx && !rn2(2)) {
|
||||
nx = dnladder.sx;
|
||||
ny = dnladder.sy;
|
||||
} else if (upladder.sx && !rn2(2)) {
|
||||
nx = upladder.sx;
|
||||
ny = upladder.sy;
|
||||
}
|
||||
if (goodpos(nx, ny, mon, gpflags))
|
||||
goto gotgood;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gotgood:
|
||||
cc->x = nx;
|
||||
cc->y = ny;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* called with [x,y] = coordinates;
|
||||
* [0,0] means anyplace
|
||||
@@ -967,19 +1029,14 @@ register int mmflags;
|
||||
|
||||
/* if caller wants random location, do it here */
|
||||
if (x == 0 && y == 0) {
|
||||
int tryct = 200; /* careful with bigrooms */
|
||||
boolean good;
|
||||
coord cc;
|
||||
struct monst fakemon;
|
||||
|
||||
fakemon.data = ptr; /* set up for goodpos */
|
||||
do {
|
||||
x = rn1(COLNO - 3, 2);
|
||||
y = rn2(ROWNO);
|
||||
if (!in_mklev && cansee(x,y)) tryct--;
|
||||
good = goodpos(x, y, ptr ? &fakemon : (struct monst *) 0, gpflags);
|
||||
} while (tryct && !good);
|
||||
if (!good)
|
||||
if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *)0, gpflags, &cc))
|
||||
return ((struct monst *) 0);
|
||||
x = cc.x;
|
||||
y = cc.y;
|
||||
} else if (byyou && !in_mklev) {
|
||||
coord bypos;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user