--- deliantra/server/random_maps/rogue_layout.C 2007/01/18 19:42:10 1.5 +++ deliantra/server/random_maps/rogue_layout.C 2008/04/15 03:00:24 1.9 @@ -16,10 +16,9 @@ int rtype; /* circle or rectangular */ } Room; -static int roguelike_place_room (Room * Rooms, int xsize, int ysize, int nrooms); -static void roguelike_make_rooms (Room * Rooms, char **maze, int options); -static void roguelike_link_rooms (Room * Rooms, char **maze, int xsize, int ysize); - +static int roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms); +static void roguelike_make_rooms (Room *rooms, char **maze, int options); +static void roguelike_link_rooms (Room *rooms, char **maze, int xsize, int ysize); int surround_check (char **layout, int i, int j, int Xsize, int Ysize) @@ -32,93 +31,93 @@ if ((i > 0) && (layout[i - 1][j] != 0 && layout[i - 1][j] != '.')) surround_index += 1; + if ((i < Xsize - 1) && (layout[i + 1][j] != 0 && layout[i + 1][j] != '.')) surround_index += 2; + if ((j > 0) && (layout[i][j - 1] != 0 && layout[i][j - 1] != '.')) surround_index += 4; + if ((j < Ysize - 1) && (layout[i][j + 1] != 0 && layout[i][j + 1] != '.')) surround_index += 8; + return surround_index; } - /* actually make the layout: we work by a reduction process: * first we make everything a wall, then we remove areas to make rooms */ - -char ** -roguelike_layout_gen (int xsize, int ysize, int options) +void +roguelike_layout_gen (Layout maze, int options) { int i, j; - Room *Rooms = 0; Room *walk; int nrooms = 0; int tries = 0; - /* allocate that array, write walls everywhere up */ - char **maze = (char **) malloc (sizeof (char *) * xsize); - - for (i = 0; i < xsize; i++) - { - maze[i] = (char *) malloc (sizeof (char) * ysize); - for (j = 0; j < ysize; j++) - maze[i][j] = '#'; - } + int xsize = maze->w; + int ysize = maze->h; /* minimum room size is basically 5x5: if xsize/ysize is less than 3x that then hollow things out, stick in a stairsup and stairs down, and exit */ - if (xsize < 11 || ysize < 11) { - for (i = 1; i < xsize - 1; i++) - for (j = 1; j < ysize - 1; j++) - maze[i][j] = 0; - maze[(xsize - 1) / 2][(ysize - 1) / 2] = '>'; + maze->clear (); + maze->border (); + + maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; - return maze; + + return; } + maze->clear ('#'); + /* decide on the number of rooms */ nrooms = rndm (10) + 6; - Rooms = (Room *) calloc (nrooms + 1, sizeof (Room)); + Room *rooms = salloc0 (nrooms + 1); /* actually place the rooms */ i = 0; while (tries < 450 && i < nrooms) { /* try to place the room */ - if (!roguelike_place_room (Rooms, xsize, ysize, nrooms)) + if (!roguelike_place_room (rooms, xsize, ysize, nrooms)) tries++; else i++; } - if (i == 0) - { /* no can do! */ - for (i = 1; i < xsize - 1; i++) - for (j = 1; j < ysize - 1; j++) - maze[i][j] = 0; - maze[(xsize - 1) / 2][(ysize - 1) / 2] = '>'; - maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; - free (Rooms); - return maze; - } + if (i == 0) /* no can do! */ + { + maze->clear (); + maze->border (); + maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; + maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; + + sfree (rooms, nrooms + 1); + return; + } /* erase the areas occupied by the rooms */ - roguelike_make_rooms (Rooms, maze, options); + roguelike_make_rooms (rooms, maze, options); - roguelike_link_rooms (Rooms, maze, xsize, ysize); + roguelike_link_rooms (rooms, maze, xsize, ysize); /* put in the stairs */ - maze[Rooms->x][Rooms->y] = '<'; + maze[rooms->x][rooms->y] = '<'; + /* get the last one */ - for (walk = Rooms; walk->x != 0; walk++); + for (walk = rooms; walk->x != 0; walk++) + ; + /* back up one */ walk--; - if (walk == Rooms) + + if (walk == rooms) { /* In this case, there is only a single room. We don't want to * clobber are up exit (above) with a down exit, so put the @@ -139,6 +138,7 @@ { if (maze[i][j] == '.') maze[i][j] = 0; + if (maze[i][j] == 'D') { /* remove bad door. */ int si = surround_check (maze, i, j, xsize, ysize); @@ -153,16 +153,12 @@ } } - free (Rooms); - return maze; + sfree (rooms, nrooms + 1); } - - static int -roguelike_place_room (Room * Rooms, int xsize, int ysize, int nrooms) +roguelike_place_room (Room *rooms, int xsize, int ysize, int nrooms) { - int tx, ty; /* trial center locations */ int sx, sy; /* trial sizes */ int ax, ay; /* min coords of rect */ @@ -172,17 +168,15 @@ Room *walk; /* decide on the base x and y sizes */ - x_basesize = xsize / isqrt (nrooms); y_basesize = ysize / isqrt (nrooms); - - tx = RANDOM () % xsize; - ty = RANDOM () % ysize; + tx = rndm (xsize); + ty = rndm (ysize); /* generate a distribution of sizes centered about basesize */ - sx = (RANDOM () % x_basesize) + (RANDOM () % x_basesize) + (RANDOM () % x_basesize); - sy = (RANDOM () % y_basesize) + (RANDOM () % y_basesize) + (RANDOM () % y_basesize); + sx = rndm (x_basesize) + rndm (x_basesize) + rndm (x_basesize); + sy = rndm (y_basesize) + rndm (y_basesize) + rndm (y_basesize); sy = (int) (sy * .5); /* renormalize */ /* find the corners */ @@ -193,17 +187,15 @@ zy = ty + sy / 2 + sy % 2; /* check to see if it's in the map */ - if (zx > xsize - 1 || ax < 1) - return 0; - if (zy > ysize - 1 || ay < 1) - return 0; + if (zx > xsize - 1 || ax < 1) return 0; + if (zy > ysize - 1 || ay < 1) return 0; /* no small fish */ if (sx < 3 || sy < 3) return 0; /* check overlap with existing rooms */ - for (walk = Rooms; walk->x != 0; walk++) + for (walk = rooms; walk->x != 0; walk++) { int dx = abs (tx - walk->x); int dy = abs (ty - walk->y); @@ -215,7 +207,9 @@ /* if we've got here, presumably the room is OK. */ /* get a pointer to the first free room */ - for (walk = Rooms; walk->x != 0; walk++); + for (walk = rooms; walk->x != 0; walk++) + ; + walk->x = tx; walk->y = ty; walk->sx = sx; @@ -224,21 +218,20 @@ walk->ay = ay; walk->zx = zx; walk->zy = zy; - return 1; /* success */ + return 1; /* success */ } - /* write all the rooms into the maze */ static void -roguelike_make_rooms (Room * Rooms, char **maze, int options) +roguelike_make_rooms (Room *rooms, char **maze, int options) { int making_circle = 0; int i, j; int R; Room *walk; - for (walk = Rooms; walk->x != 0; walk++) + for (walk = rooms; walk->x != 0; walk++) { /* first decide what shape to make */ switch (options) @@ -262,26 +255,22 @@ /* enscribe a rectangle */ for (i = walk->ax; i < walk->zx; i++) for (j = walk->ay; j < walk->zy; j++) - { - if (!making_circle || ((int) (0.5 + hypot (walk->x - i, walk->y - j))) <= R) - maze[i][j] = '.'; - } + if (!making_circle || ((int) (0.5 + hypot (walk->x - i, walk->y - j))) <= R) + maze[i][j] = '.'; } } - - static void -roguelike_link_rooms (Room * Rooms, char **maze, int xsize, int ysize) +roguelike_link_rooms (Room *rooms, char **maze, int xsize, int ysize) { Room *walk; int i, j; /* link each room to the previous room */ - if (Rooms[1].x == 0) + if (rooms[1].x == 0) return; /* only 1 room */ - for (walk = Rooms + 1; walk->x != 0; walk++) + for (walk = rooms + 1; walk->x != 0; walk++) { int x1 = walk->x; int y1 = walk->y; @@ -400,3 +389,4 @@ } } +