ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/room_gen_spiral.C
Revision: 1.5
Committed: Sun Dec 31 19:02:24 2006 UTC (17 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.4: +1 -0 lines
Log Message:
reindent, minor changes

File Contents

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