/* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2001,2007 Mark Wedel & Crossfire Development Team * Copyright (©) 1992,2007 Frank Tore Johansen * * Deliantra is free software: you can redistribute it and/or modify * it under the terms of the 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 GNU General Public License * along with this program. If not, see . * * The authors can be reached via e-mail to */ /* peterm@langmuir.eecs.berkeley.edu: this function generates a random snake-type layout. input: xsize, ysize; output: a char** array with # and . for closed and open respectively. a char value of 0 represents a blank space: a '#' is a wall. */ #include #include "random_map.h" #include "rproto.h" /* These are some helper functions which help with manipulating a centered onion and turning it into a square spiral */ /* this starts from within a centered onion layer (or between two layers), and looks up until it finds a wall, and then looks right until it finds a vertical wall, i.e., the corner. It sets cx and cy to that. it also starts from cx and cy. */ void find_top_left_corner (char **maze, int *cx, int *cy) { --(*cy); /* find the top wall. */ while (maze[*cx][*cy] == 0) --(*cy); /* proceed right until a corner is detected */ while (maze[*cx][*cy + 1] == 0) ++(*cx); /* cx and cy should now be the top-right corner of the onion layer */ } void make_square_spiral_layout (Maze maze, int options) { int i, j; int cx, cy; int tx, ty; /* generate and allocate a doorless, centered onion */ map_gen_onion (maze, RMOPT_CENTERED | RMOPT_NO_DOORS, 0); int xsize = maze->w; int ysize = maze->h; /* find the layout center. */ cx = 0; cy = 0; for (i = 0; i < xsize; i++) for (j = 0; j < ysize; j++) if (maze[i][j] == 'C') { cx = i; cy = j; } tx = cx; ty = cy; for (;;) { find_top_left_corner (maze, &tx, &ty); if (ty < 2 || tx < 2 || tx > xsize - 2 || ty > ysize - 2) break; make_wall (maze, tx, ty - 1, 1); /* make a vertical wall with a door */ maze[tx][ty - 1] = '#'; /* convert the door that make_wall puts here to a wall */ maze[tx - 1][ty] = 'D'; /* make a doorway out of this layer */ /* walk left until we find the top-left corner */ while ((tx > 2) && maze[tx - 1, ty]) tx--; make_wall (maze, tx - 1, ty, 0); /* make a horizontal wall with a door */ /* walk down until we find the bottom-left corner */ while (((ty + 1) < ysize) && maze[tx][ty + 1]) ty++; make_wall (maze, tx, ty + 1, 1); /* make a vertical wall with a door */ /* walk rightuntil we find the bottom-right corner */ while (((tx + 1) < xsize) && maze[tx + 1][ty]) tx++; make_wall (maze, tx + 1, ty, 0); /* make a horizontal wall with a door */ tx++; /* set up for next layer. */ } /* place the exits. */ if (rndm (2)) { maze[cx][cy] = '>'; maze[xsize - 2][1] = '<'; } else { maze[cx][cy] = '<'; maze[xsize - 2][1] = '>'; } }