Atrinik Server 2.5
random_maps/square_spiral.c
Go to the documentation of this file.
00001 /************************************************************************
00002 *            Atrinik, a Multiplayer Online Role Playing Game            *
00003 *                                                                       *
00004 *    Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team    *
00005 *                                                                       *
00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game)     *
00007 * and Crossfire (Multiplayer game for X-windows).                       *
00008 *                                                                       *
00009 * This program is free software; you can redistribute it and/or modify  *
00010 * it under the terms of the GNU General Public License as published by  *
00011 * the Free Software Foundation; either version 2 of the License, or     *
00012 * (at your option) any later version.                                   *
00013 *                                                                       *
00014 * This program is distributed in the hope that it will be useful,       *
00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00017 * GNU General Public License for more details.                          *
00018 *                                                                       *
00019 * You should have received a copy of the GNU General Public License     *
00020 * along with this program; if not, write to the Free Software           *
00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.             *
00022 *                                                                       *
00023 * The author can be reached at admin@atrinik.org                        *
00024 ************************************************************************/
00025 
00030 #include <global.h>
00031 
00038 void find_top_left_corner(char **maze, int *cx, int *cy)
00039 {
00040     (*cy)--;
00041 
00042     /* Find the top wall. */
00043     while (maze[*cx][*cy] == '\0')
00044     {
00045         (*cy)--;
00046     }
00047 
00048     /* Proceed right until a corner is detected */
00049     while (maze[*cx][*cy + 1] == '\0')
00050     {
00051         (*cx)++;
00052     }
00053 
00054     /* cx and cy should now be the top-right corner of the onion layer */
00055 }
00056 
00062 char **make_square_spiral_layout(int xsize, int ysize)
00063 {
00064     int i, j;
00065     int cx = 0, cy = 0;
00066     int tx, ty;
00067 
00068     /* Generate and allocate a doorless, centered onion */
00069     char **maze = map_gen_onion(xsize, ysize, OPT_CENTERED | OPT_NO_DOORS, 0);
00070 
00071     /* Find the layout center.  */
00072     for (i = 0; i < xsize; i++)
00073     {
00074         for (j = 0; j < ysize; j++)
00075         {
00076             if (maze[i][j] == 'C')
00077             {
00078                 cx = i;
00079                 cy = j;
00080             }
00081         }
00082     }
00083 
00084     tx = cx;
00085     ty = cy;
00086 
00087     while (1)
00088     {
00089         find_top_left_corner(maze, &tx, &ty);
00090 
00091         if (ty < 2 || tx < 2 || tx > xsize - 2 || ty > ysize - 2)
00092         {
00093             break;
00094         }
00095 
00096         /* make a vertical wall with a door */
00097         make_wall(maze, tx, ty - 1, 1);
00098 
00099         /* convert the door that make_wall puts here to a wall */
00100         maze[tx][ty - 1] = '#';
00101 
00102         /* make a doorway out of this layer */
00103         maze[tx - 1][ty] = 'D';
00104 
00105         /* walk left until we find the top-left corner */
00106         while (maze[tx - 1][ty])
00107         {
00108             tx--;
00109         }
00110 
00111         /* make a horizontal wall with a door */
00112         make_wall(maze, tx - 1, ty, 0);
00113 
00114         /* walk down until we find the bottom-left corner */
00115         while (maze[tx][ty + 1])
00116         {
00117             ty++;
00118         }
00119 
00120         /* make a vertical wall with a door */
00121         make_wall(maze, tx, ty + 1, 1);
00122 
00123         /* walk rightuntil we find the bottom-right corner */
00124         while (maze[tx + 1][ty])
00125         {
00126             tx++;
00127         }
00128 
00129         /* make a horizontal wall with a door */
00130         make_wall(maze, tx + 1, ty, 0);
00131 
00132         /* set up for next layer. */
00133         tx++;
00134     }
00135 
00136     /* place the exits.  */
00137     if (RANDOM() % 2)
00138     {
00139         maze[cx][cy] = '>';
00140         maze[xsize - 2][1] = '<';
00141     }
00142     else
00143     {
00144         maze[cx][cy] = '<';
00145         maze[xsize - 2][1] = '>';
00146     }
00147 
00148     return maze;
00149 }