1 | /* |
1 | /* |
2 | * static char *rcsid_random_map_c = |
2 | * static char *rcsid_random_map_c = |
3 | * "$Id: random_map.C,v 1.1 2006/08/13 17:16:03 elmex Exp $"; |
3 | * "$Id: random_map.C,v 1.2 2006/08/29 08:01:36 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
53 | mapstruct *theMap; |
53 | mapstruct *theMap; |
54 | int i; |
54 | int i; |
55 | |
55 | |
56 | /* pick a random seed, or use the one from the input file */ |
56 | /* pick a random seed, or use the one from the input file */ |
57 | if(RP->random_seed == 0) |
57 | if(RP->random_seed == 0) |
58 | RP->random_seed=time(0); |
58 | RP->random_seed=time(0); |
59 | |
59 | |
60 | SRANDOM(RP->random_seed); |
60 | SRANDOM(RP->random_seed); |
61 | |
61 | |
62 | write_map_parameters_to_string(buf, RP); |
62 | write_map_parameters_to_string(buf, RP); |
63 | |
63 | |
64 | if(RP->difficulty==0) { |
64 | if(RP->difficulty==0) { |
65 | RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */ |
65 | RP->difficulty = RP->dungeon_level; /* use this instead of a map difficulty */ |
66 | if (RP->difficulty_increase > 0.001) { |
66 | if (RP->difficulty_increase > 0.001) { |
67 | RP->difficulty = (int)((float)RP->dungeon_level * RP->difficulty_increase); |
67 | RP->difficulty = (int)((float)RP->dungeon_level * RP->difficulty_increase); |
68 | if (RP->difficulty < 1) RP->difficulty=1; |
68 | if (RP->difficulty < 1) RP->difficulty=1; |
69 | } |
69 | } |
70 | } |
70 | } |
71 | else |
71 | else |
72 | RP->difficulty_given=1; |
72 | RP->difficulty_given=1; |
73 | |
73 | |
74 | if(RP->Xsize<MIN_RANDOM_MAP_SIZE) RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM()%25 + 5; |
74 | if(RP->Xsize<MIN_RANDOM_MAP_SIZE) RP->Xsize = MIN_RANDOM_MAP_SIZE + RANDOM()%25 + 5; |
75 | if(RP->Ysize<MIN_RANDOM_MAP_SIZE) RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM()%25 + 5; |
75 | if(RP->Ysize<MIN_RANDOM_MAP_SIZE) RP->Ysize = MIN_RANDOM_MAP_SIZE + RANDOM()%25 + 5; |
76 | |
76 | |
77 | if(RP->expand2x > 0) { |
77 | if(RP->expand2x > 0) { |
78 | RP->Xsize /=2; |
78 | RP->Xsize /=2; |
79 | RP->Ysize /=2; |
79 | RP->Ysize /=2; |
80 | } |
80 | } |
81 | |
81 | |
82 | layout = layoutgen(RP); |
82 | layout = layoutgen(RP); |
83 | |
83 | |
84 | #ifdef RMAP_DEBUG |
84 | #ifdef RMAP_DEBUG |
… | |
… | |
141 | |
141 | |
142 | unblock_exits(theMap,layout,RP); |
142 | unblock_exits(theMap,layout,RP); |
143 | |
143 | |
144 | /* free the layout */ |
144 | /* free the layout */ |
145 | for(i=0;i<RP->Xsize;i++) |
145 | for(i=0;i<RP->Xsize;i++) |
146 | free(layout[i]); |
146 | free(layout[i]); |
147 | free(layout); |
147 | free(layout); |
148 | |
148 | |
149 | theMap->msg = strdup_local(buf); |
149 | theMap->msg = strdup_local(buf); |
150 | |
150 | |
151 | return theMap; |
151 | return theMap; |
… | |
… | |
157 | char **layoutgen(RMParms *RP) { |
157 | char **layoutgen(RMParms *RP) { |
158 | char **maze=0; |
158 | char **maze=0; |
159 | int oxsize= RP->Xsize, oysize=RP->Ysize; |
159 | int oxsize= RP->Xsize, oysize=RP->Ysize; |
160 | |
160 | |
161 | if(RP->symmetry == RANDOM_SYM) |
161 | if(RP->symmetry == RANDOM_SYM) |
162 | RP->symmetry_used = (RANDOM() % ( XY_SYM))+1; |
162 | RP->symmetry_used = (RANDOM() % ( XY_SYM))+1; |
163 | else RP->symmetry_used = RP->symmetry; |
163 | else RP->symmetry_used = RP->symmetry; |
164 | |
164 | |
165 | if(RP->symmetry_used==Y_SYM||RP->symmetry_used==XY_SYM) RP->Ysize = RP->Ysize/2+1; |
165 | if(RP->symmetry_used==Y_SYM||RP->symmetry_used==XY_SYM) RP->Ysize = RP->Ysize/2+1; |
166 | if(RP->symmetry_used==X_SYM||RP->symmetry_used==XY_SYM) RP->Xsize = RP->Xsize/2+1; |
166 | if(RP->symmetry_used==X_SYM||RP->symmetry_used==XY_SYM) RP->Xsize = RP->Xsize/2+1; |
167 | |
167 | |
… | |
… | |
173 | * layout style and then random layout style. Instead, figure out |
173 | * layout style and then random layout style. Instead, figure out |
174 | * the numeric layoutstyle, so there is only one area that actually |
174 | * the numeric layoutstyle, so there is only one area that actually |
175 | * calls the code to make the maps. |
175 | * calls the code to make the maps. |
176 | */ |
176 | */ |
177 | if(strstr(RP->layoutstyle,"onion")) { |
177 | if(strstr(RP->layoutstyle,"onion")) { |
178 | RP->map_layout_style = ONION_LAYOUT; |
178 | RP->map_layout_style = ONION_LAYOUT; |
179 | } |
179 | } |
180 | |
180 | |
181 | if(strstr(RP->layoutstyle,"maze")) { |
181 | if(strstr(RP->layoutstyle,"maze")) { |
182 | RP->map_layout_style = MAZE_LAYOUT; |
182 | RP->map_layout_style = MAZE_LAYOUT; |
183 | } |
183 | } |
184 | |
184 | |
185 | if(strstr(RP->layoutstyle,"spiral")) { |
185 | if(strstr(RP->layoutstyle,"spiral")) { |
186 | RP->map_layout_style = SPIRAL_LAYOUT; |
186 | RP->map_layout_style = SPIRAL_LAYOUT; |
187 | } |
187 | } |
188 | |
188 | |
189 | if(strstr(RP->layoutstyle,"rogue")) { |
189 | if(strstr(RP->layoutstyle,"rogue")) { |
190 | RP->map_layout_style = ROGUELIKE_LAYOUT; |
190 | RP->map_layout_style = ROGUELIKE_LAYOUT; |
191 | } |
191 | } |
192 | |
192 | |
193 | if(strstr(RP->layoutstyle,"snake")) { |
193 | if(strstr(RP->layoutstyle,"snake")) { |
194 | RP->map_layout_style = SNAKE_LAYOUT; |
194 | RP->map_layout_style = SNAKE_LAYOUT; |
195 | } |
195 | } |
196 | |
196 | |
197 | if(strstr(RP->layoutstyle,"squarespiral")) { |
197 | if(strstr(RP->layoutstyle,"squarespiral")) { |
198 | RP->map_layout_style = SQUARE_SPIRAL_LAYOUT; |
198 | RP->map_layout_style = SQUARE_SPIRAL_LAYOUT; |
199 | } |
199 | } |
200 | /* No style found - choose one ranomdly */ |
200 | /* No style found - choose one ranomdly */ |
201 | if (RP->map_layout_style == 0) { |
201 | if (RP->map_layout_style == 0) { |
202 | RP->map_layout_style = (RANDOM() % NROFLAYOUTS) + 1; |
202 | RP->map_layout_style = (RANDOM() % NROFLAYOUTS) + 1; |
203 | } |
203 | } |
204 | |
204 | |
205 | switch(RP->map_layout_style) { |
205 | switch(RP->map_layout_style) { |
206 | |
206 | |
207 | case ONION_LAYOUT: |
207 | case ONION_LAYOUT: |
208 | maze = map_gen_onion(RP->Xsize,RP->Ysize,RP->layoutoptions1,RP->layoutoptions2); |
208 | maze = map_gen_onion(RP->Xsize,RP->Ysize,RP->layoutoptions1,RP->layoutoptions2); |
209 | if(!(RANDOM()%3)&& !(RP->layoutoptions1 & OPT_WALLS_ONLY)) roomify_layout(maze,RP); |
209 | if(!(RANDOM()%3)&& !(RP->layoutoptions1 & OPT_WALLS_ONLY)) roomify_layout(maze,RP); |
210 | break; |
210 | break; |
211 | |
211 | |
212 | case MAZE_LAYOUT: |
212 | case MAZE_LAYOUT: |
213 | maze = maze_gen(RP->Xsize,RP->Ysize,RANDOM()%2); |
213 | maze = maze_gen(RP->Xsize,RP->Ysize,RANDOM()%2); |
214 | if(!(RANDOM()%2)) doorify_layout(maze,RP); |
214 | if(!(RANDOM()%2)) doorify_layout(maze,RP); |
215 | break; |
215 | break; |
216 | |
216 | |
217 | case SPIRAL_LAYOUT: |
217 | case SPIRAL_LAYOUT: |
218 | maze = map_gen_spiral(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
218 | maze = map_gen_spiral(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
219 | if(!(RANDOM()%2)) doorify_layout(maze,RP); |
219 | if(!(RANDOM()%2)) doorify_layout(maze,RP); |
220 | break; |
220 | break; |
221 | |
221 | |
222 | case ROGUELIKE_LAYOUT: |
222 | case ROGUELIKE_LAYOUT: |
223 | /* Don't put symmetry in rogue maps. There isn't much reason to |
223 | /* Don't put symmetry in rogue maps. There isn't much reason to |
224 | * do so in the first place (doesn't make it any more interesting), |
224 | * do so in the first place (doesn't make it any more interesting), |
225 | * but more importantly, the symmetry code presumes we are symmetrizing |
225 | * but more importantly, the symmetry code presumes we are symmetrizing |
226 | * spirals, or maps with lots of passages - making a symmetric rogue |
226 | * spirals, or maps with lots of passages - making a symmetric rogue |
227 | * map fails because its likely that the passages the symmetry process |
227 | * map fails because its likely that the passages the symmetry process |
228 | * creates may not connect the rooms. |
228 | * creates may not connect the rooms. |
229 | */ |
229 | */ |
230 | RP->symmetry_used = NO_SYM; |
230 | RP->symmetry_used = NO_SYM; |
231 | RP->Ysize = oysize; |
231 | RP->Ysize = oysize; |
232 | RP->Xsize = oxsize; |
232 | RP->Xsize = oxsize; |
233 | maze = roguelike_layout_gen(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
233 | maze = roguelike_layout_gen(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
234 | /* no doorifying... done already */ |
234 | /* no doorifying... done already */ |
235 | break; |
235 | break; |
236 | |
236 | |
237 | case SNAKE_LAYOUT: |
237 | case SNAKE_LAYOUT: |
238 | maze = make_snake_layout(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
238 | maze = make_snake_layout(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
239 | if(RANDOM()%2) roomify_layout(maze,RP); |
239 | if(RANDOM()%2) roomify_layout(maze,RP); |
240 | break; |
240 | break; |
241 | |
241 | |
242 | case SQUARE_SPIRAL_LAYOUT: |
242 | case SQUARE_SPIRAL_LAYOUT: |
243 | maze = make_square_spiral_layout(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
243 | maze = make_square_spiral_layout(RP->Xsize,RP->Ysize,RP->layoutoptions1); |
244 | if(RANDOM()%2) roomify_layout(maze,RP); |
244 | if(RANDOM()%2) roomify_layout(maze,RP); |
245 | break; |
245 | break; |
246 | } |
246 | } |
247 | |
247 | |
248 | maze = symmetrize_layout(maze, RP->symmetry_used,RP); |
248 | maze = symmetrize_layout(maze, RP->symmetry_used,RP); |
249 | #ifdef RMAP_DEBUG |
249 | #ifdef RMAP_DEBUG |
250 | dump_layout(maze,RP); |
250 | dump_layout(maze,RP); |
251 | #endif |
251 | #endif |
252 | if(RP->expand2x) { |
252 | if(RP->expand2x) { |
253 | maze = expand2x(maze,RP->Xsize,RP->Ysize); |
253 | maze = expand2x(maze,RP->Xsize,RP->Ysize); |
254 | RP->Xsize = RP->Xsize * 2 -1; |
254 | RP->Xsize = RP->Xsize * 2 -1; |
255 | RP->Ysize = RP->Ysize * 2 -1; |
255 | RP->Ysize = RP->Ysize * 2 -1; |
256 | } |
256 | } |
257 | return maze; |
257 | return maze; |
258 | } |
258 | } |
259 | |
259 | |
260 | |
260 | |
… | |
… | |
429 | if(sindex == 1) break; |
429 | if(sindex == 1) break; |
430 | if(sindex != 0) return -1; /* can't make horiz. wall here */ |
430 | if(sindex != 0) return -1; /* can't make horiz. wall here */ |
431 | if(maze[i1][y]!=0) return -1; /* can't make horiz. wall here */ |
431 | if(maze[i1][y]!=0) return -1; /* can't make horiz. wall here */ |
432 | length++; |
432 | length++; |
433 | } |
433 | } |
434 | |
434 | |
435 | for(i1=dx+1;i1<RP->Xsize-1;i1++) { |
435 | for(i1=dx+1;i1<RP->Xsize-1;i1++) { |
436 | int sindex=surround_flag2(maze,i1,y,RP); |
436 | int sindex=surround_flag2(maze,i1,y,RP); |
437 | if(sindex == 2) break; |
437 | if(sindex == 2) break; |
438 | if(sindex != 0) return -1; /* can't make horiz. wall here */ |
438 | if(sindex != 0) return -1; /* can't make horiz. wall here */ |
439 | if(maze[i1][y]!=0) return -1; /* can't make horiz. wall here */ |
439 | if(maze[i1][y]!=0) return -1; /* can't make horiz. wall here */ |
… | |
… | |
448 | if(sindex == 4) break; |
448 | if(sindex == 4) break; |
449 | if(sindex != 0) return -1; /* can't make vert. wall here */ |
449 | if(sindex != 0) return -1; /* can't make vert. wall here */ |
450 | if(maze[x][i1]!=0) return -1; /* can't make horiz. wall here */ |
450 | if(maze[x][i1]!=0) return -1; /* can't make horiz. wall here */ |
451 | length++; |
451 | length++; |
452 | } |
452 | } |
453 | |
453 | |
454 | for(i1=dy+1;i1<RP->Ysize-1;i1++) { |
454 | for(i1=dy+1;i1<RP->Ysize-1;i1++) { |
455 | int sindex=surround_flag2(maze,x,i1,RP); |
455 | int sindex=surround_flag2(maze,x,i1,RP); |
456 | if(sindex == 8) break; |
456 | if(sindex == 8) break; |
457 | if(sindex != 0) return -1; /* can't make verti. wall here */ |
457 | if(sindex != 0) return -1; /* can't make verti. wall here */ |
458 | if(maze[x][i1]!=0) return -1; /* can't make horiz. wall here */ |
458 | if(maze[x][i1]!=0) return -1; /* can't make horiz. wall here */ |
… | |
… | |
701 | int orientation_n, |
701 | int orientation_n, |
702 | int origin_x_n, |
702 | int origin_x_n, |
703 | int origin_y_n, |
703 | int origin_y_n, |
704 | int random_seed_n, |
704 | int random_seed_n, |
705 | int treasureoptions_n, |
705 | int treasureoptions_n, |
706 | float difficulty_increase) |
706 | float difficulty_increase) |
707 | { |
707 | { |
708 | |
708 | |
709 | char small_buf[256]; |
709 | char small_buf[256]; |
710 | sprintf(buf,"xsize %d\nysize %d\n",xsize_n,ysize_n); |
710 | sprintf(buf,"xsize %d\nysize %d\n",xsize_n,ysize_n); |
711 | |
711 | |