--- deliantra/server/random_maps/rogue_layout.C 2008/04/11 21:09:53 1.7 +++ deliantra/server/random_maps/rogue_layout.C 2010/06/30 20:51:02 1.13 @@ -1,8 +1,30 @@ +/* + * This file is part of Deliantra, the Roguelike Realtime MMORPG. + * + * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) Crossfire Development Team (restored, original file without copyright notice) + * + * Deliantra is free software: you can redistribute it and/or modify it under + * the terms of the Affero GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the Affero GNU General Public License + * and the GNU General Public License along with this program. If not, see + * . + * + * The authors can be reached via e-mail to + */ /* generate a rogue/nethack-like layout */ #include #include -#include +#include typedef struct { @@ -29,52 +51,46 @@ 8 = wall below */ int surround_index = 0; - 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; + 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 */ -Maze -roguelike_layout_gen (int xsize, int ysize, int options) +void +roguelike_layout_gen (Layout maze, int options) { int i, j; Room *walk; int nrooms = 0; int tries = 0; - Maze maze (xsize, ysize); - - for (i = 0; i < xsize; i++) - 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->clear (); + maze->border (); maze[(xsize - 1) / 2][(ysize - 1) / 2 ] = '>'; maze[(xsize - 1) / 2][(ysize - 1) / 2 + 1] = '<'; - return maze; + return; } + maze->fill ('#'); + /* decide on the number of rooms */ - nrooms = rndm (10) + 6; + nrooms = rmg_rndm (10) + 6; Room *rooms = salloc0 (nrooms + 1); /* actually place the rooms */ @@ -88,20 +104,18 @@ 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; + 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 maze; + return; } - /* erase the areas occupied by the rooms */ roguelike_make_rooms (rooms, maze, options); @@ -155,7 +169,6 @@ } sfree (rooms, nrooms + 1); - return maze; } static int @@ -173,12 +186,12 @@ x_basesize = xsize / isqrt (nrooms); y_basesize = ysize / isqrt (nrooms); - tx = rndm (xsize); - ty = rndm (ysize); + tx = rmg_rndm (xsize); + ty = rmg_rndm (ysize); /* generate a distribution of sizes centered about basesize */ - sx = rndm (x_basesize) + rndm (x_basesize) + rndm (x_basesize); - sy = rndm (y_basesize) + rndm (y_basesize) + rndm (y_basesize); + sx = rmg_rndm (x_basesize) + rmg_rndm (x_basesize) + rmg_rndm (x_basesize); + sy = rmg_rndm (y_basesize) + rmg_rndm (y_basesize) + rmg_rndm (y_basesize); sy = (int) (sy * .5); /* renormalize */ /* find the corners */ @@ -245,7 +258,7 @@ making_circle = 1; break; default: - making_circle = ((rndm (3) == 0) ? 1 : 0); + making_circle = ((rmg_rndm (3) == 0) ? 1 : 0); break; } @@ -280,7 +293,7 @@ int y2 = (walk - 1)->y; int in_wall = 0; - if (rndm (2)) + if (rmg_rndm (2)) { /* connect in x direction first */ /* horizontal connect */ /* swap (x1,y1) (x2,y2) if necessary */ @@ -312,12 +325,16 @@ else if (maze[i][j] != 'D' && maze[i][j] != '.') maze[i][j] = 0; } - j = MIN (y1, y2); + + j = min (y1, y2); + if (maze[i][j] == '.') in_wall = 0; + if (maze[i][j] == 0 || maze[i][j] == '#') in_wall = 1; - for ( /* j set already */ ; j < MAX (y1, y2); j++) + + for ( /* j set already */ ; j < max (y1, y2); j++) { if (in_wall == 0 && maze[i][j] == '#') { @@ -365,12 +382,15 @@ maze[i][j] = 0; } - i = MIN (x1, x2); + i = min (x1, x2); + if (maze[i][j] == '.') in_wall = 0; + if (maze[i][j] == 0 || maze[i][j] == '#') in_wall = 1; - for ( /* i set already */ ; i < MAX (x1, x2); i++) + + for ( /* i set already */ ; i < max (x1, x2); i++) { if (in_wall == 0 && maze[i][j] == '#') {