|
Atrinik Server 2.5
|
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 00036 #define RANDOM_OPTIONS 0 00037 00038 #define REGULAR_SPIRAL 1 00039 00040 #define FINE_SPIRAL 2 00041 00042 #define FIT_SPIRAL 4 00043 00044 #define MAX_SPIRAL_OPT 8 00045 00047 #include <math.h> 00048 00049 #ifndef MIN 00050 #define MIN(x, y) (((x) < (y)) ? (x) : (y)) 00051 #endif 00052 00053 #ifndef MAX 00054 #define MAX(x, y) (((x) < (y)) ? (y) : (x)) 00055 #endif 00056 00057 #define MINDIST 3 00058 00059 #define MAX_FINE .454545 00060 00061 extern int surround_check(char **maze, int i, int j, int xsize, int ysize); 00062 00069 char **map_gen_spiral(int xsize, int ysize, int option) 00070 { 00071 int i, j, ic, jc; 00072 float parm = 0, x = 0, y = 0, SizeX, SizeY, xscale,yscale; 00073 00074 /* Allocate that array, set it up */ 00075 char **maze = (char **) calloc(sizeof(char *), xsize); 00076 00077 for (i = 0; i < xsize; i++) 00078 { 00079 maze[i] = (char *) calloc(sizeof(char), ysize); 00080 } 00081 00082 /* Slightly easier to fill and then cut */ 00083 for (i = 0; i < xsize; i++) 00084 { 00085 for (j = 0; j < ysize; j++) 00086 { 00087 maze[i][j] = '#'; 00088 } 00089 } 00090 00091 ic = xsize / 2; 00092 jc = ysize / 2; 00093 00094 SizeX = (float) xsize / 2.0f - 2.0f; 00095 SizeY = (float) ysize / 2.0f - 2.0f; 00096 00097 /* Select random options if necessary */ 00098 if (option == 0) 00099 { 00100 option = RANDOM() % MAX_SPIRAL_OPT; 00101 } 00102 00103 /* the order in which these are evaluated matters */ 00104 00105 /* the following two are mutually exclusive. 00106 pick one if they're both set. */ 00107 if ((option & REGULAR_SPIRAL) && (option & FIT_SPIRAL)) 00108 { 00109 /* unset REGULAR_SPIRAL half the time */ 00110 if (RANDOM() % 2 && (option & REGULAR_SPIRAL)) 00111 { 00112 option -= REGULAR_SPIRAL; 00113 } 00114 else 00115 { 00116 option -= FIT_SPIRAL; 00117 } 00118 } 00119 00120 /* fine spiral */ 00121 xscale = yscale= ( float) MAX_FINE; 00122 00123 /* choose the spiral pitch */ 00124 if (!(option & FINE_SPIRAL)) 00125 { 00126 float pitch = (float) (RANDOM() % 5) / 10.0f + 10.0f / 22.0f; 00127 00128 xscale = yscale = pitch; 00129 } 00130 00131 if ((option & FIT_SPIRAL) && (xsize != ysize)) 00132 { 00133 if (xsize > ysize) 00134 { 00135 xscale *= (float) xsize / (float) ysize; 00136 } 00137 else 00138 { 00139 yscale *= (float) ysize / (float) xsize; 00140 } 00141 } 00142 00143 if (option & REGULAR_SPIRAL) 00144 { 00145 float scale = MIN(xscale, yscale); 00146 xscale = yscale = scale; 00147 } 00148 00149 /* cut out the spiral */ 00150 while ((FABS(x) < SizeX) && (FABS(y) < SizeY)) 00151 { 00152 x = parm * (float) cos((double) parm) * xscale; 00153 y = parm * (float) sin((double) parm) * yscale; 00154 00155 maze[(int) (ic + x)][(int) (jc + y)] = '\0'; 00156 00157 parm += 0.01f; 00158 } 00159 00160 maze[(int) (ic + x + 0.5)][(int) (jc + y + 0.5)] = '<'; 00161 00162 /* Cut out the center in a 2x2 and place the center and downexit */ 00163 maze[ic][jc + 1] = '>'; 00164 maze[ic][jc] = 'C'; 00165 00166 return maze; 00167 } 00168 00176 void connect_spirals(int xsize, int ysize, int sym, char **layout) 00177 { 00178 int i, j, ic = xsize / 2, jc = ysize / 2; 00179 00180 if (sym == X_SYM) 00181 { 00182 layout[ic][jc] = 0; 00183 00184 /* go left from map center */ 00185 for (i = ic - 1, j = jc; i > 0 && layout[i][j] == '#'; i--) 00186 { 00187 layout[i][j] = 0; 00188 } 00189 00190 /* go right */ 00191 for (i = ic + 1, j = jc; i < xsize - 1 && layout[i][j] == '#'; i++) 00192 { 00193 layout[i][j] = 0; 00194 } 00195 } 00196 00197 if (sym == Y_SYM) 00198 { 00199 layout[ic][jc] = 0; 00200 00201 /* go up */ 00202 for (i = ic, j = jc - 1; j > 0 && layout[i][j] == '#'; j--) 00203 { 00204 layout[i][j] = 0; 00205 } 00206 00207 /* go down */ 00208 for (i = ic, j = jc + 1; j < ysize - 1 && layout[i][j] == '#'; j++) 00209 { 00210 layout[i][j] = 0; 00211 } 00212 } 00213 00214 if (sym == XY_SYM) 00215 { 00216 layout[ic][jc / 2] = 0; 00217 layout[ic / 2][jc] = 0; 00218 layout[ic][jc / 2 + jc] = 0; 00219 layout[ic / 2 + ic][jc] = 0; 00220 00221 /* go left from map center */ 00222 for (i = ic - 1, j = jc / 2; i > 0 && layout[i][j] == '#'; i--) 00223 { 00224 layout[i][j + jc] = 0; 00225 layout[i][j] = 0; 00226 } 00227 00228 /* go right */ 00229 for (i = ic + 1, j = jc / 2; i < xsize - 1 && layout[i][j] == '#'; i++) 00230 { 00231 layout[i][j + jc] = 0; 00232 layout[i][j] = 0; 00233 } 00234 00235 /* go up */ 00236 for (i = ic / 2, j = jc - 1; j > 0 && layout[i][j] == '#'; j--) 00237 { 00238 layout[i][j] = 0; 00239 layout[i + ic][j] = 0; 00240 } 00241 00242 /* go down */ 00243 for (i = ic / 2, j = jc + 1; j < ysize - 1 && layout[i][j] == '#'; j++) 00244 { 00245 layout[i][j] = 0; 00246 layout[i + ic][j] = 0; 00247 } 00248 } 00249 00250 /* Get rid of bad doors. */ 00251 for (i = 0; i < xsize; i++) 00252 { 00253 for (j = 0; j < ysize; j++) 00254 { 00255 /* Remove bad door. */ 00256 if (layout[i][j] == 'D') 00257 { 00258 int si = surround_check(layout, i, j, xsize, ysize); 00259 00260 if (si != 3 && si != 12) 00261 { 00262 layout[i][j] = 0; 00263 00264 /* Back up and recheck any nearby doors */ 00265 i = 0; 00266 j = 0; 00267 } 00268 } 00269 } 00270 } 00271 }
1.7.4