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:
Pasi Kallinen
2015-10-12 12:00:51 +03:00
parent b2aea3e9d7
commit 2f54ed8eae
+66 -9
View File
@@ -944,6 +944,68 @@ newmextra()
return mextra; 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; * called with [x,y] = coordinates;
* [0,0] means anyplace * [0,0] means anyplace
@@ -967,19 +1029,14 @@ register int mmflags;
/* if caller wants random location, do it here */ /* if caller wants random location, do it here */
if (x == 0 && y == 0) { if (x == 0 && y == 0) {
int tryct = 200; /* careful with bigrooms */ coord cc;
boolean good;
struct monst fakemon; struct monst fakemon;
fakemon.data = ptr; /* set up for goodpos */ fakemon.data = ptr; /* set up for goodpos */
do { if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *)0, gpflags, &cc))
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)
return ((struct monst *) 0); return ((struct monst *) 0);
x = cc.x;
y = cc.y;
} else if (byyou && !in_mklev) { } else if (byyou && !in_mklev) {
coord bypos; coord bypos;