static void join(int a, int b) { coord cc,tt; int tx, ty, xx, yy; struct rm *crm; struct mkroom *croom, *troom; int dx, dy, dix, diy, cct; croom = &rooms[a]; troom = &rooms[b]; /* find positions cc and tt for doors in croom and troom and direction for a corridor between them */ if(troom->hx < 0 || croom->hx < 0 || doorindex >= DOORMAX) return; if(troom->lx > croom->hx) { dx = 1; dy = 0; xx = croom->hx+1; tx = troom->lx-1; cc = finddpos(xx,croom->ly,xx,croom->hy); tt = finddpos(tx,troom->ly,tx,troom->hy); } else if(troom->hy < croom->ly) { dy = -1; dx = 0; yy = croom->ly-1; cc = finddpos(croom->lx,yy,croom->hx,yy); ty = troom->hy+1; tt = finddpos(troom->lx,ty,troom->hx,ty); } else if(troom->hx < croom->lx) { dx = -1; dy = 0; xx = croom->lx-1; tx = troom->hx+1; cc = finddpos(xx,croom->ly,xx,croom->hy); tt = finddpos(tx,troom->ly,tx,troom->hy); } else { dy = 1; dx = 0; yy = croom->hy+1; ty = troom->ly-1; cc = finddpos(croom->lx,yy,croom->hx,yy); tt = finddpos(troom->lx,ty,troom->hx,ty); } xx = cc.x; yy = cc.y; tx = tt.x - dx; ty = tt.y - dy; if(nxcor && levl[xx+dx][yy+dy].typ) return; dodoor(xx,yy,croom); cct = 0; while(xx != tx || yy != ty) { xx += dx; yy += dy; /* loop: dig corridor at [xx,yy] and find new [xx,yy] */ if(cct++ > 500 || (nxcor && !rn2(35))) return; if(xx == COLNO-1 || xx == 0 || yy == 0 || yy == ROWNO-1) return; /* impossible */ crm = &levl[xx][yy]; if(!(crm->typ)) { if(rn2(100)) { crm->typ = CORR; crm->scrsym = CORR_SYM; if(nxcor && !rn2(50)) mkobj_at(ROCK_SYM, xx, yy); } else { crm->typ = SCORR; crm->scrsym = ' '; } } else if(crm->typ != CORR && crm->typ != SCORR) { /* strange ... */ return; } /* find next corridor position */ dix = abs(xx-tx); diy = abs(yy-ty); /* do we have to change direction ? */ if(dy && dix > diy) { int ddx = (xx > tx) ? -1 : 1; crm = &levl[xx+ddx][yy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { dx = ddx; dy = 0; continue; } } else if(dx && diy > dix) { int ddy = (yy > ty) ? -1 : 1; crm = &levl[xx][yy+ddy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) { dy = ddy; dx = 0; continue; } } /* continue straight on? */ crm = &levl[xx+dx][yy+dy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) continue; /* no, what must we do now?? */ if(dx) { dx = 0; dy = (ty < yy) ? -1 : 1; crm = &levl[xx+dx][yy+dy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) continue; dy = -dy; continue; } else { dy = 0; dx = (tx < xx) ? -1 : 1; crm = &levl[xx+dx][yy+dy]; if(!crm->typ || crm->typ == CORR || crm->typ == SCORR) continue; dx = -dx; continue; } } /* we succeeded in digging the corridor */ dodoor(tt.x, tt.y, troom); if(smeq[a] < smeq[b]) smeq[b] = smeq[a]; else smeq[a] = smeq[b]; }
static void roguecorr(struct level *lev, int x, int y, int dir) { int fromx, fromy, tox, toy; if (dir==DOWN) { r[x][y].doortable &= ~DOWN; if (!r[x][y].real) { fromx = r[x][y].rlx; fromy = r[x][y].rly; fromx += 1 + 26*x; fromy += 7*y; } else { fromx = r[x][y].rlx + rn2(r[x][y].dx); fromy = r[x][y].rly + r[x][y].dy; fromx += 1 + 26*x; fromy += 7*y; if (!IS_WALL(lev->locations[fromx][fromy].typ)) impossible("down: no wall at %d,%d?",fromx, fromy); dodoor(lev, fromx, fromy, &lev->rooms[r[x][y].nroom]); lev->locations[fromx][fromy].doormask = D_NODOOR; fromy++; } if (y >= 2) { impossible("down door from %d,%d going nowhere?",x,y); return; } y++; r[x][y].doortable &= ~UP; if (!r[x][y].real) { tox = r[x][y].rlx; toy = r[x][y].rly; tox += 1 + 26*x; toy += 7*y; } else { tox = r[x][y].rlx + rn2(r[x][y].dx); toy = r[x][y].rly - 1; tox += 1 + 26*x; toy += 7*y; if (!IS_WALL(lev->locations[tox][toy].typ)) impossible("up: no wall at %d,%d?",tox,toy); dodoor(lev, tox, toy, &lev->rooms[r[x][y].nroom]); lev->locations[tox][toy].doormask = D_NODOOR; toy--; } roguejoin(lev, fromx, fromy, tox, toy, FALSE); return; } else if (dir == RIGHT) { r[x][y].doortable &= ~RIGHT; if (!r[x][y].real) { fromx = r[x][y].rlx; fromy = r[x][y].rly; fromx += 1 + 26*x; fromy += 7*y; } else { fromx = r[x][y].rlx + r[x][y].dx; fromy = r[x][y].rly + rn2(r[x][y].dy); fromx += 1 + 26*x; fromy += 7*y; if (!IS_WALL(lev->locations[fromx][fromy].typ)) impossible("down: no wall at %d,%d?",fromx, fromy); dodoor(lev, fromx, fromy, &lev->rooms[r[x][y].nroom]); lev->locations[fromx][fromy].doormask = D_NODOOR; fromx++; } if (x >= 2) { impossible("right door from %d,%d going nowhere?",x,y); return; } x++; r[x][y].doortable &= ~LEFT; if (!r[x][y].real) { tox = r[x][y].rlx; toy = r[x][y].rly; tox += 1 + 26*x; toy += 7*y; } else { tox = r[x][y].rlx - 1; toy = r[x][y].rly + rn2(r[x][y].dy); tox += 1 + 26*x; toy += 7*y; if (!IS_WALL(lev->locations[tox][toy].typ)) impossible("left: no wall at %d,%d?",tox,toy); dodoor(lev, tox, toy, &lev->rooms[r[x][y].nroom]); lev->locations[tox][toy].doormask = D_NODOOR; tox--; } roguejoin(lev, fromx, fromy, tox, toy, TRUE); return; } else impossible("corridor in direction %d?",dir); }