Crossfire Server, Branch 1.12
R12190
|
00001 /* 00002 CrossFire, A Multiplayer game for X-windows 00003 00004 Copyright (C) 1994 Mark Wedel 00005 Copyright (C) 1992 Frank Tore Johansen 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 2 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00020 00021 The author can be reached via e-mail to mark@pyramid.com 00022 */ 00023 00024 00031 #include <global.h> 00032 #include <random_map.h> 00033 00038 #define RANDOM_OPTIONS 0 00039 #define REGULAR_SPIRAL 1 00040 #define FINE_SPIRAL 2 00041 #define FIT_SPIRAL 4 00042 #define MAX_SPIRAL_OPT 8 00044 00045 #include <math.h> 00046 00047 #ifndef MIN 00048 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 00049 #endif 00050 #ifndef MAX 00051 #define MAX(x, y) (((x) < (y)) ? (y) : (x)) 00052 #endif 00053 00054 #define MAX_FINE .454545 00055 00056 extern int surround_check(char **maze, int i, int j, int xsize, int ysize); 00057 00068 char **map_gen_spiral(int xsize, int ysize, int option) { 00069 int i, j; 00070 float parm = 0; 00071 float x = 0, y = 0; 00072 int ic, jc; 00073 float SizeX, SizeY; 00074 float xscale, yscale; 00075 00076 /* allocate that array, set it up */ 00077 char **maze = (char **)calloc(sizeof(char *), xsize); 00078 00079 for (i = 0; i < xsize; i++) { 00080 maze[i] = (char *)calloc(sizeof(char), ysize); 00081 } 00082 00083 /* slightly easier to fill and then cut */ 00084 for (i = 0; i < xsize; i++) 00085 for (j = 0; j < ysize; j++) 00086 maze[i][j] = '#'; 00087 00088 ic = xsize/2; 00089 jc = ysize/2; 00090 SizeX = xsize/2-2; 00091 SizeY = ysize/2-2; 00092 00093 /* select random options if necessary */ 00094 if (option == 0) { 00095 option = RANDOM()%MAX_SPIRAL_OPT; 00096 } 00097 00098 /* the order in which these are evaluated matters*/ 00099 00100 /* the following two are mutually exclusive. 00101 pick one if they're both set. */ 00102 if ((option®ULAR_SPIRAL) && (option&FIT_SPIRAL)) { 00103 /* unset REGULAR_SPIRAL half the time */ 00104 if (RANDOM()%2 && (option®ULAR_SPIRAL)) 00105 option -= REGULAR_SPIRAL; 00106 else 00107 option -= FIT_SPIRAL; 00108 } 00109 00110 xscale = yscale = MAX_FINE; /* fine spiral */ 00111 00112 /* choose the spiral pitch */ 00113 if (!(option&FINE_SPIRAL)) { 00114 float pitch = (RANDOM()%5)/10.+10./22.; 00115 00116 xscale = yscale = pitch; 00117 } 00118 00119 if ((option&FIT_SPIRAL) && (xsize != ysize)) { 00120 if (xsize > ysize) 00121 xscale *= (float)xsize/(float)ysize; 00122 else 00123 yscale *= (float)ysize/(float)xsize; 00124 } 00125 00126 if (option®ULAR_SPIRAL) { 00127 float scale = MIN(xscale, yscale); 00128 00129 xscale = yscale = scale; 00130 } 00131 00132 /* cut out the spiral */ 00133 while ((abs(x) < SizeX) && (abs(y) < SizeY)) { 00134 x = parm*cos(parm)*xscale; 00135 y = parm*sin(parm)*yscale; 00136 maze[(int)(ic+x)][(int)(jc+y)] = '\0'; 00137 parm += 0.01; 00138 }; 00139 00140 maze[(int)(ic+x+0.5)][(int)(jc+y+0.5)] = '<'; 00141 00142 /* cut out the center in a 2x2 and place the center and downexit */ 00143 maze[ic][jc+1] = '>'; 00144 maze[ic][jc] = 'C'; 00145 00146 return maze; 00147 } 00148 00159 void connect_spirals(int xsize, int ysize, int sym, char **layout) { 00160 int i, j, ic = xsize/2, jc = ysize/2; 00161 00162 if (sym == X_SYM) { 00163 layout[ic][jc] = 0; 00164 /* go left from map center */ 00165 for (i = ic-1, j = jc; i > 0 && layout[i][j] == '#'; i--) 00166 layout[i][j] = 0; 00167 /* go right */ 00168 for (i = ic+1, j = jc; i < xsize-1 && layout[i][j] == '#'; i++) 00169 layout[i][j] = 0; 00170 } 00171 00172 if (sym == Y_SYM) { 00173 layout[ic][jc] = 0; 00174 /* go up */ 00175 for (i = ic, j = jc-1; j > 0 && layout[i][j] == '#'; j--) 00176 layout[i][j] = 0; 00177 /* go down */ 00178 for (i = ic, j = jc+1; j < ysize-1 && layout[i][j] == '#'; j++) 00179 layout[i][j] = 0; 00180 } 00181 00182 if (sym == XY_SYM) { 00183 /* go left from map center */ 00184 layout[ic][jc/2] = 0; 00185 layout[ic/2][jc] = 0; 00186 layout[ic][jc/2+jc] = 0; 00187 layout[ic/2+ic][jc] = 0; 00188 for (i = ic-1, j = jc/2; i > 0 && layout[i][j] == '#'; i--) { 00189 layout[i][j+jc] = 0; 00190 layout[i][j] = 0; 00191 } 00192 /* go right */ 00193 for (i = ic+1, j = jc/2; i < xsize-1 && layout[i][j] == '#'; i++) { 00194 layout[i][j+jc] = 0; 00195 layout[i][j] = 0; 00196 } 00197 /* go up */ 00198 for (i = ic/2, j = jc-1; j > 0 && layout[i][j] == '#'; j--) { 00199 layout[i][j] = 0; 00200 layout[i+ic][j] = 0; 00201 } 00202 /* go down */ 00203 for (i = ic/2, j = jc+1; j < ysize-1 && layout[i][j] == '#'; j++) { 00204 layout[i][j] = 0; 00205 layout[i+ic][j] = 0; 00206 } 00207 } 00208 00209 /* get rid of bad doors. */ 00210 for (i = 0; i < xsize; i++) 00211 for (j = 0; j < ysize; j++) { 00212 if (layout[i][j] == 'D') { /* remove bad door. */ 00213 int si = surround_check(layout, i, j, xsize, ysize); 00214 if (si != 3 && si != 12) { 00215 layout[i][j] = 0; 00216 /* back up and recheck any nearby doors */ 00217 i = 0; 00218 j = 0; 00219 } 00220 } 00221 } 00222 }