ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/random_maps/room_gen_onion.c
Revision: 1.2
Committed: Sun Aug 13 17:16:03 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.1: +1 -1 lines
State: FILE REMOVED
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# User Rev Content
1 root 1.1 /*
2     * static char *room_gen_onion_c =
3 elmex 1.2 * "$Id$";
4 root 1.1 */
5    
6     /*
7     CrossFire, A Multiplayer game for X-windows
8    
9     Copyright (C) 2001 Mark Wedel & Crossfire Development Team
10     Copyright (C) 1992 Frank Tore Johansen
11    
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16    
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     GNU General Public License for more details.
21    
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25    
26     The authors can be reached via e-mail at crossfire-devel@real-time.com
27     */
28    
29    
30     /* The onion room generator:
31     Onion rooms are like this:
32    
33     char **map_gen_onion(int xsize, int ysize, int option, int layers);
34    
35     like this:
36     regular random
37     centered, linear onion bottom/right centered, nonlinear
38    
39     ######################### #########################
40     # # # #
41     # ######## ########## # # #####################
42     # # # # # # #
43     # # ###### ######## # # # # #
44     # # # # # # # # ######## ########
45     # # # #### ###### # # # # # # #
46     # # # # # # # # # # # #
47     # # # ############ # # # # # # ########### ##
48     # # # # # # # # # # #
49     # # ################ # # # # # # #########
50     # # # # # # # # #
51     # #################### # # # # # #
52     # # # # # # # #
53     ######################### #########################
54    
55     */
56    
57    
58     int *free_x_list;
59     int *free_y_list;
60     #include <global.h>
61     #include <random_map.h>
62    
63     #ifndef MIN
64     #define MIN(x,y) (((x)<(y))? (x):(y))
65     #endif
66     void centered_onion(char **maze, int xsize, int ysize, int option, int layers);
67     void bottom_centered_onion(char **maze, int xsize, int ysize, int option, int layers);
68     void bottom_right_centered_onion(char **maze, int xsize, int ysize, int option, int layers);
69    
70    
71     void draw_onion(char **maze,float *xlocations,float *ylocations,int layers);
72     void make_doors(char **maze,float *xlocations,float *ylocations,int layers,int options);
73    
74     char **map_gen_onion(int xsize, int ysize, int option, int layers) {
75     int i,j;
76    
77     /* allocate that array, set it up */
78     char **maze = (char **)calloc(sizeof(char*),xsize);
79     for(i=0;i<xsize;i++) {
80     maze[i] = (char *) calloc(sizeof(char),ysize);
81     }
82    
83     /* pick some random options if option = 0 */
84     if(option == 0) {
85     switch(RANDOM()%3) {
86     case 0:
87     option |= OPT_CENTERED;
88     break;
89     case 1:
90     option |= OPT_BOTTOM_C;
91     break;
92     case 2:
93     option |= OPT_BOTTOM_R;
94     break;
95     }
96     if(RANDOM()%2) option |=OPT_LINEAR;
97     if(RANDOM()%2) option |=OPT_IRR_SPACE;
98     }
99    
100     /* write the outer walls, if appropriate. */
101     if(!(option & OPT_WALL_OFF )) {
102     for(i=0;i<xsize;i++)
103     maze[i][0] = maze[i][ysize-1] = '#';
104     for(j=0;j<ysize;j++)
105     maze[0][j] = maze[xsize-1][j] = '#';
106     };
107    
108     if(option & OPT_WALLS_ONLY) return maze;
109    
110     /* pick off the mutually exclusive options */
111     if(option & OPT_BOTTOM_R)
112     bottom_right_centered_onion(maze,xsize,ysize,option,layers);
113     else if(option & OPT_BOTTOM_C)
114     bottom_centered_onion(maze,xsize,ysize,option,layers);
115     else if(option & OPT_CENTERED)
116     centered_onion(maze,xsize,ysize,option,layers);
117    
118     return maze;
119     }
120    
121     void centered_onion(char **maze, int xsize, int ysize, int option, int layers) {
122     int i,maxlayers;
123     float *xlocations;
124     float *ylocations;
125    
126     maxlayers = (MIN(xsize,ysize)-2)/5;
127     if(!maxlayers) return; /* map too small to onionize */
128     if(layers > maxlayers) layers = maxlayers;
129     if(layers == 0) layers = (RANDOM() % maxlayers)+1;
130     xlocations = (float *) calloc(sizeof(float),2 * layers);
131     ylocations = (float *) calloc(sizeof(float),2 * layers);
132    
133    
134     /* place all the walls */
135     if(option & OPT_IRR_SPACE) /* randomly spaced */ {
136     int x_spaces_available, y_spaces_available;
137     /* the "extra" spaces available for spacing between layers */
138     x_spaces_available = (xsize -2) - 6*layers +1;
139     y_spaces_available = (ysize -2) - 6*layers +1;
140    
141    
142     /* pick an initial random pitch */
143     for(i=0;i<2*layers;i++) {
144     float xpitch=2,ypitch=2;
145     if(x_spaces_available>0)
146     xpitch = 2 + (RANDOM()%x_spaces_available +
147     RANDOM()%x_spaces_available +
148     RANDOM()%x_spaces_available)/3;
149    
150     if(y_spaces_available>0)
151     ypitch = 2 + (RANDOM()%y_spaces_available +
152     RANDOM()%y_spaces_available +
153     RANDOM()%y_spaces_available)/3;
154     xlocations[i] = ( (i>0)?xlocations[i-1]:0) + xpitch;
155     ylocations[i] = ( (i>0)?ylocations[i-1]:0) + ypitch;
156     x_spaces_available-=xpitch -2;
157     y_spaces_available-=ypitch -2;
158     }
159    
160     }
161     if(!(option&OPT_IRR_SPACE)){ /* evenly spaced */
162     float xpitch, ypitch; /* pitch of the onion layers */
163     xpitch = (xsize-2.0)/(2.0*layers+1);
164     ypitch = (ysize-2.0)/(2.0*layers+1);
165     xlocations[0] = xpitch;
166     ylocations[0] = ypitch;
167     for(i=1;i<2*layers;i++) {
168     xlocations[i] = xlocations[i-1] + xpitch;
169     ylocations[i] = ylocations[i-1] + ypitch;
170     }
171     }
172    
173     /* draw all the onion boxes. */
174    
175     draw_onion(maze,xlocations,ylocations,layers);
176     make_doors(maze,xlocations,ylocations,layers,option);
177    
178     }
179    
180     void bottom_centered_onion(char **maze, int xsize, int ysize, int option, int layers) {
181     int i,maxlayers;
182     float *xlocations;
183     float *ylocations;
184    
185     maxlayers = (MIN(xsize,ysize)-2)/5;
186     if(!maxlayers) return; /* map too small to onionize */
187     if(layers > maxlayers) layers = maxlayers;
188     if(layers == 0) layers = (RANDOM() % maxlayers)+1;
189     xlocations = (float *) calloc(sizeof(float),2 * layers);
190     ylocations = (float *) calloc(sizeof(float),2 * layers);
191    
192    
193     /* place all the walls */
194     if(option & OPT_IRR_SPACE) /* randomly spaced */ {
195     int x_spaces_available, y_spaces_available;
196     /* the "extra" spaces available for spacing between layers */
197     x_spaces_available = (xsize -2) - 6*layers +1;
198     y_spaces_available = (ysize -2) - 3*layers +1;
199    
200    
201     /* pick an initial random pitch */
202     for(i=0;i<2*layers;i++) {
203     float xpitch=2,ypitch=2;
204     if(x_spaces_available>0)
205     xpitch = 2 + (RANDOM()%x_spaces_available +
206     RANDOM()%x_spaces_available +
207     RANDOM()%x_spaces_available)/3;
208    
209     if(y_spaces_available>0)
210     ypitch = 2 + (RANDOM()%y_spaces_available +
211     RANDOM()%y_spaces_available +
212     RANDOM()%y_spaces_available)/3;
213     xlocations[i] = ( (i>0)?xlocations[i-1]:0) + xpitch;
214     if(i < layers) ylocations[i] = ( (i>0)?ylocations[i-1]:0) + ypitch;
215     else ylocations[i] = ysize-1;
216     x_spaces_available-=xpitch -2;
217     y_spaces_available-=ypitch -2;
218     }
219    
220     }
221     if(!(option&OPT_IRR_SPACE)){ /* evenly spaced */
222     float xpitch, ypitch; /* pitch of the onion layers */
223     xpitch = (xsize-2.0)/(2.0*layers+1);
224     ypitch = (ysize-2.0)/(layers+1);
225     xlocations[0] = xpitch;
226     ylocations[0] = ypitch;
227     for(i=1;i<2*layers;i++) {
228     xlocations[i] = xlocations[i-1] + xpitch;
229     if(i < layers) ylocations[i] = ylocations[i-1] + ypitch;
230     else ylocations[i]=ysize-1;
231     }
232     }
233    
234     /* draw all the onion boxes. */
235    
236     draw_onion(maze,xlocations,ylocations,layers);
237     make_doors(maze,xlocations,ylocations,layers,option);
238    
239     }
240    
241    
242     /* draw_boxes: draws the lines in the maze defining the onion layers */
243    
244     void draw_onion(char **maze,float *xlocations,float *ylocations, int layers) {
245     int i,j,l;
246    
247     for(l=0;l<layers;l++) {
248     int x1,x2,y1,y2;
249     /* horizontal segments */
250     y1 = (int)ylocations[l];
251     y2 = (int)ylocations[2*layers -l-1];
252     for(i=(int)xlocations[l];i<=(int)xlocations[2*layers -l -1];i++) {
253     maze[i][y1] = '#';
254     maze[i][y2] = '#';
255     }
256    
257     /* vertical segments */
258     x1 = (int)xlocations[l];
259     x2 = (int)xlocations[2*layers-l-1];
260     for(j=(int)ylocations[l];j<=(int)ylocations[2*layers -l -1];j++) {
261     maze[x1][j] = '#';
262     maze[x2][j] = '#';
263     }
264    
265     }
266     }
267    
268     void make_doors(char **maze, float *xlocations,float *ylocations,int layers,int options) {
269     int freedoms; /* number of different walls on which we could place a door */
270     int which_wall; /* left, 1, top, 2, right, 3, bottom 4 */
271     int l,x1=0,x2,y1=0,y2;
272     freedoms = 4; /* centered */
273     if(options & OPT_BOTTOM_C) freedoms=3;
274     if(options & OPT_BOTTOM_R) freedoms=2;
275     if(layers<= 0) return;
276     /* pick which wall will have a door. */
277     which_wall = RANDOM() %freedoms + 1;
278     for(l=0;l<layers;l++) {
279     if(options & OPT_LINEAR) { /* linear door placement. */
280     switch(which_wall) {
281     case 1: { /* left hand wall */
282     x1 = (int)xlocations[l];
283     y1 = (int)( (ylocations[l] + ylocations[2*layers-l-1])/2);
284     break;
285     }
286     case 2: { /* top wall placement */
287     x1 = (int)( (xlocations[l] + xlocations[2*layers-l-1])/2);
288     y1 = (int)ylocations[l];
289     break;
290     }
291     case 3: { /* right wall placement */
292     x1 = (int)xlocations[2*layers-l-1];
293     y1 = (int)( (ylocations[l] + ylocations[2*layers-l-1])/2);
294     break;
295     }
296     case 4: { /* bottom wall placement */
297     x1 = (int)( (xlocations[l] + xlocations[2*layers-l-1])/2);
298     y1 = (int)ylocations[2*layers -l -1];
299     break;
300     }
301     }
302     }
303     else { /* random door placement. */
304     which_wall=RANDOM()%freedoms + 1;
305     switch(which_wall) {
306     case 1: { /* left hand wall */
307     x1 = (int)xlocations[l];
308     y2 = ylocations[2*layers-l-1]-ylocations[l]-1;
309     if(y2 > 0) y1 = ylocations[l]+RANDOM() %y2 + 1;
310     else y1 = ylocations[l]+1;
311     break;
312     }
313     case 2: { /* top wall placement */
314     x2 = (int)( (-xlocations[l] + xlocations[2*layers-l-1]))-1;
315     if (x2 > 0) x1 = xlocations[l]+RANDOM()%x2 + 1;
316     else x1 = xlocations[l]+1;
317     y1 = (int)ylocations[l];
318     break;
319     }
320     case 3: { /* right wall placement */
321     x1 = (int)xlocations[2*layers-l-1];
322     y2 = (int)( (-ylocations[l] + ylocations[2*layers-l-1]))-1;
323     if(y2 > 0) y1 = ylocations[l]+RANDOM() %y2 + 1;
324     else y1 = ylocations[l]+1;
325    
326     break;
327     }
328     case 4: { /* bottom wall placement */
329     x2 = (int)( (-xlocations[l] + xlocations[2*layers-l-1]))-1;
330     if (x2 > 0) x1 = xlocations[l]+RANDOM()%x2 + 1;
331     else x1 = xlocations[l]+1;
332     y1 = (int)ylocations[2*layers-l-1];
333     break;
334     }
335    
336     }
337     }
338     if(options & OPT_NO_DOORS)
339     maze[x1][y1] = '#'; /* no door. */
340     else
341     maze[x1][y1] = 'D'; /* write the door */
342    
343     }
344     /* mark the center of the maze with a C */
345     l = layers -1;
346     x1 = (int) (xlocations[l] + xlocations[2*layers -l -1])/2;
347     y1 = (int) (ylocations[l] + ylocations[2*layers -l -1])/2;
348     maze[x1][y1] = 'C';
349    
350     /* not needed anymore */
351     free(xlocations);
352     free(ylocations);
353    
354     }
355    
356     void bottom_right_centered_onion(char **maze, int xsize, int ysize, int option, int layers){
357     int i,maxlayers;
358     float *xlocations;
359     float *ylocations;
360    
361     maxlayers = (MIN(xsize,ysize)-2)/5;
362     if(!maxlayers) return; /* map too small to onionize */
363     if(layers > maxlayers) layers = maxlayers;
364     if(layers == 0) layers = (RANDOM() % maxlayers)+1;
365     xlocations = (float *) calloc(sizeof(float),2 * layers);
366     ylocations = (float *) calloc(sizeof(float),2 * layers);
367    
368    
369     /* place all the walls */
370     if(option & OPT_IRR_SPACE) /* randomly spaced */ {
371     int x_spaces_available, y_spaces_available;
372     /* the "extra" spaces available for spacing between layers */
373     x_spaces_available = (xsize -2) - 3*layers +1;
374     y_spaces_available = (ysize -2) - 3*layers +1;
375    
376    
377     /* pick an initial random pitch */
378     for(i=0;i<2*layers;i++) {
379     float xpitch=2,ypitch=2;
380     if(x_spaces_available>0)
381     xpitch = 2 + (RANDOM()%x_spaces_available +
382     RANDOM()%x_spaces_available +
383     RANDOM()%x_spaces_available)/3;
384    
385     if(y_spaces_available>0)
386     ypitch = 2 + (RANDOM()%y_spaces_available +
387     RANDOM()%y_spaces_available +
388     RANDOM()%y_spaces_available)/3;
389     if(i < layers) xlocations[i] = ( (i>0)?xlocations[i-1]:0) + xpitch;
390     else xlocations[i] = xsize-1;
391    
392     if(i < layers) ylocations[i] = ( (i>0)?ylocations[i-1]:0) + ypitch;
393     else ylocations[i] = ysize-1;
394     x_spaces_available-=xpitch -2;
395     y_spaces_available-=ypitch -2;
396     }
397    
398     }
399     if(!(option&OPT_IRR_SPACE)){ /* evenly spaced */
400     float xpitch, ypitch; /* pitch of the onion layers */
401     xpitch = (xsize-2.0)/(2.0*layers+1);
402     ypitch = (ysize-2.0)/(layers+1);
403     xlocations[0] = xpitch;
404     ylocations[0] = ypitch;
405     for(i=1;i<2*layers;i++) {
406     if(i < layers) xlocations[i] = xlocations[i-1] + xpitch;
407     else xlocations[i]=xsize-1;
408     if(i < layers) ylocations[i] = ylocations[i-1] + ypitch;
409     else ylocations[i]=ysize-1;
410     }
411     }
412    
413     /* draw all the onion boxes. */
414    
415     draw_onion(maze,xlocations,ylocations,layers);
416     make_doors(maze,xlocations,ylocations,layers,option);
417    
418     }