ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/room_gen_spiral.C
Revision: 1.14
Committed: Tue Apr 15 03:00:24 2008 UTC (16 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_5, rel-2_52
Changes since 1.13: +11 -5 lines
Log Message:
new logging thread, fix bugs in random map generator

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.11 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.7 *
4 root 1.12 * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 root 1.10 * Copyright (©) 1994,2007 Mark Wedel
6     * Copyright (©) 1992,2007 Frank Tore Johansen
7 pippijn 1.7 *
8 root 1.11 * Deliantra is free software: you can redistribute it and/or modify
9 pippijn 1.7 * it under the terms of the GNU General Public License as published by
10 root 1.10 * the Free Software Foundation, either version 3 of the License, or
11 pippijn 1.7 * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 root 1.10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 pippijn 1.7 * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19 root 1.10 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20     *
21 root 1.11 * The authors can be reached via e-mail to <support@deliantra.net>
22 pippijn 1.7 */
23 elmex 1.1
24     /* The onion room generator:
25     Onion rooms are like this:
26    
27     char **map_gen_spiral(int xsize, int ysize, int option);
28 root 1.14 */
29 elmex 1.1
30     #include <global.h>
31     #include <random_map.h>
32    
33 root 1.2 #define RANDOM_OPTIONS 0 /* Pick random options below */
34     #define REGULAR_SPIRAL 1 /* Regular spiral--distance increases constantly */
35     #define FINE_SPIRAL 2 /* uses the min. separation: most coiling */
36     #define FIT_SPIRAL 4 /* scale to a rectangular region, not square */
37     #define MAX_SPIRAL_OPT 8 /* this should be 2x the last real option */
38 elmex 1.1 #include <math.h>
39    
40     #ifndef MIN
41 root 1.2 # define MIN(x,y) (((x)<(y))? (x):(y))
42 elmex 1.1 #endif
43     #ifndef MAX
44 root 1.2 # define MAX(x,y) (((x)<(y))? (y):(x))
45 elmex 1.1 #endif
46    
47     #define MINDIST 3
48    
49     #define MAX_FINE .454545
50    
51 root 1.2 extern int surround_check (char **maze, int i, int j, int xsize, int ysize);
52    
53 root 1.13 void
54 root 1.14 map_gen_spiral (Layout maze, int option)
55 root 1.2 {
56     int i, j;
57     float parm = 0;
58     float x = 0, y = 0;
59     int ic, jc;
60     float SizeX, SizeY;
61     float xscale, yscale;
62 elmex 1.1
63 root 1.13 /* slightly easier to fill and then cut */
64     maze->clear ('#');
65 elmex 1.1
66 root 1.13 int xsize = maze->w;
67     int ysize = maze->h;
68 root 1.2
69     ic = xsize / 2;
70     jc = ysize / 2;
71     SizeX = xsize / 2 - 2;
72     SizeY = ysize / 2 - 2;
73 elmex 1.1
74     /* select random options if necessary */
75 root 1.2 if (option == 0)
76 root 1.12 option = rndm (MAX_SPIRAL_OPT);
77 elmex 1.1
78 root 1.2 /* the order in which these are evaluated matters */
79 elmex 1.1
80     /* the following two are mutually exclusive.
81     pick one if they're both set. */
82 root 1.2 if ((option & REGULAR_SPIRAL) && (option & FIT_SPIRAL))
83 elmex 1.1 {
84     /* unset REGULAR_SPIRAL half the time */
85 root 1.8 if (rndm (2) && (option & REGULAR_SPIRAL))
86 elmex 1.1 option -= REGULAR_SPIRAL;
87     else
88     option -= FIT_SPIRAL;
89     }
90    
91 root 1.2 xscale = yscale = MAX_FINE; /* fine spiral */
92    
93 elmex 1.1 /* choose the spiral pitch */
94 root 1.2 if (!(option & FINE_SPIRAL))
95     {
96 root 1.8 float pitch = (rndm (5)) / 10. + 10. / 22.;
97 root 1.2
98     xscale = yscale = pitch;
99     }
100    
101     if ((option & FIT_SPIRAL) && (xsize != ysize))
102     {
103     if (xsize > ysize)
104     xscale *= (float) xsize / (float) ysize;
105     else
106     yscale *= (float) ysize / (float) xsize;
107     }
108    
109     if (option & REGULAR_SPIRAL)
110     {
111     float scale = MIN (xscale, yscale);
112    
113     xscale = yscale = scale;
114     }
115 elmex 1.1
116     /* cut out the spiral */
117 root 1.2 while ((fabs (x) < SizeX) && (fabs (y) < SizeY))
118 elmex 1.1 {
119 root 1.2 x = parm * cos (parm) * xscale;
120     y = parm * sin (parm) * yscale;
121 root 1.12 maze[int (ic + x)][int (jc + y)] = '\0';
122 root 1.2 parm += 0.01;
123 root 1.13 }
124 root 1.2
125 root 1.12 maze[int (ic + x + 0.5)][int (jc + y + 0.5)] = '<';
126 elmex 1.1
127     /* cut out the center in a 2x2 and place the center and downexit */
128 root 1.2 maze[ic][jc + 1] = '>';
129     maze[ic][jc] = 'C';
130 elmex 1.1 }
131    
132     /* the following function connects disjoint spirals which may
133     result from the symmetrization process. */
134 root 1.2 void
135     connect_spirals (int xsize, int ysize, int sym, char **layout)
136     {
137     int i, j, ic = xsize / 2, jc = ysize / 2;
138 elmex 1.1
139 root 1.4 if (sym == SYMMETRY_X)
140 root 1.2 {
141     layout[ic][jc] = 0;
142 root 1.14
143 root 1.2 /* go left from map center */
144     for (i = ic - 1, j = jc; i > 0 && layout[i][j] == '#'; i--)
145     layout[i][j] = 0;
146 root 1.14
147 root 1.2 /* go right */
148     for (i = ic + 1, j = jc; i < xsize - 1 && layout[i][j] == '#'; i++)
149     layout[i][j] = 0;
150 elmex 1.1 }
151    
152 root 1.4 if (sym == SYMMETRY_Y)
153 root 1.2 {
154 root 1.14 layout[ic][jc] = 0;
155 root 1.2
156     /* go up */
157     for (i = ic, j = jc - 1; j > 0 && layout[i][j] == '#'; j--)
158     layout[i][j] = 0;
159 root 1.14
160 root 1.2 /* go down */
161     for (i = ic, j = jc + 1; j < ysize - 1 && layout[i][j] == '#'; j++)
162     layout[i][j] = 0;
163     }
164    
165 root 1.4 if (sym == SYMMETRY_XY)
166 root 1.2 {
167     /* go left from map center */
168     layout[ic][jc / 2] = 0;
169     layout[ic / 2][jc] = 0;
170     layout[ic][jc / 2 + jc] = 0;
171     layout[ic / 2 + ic][jc] = 0;
172 root 1.14
173 root 1.2 for (i = ic - 1, j = jc / 2; i > 0 && layout[i][j] == '#'; i--)
174     {
175     layout[i][j + jc] = 0;
176     layout[i][j] = 0;
177     }
178 root 1.14
179 root 1.2 /* go right */
180     for (i = ic + 1, j = jc / 2; i < xsize - 1 && layout[i][j] == '#'; i++)
181     {
182     layout[i][j + jc] = 0;
183     layout[i][j] = 0;
184     }
185 root 1.14
186 root 1.2 /* go up */
187     for (i = ic / 2, j = jc - 1; j > 0 && layout[i][j] == '#'; j--)
188     {
189     layout[i][j] = 0;
190     layout[i + ic][j] = 0;
191     }
192 root 1.14
193 root 1.2 /* go down */
194     for (i = ic / 2, j = jc + 1; j < ysize - 1 && layout[i][j] == '#'; j++)
195     {
196     layout[i][j] = 0;
197     layout[i + ic][j] = 0;
198     }
199    
200     }
201 elmex 1.1
202     /* get rid of bad doors. */
203 root 1.2 for (i = 0; i < xsize; i++)
204     for (j = 0; j < ysize; j++)
205     {
206     if (layout[i][j] == 'D')
207     { /* remove bad door. */
208     int si = surround_check (layout, i, j, xsize, ysize);
209    
210     if (si != 3 && si != 12)
211     {
212     layout[i][j] = 0;
213     /* back up and recheck any nearby doors */
214     i = 0;
215     j = 0;
216     }
217     }
218 elmex 1.1 }
219     }
220 root 1.14