--- deliantra/server/random_maps/rogue_layout.C 2006/09/10 16:06:37 1.3 +++ deliantra/server/random_maps/rogue_layout.C 2008/04/11 21:09:53 1.7 @@ -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) @@ -41,29 +40,22 @@ 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 ** +Maze roguelike_layout_gen (int xsize, int ysize, 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); + Maze maze (xsize, ysize); for (i = 0; i < xsize; i++) - { - maze[i] = (char *) malloc (sizeof (char) * ysize); - for (j = 0; j < ysize; j++) - maze[i][j] = '#'; - } + for (j = 0; j < ysize; j++) + maze[i][j] = '#'; /* minimum room size is basically 5x5: if xsize/ysize is less than 3x that then hollow things out, stick in @@ -74,21 +66,23 @@ 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 ] = '>'; maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; + return maze; } /* decide on the number of rooms */ - nrooms = RANDOM () % 10 + 6; - Rooms = (Room *) calloc (nrooms + 1, sizeof (Room)); + nrooms = rndm (10) + 6; + 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++; @@ -99,26 +93,32 @@ 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); + + maze [(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; + maze [(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; + + sfree (rooms, nrooms + 1); return maze; } /* 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 +139,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 +154,13 @@ } } - free (Rooms); + sfree (rooms, nrooms + 1); return maze; } - - 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 +170,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 +189,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 +209,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,34 +220,33 @@ 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) { - case 1: - making_circle = 0; - break; - case 2: - making_circle = 1; - break; - default: - making_circle = ((RANDOM () % 3 == 0) ? 1 : 0); - break; + case 1: + making_circle = 0; + break; + case 2: + making_circle = 1; + break; + default: + making_circle = ((rndm (3) == 0) ? 1 : 0); + break; } if (walk->sx < walk->sy) @@ -262,26 +257,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; @@ -289,7 +280,7 @@ int y2 = (walk - 1)->y; int in_wall = 0; - if (RANDOM () % 2) + if (rndm (2)) { /* connect in x direction first */ /* horizontal connect */ /* swap (x1,y1) (x2,y2) if necessary */ @@ -400,3 +391,4 @@ } } +