From 39e719ef441114ecd73c30261d98c970f7ab4133 Mon Sep 17 00:00:00 2001 From: jwalz Date: Sat, 5 Jan 2002 21:05:49 +0000 Subject: [PATCH] *** empty log message *** --- src/mkmap.c | 411 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 411 insertions(+) create mode 100644 src/mkmap.c diff --git a/src/mkmap.c b/src/mkmap.c new file mode 100644 index 000000000..3715116c0 --- /dev/null +++ b/src/mkmap.c @@ -0,0 +1,411 @@ +/* SCCS Id: @(#)mkmap.c 3.3 96/05/23 */ +/* Copyright (c) J. C. Collet, M. Stephenson and D. Cohrs, 1992 */ +/* NetHack may be freely redistributed. See license for details. */ + +#include "hack.h" +#include "sp_lev.h" + +#define HEIGHT (ROWNO - 1) +#define WIDTH (COLNO - 2) + +STATIC_DCL void FDECL(init_map,(SCHAR_P)); +STATIC_DCL void FDECL(init_fill,(SCHAR_P,SCHAR_P)); +STATIC_DCL schar FDECL(get_map,(int,int,SCHAR_P)); +STATIC_DCL void FDECL(pass_one,(SCHAR_P,SCHAR_P)); +STATIC_DCL void FDECL(pass_two,(SCHAR_P,SCHAR_P)); +STATIC_DCL void FDECL(pass_three,(SCHAR_P,SCHAR_P)); +STATIC_DCL void NDECL(wallify_map); +STATIC_DCL void FDECL(join_map,(SCHAR_P,SCHAR_P)); +STATIC_DCL void FDECL(finish_map,(SCHAR_P,SCHAR_P,XCHAR_P,XCHAR_P)); +void FDECL(mkmap, (lev_init *)); + +char *new_locations; +int min_rx, max_rx, min_ry, max_ry; /* rectangle bounds for regions */ +static int n_loc_filled; + +STATIC_OVL void +init_map(bg_typ) + schar bg_typ; +{ + register int i,j; + + for(i=1; i WIDTH || row >= HEIGHT) + return bg_typ; + return levl[col][row].typ; +} + +static int dirs[16] = { + -1, -1 /**/, -1, 0 /**/, -1, 1 /**/, + 0, -1 /**/, 0, 1 /**/, + 1, -1 /**/, 1, 0 /**/, 1, 1}; + +STATIC_OVL void +pass_one(bg_typ, fg_typ) + schar bg_typ, fg_typ; +{ + register int i,j; + short count, dr; + + for(i=2; i<=WIDTH; i++) + for(j=1; j 0 && + (anyroom ? IS_ROOM(levl[sx][sy].typ) : levl[sx][sy].typ == fg_typ) && + (int) levl[sx][sy].roomno != rmno) + sx--; + sx++; /* compensate for extra decrement */ + + /* assume sx,sy is valid */ + if(sx < min_rx) min_rx = sx; + if(sy < min_ry) min_ry = sy; + + for(i=sx; i<=WIDTH && levl[i][sy].typ == fg_typ; i++) { + levl[i][sy].roomno = rmno; + levl[i][sy].lit = lit; + if(anyroom) { + /* add walls to room as well */ + register int ii,jj; + for(ii= (i == sx ? i-1 : i); ii <= i+1; ii++) + for(jj = sy-1; jj <= sy+1; jj++) + if(isok(ii,jj) && + (IS_WALL(levl[ii][jj].typ) || + IS_DOOR(levl[ii][jj].typ))) { + levl[ii][jj].edge = 1; + if(lit) levl[ii][jj].lit = lit; + if ((int) levl[ii][jj].roomno != rmno) + levl[ii][jj].roomno = SHARED; + } + } + n_loc_filled++; + } + nx = i; + + if(isok(sx,sy-1)) { + for(i=sx; isx || isok(i-1,sy-1)) && + levl[i-1][sy-1].typ == fg_typ) { + if ((int) levl[i-1][sy-1].roomno != rmno) + flood_fill_rm(i-1,sy-1,rmno,lit,anyroom); + } + if((isx || isok(i-1,sy+1)) && + levl[i-1][sy+1].typ == fg_typ) { + if ((int) levl[i-1][sy+1].roomno != rmno) + flood_fill_rm(i-1,sy+1,rmno,lit,anyroom); + } + if((i max_rx) max_rx = nx - 1; /* nx is just past valid region */ + if(sy > max_ry) max_ry = sy; +} + +/* + * If we have drawn a map without walls, this allows us to + * auto-magically wallify it. Taken from lev_main.c. + */ +STATIC_OVL void +wallify_map() +{ + + int x, y, xx, yy; + + for(x = 1; x < COLNO; x++) + for(y = 0; y < ROWNO; y++) + if(levl[x][y].typ == STONE) { + for(yy = y - 1; yy <= y+1; yy++) + for(xx = x - 1; xx <= x+1; xx++) + if(isok(xx,yy) && levl[xx][yy].typ == ROOM) { + if(yy != y) levl[x][y].typ = HWALL; + else levl[x][y].typ = VWALL; + } + } +} + +STATIC_OVL void +join_map(bg_typ, fg_typ) + schar bg_typ, fg_typ; +{ + register struct mkroom *croom, *croom2; + + register int i, j; + int sx, sy; + coord sm, em; + + /* first, use flood filling to find all of the regions that need joining */ + for(i=2; i<=WIDTH; i++) + for(j=1; j 3) { + add_room(min_rx, min_ry, max_rx, max_ry, + FALSE, OROOM, TRUE); + rooms[nroom-1].irregular = TRUE; + if(nroom >= (MAXNROFROOMS*2)) + goto joinm; + } else { + /* + * it's a tiny hole; erase it from the map to avoid + * having the player end up here with no way out. + */ + for(sx = min_rx; sx<=max_rx; sx++) + for(sy = min_ry; sy<=max_ry; sy++) + if ((int) levl[sx][sy].roomno == + nroom + ROOMOFFSET) { + levl[sx][sy].typ = bg_typ; + levl[sx][sy].roomno = NO_ROOM; + } + } + } + } + +joinm: + /* + * Ok, now we can actually join the regions with fg_typ's. + * The rooms are already sorted due to the previous loop, + * so don't call sort_rooms(), which can screw up the roomno's + * validity in the levl structure. + */ + for(croom = &rooms[0], croom2 = croom + 1; croom2 < &rooms[nroom]; ) { + /* pick random starting and end locations for "corridor" */ + if(!somexy(croom, &sm) || !somexy(croom2, &em)) { + /* ack! -- the level is going to be busted */ + /* arbitrarily pick centers of both rooms and hope for the best */ + impossible("No start/end room loc in join_map."); + sm.x = croom->lx + ((croom->hx - croom->lx) / 2); + sm.y = croom->ly + ((croom->hy - croom->ly) / 2); + em.x = croom2->lx + ((croom2->hx - croom2->lx) / 2); + em.y = croom2->ly + ((croom2->hy - croom2->ly) / 2); + } + + (void) dig_corridor(&sm, &em, FALSE, fg_typ, bg_typ); + + /* choose next region to join */ + /* only increment croom if croom and croom2 are non-overlapping */ + if(croom2->lx > croom->hx || + ((croom2->ly > croom->hy || croom2->hy < croom->ly) && rn2(3))) { + croom = croom2; + } + croom2++; /* always increment the next room */ + } +} + +STATIC_OVL void +finish_map(fg_typ, bg_typ, lit, walled) + schar fg_typ, bg_typ; + boolean lit, walled; +{ + int i, j; + + if(walled) wallify_map(); + + if(lit) { + for(i=1; ibg, + fg_typ = init_lev->fg; + boolean smooth = init_lev->smoothed, + join = init_lev->joined; + xchar lit = init_lev->lit, + walled = init_lev->walled; + int i; + + if(lit < 0) + lit = (rnd(1+abs(depth(&u.uz))) < 11 && rn2(77)) ? 1 : 0; + + new_locations = (char *)alloc((WIDTH+1) * HEIGHT); + + init_map(bg_typ); + init_fill(bg_typ, fg_typ); + + for(i = 0; i < N_P1_ITER; i++) + pass_one(bg_typ, fg_typ); + + for(i = 0; i < N_P2_ITER; i++) + pass_two(bg_typ, fg_typ); + + if(smooth) + for(i = 0; i < N_P3_ITER; i++) + pass_three(bg_typ, fg_typ); + + if(join) + join_map(bg_typ, fg_typ); + + finish_map(fg_typ, bg_typ, (boolean)lit, (boolean)walled); + /* a walled, joined level is cavernous, not mazelike -dlc */ + if (walled && join) { + level.flags.is_maze_lev = FALSE; + level.flags.is_cavernous_lev = TRUE; + } + free(new_locations); +} + +/*mkmap.c*/