Fix crash in linkexit()
This commit is contained in:
parent
81c033d7dc
commit
b2bfca3ca1
6
lf.c
6
lf.c
|
@ -4508,7 +4508,7 @@ int genalignmentlist(flagpile_t *fp, char *buf) {
|
|||
|
||||
// for each G, N, E
|
||||
for (n = 0; n < 3; n++ ) {
|
||||
char candidate;
|
||||
char candidate = '\0';
|
||||
candidate = allaligns[n];
|
||||
|
||||
// does it match all flags?
|
||||
|
@ -4523,7 +4523,7 @@ int genalignmentlist(flagpile_t *fp, char *buf) {
|
|||
|
||||
default:
|
||||
case AL_NONE:
|
||||
strcpy(this, retflag[i]->text);
|
||||
strncpy(this, retflag[i]->text, BUFLEN);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -4539,7 +4539,7 @@ int genalignmentlist(flagpile_t *fp, char *buf) {
|
|||
if (!strchr(localposs, candidate)) { // not already in list?
|
||||
char letter[2];
|
||||
// this one is okay.
|
||||
snprintf(letter, 1, "%c", candidate);
|
||||
snprintf(letter, 2, "%c", candidate);
|
||||
strcat(localposs, letter);
|
||||
nposs++;
|
||||
}
|
||||
|
|
288
map.c
288
map.c
|
@ -4652,7 +4652,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
int nthings = 0,failed,nstairslinked = 0;
|
||||
int nprevaults = 0;
|
||||
int db = B_TRUE;
|
||||
char dbtag[BUFLEN],dbbuf[BUFLEN];
|
||||
char dbtag[BUFLEN],dbbuf[BIGBUFLEN];
|
||||
|
||||
snprintf(dbtag, BUFLEN, "[createmap.c]");
|
||||
|
||||
|
@ -4819,7 +4819,7 @@ void createmap(map_t *map, int depth, region_t *region, map_t *parentmap, int ex
|
|||
snprintf(buf, BUFLEN, "%s (id #%d)",buf2, map->id);
|
||||
map->name = strdup(buf);
|
||||
|
||||
snprintf(dbbuf, BUFLEN, "%s -about to check outline",dbtag);
|
||||
snprintf(dbbuf, BIGBUFLEN, "%s -about to check outline",dbtag);
|
||||
dblog(dbbuf);
|
||||
|
||||
// get a list of what things are here based on the region's outline
|
||||
|
@ -6019,7 +6019,7 @@ void killregion(region_t *r) {
|
|||
// if 'wantfilled' is set, only link to "filled" cells.
|
||||
// return TRUE on failure.
|
||||
int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
||||
int db = B_FALSE;
|
||||
int db = B_TRUE;
|
||||
int d, roomid,startd,endd;
|
||||
int poss2[MAXCANDIDATES],nposs2;
|
||||
int dist[MAXDIR_ORTH],hitsedge[MAXDIR_ORTH], sameroom[MAXDIR_ORTH];
|
||||
|
@ -6030,6 +6030,8 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
int forcedir = D_NONE;
|
||||
|
||||
if (ncellsadded) *ncellsadded = 0;
|
||||
node_t open[MAX_PATHFIND_ADJ];
|
||||
node_t closed[MAX_PATHFIND_ADJ];
|
||||
|
||||
roomid = getroomid(startcell);
|
||||
if (db) dblog(" calling linkexit() for cell at %d,%d in roomid %d", startcell->x, startcell->y, roomid);
|
||||
|
@ -6114,279 +6116,6 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
}
|
||||
|
||||
if (mindist == 999) {
|
||||
/*
|
||||
cell_t *turncell = NULL,*endcell = NULL;
|
||||
cell_t *perpcell[MAX_MAPW*MAX_MAPH];
|
||||
cell_t *perpturncell1[MAX_MAPW*MAX_MAPH];
|
||||
int perpturndir1[MAX_MAPW*MAX_MAPH];
|
||||
int nperpcells = 0;
|
||||
int perpdir[2];
|
||||
int startdir = D_NONE;
|
||||
int turndir = D_NONE;
|
||||
int startdist = 0;
|
||||
int maxdist2 = -1;
|
||||
int startposs[MAXDIR_ORTH];
|
||||
int nstartposs = 0;
|
||||
// no good directions.
|
||||
if (db) dblog(" No directions lead to valid cells. Trying turns.");
|
||||
|
||||
|
||||
if (forcedir != D_NONE) {
|
||||
startdir = forcedir;
|
||||
} else {
|
||||
// starting at the LONGEST distance, traverse up each dir,
|
||||
// branching off looking for rooms.
|
||||
|
||||
// if start cell is inside a room, find longest distance which
|
||||
// doesn't go through the same room
|
||||
if (db) dblog(" Selecting startdir to find turns.");
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if (baddir[d]) {
|
||||
if (db) dblog(" %s bad (baddir is set)", getdirname(d));
|
||||
} else if (isroom(startcell)) {
|
||||
if (!sameroom[d] && (dist[d] > maxdist2)) {
|
||||
if (db) dblog(" %s ok (diff room and %d is best distance so far)",
|
||||
getdirname(d), dist[d]);
|
||||
maxdist2 = dist[d];
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(" %s ok (start not room and %d is best distance so far)",
|
||||
getdirname(d), dist[d]);
|
||||
maxdist2 = dist[d];
|
||||
}
|
||||
}
|
||||
// pick one randomly
|
||||
for (d = D_N; d <= D_W; d++) {
|
||||
if ((dist[d] == maxdist2) && !baddir[d]) {
|
||||
startposs[nstartposs++] = d;
|
||||
}
|
||||
}
|
||||
if (db) dblog(" %d possibilities found (maxdist2=%d).",nstartposs,maxdist2);
|
||||
if (nstartposs) {
|
||||
startdir = startposs[rnd(0,nstartposs-1)];
|
||||
if (db) dblog(" Selected %s.",getdirname(startdir));
|
||||
}
|
||||
}
|
||||
|
||||
//assert((startdir >= D_N) && (startdir <= D_W));
|
||||
if ((startdir < D_N) || (startdir > D_W)) {
|
||||
// couldn't find any valid start dirs!
|
||||
if (db) dblog(" Cannot find a valid startdir.");
|
||||
return B_TRUE;
|
||||
}
|
||||
|
||||
// figure out perpendicular dirs
|
||||
perpdir[0] = startdir - 1; if (perpdir[0] < D_N) perpdir[0] = D_W;
|
||||
perpdir[1] = startdir + 1; if (perpdir[1] > D_W) perpdir[1] = D_N;
|
||||
|
||||
assert(perpdir[0] != startdir);
|
||||
assert(perpdir[1] != startdir);
|
||||
|
||||
if (db) dblog(" Will walk %s (dist %d), checking %s and %s.", getdirname(startdir), maxdist,
|
||||
getdirname(perpdir[0]), getdirname(perpdir[1]));
|
||||
|
||||
// check in startdir
|
||||
c = getcellindir(startcell, startdir);
|
||||
while (c && !turncell) {
|
||||
int n;
|
||||
cell_t *c2;
|
||||
startdist++;
|
||||
// don't bother checking left/right if this cell isn't okay to be cleared.
|
||||
if (cellokforreachability(startcell, c, roomid, d, wantfilled, NULL)) {
|
||||
// check left/right from this cell for rooms
|
||||
for (n = 0; n <= 1; n++) {
|
||||
int turndist = 0;
|
||||
|
||||
if (db) {
|
||||
dblog("Travelling %s, checking %s from %d,%d.", getdirname(startdir),
|
||||
getdirname(perpdir[n]), c->x, c->y);
|
||||
}
|
||||
c2 = getcellindir(c, perpdir[n]);
|
||||
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
int rv;
|
||||
turndist++;
|
||||
|
||||
assert((n >= 0) && (n <= 1));
|
||||
perpcell[nperpcells] = c2; // this will be used if we need to make 2 turns
|
||||
perpturncell1[nperpcells] = c;
|
||||
perpturndir1[nperpcells] = perpdir[n];
|
||||
nperpcells++;
|
||||
|
||||
if (db) {
|
||||
dblog_nocr("(%d,%d)",c2->x, c2->y);
|
||||
}
|
||||
rv = cellokforreachability(startcell, c2, roomid, perpdir[n], wantfilled, NULL);
|
||||
|
||||
if (rv == B_FALSE) {
|
||||
break;
|
||||
} else if (rv == B_TRUE) {
|
||||
gotsolution = B_TRUE;
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
|
||||
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
|
||||
for (nn = 0; nn <= 1; nn++) {
|
||||
pcell = getcellindir(c2, perpdir2[nn]);
|
||||
if (pcell && adjcellokforreachability(pcell, roomid, perpdir2[nn], wantfilled)) {
|
||||
// finished.
|
||||
if (db) dblog(" Got to an empty cell next to us.");
|
||||
gotsolution = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotsolution) {
|
||||
if (db) dblog(" Solution found: Walk %d %s, then %d %s.",
|
||||
startdist, getdirname(startdir),
|
||||
turndist, getdirname(perpdir[n]));
|
||||
// walkable and not in this roomid. ok!
|
||||
turncell = c;
|
||||
endcell = c2;
|
||||
turndir = perpdir[n];
|
||||
break;
|
||||
}
|
||||
// check next cell
|
||||
c2 = getcellindir(c2, perpdir[n]);
|
||||
}
|
||||
if (turncell) break;
|
||||
}
|
||||
}
|
||||
// now keep going in main direction.
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
|
||||
if (turncell) {
|
||||
// make a path up to the turn point.
|
||||
if (db) dblog(" Making path from vault to corner, initdir=%s", getdirname(startdir));
|
||||
c = getcellindir(startcell, startdir);
|
||||
while (c != turncell) {
|
||||
breakwall(c, "turnset=1, making path from vault %d to corner", getroomid(startcell));
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
// clear the corner cell
|
||||
breakwall(c, "turncell=1, this is the corner (from vault %d)",getroomid(startcell));
|
||||
if (db) dblog(" Making path from corner to rest of map, turndir=%s", getdirname(turndir));
|
||||
// now turn and clear up to the next room/empty cell
|
||||
c = getcellindir(c, turndir);
|
||||
while (c != endcell) {
|
||||
breakwall(c, "turncell=1, clearing from corner to end (from vault %d)", getroomid(startcell));
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, turndir);
|
||||
}
|
||||
} else {
|
||||
// We need to make 2 turns.
|
||||
// for each perpcell[], look in startdir + diropposite(startdir)
|
||||
int dir3[2],i,n;
|
||||
cell_t *turncell2 = NULL;
|
||||
int turndir2;
|
||||
dir3[0] = startdir;
|
||||
dir3[1] = diropposite(startdir);
|
||||
if (db) dblog(" Need to make two turns. Searching %s and %s from each perpcell.", getdirname(dir3[0]),
|
||||
getdirname(dir3[1]));
|
||||
for (i = 0; i < nperpcells; i++) {
|
||||
for (n = 0; n < 2; n++) {
|
||||
cell_t *c2;
|
||||
int turndist = 0;
|
||||
|
||||
if (db) dblog_nocr("looking %s from %d,%d: ", getdirname(dir3[n]),
|
||||
perpcell[i]->x, perpcell[i]->y);
|
||||
|
||||
c2 = getcellindir(perpcell[i], dir3[n]);
|
||||
while (c2) {
|
||||
int gotsolution = B_FALSE;
|
||||
int rv;
|
||||
turndist++;
|
||||
if (db) dblog_nocr("(%d,%d)",c2->x,c2->y);
|
||||
|
||||
rv = cellokforreachability(startcell, c2, roomid, perpdir[n], wantfilled, NULL);
|
||||
|
||||
if (rv == B_FALSE) {
|
||||
break;
|
||||
} else if (rv == B_TRUE) {
|
||||
gotsolution = B_TRUE;
|
||||
} else if (turndist > 1) {
|
||||
// check l/r too
|
||||
int perpdir2[2],nn;
|
||||
cell_t *pcell = NULL;
|
||||
perpdir2[0] = perpdir[n] - 1; if (perpdir2[0] < D_N) perpdir2[0] = D_W;
|
||||
perpdir2[1] = perpdir[n] + 1; if (perpdir2[1] > D_W) perpdir2[1] = D_N;
|
||||
for (nn = 0; nn <= 1; nn++) {
|
||||
pcell = getcellindir(c2, perpdir2[nn]);
|
||||
if (pcell && adjcellokforreachability(pcell, roomid, perpdir2[nn], wantfilled)) {
|
||||
// finished.
|
||||
if (db) dblog(" Got to an empty cell next to us.");
|
||||
gotsolution = B_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotsolution) {
|
||||
turncell = perpturncell1[i];
|
||||
turndir = perpturndir1[i];
|
||||
turncell2 = perpcell[i];
|
||||
turndir2 = dir3[n];
|
||||
|
||||
endcell = c2;
|
||||
break;
|
||||
}
|
||||
// check next cell
|
||||
c2 = getcellindir(c2, dir3[n]);
|
||||
} // end while c2
|
||||
if (turncell2) break;
|
||||
|
||||
if (db) dblog("");
|
||||
} // end for n=1-2
|
||||
if (turncell2) break;
|
||||
} // end foreach perpcell
|
||||
|
||||
// if we find a solution, fill in turncell2 and make path.
|
||||
if (turncell2) {
|
||||
if (db) dblog(" Twoturn solution found: Walk %s, then %s, then %s.",
|
||||
getdirname(startdir), getdirname(turndir), getdirname(turndir2));
|
||||
|
||||
// make a path up to the turn point.
|
||||
if (db) dblog(" Making path from vault to first corner, initdir=%s", getdirname(startdir));
|
||||
c = getcellindir(startcell, startdir);
|
||||
while (c != turncell) {
|
||||
breakwall(c, "twoturn: path from vault %d to first corner 1", getroomid(startcell));
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, startdir);
|
||||
}
|
||||
// clear the corner cell
|
||||
breakwall(c, "twoturn: corner 1 (from vault %d)", getroomid(startcell));
|
||||
// now turn and clear up to the next turn
|
||||
if (db) dblog(" Making path from 1st corner to 2nd corner, turndir=%s", getdirname(turndir));
|
||||
c = getcellindir(c, turndir);
|
||||
while (c != turncell2) {
|
||||
breakwall(c, "twoturn: path from 1st corner to 2nd corner (from vault %d)", getroomid(startcell));
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, turndir);
|
||||
}
|
||||
|
||||
// now turn and clear up to the next room/empty cell
|
||||
if (db) dblog(" Making path from 2nd corner to rest of map, turndir=%s", getdirname(turndir2));
|
||||
c = getcellindir(c, turndir2);
|
||||
while (c != endcell) {
|
||||
breakwall(c, "twoturn: path from 2nd corner to end (from vault %d)", getroomid(startcell));
|
||||
if (ncellsadded) (*ncellsadded)++;
|
||||
c = getcellindir(c, turndir2);
|
||||
}
|
||||
} else {
|
||||
if (db) dblog(" Cannot find a way to link up.");
|
||||
// debugging - a failure here during fix_reachability is fatal.
|
||||
//if (wantfilled) {
|
||||
// assert(0 == 1);
|
||||
//}
|
||||
return B_TRUE;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
int roomidx[MAXROOMS];
|
||||
cell_t *midcell[MAXROOMS];
|
||||
int donesomething,a,i,foundpath;
|
||||
|
@ -6437,8 +6166,6 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
for (a = 0 ; (a < m->nrooms) && !foundpath; a++) {
|
||||
int destroomid;
|
||||
int done = B_FALSE,i,n;
|
||||
node_t open[MAX_PATHFIND_ADJ];
|
||||
node_t closed[MAX_PATHFIND_ADJ];
|
||||
node_t *cur;
|
||||
int nopen = 0,nclosed = 0;
|
||||
int okforreach;
|
||||
|
@ -6610,9 +6337,8 @@ int linkexit(cell_t *startcell, int wantfilled, int *ncellsadded) {
|
|||
char reasontext[BUFLEN];
|
||||
// work backwards from node[cur] (ie. targcell) following parents.
|
||||
// populate path and return
|
||||
if (db) dblog("linkexit() - found path!\n");
|
||||
|
||||
sprintf(reasontext, "astar pathfind link (from roomid %d)",roomid);
|
||||
snprintf(reasontext, BUFLEN, "astar pathfind link (from roomid %d)",roomid);
|
||||
|
||||
while (solnode) {
|
||||
pathlen++;
|
||||
if (pathlen >= MAX_PATHFIND_STEPS) {
|
||||
|
|
Loading…
Reference in New Issue