--- deliantra/server/random_maps/rogue_layout.C 2007/01/27 02:19:37 1.6 +++ deliantra/server/random_maps/rogue_layout.C 2008/04/11 21:09:53 1.7 @@ -16,9 +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) @@ -40,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 @@ -73,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 = 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++; @@ -98,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 @@ -138,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); @@ -152,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 */ @@ -171,7 +170,6 @@ Room *walk; /* decide on the base x and y sizes */ - x_basesize = xsize / isqrt (nrooms); y_basesize = ysize / isqrt (nrooms); @@ -191,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); @@ -213,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; @@ -222,21 +220,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) @@ -260,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; @@ -398,3 +391,4 @@ } } +